sqlsrv.install 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. use DatabaseConnection_sqlsrv as Connection;
  3. /**
  4. * Implements hook_requirements().
  5. *
  6. * @status: Needs global revision.
  7. */
  8. function sqlsrv_requirements($phase) {
  9. $requirements = array();
  10. if ($phase == 'runtime') {
  11. $connection = Database::getConnection();
  12. if ($connection->driver() == 'sqlsrv') {
  13. $options = $connection->getConnectionOptions();
  14. $schema = $connection->schema();
  15. $version = $schema->EngineVersion();
  16. // Find out where the driver is.
  17. $object = new ReflectionObject($connection);
  18. $driver_path = dirname($object->getFileName());
  19. include_once($driver_path . DIRECTORY_SEPARATOR . 'reflexiondata.inc');
  20. // Report PDO version
  21. $extensiondata = sqlsrv_REData(new ReflectionExtension('pdo_sqlsrv'));
  22. // Report database engine version
  23. $uinfo = $schema->UserOptions();
  24. $uinfo_parts = array_map(function($a, $b) { $a = strtoupper($a); $b = strtoupper($b); return "$a=$b"; }, array_keys($uinfo), $uinfo);
  25. $requirements['sqlsrv_edition'] = array(
  26. 'title' => t('MS SQL Server'),
  27. 'severity' => REQUIREMENT_INFO,
  28. 'description' => implode(' | ', $uinfo_parts),
  29. 'value' => t('@version [@level] @edition',
  30. array('@version' => $version['VERSION'],
  31. '@level' => $version['LEVEL'],
  32. '@edition' => $version['EDITION'])),
  33. );
  34. // Report database name and size.
  35. $size = $schema->getSizeInfo();
  36. $size_db = format_size($size->RowSizeMB * 1024 * 1024);
  37. $requirements['sqlsrv_database'] = array(
  38. 'title' => t('MS SQL Server Database'),
  39. 'severity' => REQUIREMENT_OK,
  40. 'value' => "{$options['database']} ({$size_db})",
  41. );
  42. // Make sure enough size is set for buffered queries
  43. $buffer_size = $extensiondata['getINIEntries']['pdo_sqlsrv.client_buffer_max_kb_size'];
  44. $buffer_size_min = (12240 * 2);
  45. $buffer_size_ok = $buffer_size >= $buffer_size_min;
  46. $requirements['sqlsrv_database'] = array(
  47. 'title' => t('MS SQL Server client buffer size'),
  48. 'severity' => $buffer_size_ok ? REQUIREMENT_OK : REQUIREMENT_WARNING,
  49. 'value' => "{$buffer_size} Kb",
  50. 'description' => "pdo_sqlsrv.client_buffer_max_kb_size setting must be of at least {$buffer_size_min}Kb. Currently {$buffer_size}Kb.",
  51. );
  52. // Is this a windows server?
  53. // Probably yes, because this is the MS SQL Server driver!
  54. $is_windows = strncasecmp(PHP_OS, 'WIN', 3) == 0;
  55. if ($is_windows) {
  56. // Test WinCache.
  57. $wincache_enabled = fastcache::Enabled();
  58. $wincache_module = module_exists('wincachedrupal');
  59. $requirements['sqlsrv_wincache_extension'] = array(
  60. 'title' => t('MS SQL Server Wincache extension'),
  61. 'value' => $wincache_module ? phpversion('wincache') : t('Not available'),
  62. 'severity' => $wincache_module ? REQUIREMENT_OK : REQUIREMENT_ERROR,
  63. 'description' => $wincache_module ? NULL : t('It is highly recommended to install and enable the <a href="http://sourceforge.net/projects/wincache/files/">Wincache PHP extension</a> on Windows Server systems to get the best performance from Drupal.'),
  64. );
  65. $requirements['sqlsrv_wincache_integration'] = array(
  66. 'title' => t('MS SQL Server Wincache integration'),
  67. 'value' => $wincache_enabled ? t('Available') : t('Not available'),
  68. 'severity' => $wincache_enabled ? REQUIREMENT_OK : REQUIREMENT_ERROR,
  69. 'description' => $wincache_enabled ? NULL : t('To enable the SQL Server driver wincache integration the fastcache backend and the locking backend must be set to use Wincache.'),
  70. );
  71. }
  72. // Report encoding for database.
  73. $collation = $schema->getCollation();
  74. $case_insensitive = stripos($collation, '_CI') !== FALSE;
  75. $requirements['sqlsrv_encoding_database'] = array(
  76. 'title' => t('MS SQL Server Database encoding'),
  77. 'severity' => $case_insensitive ? REQUIREMENT_OK : REQUIREMENT_ERROR,
  78. 'description' => $case_insensitive ? NULL : t('Drupal needs a default case insensitive collation database to run on.'),
  79. 'value' => t('@collation', array('@collation' => $collation)),
  80. );
  81. // Report PDO version, and require at lest 3.2 version.
  82. $version_ok = version_compare($extensiondata['getVersion'] , '3.2') >= 0;
  83. $requirements['sqlsrv_pdo'] = array(
  84. 'title' => t('MS SQL Server PDO extension'),
  85. 'severity' => $version_ok ? REQUIREMENT_OK : REQUIREMENT_ERROR,
  86. 'value' => t('@level', array('@level' => $extensiondata['getVersion'])),
  87. 'description' => t('Use at least the 3.2.0.0 version of the MSSQL PDO driver.')
  88. );
  89. // Make sure that the module's driver code is the same one as the effectively
  90. // deployed driver code....
  91. // TODO:// Nicer than just showing the error,
  92. // would be to offer the option to autodploy the driver...
  93. $deployed_ok = sqlsrv_verify_driver();
  94. $requirements['sqlsrv_deployed_files'] = array(
  95. 'title' => t('MSSQL Server Deployed Driver'),
  96. 'description' => t('Deployed driver match.'),
  97. 'severity' => $deployed_ok === TRUE ? REQUIREMENT_OK : REQUIREMENT_ERROR,
  98. 'description' => $deployed_ok === TRUE ? t('Deployed driver matches module version.') : t('The deployed driver files do not match the module driver.'),
  99. );
  100. }
  101. }
  102. return $requirements;
  103. }
  104. /**
  105. * Verify that the deployed driver is the same one as the module
  106. * version.
  107. *
  108. * @return bool
  109. */
  110. function sqlsrv_verify_driver() {
  111. // Location of the effective driver.
  112. $class = Connection::class;
  113. $reflector = new ReflectionClass($class);
  114. $driver_dir = dirname($reflector->getFileName());
  115. // Location for the module's driver.
  116. $module_dir = dirname(__FILE__) . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, array('sqlsrv'));
  117. return sqlsrv_directory_checksum($driver_dir) === sqlsrv_directory_checksum($module_dir);
  118. }
  119. /**
  120. * Calculate a unique identifier for a directory and it's contents
  121. * based on file sizes and names.
  122. *
  123. * TODO:// This thing will not notice files being moved around in directories
  124. * as long as they keep same name and size.
  125. *
  126. * @param string $directory
  127. * @return string
  128. */
  129. function sqlsrv_directory_checksum($directory) {
  130. $files = file_scan_directory($directory, '/\.*/i');
  131. $checksum = 0;
  132. $names = '';
  133. foreach ($files as $file) {
  134. $checksum += filesize($file->uri);
  135. $names .= $file->name;
  136. }
  137. return $checksum . '-' . md5($names);
  138. }