First, sorry for the big, all-encompassing patch. Following the thread of one issue (duplicate vids and uuids) led to a rewrite that touched most parts of the module. At that point, I had a choice of undoing all the code and then separating out the new code by issue, making sure each set of changes were fully encapsulated, and rolling out a patch per each one.
At that point, I figured it would probably be just as difficult for you to digest five different patches as it would be to look through one changeset and roll changes in manually, based on your own evaluation.
At the very least, perhaps there are approaches in this patch that look promising and helpful.
I am attaching the patch, and will post an annottated comment on the lines in the patch below.
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | uuid.class_.inc_.txt | 3.54 KB | apotek |
| #3 | uuid.class_.inc_.txt | 3.43 KB | apotek |
| uuid_revisions_support.patch | 16.74 KB | apotek |
Comments
Comment #1
apotek commentedOkay, so I thought maybe I should explain some of these rewrites, additions, inline. I added line numbers to the patch to make it easier to pinpoint sections:
Create form widgets for uuid generation version selector and the default uuid namespace (to be displayed, probably not necessary). Set this to collapsed so as to not get in the way.
I did choose to make the default uuid version v4 (pseudo random, see line 237).
Added a @todo. Sync only adds uuids. It does not remove them from content types that have been de-activated. I can see good points with both approaches, but wanted to make a note of it in the code.
The "NOT IN (potentially massive subselect)" syntax will collapse on a site with a sizeable data collection. In fact, there is a limit to how many parameters can go in the NOT IN () parens. And yes, I have hit that limit before. So, rewriting with the faster and more scaleable LEFT JOIN. You'll see a few more of these rewrites.
Again, rewriting the subselect into the more efficient and scalable LEFT JOIN
Also, note the inserts are rewritten (line 69) to handle the new schema for the uuid_node_revisions table. The nid column was added (though redundant) in order to allow revisions uuids to be deleted when nodes are deleted. (You'll see why in my ticket on the issue http://drupal.org/node/915254).
Added a uuid generating class file to encapsulate different methods of generating uuids. I think we could add methods for mysql or PECL to this class.
The setting for the site's uuid namespace should be set when someone enables the module.
Of course, the schema for uuid_node_revisions needs so support a column with nids, so the schema needs to be customized. So I broke that out into its own function, which wraps around the default uuid_table_schema() and just extends it:
Handle issue http://drupal.org/node/913820
Custom schema for the uuid_node_revisions table. As you see, it first calls the default schema, and then just adds fields to it, so the basics remain the same.
Of course, I have to delete the new variables for uuid_version and uuid_namespace when the module is uninstalled
This should get called when the module is enabled in order to set a default uuid namespace.
The changes in the schema necessitated a lot of rewriting of the forthcoming update_6003() hook.
I think it's pretty self-explanatory.
First, I just wrapped the create uuid_comments in a "if table doesn't exist" statement, cause it's easy to do and makes for fewer SQL errors if the hook is re-run.
Change the column def from varchar to char for any existing schema tables
Add the nid column to any previously existing uuid_node_revisions table
Add node ids to the new column, for revisions that exist, but now have a default value of 0 in uuid_node_revisions due to the new column having been added.
Add uuid_node_revision rows for rows that don't exist, but should (fixes node syncing with regard to the new column)
Delete any orphaned revision vid, uuid pairs. there is no way to know which nodes they used to belong to, and any revisions that they used to be attached to are now long gone, so they cannot be re-attached. Best to delete them. This should not be a problem moving forward since implementing http://drupal.org/node/915254
Setting the default UUID version to v4 (pseudo-random). Probably a lot of discussion to be had about this.
Efficiency: especially/critically important on the load op of nodeapi.
Account for the changes in the uuid_node_revisions schema (the added nid column).
Also, in appropriate situations (a node is being loaded or may likely be re-used down the line, if a uuid is generated for its revision, attach it to the node object so it's available later on, don't just stick in the database but leave the node unaware of its new property (line 274, 282 etc)
Delete from uuid_node_revision before updating a node revision. There should only ever be one vid::uuid pair, so get rid of any pre-existing ones before doing the insert. We could avail ourselves of UPDATE... and check for an error and if not updated, then do a insert, but this seemed cleaner to me.
Here's where we get the payoff from having added the nid column to the uuid_node_revisions table: We can finally delete all the rows that belong to the revisions of a deleted node. As you'll see in http://drupal.org/node/915254, these cannot be deleted by any other means than having the nid column due to uuid coming fairly late in the nodeapi cycle, and there being no array of available revision ids attached to the node.
Added some documentation, and rewrote the query in order to take advantage of the new schema in the uuid_node_revisions table.
The @todo raises a somewhat thorny question about how this function should behave. I left it default at its current implementation, but rewrote it to allow for another possibility.
Rewrite uuid_uuid() to use the uuid generator class. I like some of the subsequent thoughts I read about the utility of the MYSQL function, so perhaps the approach is to expand the class methods. The mysql uuid() function only generates v4 uuids, though, right?
Again, sorry this got so long, but I think you'll see how all these modifications are chained together and dependent on each other.
Take what you like. Hopefully you will find something useful in here. I
If you'd rather I gen the patch against the dev release rather than beta2, I can do that, or I could run it against latest in CVS.
Comment #2
recidive commented@klktrk thanks for the patch and the extensive explanation.
I think this patch should really focus on providing a PHP based UUID generation.
Some issues such as #915254 (revision uuids are not deleted upon deleting all revisions) and #913820 (uuid schema: since uuids are *always* 64 characters long, save time and db space by defining the column as CHAR) are in no way related to this issue and should be developed on their own issues.
You patch contains tabs and this is not permitted. Also it needs to follow some coding conventions in order to be accepted.
Also, the patch is missing the uuid class.
Please take patches against DRUPAL-6--1 branch.
Thanks again!
Comment #3
apotek commentedClass for generating uuids in 3 versions with pure PHP. from php.net, but with no attribution of origin.
Comment #4
apotek commentedWoops, better coding standards for the class. Passes coder now.
Comment #5
recidive commented@klktrk, could you sent the changes and the class file all on a single patch to make it easy to review?
I see your class don't implement versions 1 and 2 which are IMO the most reliable. Thus we should still use the mysql and PECL extension when available. PECL is capable of generating all versions, and should take precedence over the class when available, so the flow in uuid_uuid() should look like this:
The only scenario that's not possible to generate is when user request UUID version 2 and there's not PECL extension. When this occur, no version 2 should be available to the user.
Also all logic in uuid_uuid() can be moved to the class, leaving it as just a wrapper to some class method.
Thanks for working on this!
Comment #6
skwashd commentedDrupal 6 core is no longer supported. We are no longer supporting 6.x-1.x versions of this module. I am closing this issue as won't fix.