On 3/22/06, Sean Davis <[EMAIL PROTECTED]> wrote:
> I would like to do a large amount of read->parse->store operations.  In
> short, I have a large text file with one record per line.  To speed things
> up, I have seen others "reuse" objects rather than allocating new ones for
> each record.  Can I safely do this with Rose::DB::Objects?  Is it as simple
> as reseting the primary key column(s) to undef for autoincrement primary
> keys or setting the primary key column(s) to some new values and then
> calling save?

Let me start by saying that I think it's probably better to create a
new object each time.  I doubt you'll be able to measure the
difference in performance, and the code will be simpler and more
clear.

That said, here's how to do what you described.  You should make sure
you set all column values so that no values from the "previous" object
are carried over to the new one.  Setting auto-increment PK values to
undef should be sufficient to make them get new values the next time
around.

There is only one wrinkle I can think of, and it's demonstrated below:

    my $o = MyObject->new; # We'll reuse this object

    foreach my $info (...lines from a file, whatever...)
    {
      # Make sure %values contains keys for ALL column values
      my %values = parse_info($info);

      $o->init(%values); # Replace old values with new values

      $o->save; # PROBLEM HERE!
    }

That code will work the first time through the loop, but the second
time, the call to save() will try to UPDATE instead of INSERT.  After
the first save(), $o thinks it's already in the database.  You can
forcefully convince it otherwise if you want to:

    use Rose::DB::Object::Util qw(unset_state_in_db);

    foreach my $info (..)
    {
      ...
      $o->init(%values);     # Replace old values with new values
      unset_state_in_db($o); # Convince $o that it wasn't previously save()d
      $o->save;              # This always does an INSERT now
    }

But there's a much more straightforward way to do this:

    foreach my $info (..)
    {
      ...
      $o->init(%values); # Replace old values with new values
      $o->insert;        # Explicitly do an insert
    }

When it doubt, just throw this in the loop to see the generated SQL:

    local $Rose::DB::Object::Debug = 1;

-John


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid0944&bid$1720&dat1642
_______________________________________________
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object

Reply via email to