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/
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]
