Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

last_insert_id added #2

Merged
merged 1 commit into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Revision history for SQL-Inserter

0.04 2023-12-17
- Add last_insert_id.

0.03 2023-10-29
- Add support for Oracle Database.

Expand Down
30 changes: 22 additions & 8 deletions README.pod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ SQL::Inserter - Efficient buffered DBI inserter and fast INSERT SQL builder

=head1 VERSION

Version 0.03
Version 0.04

=head1 SYNOPSIS

Expand All @@ -17,21 +17,22 @@ Version 0.03
buffer => 100? # Default buffer is 100 rows
);

# Fastest method: pass single or multiple rows of data as an array
# Pass single or multiple rows of data as an array (fastest method):
$sql->insert($col1_row1, $col2_row1, $col1_row2...);

# You can manually flush the buffer at any time with no argument on insert
# (otherwise there is auto-flush on the object's destruction)
$sql->insert();

# Alternative, pass a single row as a hash, allows SQL code passed as
# references instead of values (no need to define cols in constructor)
# Alternatively, pass a single row as a hash, allows SQL code passed as
# references instead of values (no need to define cols in constructor):
$sql->insert({
column1 => $data1,
column2 => \'NOW()',
...
});

# Since the inserts are buffered, they might not have been executed yet.
# You can manually flush the buffer at any time with no argument on insert
# (otherwise there is auto-flush on the object's destruction):
$sql->insert();

# There are also functions to just get the SQL statement and its bind vars
# similar to SQL::Abstract or SQL::Maker insert, but with much less overhead:
my ($sql, @bind) = simple_insert($table, {col1=>$val...});
Expand Down Expand Up @@ -179,6 +180,19 @@ from the very first hash), and after flushing the buffer you can switch to array

=back

=head2 last_insert_id

# MySQL
my $id = $sql->last_insert_id;

# Depending on the driver you might need parameters
my $id = $sql->last_insert_id($catalog, $schema, $table, $field, \%attr);

Returns the id of the last insert row, if available, after emptying the buffer.

Convenience wrapper around L<DBI>'s database handle method of the same name. See
that method's documentation for details and caveats depending on your DB driver.

=head1 ATTRIBUTES

=head2 C<last_retval>
Expand Down
42 changes: 33 additions & 9 deletions lib/SQL/Inserter.pm
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ SQL::Inserter - Efficient buffered DBI inserter and fast INSERT SQL builder

=head1 VERSION

Version 0.03
Version 0.04

=cut

our $VERSION = '0.03';
our $VERSION = '0.04';

our @EXPORT_OK = qw(simple_insert multi_insert_sql);

Expand All @@ -32,21 +32,22 @@ our @EXPORT_OK = qw(simple_insert multi_insert_sql);
buffer => 100? # Default buffer is 100 rows
);

# Fastest method: pass single or multiple rows of data as an array
# Pass single or multiple rows of data as an array (fastest method):
$sql->insert($col1_row1, $col2_row1, $col1_row2...);

# You can manually flush the buffer at any time with no argument on insert
# (otherwise there is auto-flush on the object's destruction)
$sql->insert();

# Alternative, pass a single row as a hash, allows SQL code passed as
# references instead of values (no need to define cols in constructor)
# Alternatively, pass a single row as a hash, allows SQL code passed as
# references instead of values (no need to define cols in constructor):
$sql->insert({
column1 => $data1,
column2 => \'NOW()',
...
});

# Since the inserts are buffered, they might not have been executed yet.
# You can manually flush the buffer at any time with no argument on insert
# (otherwise there is auto-flush on the object's destruction):
$sql->insert();

# There are also functions to just get the SQL statement and its bind vars
# similar to SQL::Abstract or SQL::Maker insert, but with much less overhead:
my ($sql, @bind) = simple_insert($table, {col1=>$val...});
Expand Down Expand Up @@ -263,6 +264,29 @@ sub insert {
return $ret;
}

=head2 last_insert_id

# MySQL
my $id = $sql->last_insert_id;

# Depending on the driver you might need parameters
my $id = $sql->last_insert_id($catalog, $schema, $table, $field, \%attr);

Returns the id of the last insert row, if available, after emptying the buffer.

Convenience wrapper around L<DBI>'s database handle method of the same name. See
that method's documentation for details and caveats depending on your DB driver.

=cut

sub last_insert_id {
my $self = shift;

$self->_empty_buffer() if $self->{buffer_counter};

return $self->{dbh}->last_insert_id(@_);
}

=head1 ATTRIBUTES

=head2 C<last_retval>
Expand Down
19 changes: 17 additions & 2 deletions t/simple.t
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ my @execute = ();

my $dbh = mock {} => (
add => [
prepare => sub { my $self = shift; push @prepare, @_ ; return $self},
execute => sub { shift; @execute = @_ ; return 1},
prepare => sub {my $self = shift; push @prepare, @_ ; return $self},
execute => sub {shift; @execute = @_ ; return 1},
last_insert_id => sub {1},
]
);

Expand Down Expand Up @@ -197,4 +198,18 @@ subtest 'new' => sub {
ok(!$sql->{oracle}, "Oracle not detected");
};

subtest 'last_insert_id' => sub {
@execute = ();
@prepare = ();
my $sql = SQL::Inserter->new(dbh=>$dbh,table=>'table',cols=>[qw/col1 col2/],buffer=>3);
$sql->last_insert_id;
is([@prepare],[], "No prepared statement");
is($sql->insert(1,2),0, "No execute");
is($sql->{row_total}, undef, "No row_total");

is($sql->last_insert_id, 1, "Last insert id");
is([@execute],[1,2], "Last execute bind vars");
is($sql->{row_total}, 1, "1 execute");
};

done_testing;