Sponsoring The Perl Toolchain Summit 2025: Help make this important event another success Learn more

use strict;
use Test::Requires 'DateTime';
use Test::Requires 'Tie::IxHash';
sub ordered_hashref {
tie my %params, Tie::IxHash::, @_;
return \%params;
}
SQL::Maker->load_plugin('InsertMulti');
subtest 'mysql' => sub {
subtest 'insert_multi( $table, \@colvals, \%opts )' => sub {
subtest 'ok' => sub {
my $builder = SQL::Maker->new( driver => 'mysql' );
my ( $sql, @binds ) = $builder->insert_multi(
'foo' => [
ordered_hashref( bar => 'baz', john => 'man' ),
ordered_hashref( bar => 'bee', john => 'row' )
]
);
is $sql, "INSERT INTO `foo`\n(`bar`, `john`)\nVALUES (?, ?),\n(?, ?)";
is join( ',', @binds ), 'baz,man,bee,row';
};
subtest 'confused' => sub {
my $builder = SQL::Maker->new( driver => 'mysql' );
my ( $sql, @binds ) = $builder->insert_multi(
'foo' => [
ordered_hashref( bar => 'baz', john => 'man' ),
ordered_hashref( john => 'row', bar => 'bee' )
]
);
is $sql, "INSERT INTO `foo`\n(`bar`, `john`)\nVALUES (?, ?),\n(?, ?)";
is join( ',', @binds ), 'baz,man,bee,row';
};
subtest 'insert ignore' => sub {
my $builder = SQL::Maker->new( driver => 'mysql' );
my ( $sql, @binds ) = $builder->insert_multi(
'foo' => [
ordered_hashref( bar => 'baz', john => 'man' ),
ordered_hashref( bar => 'bee', john => 'row' )
],
+{ prefix => 'INSERT IGNORE' },
);
is $sql, "INSERT IGNORE `foo`\n(`bar`, `john`)\nVALUES (?, ?),\n(?, ?)";
is join( ',', @binds ), 'baz,man,bee,row';
};
subtest 'on duplicate key update' => sub {
my $builder = SQL::Maker->new( driver => 'mysql' );
my ( $sql, @binds ) = $builder->insert_multi(
'foo' => [
ordered_hashref(
bar => 'baz',
john => 'man',
created_on => \"UNIX_TIMESTAMP()",
updated_on => \[ "UNIX_TIMESTAMP(?)", "2011-04-12" ],
expires => DateTime->new(year => 2024),
),
ordered_hashref(
bar => 'bee',
john => 'row',
created_on => \"UNIX_TIMESTAMP()",
updated_on => \[ "UNIX_TIMESTAMP(?)", "2011-04-13" ],
expires => DateTime->new(year => 2025),
),
],
+{
update => ordered_hashref(
bar => \"VALUES(bar)",
john => "john",
updated_on => \[ "UNIX_TIMESTAMP(?)", "2011-04-14" ],
expires => DateTime->new(year => 2025),
)
},
);
is $sql, substr(<< 'SQL', 0, -1);
INSERT INTO `foo`
(`bar`, `john`, `created_on`, `updated_on`, `expires`)
VALUES (?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(?), ?),
(?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(?), ?)
ON DUPLICATE KEY UPDATE `bar` = VALUES(bar), `john` = ?, `updated_on` = UNIX_TIMESTAMP(?), `expires` = ?
SQL
is join( ',', @binds ), 'baz,man,2011-04-12,2024-01-01T00:00:00,bee,row,2011-04-13,2025-01-01T00:00:00,john,2011-04-14,2025-01-01T00:00:00';
};
subtest 'on duplicate key update (term)' => sub {
my $builder = SQL::Maker->new( driver => 'mysql' );
my ( $sql, @binds ) = $builder->insert_multi(
'foo' => [
ordered_hashref(
bar => 'baz',
john => 'man',
created_on => sql_raw("UNIX_TIMESTAMP()"),
updated_on => sql_raw("UNIX_TIMESTAMP(?)", "2011-04-12"),
),
ordered_hashref(
bar => 'bee',
john => 'row',
created_on => sql_raw("UNIX_TIMESTAMP()"),
updated_on => sql_raw("UNIX_TIMESTAMP(?)", "2011-04-13"),
),
],
+{
update => ordered_hashref(
bar => \"VALUES(bar)",
john => "john",
updated_on => sql_raw("UNIX_TIMESTAMP(?)", "2011-04-14"),
)
},
);
is $sql, substr(<< 'SQL', 0, -1);
INSERT INTO `foo`
(`bar`, `john`, `created_on`, `updated_on`)
VALUES (?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(?)),
(?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(?))
ON DUPLICATE KEY UPDATE `bar` = VALUES(bar), `john` = ?, `updated_on` = UNIX_TIMESTAMP(?)
SQL
is join( ',', @binds ), 'baz,man,2011-04-12,bee,row,2011-04-13,john,2011-04-14';
};
};
subtest 'insert_multi( $table, \@cols, \@values, \%opts )' => sub {
subtest 'ok' => sub {
my $builder = SQL::Maker->new( driver => 'mysql' );
my ( $sql, @binds ) = $builder->insert_multi(
'foo' => [qw/bar john/],
[ [qw/baz man/], [qw/bee row/], ],
);
is $sql, "INSERT INTO `foo`\n(`bar`, `john`)\nVALUES (?, ?),\n(?, ?)";
is join( ',', @binds ), 'baz,man,bee,row';
};
subtest 'insert ignore' => sub {
my $builder = SQL::Maker->new( driver => 'mysql' );
my ( $sql, @binds ) = $builder->insert_multi(
'foo' => [qw/bar john/],
[ [qw/baz man/], [qw/bee row/], ],
+{ prefix => 'INSERT IGNORE' },
);
is $sql, "INSERT IGNORE `foo`\n(`bar`, `john`)\nVALUES (?, ?),\n(?, ?)";
is join( ',', @binds ), 'baz,man,bee,row';
};
subtest 'on duplicate key update' => sub {
my $builder = SQL::Maker->new( driver => 'mysql' );
my ( $sql, @binds ) = $builder->insert_multi(
'foo' => [qw/bar john created_on updated_on/],
[
[
'baz', 'man', \"UNIX_TIMESTAMP()",
\[ "UNIX_TIMESTAMP(?)", "2011-04-12" ]
],
[
'bee', 'row', \"UNIX_TIMESTAMP()",
\[ "UNIX_TIMESTAMP(?)", "2011-04-13" ]
],
],
+{
update => [
bar => \"VALUES(bar)",
john => "john",
updated_on => \[ "UNIX_TIMESTAMP(?)", "2011-04-14" ],
],
},
);
is $sql, substr( << 'SQL', 0, -1 );
INSERT INTO `foo`
(`bar`, `john`, `created_on`, `updated_on`)
VALUES (?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(?)),
(?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(?))
ON DUPLICATE KEY UPDATE `bar` = VALUES(bar), `john` = ?, `updated_on` = UNIX_TIMESTAMP(?)
SQL
is join( ',', @binds ),
'baz,man,2011-04-12,bee,row,2011-04-13,john,2011-04-14';
};
};
};
done_testing;