5 * Schema API handling functions.
9 * @addtogroup schemaapi
14 * Indicates that a module has not been installed yet.
16 const SCHEMA_UNINSTALLED = -1;
19 * Returns an array of available schema versions for a module.
21 * @param string $module
25 * If the module has updates, an array of available updates sorted by
26 * version. Otherwise, FALSE.
28 function drupal_get_schema_versions($module) {
29 $updates = &drupal_static(__FUNCTION__, NULL);
30 if (!isset($updates[$module])) {
32 foreach (\Drupal::moduleHandler()->getModuleList() as $loaded_module => $filename) {
33 $updates[$loaded_module] = [];
36 // Prepare regular expression to match all possible defined hook_update_N().
37 $regexp = '/^(?<module>.+)_update_(?<version>\d+)$/';
38 $functions = get_defined_functions();
39 // Narrow this down to functions ending with an integer, since all
40 // hook_update_N() functions end this way, and there are other
41 // possible functions which match '_update_'. We use preg_grep() here
42 // instead of foreaching through all defined functions, since the loop
43 // through all PHP functions can take significant page execution time
44 // and this function is called on every administrative page via
45 // system_requirements().
46 foreach (preg_grep('/_\d+$/', $functions['user']) as $function) {
47 // If this function is a module update function, add it to the list of
49 if (preg_match($regexp, $function, $matches)) {
50 $updates[$matches['module']][] = $matches['version'];
53 // Ensure that updates are applied in numerical order.
54 foreach ($updates as &$module_updates) {
55 sort($module_updates, SORT_NUMERIC);
58 return empty($updates[$module]) ? FALSE : $updates[$module];
62 * Returns the currently installed schema version for a module.
64 * @param string $module
67 * Set to TRUE after installing or uninstalling an extension.
69 * Set to TRUE if you want to get information about all modules in the
73 * The currently installed schema version, or SCHEMA_UNINSTALLED if the
74 * module is not installed.
76 function drupal_get_installed_schema_version($module, $reset = FALSE, $array = FALSE) {
77 $versions = &drupal_static(__FUNCTION__, []);
84 if (!$versions = \Drupal::keyValue('system.schema')->getAll()) {
93 return isset($versions[$module]) ? $versions[$module] : SCHEMA_UNINSTALLED;
98 * Updates the installed version information for a module.
100 * @param string $module
102 * @param string $version
103 * The new schema version.
105 function drupal_set_installed_schema_version($module, $version) {
106 \Drupal::keyValue('system.schema')->set($module, $version);
107 // Reset the static cache of module schema versions.
108 drupal_get_installed_schema_version(NULL, TRUE);
112 * Creates all tables defined in a module's hook_schema().
114 * @param string $module
115 * The module for which the tables will be created.
117 function drupal_install_schema($module) {
118 $schema = drupal_get_module_schema($module);
119 _drupal_schema_initialize($schema, $module, FALSE);
121 foreach ($schema as $name => $table) {
122 db_create_table($name, $table);
127 * Removes all tables defined in a module's hook_schema().
129 * @param string $module
130 * The module for which the tables will be removed.
132 function drupal_uninstall_schema($module) {
133 $schema = drupal_get_module_schema($module);
134 _drupal_schema_initialize($schema, $module, FALSE);
136 foreach ($schema as $table) {
137 if (db_table_exists($table['name'])) {
138 db_drop_table($table['name']);
144 * Returns a module's schema.
146 * This function can be used to retrieve a schema specification in
147 * hook_schema(), so it allows you to derive your tables from existing
150 * @param string $module
151 * The module to which the table belongs.
152 * @param string $table
153 * The name of the table. If not given, the module's complete schema
156 function drupal_get_module_schema($module, $table = NULL) {
157 // Load the .install file to get hook_schema.
158 module_load_install($module);
159 $schema = \Drupal::moduleHandler()->invoke($module, 'schema');
162 if (isset($schema[$table])) {
163 return $schema[$table];
167 elseif (!empty($schema)) {
174 * Fills in required default values for table definitions from hook_schema().
176 * @param array $schema
177 * The schema definition array as it was returned by the module's
179 * @param string $module
180 * The module for which hook_schema() was invoked.
181 * @param bool $remove_descriptions
182 * (optional) Whether to additionally remove 'description' keys of all tables
183 * and fields to improve performance of serialize() and unserialize().
186 function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRUE) {
187 // Set the name and module key for all tables.
188 foreach ($schema as $name => &$table) {
189 if (empty($table['module'])) {
190 $table['module'] = $module;
192 if (!isset($table['name'])) {
193 $table['name'] = $name;
195 if ($remove_descriptions) {
196 unset($table['description']);
197 foreach ($table['fields'] as &$field) {
198 unset($field['description']);
205 * Typecasts values to proper datatypes.
207 * MySQL PDO silently casts, e.g. FALSE and '' to 0, when inserting the value
208 * into an integer column, but PostgreSQL PDO does not. Look up the schema
209 * information and use that to correctly typecast the value.
212 * An array describing the schema field info.
213 * @param mixed $value
214 * The value to be converted.
217 * The converted value.
219 function drupal_schema_get_field_value(array $info, $value) {
220 // Preserve legal NULL values.
221 if (isset($value) || !empty($info['not null'])) {
222 if ($info['type'] == 'int' || $info['type'] == 'serial') {
223 $value = (int) $value;
225 elseif ($info['type'] == 'float') {
226 $value = (float) $value;
228 elseif (!is_array($value)) {
229 $value = (string) $value;
236 * @} End of "addtogroup schemaapi".