Hello, I have a problem using default_primary_key_generator. I'm new to RDBO, so please be clement. ;o) It' really complex and so not easy to learn. (Well, for me.)
I am writing a "generic" application for data synchronisation. The sync script itself does not "know" anything about the underlying schema, column names etc. This means, it cannot make use of column accessors and such things. (In fact it does occasionally, but let's ignore this at this point.) I have no influence on the DB schema, so I cannot make any changes there. The application maps source and target attribute names using a "map file", so they can be configured outside without any changes to the code, and loads the required information about the database schema, where needed, from a Rose::DB::Object schema created by RDBO::Loader. For example, it loads the column names from the row object to be sure that the data hash uses correct key names before storing it into the database. So I can use a case insensitive map file. As the database schema (it's Oracle 9i, by the way, but I don't think this really matters) does not have any triggers for "auto increment" columns, I have created a generic default_primary_key_generator() function which is used for all tables. This function loads the entry with the max id (using a simple sort), increments this value and returns it. (In fact the content of the primary key field is a string, but I think this doesn't matter either.) Now, the current task I am working on is to synchronize an object that exists on both sides, the source (LDAP in this case) and the database. At this point, lot's of work is done to see if there are any changes, so I'm pretty sure there are. :o) I have a hash now where the changes are stored. Some of the data affects related tables. Example: { 'CMP_NETWORK' => { 'NICADDRESS' => '111122223331' }, 'HWLASTSCANDATE' => '2008011518:02:00' } Currently, I try this to load the row from the database and store the changes to the RDBO object: my $row = $schema->new( db => $dbh, %{ $self->_prepare_data( $schema, { $self->tableset( 'idfield' ) => $attrs{'dn'} } ) } )->load; $row->init( %$data ); (Where _prepare_data is the function to correctly map column names to hash keys and tableset() is a "driver function" that provides access to some config data for the current table. Please remember, this is a generic application which does not only synchronize databases.) Now, wenn storing the changes with $row->save( cascade => 1 ), the changes are stored as expected, _but_, a new "primary key" value is generated. So, for each update of this object, the value of the key field in the related table (CMP_NETWORK in this case) is incremented. I have tried other ways, f. e. using a foreach() construct to iterate over the keys in the $data hash(ref), but as I can't be sure that there's only one sublevel, I would have to use a recursive function to do this. I'm sure there's a better way to do this. I have also tried to add CMP_NETWORK to the 'with' param in load(). Here's my primary key generator: sub default_primary_key_generator { my( $class, $db ) = @_; my $key = $class->meta->primary_key->column_names->[0]; my %params = ( query => [ $key => { like => 'MAT.'.$key.'.%' }, ], sort_by => $key . ' DESC', limit => 1, ); my $max_id = Rose::DB::Object::Manager->get_objects( object_class => $class, %params ); my $current = 0; if ( $max_id->[0]->{$key} =~ m|^MAT\..*\.(\d+)$| ) { $current = $1; } $current++; my $id = 'MAT.'.$key.'.'.sprintf( '%06d', $current ); return $id; } # --- end sub default_primary_key_generator --- As you can see, the content of the key field is generated using the very simple schema 'MAT.<FIELDNAME>.<NUMBER>'. I _can_ be sure that there's only one primary key field in each table, and I _can_ be sure that this schema is the same in any table I use. I'm afraid I'm a bit blind at this point, so any help is VERY appreciated. I have digged this mailing list very deep within the last weeks and found it very helpful. :o) Many of my problems so far could be solved by doing a search here. Greetings, Bianka ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Rose-db-object mailing list Rose-db-object@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rose-db-object