A quick thought in terms of the Schema API and writing system/module updates: As far as I understand, on e shouldn't use functions like drupal_install_schema() in update functions since one cannot rely upon which version of the schema presently exists int he .schema file. To me this suggests that there should be a way having several different schema in the .schema file with different version numbers. Then functions like drupal_install_schema() could take an optional argument for the schema version. Does that make sense? -Peter
"Peter Wolanin" <pwolanin@gmail.com> writes:
To me this suggests that there should be a way having several different schema in the .schema file with different version numbers.
Yes. I intentionally left this out because I wasn't sure of the best way to do it (or even a necessarily good way). Some options: 1. hook_schema_1(), hook_schema_2(), etc. 2. hook_schema($version = SCHEMA_CURRENT) 3. Optionally encoding a version number with each element of the schema; "this field was added in version 3", "this index was removed in version 4." I kinda like #2 the best, but #1 may make more sense with our current hook_update_N() system. (#3 has the "advantage" that we might be able to automatically update from one version to the next, but it could also be very complicated.) Perhaps hook_schema_N() and hook_update_N() should be tied together in some way so that the new schema and the upgrade path to get to it from the previous one are always specified together. Feel free to make a proposal. :-) Thanks, Barry
I kinda like #2 the best, but #1 may make more sense with our current hook_update_N() system. (#3 has the "advantage" that we might be able to automatically update from one version to the next, but it could also be very complicated.) Perhaps hook_schema_N() and hook_update_N() should be tied together in some way so that the new schema and the upgrade path to get to it from the previous one are always specified together.
Have you considered querying the database to check what fields are already there and add the missing ones based on the latest schema? The problem is what to do when a field changes type / name between two versions of the schema. But does it happen often? This would make it very easy for module developpers : simply add the field in the schema, and the schema api take cares of adding the required fields. More complex operations could be handled with #1. We did this with our cms, and it worked great. (this way you have schema versioned like code in cvs). I would not touch the fields found in the DB and not found in the schema, just in case :-) Philippe
Barry
Maybe we can borrow from the rails world and base this versioning on rake's db migrations[0]? blake hall [0] http://wiki.rubyonrails.org/rails/pages/UsingMigrations On Jun 11, 2007, at 1:24 PM, Philippe Jadin wrote:
I kinda like #2 the best, but #1 may make more sense with our current hook_update_N() system. (#3 has the "advantage" that we might be able to automatically update from one version to the next, but it could also be very complicated.) Perhaps hook_schema_N() and hook_update_N() should be tied together in some way so that the new schema and the upgrade path to get to it from the previous one are always specified together.
Have you considered querying the database to check what fields are already there and add the missing ones based on the latest schema?
The problem is what to do when a field changes type / name between two versions of the schema. But does it happen often?
This would make it very easy for module developpers : simply add the field in the schema, and the schema api take cares of adding the required fields. More complex operations could be handled with #1. We did this with our cms, and it worked great. (this way you have schema versioned like code in cvs). I would not touch the fields found in the DB and not found in the schema, just in case :-)
Philippe
Barry
On 11 Jun 2007 00:03:03 -0400, Barry Jaspan <barry@jaspan.org> wrote:
"Peter Wolanin" <pwolanin@gmail.com> writes:
To me this suggests that there should be a way having several different schema in the .schema file with different version numbers.
Yes. I intentionally left this out because I wasn't sure of the best
I think that a combination of #1 and #2 might make sense: For each different schema there is a convention to have a function like hook_schema_6000(). hook_schema($version = NULL) can then just dispatch the right version. The developer has to manually set in the hook_schema code which is the most recent - i.e. what is returned if $version == NULL, and which to return for any other value of $version. A potential advantage of this - if you look in the system table and see that schema == 6023, but update 6023 did not change the table structure ()see, for example, function system_update_1002()), hook_schema can easily return the same schema for hook_schema(6022) or hook_schema(6023) i.e. "return hook_schema_6022();". -Peter
way to do it (or even a necessarily good way). Some options:
1. hook_schema_1(), hook_schema_2(), etc.
2. hook_schema($version = SCHEMA_CURRENT)
3. Optionally encoding a version number with each element of the schema; "this field was added in version 3", "this index was removed in version 4."
I kinda like #2 the best, but #1 may make more sense with our current hook_update_N() system. (#3 has the "advantage" that we might be able to automatically update from one version to the next, but it could also be very complicated.) Perhaps hook_schema_N() and hook_update_N() should be tied together in some way so that the new schema and the upgrade path to get to it from the previous one are always specified together.
Feel free to make a proposal. :-)
Thanks,
Barry
On 11 Jun 2007 00:03:03 -0400, Barry Jaspan <barry@jaspan.org> wrote:
2. hook_schema($version = SCHEMA_CURRENT)
I kinda like #2 the best, but #1 may make more sense with our current hook_update_N() system. (#3 has the "advantage" that we might be able to automatically update from one version to the next, but it could also be very complicated.) Perhaps hook_schema_N() and hook_update_N() should be tied together in some way so that the new schema and the upgrade path to get to it from the previous one are always specified together.
The problem I see with #2 is that the .install files would quickly become huge. I'm imagining hook_schema() would have a big case statement with a complete copy of every version. I guess we don't need to load the .schema files often but it seems like it'd cause some memory issues when several are loaded. andrew
Well, these files are pretty small compared to all the .module and .inc files, so I don't think that's an issue. One could minimize the code by making changes to the array rather than re-declaring the whole thing. Something like: node_schema_6000() { $schema = node_schema_5000(); $schema['node']['fields']['newcolumn'] = array('type' => 'int', 'not null' => TRUE, 'default' => 1); return $schema; } node_schema_5000() { $schema['node'] = array( // define schema here ); return $schema; } -Peter On 6/12/07, andrew morton <drewish@katherinehouse.com> wrote:
The problem I see with #2 is that the .install files would quickly become huge. I'm imagining hook_schema() would have a big case statement with a complete copy of every version. I guess we don't need to load the .schema files often but it seems like it'd cause some memory issues when several are loaded.
andrew
One could minimize the code by making changes to the array rather than re-declaring the whole thing. Something like:
node_schema_6000() { $schema = node_schema_5000();
$schema['node']['fields']['newcolumn'] = array('type' => 'int', 'not null' => TRUE, 'default' => 1);
return $schema; }
The downside here is that there is nowhere a developer can look to find the current node_schema. Well, actually, schema.module can easily provide this, but (I suspect) developers would prefer to look at a file than visit a Drupal page for this info. Barry
It's not something I would recommend either, but it's an option some module developers might choose. -Peter On 12 Jun 2007 17:58:11 -0400, Barry Jaspan <barry@jaspan.org> wrote:
One could minimize the code by making changes to the array rather than re-declaring the whole thing. Something like:
node_schema_6000() { $schema = node_schema_5000();
$schema['node']['fields']['newcolumn'] = array('type' => 'int', 'not null' => TRUE, 'default' => 1);
return $schema; }
The downside here is that there is nowhere a developer can look to find the current node_schema. Well, actually, schema.module can easily provide this, but (I suspect) developers would prefer to look at a file than visit a Drupal page for this info.
Barry
Quoting Peter Wolanin <pwolanin@gmail.com>:
It's not something I would recommend either, but it's an option some module developers might choose.
-Peter
On 12 Jun 2007 17:58:11 -0400, Barry Jaspan <barry@jaspan.org> wrote:
One could minimize the code by making changes to the array rather than re-declaring the whole thing. Something like:
node_schema_6000() { $schema = node_schema_5000();
$schema['node']['fields']['newcolumn'] = array('type' => 'int', 'not null' => TRUE, 'default' => 1);
return $schema; }
The downside here is that there is nowhere a developer can look to find the current node_schema. Well, actually, schema.module can easily provide this, but (I suspect) developers would prefer to look at a file than visit a Drupal page for this info.
Why not store the schema to the DB on install/update? I understand the catch 22 but {schema} could be the first table on install. Of course this would introduce another cache but the cache would only need to be rebuilt on schema update. Earnie
participants (6)
-
andrew morton -
Barry Jaspan -
blake hall -
Earnie Boyd -
Peter Wolanin -
Philippe Jadin