/[drupal]/contributions/sandbox/crell/pdo/schema.inc
ViewVC logotype

Contents of /contributions/sandbox/crell/pdo/schema.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Fri Feb 15 05:46:13 2008 UTC (21 months, 1 week ago) by crell
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +35 -11 lines
File MIME type: text/x-php
- Table creation now works.
1 <?php
2
3 /**
4 * @defgroup schemaapi Schema API
5 * @{
6 *
7 * A Drupal schema definition is an array structure representing one or
8 * more tables and their related keys and indexes. A schema is defined by
9 * hook_schema(), which usually lives in a modulename.install file.
10 *
11 * By implementing hook_schema() and specifying the tables your module
12 * declares, you can easily create and drop these tables on all
13 * supported database engines. You don't have to deal with the
14 * different SQL dialects for table creation and alteration of the
15 * supported database engines.
16 *
17 * hook_schema() should return an array with a key for each table that
18 * the module defines.
19 *
20 * The following keys are defined:
21 *
22 * - 'description': A string describing this table and its purpose.
23 * References to other tables should be enclosed in
24 * curly-brackets. For example, the node_revisions table
25 * description field might contain "Stores per-revision title and
26 * body data for each {node}."
27 * - 'fields': An associative array ('fieldname' => specification)
28 * that describes the table's database columns. The specification
29 * is also an array. The following specification parameters are defined:
30 *
31 * - 'description': A string describing this field and its purpose.
32 * References to other tables should be enclosed in
33 * curly-brackets. For example, the node table vid field
34 * description might contain "Always holds the largest (most
35 * recent) {node_revisions}.vid value for this nid."
36 * - 'type': The generic datatype: 'varchar', 'int', 'serial'
37 * 'float', 'numeric', 'text', 'blob' or 'datetime'. Most types
38 * just map to the according database engine specific
39 * datatypes. Use 'serial' for auto incrementing fields. This
40 * will expand to 'int auto_increment' on mysql.
41 * - 'size': The data size: 'tiny', 'small', 'medium', 'normal',
42 * 'big'. This is a hint about the largest value the field will
43 * store and determines which of the database engine specific
44 * datatypes will be used (e.g. on MySQL, TINYINT vs. INT vs. BIGINT).
45 * 'normal', the default, selects the base type (e.g. on MySQL,
46 * INT, VARCHAR, BLOB, etc.).
47 *
48 * Not all sizes are available for all data types. See
49 * db_type_map() for possible combinations.
50 * - 'not null': If true, no NULL values will be allowed in this
51 * database column. Defaults to false.
52 * - 'default': The field's default value. The PHP type of the
53 * value matters: '', '0', and 0 are all different. If you
54 * specify '0' as the default value for a type 'int' field it
55 * will not work because '0' is a string containing the
56 * character "zero", not an integer.
57 * - 'length': The maximal length of a type 'varchar' or 'text'
58 * field. Ignored for other field types.
59 * - 'unsigned': A boolean indicating whether a type 'int', 'float'
60 * and 'numeric' only is signed or unsigned. Defaults to
61 * FALSE. Ignored for other field types.
62 * - 'precision', 'scale': For type 'numeric' fields, indicates
63 * the precision (total number of significant digits) and scale
64 * (decimal digits right of the decimal point). Both values are
65 * mandatory. Ignored for other field types.
66 *
67 * All parameters apart from 'type' are optional except that type
68 * 'numeric' columns must specify 'precision' and 'scale'.
69 *
70 * - 'primary key': An array of one or more key column specifiers (see below)
71 * that form the primary key.
72 * - 'unique key': An associative array of unique keys ('keyname' =>
73 * specification). Each specification is an array of one or more
74 * key column specifiers (see below) that form a unique key on the table.
75 * - 'indexes': An associative array of indexes ('indexame' =>
76 * specification). Each specification is an array of one or more
77 * key column specifiers (see below) that form an index on the
78 * table.
79 *
80 * A key column specifier is either a string naming a column or an
81 * array of two elements, column name and length, specifying a prefix
82 * of the named column.
83 *
84 * As an example, here is a SUBSET of the schema definition for
85 * Drupal's 'node' table. It show four fields (nid, vid, type, and
86 * title), the primary key on field 'nid', a unique key named 'vid' on
87 * field 'vid', and two indexes, one named 'nid' on field 'nid' and
88 * one named 'node_title_type' on the field 'title' and the first four
89 * bytes of the field 'type':
90 *
91 * @code
92 * $schema['node'] = array(
93 * 'fields' => array(
94 * 'nid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
95 * 'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
96 * 'type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
97 * 'title' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''),
98 * ),
99 * 'primary key' => array('nid'),
100 * 'unique keys' => array(
101 * 'vid' => array('vid')
102 * ),
103 * 'indexes' => array(
104 * 'nid' => array('nid'),
105 * 'node_title_type' => array('title', array('type', 4)),
106 * ),
107 * );
108 * @endcode
109 *
110 * @see drupal_install_schema()
111 */
112
113 abstract class DatabaseSchema {
114
115 protected $connection;
116
117 public function __construct($connection) {
118 $this->connection = $connection;
119 }
120
121 /**
122 * Check if a table exists.
123 */
124 abstract public function tableExists($table);
125
126 /**
127 * Check if a column exists in the given table.
128 */
129 abstract public function columnExists($table, $column);
130
131 /**
132 * This maps a generic data type in combination with its data size
133 * to the engine-specific data type.
134 */
135 abstract public function getFieldTypeMap();
136
137 /**
138 * Create an SQL string for a field to be used in table creation or alteration.
139 *
140 * Before passing a field out of a schema definition into this function it has
141 * to be processed by _db_process_field().
142 *
143 * @param $name
144 * Name of the field.
145 * @param $spec
146 * The field specification, as per the schema data structure format.
147 */
148 abstract protected function createFieldSql($name, $spec);
149
150 /**
151 * Set database-engine specific properties for a field.
152 *
153 * @param $field
154 * A field description array, as specified in the schema documentation.
155 */
156 abstract protected function processField($field);
157
158 abstract protected function createKeySql($fields);
159
160 abstract protected function createKeysSql($spec);
161
162 abstract protected function createKeysSqlHelper($fields);
163
164 /**
165 * Rename a table.
166 *
167 * @param $ret
168 * Array to which query results will be added.
169 * @param $table
170 * The table to be renamed.
171 * @param $new_name
172 * The new name for the table.
173 */
174 abstract public function renameTable(&$ret, $table, $new_name);
175
176 /**
177 * Drop a table.
178 *
179 * @param $ret
180 * Array to which query results will be added.
181 * @param $table
182 * The table to be dropped.
183 */
184 abstract public function dropTable(&$ret, $table);
185
186 /**
187 * Add a new field to a table.
188 *
189 * @param $ret
190 * Array to which query results will be added.
191 * @param $table
192 * Name of the table to be altered.
193 * @param $field
194 * Name of the field to be added.
195 * @param $spec
196 * The field specification array, as taken from a schema definition.
197 * The specification may also contain the key 'initial', the newly
198 * created field will be set to the value of the key in all rows.
199 * This is most useful for creating NOT NULL columns with no default
200 * value in existing tables.
201 * @param $keys_new
202 * Optional keys and indexes specification to be created on the
203 * table along with adding the field. The format is the same as a
204 * table specification but without the 'fields' element. If you are
205 * adding a type 'serial' field, you MUST specify at least one key
206 * or index including it in this array. @see db_change_field for more
207 * explanation why.
208 */
209 abstract public function addField(&$ret, $table, $field, $spec, $keys_new = array());
210
211 /**
212 * Drop a field.
213 *
214 * @param $ret
215 * Array to which query results will be added.
216 * @param $table
217 * The table to be altered.
218 * @param $field
219 * The field to be dropped.
220 */
221 abstract public function dropField(&$ret, $table, $field);
222
223 /**
224 * Set the default value for a field.
225 *
226 * @param $ret
227 * Array to which query results will be added.
228 * @param $table
229 * The table to be altered.
230 * @param $field
231 * The field to be altered.
232 * @param $default
233 * Default value to be set. NULL for 'default NULL'.
234 */
235 abstract public function fieldSetDefault(&$ret, $table, $field, $default);
236
237 /**
238 * Set a field to have no default value.
239 *
240 * @param $ret
241 * Array to which query results will be added.
242 * @param $table
243 * The table to be altered.
244 * @param $field
245 * The field to be altered.
246 */
247 abstract public function fieldSetNoDefault(&$ret, $table, $field);
248
249 /**
250 * Add a primary key.
251 *
252 * @param $ret
253 * Array to which query results will be added.
254 * @param $table
255 * The table to be altered.
256 * @param $fields
257 * Fields for the primary key.
258 */
259 abstract public function addPrimaryKey(&$ret, $table, $fields);
260
261 /**
262 * Drop the primary key.
263 *
264 * @param $ret
265 * Array to which query results will be added.
266 * @param $table
267 * The table to be altered.
268 */
269 abstract public function dropPrimaryKey(&$ret, $table);
270
271 /**
272 * Add a unique key.
273 *
274 * @param $ret
275 * Array to which query results will be added.
276 * @param $table
277 * The table to be altered.
278 * @param $name
279 * The name of the key.
280 * @param $fields
281 * An array of field names.
282 */
283 abstract public function addUniqueKey(&$ret, $table, $name, $fields);
284
285 /**
286 * Drop a unique key.
287 *
288 * @param $ret
289 * Array to which query results will be added.
290 * @param $table
291 * The table to be altered.
292 * @param $name
293 * The name of the key.
294 */
295 abstract public function dropUniqueKey(&$ret, $table, $name);
296
297 /**
298 * Add an index.
299 *
300 * @param $ret
301 * Array to which query results will be added.
302 * @param $table
303 * The table to be altered.
304 * @param $name
305 * The name of the index.
306 * @param $fields
307 * An array of field names.
308 */
309 abstract public function addIndex(&$ret, $table, $name, $fields);
310
311 /**
312 * Drop an index.
313 *
314 * @param $ret
315 * Array to which query results will be added.
316 * @param $table
317 * The table to be altered.
318 * @param $name
319 * The name of the index.
320 */
321 abstract public function dropIndex(&$ret, $table, $name);
322
323
324 /**
325 * Change a field definition.
326 *
327 * IMPORTANT NOTE: To maintain database portability, you have to explicitly
328 * recreate all indices and primary keys that are using the changed field.
329 *
330 * That means that you have to drop all affected keys and indexes with
331 * db_drop_{primary_key,unique_key,index}() before calling db_change_field().
332 * To recreate the keys and indices, pass the key definitions as the
333 * optional $keys_new argument directly to db_change_field().
334 *
335 * For example, suppose you have:
336 * @code
337 * $schema['foo'] = array(
338 * 'fields' => array(
339 * 'bar' => array('type' => 'int', 'not null' => TRUE)
340 * ),
341 * 'primary key' => array('bar')
342 * );
343 * @endcode
344 * and you want to change foo.bar to be type serial, leaving it as the
345 * primary key. The correct sequence is:
346 * @code
347 * db_drop_primary_key($ret, 'foo');
348 * db_change_field($ret, 'foo', 'bar', 'bar',
349 * array('type' => 'serial', 'not null' => TRUE),
350 * array('primary key' => array('bar')));
351 * @endcode
352 *
353 * The reasons for this are due to the different database engines:
354 *
355 * On PostgreSQL, changing a field definition involves adding a new field
356 * and dropping an old one which* causes any indices, primary keys and
357 * sequences (from serial-type fields) that use the changed field to be dropped.
358 *
359 * On MySQL, all type 'serial' fields must be part of at least one key
360 * or index as soon as they are created. You cannot use
361 * db_add_{primary_key,unique_key,index}() for this purpose because
362 * the ALTER TABLE command will fail to add the column without a key
363 * or index specification. The solution is to use the optional
364 * $keys_new argument to create the key or index at the same time as
365 * field.
366 *
367 * You could use db_add_{primary_key,unique_key,index}() in all cases
368 * unless you are converting a field to be type serial. You can use
369 * the $keys_new argument in all cases.
370 *
371 * @param $ret
372 * Array to which query results will be added.
373 * @param $table
374 * Name of the table.
375 * @param $field
376 * Name of the field to change.
377 * @param $field_new
378 * New name for the field (set to the same as $field if you don't want to change the name).
379 * @param $spec
380 * The field specification for the new field.
381 * @param $keys_new
382 * Optional keys and indexes specification to be created on the
383 * table along with changing the field. The format is the same as a
384 * table specification but without the 'fields' element.
385 */
386 abstract public function changeField(&$ret, $table, $field, $field_new, $spec, $keys_new = array());
387
388 /**
389 * Create a new table from a Drupal table definition.
390 *
391 * @param $ret
392 * Array to which query results will be added.
393 * @param $name
394 * The name of the table to create.
395 * @param $table
396 * A Schema API table definition array.
397 */
398 public function createTable(&$ret, $name, $table) {
399 $statements = $this->createTableSql($name, $table);
400 foreach ($statements as $statement) {
401 $ret[] = update_sql($statement);
402 }
403 }
404
405 /**
406 * Generate SQL to create a new table from a Drupal schema definition.
407 *
408 * @param $name
409 * The name of the table to create.
410 * @param $table
411 * A Schema API table definition array.
412 * @return
413 * An array of SQL statements to create the table.
414 */
415 abstract protected function createTableSql($name, $table);
416
417
418 /**
419 * Return an array of field names from an array of key/index column specifiers.
420 *
421 * This is usually an identity function but if a key/index uses a column prefix
422 * specification, this function extracts just the name.
423 *
424 * @param $fields
425 * An array of key/index column specifiers.
426 * @return
427 * An array of field names.
428 */
429 public function fieldNames($fields) {
430 $ret = array();
431 foreach ($fields as $field) {
432 if (is_array($field)) {
433 $ret[] = $field[0];
434 }
435 else {
436 $ret[] = $field;
437 }
438 }
439 return $ret;
440 }
441
442 }
443
444 /**
445 * @} End of "defgroup schemaapi".
446 */
447

  ViewVC Help
Powered by ViewVC 1.1.2