I know this is again not very usual setup - but I provide this info -
so that you can make an informed decision about how much
back-compatibillity you are going to support for the next version of
DBIC.   In the past insert worked only on the record passed to it -
now it recurses to related records. This fixes some multi-create
scenarios - but might be sometimes unexpected.

In the current CPAN DBIC version to insert dvd and it's owner you'd do
something like:

use strict;
use warnings;
use lib 'lib';
use DBSchema;

my $dsn = 'dbi:SQLite:dbname=dvdzbr.db';
my $schema = DBSchema->connect( $dsn ); #, $user, $pass, {} );
print "Count: " . $schema->resultset( 'Dvd' )->count, "\n";

    my $dvd = $schema->resultset( 'Dvd' )->new_result({});
    my $owner = $dvd->related_resultset( 'owner' )->new( {
             name => 'temp name',
             username => 'temp name',
             password => 'temp name',
         }
    );
    $owner->insert;  # owner inserted first - so that FK can be set in dvd
    $dvd->owner( $owner );
    $dvd->name( "Deer Hunter" );
    $dvd->insert;

print "New count: " . $schema->resultset( 'Dvd' )->count, "\n";

Unfortunately, now this results in two inserts on the Dvd table:

[EMAIL PROTECTED]:~/progs/fails_at_insert> perl fails_at_insert.pl
Count: 15
New count: 17
[EMAIL PROTECTED]:~/progs/fails_at_insert>

Or if you want to see exactly what happens:

[EMAIL PROTECTED]:~/progs/fails_at_insert> DBIC_TRACE=1 perl fails_at_insert.pl
SELECT COUNT( * ) FROM dvd me:
Count: 17
BEGIN WORK
INSERT INTO usr (name, password, username) VALUES (?, ?, ?): 'temp
name', 'temp name', 'temp name'
SELECT me.id, me.username, me.password, me.name FROM usr me WHERE ( (
( me.id = ? ) ) ): '17'
SELECT me.id, me.name, me.imdb_id, me.owner, me.current_borrower,
me.creation_date, me.alter_date FROM dvd me WHERE ( ( ( ( ( ( me.id IS
NULL ) ) ) ) AND ( me.owner = ? ) ) ): '17'
INSERT INTO dvd (alter_date, creation_date, current_borrower, id,
imdb_id, name, owner) VALUES (?, ?, ?, ?, ?, ?, ?): 'NULL', 'NULL',
'NULL', 'NULL', 'NULL', 'NULL', '17'
COMMIT
INSERT INTO dvd (current_borrower, name, owner) VALUES (?, ?, ?):
'NULL', 'Deer Hunter', '17'
SELECT COUNT( * ) FROM dvd me:
New count: 19
[EMAIL PROTECTED]:~/progs/fails_at_insert>

The first insert into dvd is triggered by the insert of the user record.

In the CPAN version this works as expected:

[EMAIL PROTECTED]:~/progs/fails_at_insert> export PERL5LIB=
[EMAIL PROTECTED]:~/progs/fails_at_insert> DBIC_TRACE=1 perl fails_at_insert.pl
SELECT COUNT( * ) FROM dvd me:
Count: 19
INSERT INTO usr (name, password, username) VALUES (?, ?, ?): 'temp
name', 'temp name', 'temp name'
INSERT INTO dvd (name, owner) VALUES (?, ?): 'Deer Hunter', '18'
SELECT COUNT( * ) FROM dvd me:
New count: 20
[EMAIL PROTECTED]:~/progs/fails_at_insert>


Some ideas how to fix it:
- rename the current insert to recursive_insert, revert the old insert
and use recursive_insert only when needed
- add additional parameter to insert so that you can switch off the
recursive behaviour

The code is attached (it is my previous example - with the fix adviced at IRC).

-- 
Zbigniew Lukasiak
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/

Attachment: fails_at_insert.tgz
Description: GNU Zip compressed data

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/[email protected]

Reply via email to