comparison core/includes/schema.inc @ 0:c75dbcec494b

Initial commit from drush-created site
author Chris Cannam
date Thu, 05 Jul 2018 14:24:15 +0000
parents
children a9cd425dd02b
comparison
equal deleted inserted replaced
-1:000000000000 0:c75dbcec494b
1 <?php
2
3 /**
4 * @file
5 * Schema API handling functions.
6 */
7
8 /**
9 * @addtogroup schemaapi
10 * @{
11 */
12
13 /**
14 * Indicates that a module has not been installed yet.
15 */
16 const SCHEMA_UNINSTALLED = -1;
17
18 /**
19 * Returns an array of available schema versions for a module.
20 *
21 * @param string $module
22 * A module name.
23 *
24 * @return array|bool
25 * If the module has updates, an array of available updates sorted by
26 * version. Otherwise, FALSE.
27 */
28 function drupal_get_schema_versions($module) {
29 $updates = &drupal_static(__FUNCTION__, NULL);
30 if (!isset($updates[$module])) {
31 $updates = [];
32 foreach (\Drupal::moduleHandler()->getModuleList() as $loaded_module => $filename) {
33 $updates[$loaded_module] = [];
34 }
35
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
48 // module updates.
49 if (preg_match($regexp, $function, $matches)) {
50 $updates[$matches['module']][] = $matches['version'];
51 }
52 }
53 // Ensure that updates are applied in numerical order.
54 foreach ($updates as &$module_updates) {
55 sort($module_updates, SORT_NUMERIC);
56 }
57 }
58 return empty($updates[$module]) ? FALSE : $updates[$module];
59 }
60
61 /**
62 * Returns the currently installed schema version for a module.
63 *
64 * @param string $module
65 * A module name.
66 * @param bool $reset
67 * Set to TRUE after installing or uninstalling an extension.
68 * @param bool $array
69 * Set to TRUE if you want to get information about all modules in the
70 * system.
71 *
72 * @return string|int
73 * The currently installed schema version, or SCHEMA_UNINSTALLED if the
74 * module is not installed.
75 */
76 function drupal_get_installed_schema_version($module, $reset = FALSE, $array = FALSE) {
77 $versions = &drupal_static(__FUNCTION__, []);
78
79 if ($reset) {
80 $versions = [];
81 }
82
83 if (!$versions) {
84 if (!$versions = \Drupal::keyValue('system.schema')->getAll()) {
85 $versions = [];
86 }
87 }
88
89 if ($array) {
90 return $versions;
91 }
92 else {
93 return isset($versions[$module]) ? $versions[$module] : SCHEMA_UNINSTALLED;
94 }
95 }
96
97 /**
98 * Updates the installed version information for a module.
99 *
100 * @param string $module
101 * A module name.
102 * @param string $version
103 * The new schema version.
104 */
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);
109 }
110
111 /**
112 * Creates all tables defined in a module's hook_schema().
113 *
114 * @param string $module
115 * The module for which the tables will be created.
116 */
117 function drupal_install_schema($module) {
118 $schema = drupal_get_module_schema($module);
119 _drupal_schema_initialize($schema, $module, FALSE);
120
121 foreach ($schema as $name => $table) {
122 \Drupal::database()->schema()->createTable($name, $table);
123 }
124 }
125
126 /**
127 * Removes all tables defined in a module's hook_schema().
128 *
129 * @param string $module
130 * The module for which the tables will be removed.
131 */
132 function drupal_uninstall_schema($module) {
133 $schema = drupal_get_module_schema($module);
134 _drupal_schema_initialize($schema, $module, FALSE);
135
136 foreach ($schema as $table) {
137 if (db_table_exists($table['name'])) {
138 db_drop_table($table['name']);
139 }
140 }
141 }
142
143 /**
144 * Returns a module's schema.
145 *
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
148 * specifications.
149 *
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
154 * is returned.
155 */
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');
160
161 if (isset($table)) {
162 if (isset($schema[$table])) {
163 return $schema[$table];
164 }
165 return [];
166 }
167 elseif (!empty($schema)) {
168 return $schema;
169 }
170 return [];
171 }
172
173 /**
174 * Fills in required default values for table definitions from hook_schema().
175 *
176 * @param array $schema
177 * The schema definition array as it was returned by the module's
178 * hook_schema().
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().
184 * Defaults to TRUE.
185 */
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;
191 }
192 if (!isset($table['name'])) {
193 $table['name'] = $name;
194 }
195 if ($remove_descriptions) {
196 unset($table['description']);
197 foreach ($table['fields'] as &$field) {
198 unset($field['description']);
199 }
200 }
201 }
202 }
203
204 /**
205 * Typecasts values to proper data types.
206 *
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.
210 *
211 * @param array $info
212 * An array describing the schema field info.
213 * @param mixed $value
214 * The value to be converted.
215 *
216 * @return mixed
217 * The converted value.
218 */
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;
224 }
225 elseif ($info['type'] == 'float') {
226 $value = (float) $value;
227 }
228 elseif (!is_array($value)) {
229 $value = (string) $value;
230 }
231 }
232 return $value;
233 }
234
235 /**
236 * @} End of "addtogroup schemaapi".
237 */