annotate core/includes/schema.inc @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /**
Chris@0 4 * @file
Chris@0 5 * Schema API handling functions.
Chris@0 6 */
Chris@0 7
Chris@0 8 /**
Chris@0 9 * @addtogroup schemaapi
Chris@0 10 * @{
Chris@0 11 */
Chris@0 12
Chris@0 13 /**
Chris@0 14 * Indicates that a module has not been installed yet.
Chris@0 15 */
Chris@0 16 const SCHEMA_UNINSTALLED = -1;
Chris@0 17
Chris@0 18 /**
Chris@0 19 * Returns an array of available schema versions for a module.
Chris@0 20 *
Chris@0 21 * @param string $module
Chris@0 22 * A module name.
Chris@0 23 *
Chris@0 24 * @return array|bool
Chris@0 25 * If the module has updates, an array of available updates sorted by
Chris@0 26 * version. Otherwise, FALSE.
Chris@0 27 */
Chris@0 28 function drupal_get_schema_versions($module) {
Chris@0 29 $updates = &drupal_static(__FUNCTION__, NULL);
Chris@0 30 if (!isset($updates[$module])) {
Chris@0 31 $updates = [];
Chris@0 32 foreach (\Drupal::moduleHandler()->getModuleList() as $loaded_module => $filename) {
Chris@0 33 $updates[$loaded_module] = [];
Chris@0 34 }
Chris@0 35
Chris@0 36 // Prepare regular expression to match all possible defined hook_update_N().
Chris@0 37 $regexp = '/^(?<module>.+)_update_(?<version>\d+)$/';
Chris@0 38 $functions = get_defined_functions();
Chris@0 39 // Narrow this down to functions ending with an integer, since all
Chris@0 40 // hook_update_N() functions end this way, and there are other
Chris@0 41 // possible functions which match '_update_'. We use preg_grep() here
Chris@0 42 // instead of foreaching through all defined functions, since the loop
Chris@0 43 // through all PHP functions can take significant page execution time
Chris@0 44 // and this function is called on every administrative page via
Chris@0 45 // system_requirements().
Chris@0 46 foreach (preg_grep('/_\d+$/', $functions['user']) as $function) {
Chris@0 47 // If this function is a module update function, add it to the list of
Chris@0 48 // module updates.
Chris@0 49 if (preg_match($regexp, $function, $matches)) {
Chris@0 50 $updates[$matches['module']][] = $matches['version'];
Chris@0 51 }
Chris@0 52 }
Chris@0 53 // Ensure that updates are applied in numerical order.
Chris@0 54 foreach ($updates as &$module_updates) {
Chris@0 55 sort($module_updates, SORT_NUMERIC);
Chris@0 56 }
Chris@0 57 }
Chris@0 58 return empty($updates[$module]) ? FALSE : $updates[$module];
Chris@0 59 }
Chris@0 60
Chris@0 61 /**
Chris@0 62 * Returns the currently installed schema version for a module.
Chris@0 63 *
Chris@0 64 * @param string $module
Chris@0 65 * A module name.
Chris@0 66 * @param bool $reset
Chris@0 67 * Set to TRUE after installing or uninstalling an extension.
Chris@0 68 * @param bool $array
Chris@0 69 * Set to TRUE if you want to get information about all modules in the
Chris@0 70 * system.
Chris@0 71 *
Chris@0 72 * @return string|int
Chris@0 73 * The currently installed schema version, or SCHEMA_UNINSTALLED if the
Chris@0 74 * module is not installed.
Chris@0 75 */
Chris@0 76 function drupal_get_installed_schema_version($module, $reset = FALSE, $array = FALSE) {
Chris@0 77 $versions = &drupal_static(__FUNCTION__, []);
Chris@0 78
Chris@0 79 if ($reset) {
Chris@0 80 $versions = [];
Chris@0 81 }
Chris@0 82
Chris@0 83 if (!$versions) {
Chris@0 84 if (!$versions = \Drupal::keyValue('system.schema')->getAll()) {
Chris@0 85 $versions = [];
Chris@0 86 }
Chris@0 87 }
Chris@0 88
Chris@0 89 if ($array) {
Chris@0 90 return $versions;
Chris@0 91 }
Chris@0 92 else {
Chris@0 93 return isset($versions[$module]) ? $versions[$module] : SCHEMA_UNINSTALLED;
Chris@0 94 }
Chris@0 95 }
Chris@0 96
Chris@0 97 /**
Chris@0 98 * Updates the installed version information for a module.
Chris@0 99 *
Chris@0 100 * @param string $module
Chris@0 101 * A module name.
Chris@0 102 * @param string $version
Chris@0 103 * The new schema version.
Chris@0 104 */
Chris@0 105 function drupal_set_installed_schema_version($module, $version) {
Chris@0 106 \Drupal::keyValue('system.schema')->set($module, $version);
Chris@0 107 // Reset the static cache of module schema versions.
Chris@0 108 drupal_get_installed_schema_version(NULL, TRUE);
Chris@0 109 }
Chris@0 110
Chris@0 111 /**
Chris@0 112 * Creates all tables defined in a module's hook_schema().
Chris@0 113 *
Chris@0 114 * @param string $module
Chris@0 115 * The module for which the tables will be created.
Chris@0 116 */
Chris@0 117 function drupal_install_schema($module) {
Chris@0 118 $schema = drupal_get_module_schema($module);
Chris@0 119 _drupal_schema_initialize($schema, $module, FALSE);
Chris@0 120
Chris@0 121 foreach ($schema as $name => $table) {
Chris@0 122 \Drupal::database()->schema()->createTable($name, $table);
Chris@0 123 }
Chris@0 124 }
Chris@0 125
Chris@0 126 /**
Chris@0 127 * Removes all tables defined in a module's hook_schema().
Chris@0 128 *
Chris@0 129 * @param string $module
Chris@0 130 * The module for which the tables will be removed.
Chris@0 131 */
Chris@0 132 function drupal_uninstall_schema($module) {
Chris@17 133 $tables = drupal_get_module_schema($module);
Chris@17 134 _drupal_schema_initialize($tables, $module, FALSE);
Chris@17 135 $schema = \Drupal::database()->schema();
Chris@17 136 foreach ($tables as $table) {
Chris@17 137 if ($schema->tableExists($table['name'])) {
Chris@17 138 $schema->dropTable($table['name']);
Chris@0 139 }
Chris@0 140 }
Chris@0 141 }
Chris@0 142
Chris@0 143 /**
Chris@0 144 * Returns a module's schema.
Chris@0 145 *
Chris@0 146 * This function can be used to retrieve a schema specification in
Chris@0 147 * hook_schema(), so it allows you to derive your tables from existing
Chris@0 148 * specifications.
Chris@0 149 *
Chris@0 150 * @param string $module
Chris@0 151 * The module to which the table belongs.
Chris@0 152 * @param string $table
Chris@0 153 * The name of the table. If not given, the module's complete schema
Chris@0 154 * is returned.
Chris@0 155 */
Chris@0 156 function drupal_get_module_schema($module, $table = NULL) {
Chris@0 157 // Load the .install file to get hook_schema.
Chris@0 158 module_load_install($module);
Chris@0 159 $schema = \Drupal::moduleHandler()->invoke($module, 'schema');
Chris@0 160
Chris@0 161 if (isset($table)) {
Chris@0 162 if (isset($schema[$table])) {
Chris@0 163 return $schema[$table];
Chris@0 164 }
Chris@0 165 return [];
Chris@0 166 }
Chris@0 167 elseif (!empty($schema)) {
Chris@0 168 return $schema;
Chris@0 169 }
Chris@0 170 return [];
Chris@0 171 }
Chris@0 172
Chris@0 173 /**
Chris@0 174 * Fills in required default values for table definitions from hook_schema().
Chris@0 175 *
Chris@0 176 * @param array $schema
Chris@0 177 * The schema definition array as it was returned by the module's
Chris@0 178 * hook_schema().
Chris@0 179 * @param string $module
Chris@0 180 * The module for which hook_schema() was invoked.
Chris@0 181 * @param bool $remove_descriptions
Chris@0 182 * (optional) Whether to additionally remove 'description' keys of all tables
Chris@0 183 * and fields to improve performance of serialize() and unserialize().
Chris@0 184 * Defaults to TRUE.
Chris@0 185 */
Chris@0 186 function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRUE) {
Chris@0 187 // Set the name and module key for all tables.
Chris@0 188 foreach ($schema as $name => &$table) {
Chris@0 189 if (empty($table['module'])) {
Chris@0 190 $table['module'] = $module;
Chris@0 191 }
Chris@0 192 if (!isset($table['name'])) {
Chris@0 193 $table['name'] = $name;
Chris@0 194 }
Chris@0 195 if ($remove_descriptions) {
Chris@0 196 unset($table['description']);
Chris@0 197 foreach ($table['fields'] as &$field) {
Chris@0 198 unset($field['description']);
Chris@0 199 }
Chris@0 200 }
Chris@0 201 }
Chris@0 202 }
Chris@0 203
Chris@0 204 /**
Chris@16 205 * Typecasts values to proper data types.
Chris@0 206 *
Chris@0 207 * MySQL PDO silently casts, e.g. FALSE and '' to 0, when inserting the value
Chris@0 208 * into an integer column, but PostgreSQL PDO does not. Look up the schema
Chris@0 209 * information and use that to correctly typecast the value.
Chris@0 210 *
Chris@0 211 * @param array $info
Chris@0 212 * An array describing the schema field info.
Chris@0 213 * @param mixed $value
Chris@0 214 * The value to be converted.
Chris@0 215 *
Chris@0 216 * @return mixed
Chris@0 217 * The converted value.
Chris@0 218 */
Chris@0 219 function drupal_schema_get_field_value(array $info, $value) {
Chris@0 220 // Preserve legal NULL values.
Chris@0 221 if (isset($value) || !empty($info['not null'])) {
Chris@0 222 if ($info['type'] == 'int' || $info['type'] == 'serial') {
Chris@0 223 $value = (int) $value;
Chris@0 224 }
Chris@0 225 elseif ($info['type'] == 'float') {
Chris@0 226 $value = (float) $value;
Chris@0 227 }
Chris@0 228 elseif (!is_array($value)) {
Chris@0 229 $value = (string) $value;
Chris@0 230 }
Chris@0 231 }
Chris@0 232 return $value;
Chris@0 233 }
Chris@0 234
Chris@0 235 /**
Chris@0 236 * @} End of "addtogroup schemaapi".
Chris@0 237 */