On 5/29/06 6:21 AM, Svilen Ivanov wrote: > I would like to extend RDBO to support versioning of properties for each > instance. To explain it better I will use analogy with CVS: > * calling "->save" will make new revision of the object ("cvs commit") > * "->load(id=>1)" will get by default the latest version ("cvs checkout") > * "->load(id=>1, rev => 5)" will get the fifth revison of this particular > instance ("cvs -r 1.5 checkout") > The ultimate goal is to have ability to rollback the objects to their state at > a specific point of time in the past. It would be the best if I can do it as > layer on top of existing RDBO.
I've done this a few different ways in the past. The "safest" way, IME, is to let the database do almost all of the work, and then do the rest "manually" on the RDBO side. This requires a database with triggers and transactions. Here's the setup. 1. Create a table called "products" with the normal columns you need. (i.e., no special columns for versioning) 2. Create a "products_history" table with the same columns as the "products" table, and a few more columns for versioning. You can use dates, revision integers, whatever you want. 3. Set up triggers for the products table on insert and update. For both events, insert a new row in the products_history before inserting or updating a row in the products table. The new products_history row should be an exact copy of the products row before an update operation, or an exact copy of the new products row during an insert operation, but with the addition of the versioning columns. 4. Make RDBO classes for the products and products_history tables in the normal manner. Advantages of this approach: * The products and products_history tables are always in sync and consistent, no matter how the database is updated. * It's very clear what things do from the RDBO side. There's nothing special about the RDBO classes at all. * The performance of "current" data is not very different than if you were not doing any versioning at all. IOW, the product table only contains the most recent revisions, and is therefore as small as possible. All the "bloat" goes in the products_history table. Disadvantages: * You must use a different class when you want to look at historic data. If you need to know what revision the "current" version is, you can also put the versioning columns in the "products" table. If you want to make this more transparent from the Perl side, or if you're forced to use a database without trigger support and transactions, try this approach: 1. Set up two tables as described above, sans triggers. 2. Set up two RDBO classes for those tables in the usual manner. 3. Modify the class that fronts the "products" table in the following ways: 3.1 Add attributes for your versioning data. Don't add actual columns, just make the accessor methods. 3.2 Override load(). If a versioning attribute is set, load from the products_history table using the RDBO class that fronts it, then "suck out" all the column data and stick it in the current object. Then discard the products_history object. 3.3 Override save(). On save, start a transaction and create a new row in the products_history table using the appropriate RDBO class, pushing the column values from the current object into the history object. Then save the current object into the products table and commit the transaction. 4. Modify the manager's get_objects() method. If versioning data is specified in the query, call the products_history manager instead. Otherwise, call the regular superclass method. I glossed over a lot of details there, but the idea is to do on the Perl side what was done in the triggers in the earlier setup. As usual, there are many different ways to do this. I've just (briefly) described two ways. I'm sure you can come up with more :) -John ------------------------------------------------------- All the advantages of Linux Managed Hosting--Without the Cost and Risk! Fully trained technicians. The highest number of Red Hat certifications in the hosting industry. Fanatical Support. Click to learn more http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642 _______________________________________________ Rose-db-object mailing list Rose-db-object@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rose-db-object