File Coverage

blib/lib/DBIx/Insert/Multi.pm
Criterion Covered Total %
statement 8 13 61.5
branch n/a
condition n/a
subroutine 3 6 50.0
pod 1 1 100.0
total 12 20 60.0


line stmt bran cond sub pod time code
1             package DBIx::Insert::Multi;
2 2     2   124986 use 5.010000;
  2         15  
3              
4             our $VERSION = "0.003";
5              
6 2     2   907 use Moo;
  2         19736  
  2         11  
7              
8             =head1 NAME
9              
10             DBIx::Insert::Multi -- Insert multiple table rows in a single statement
11              
12             =head1 SYNOPSIS
13              
14             use DBIx::Insert::Multi;
15              
16             my $dbh = DBI->connect(...);
17              
18             my $multi = DBIx::Insert::Multi->new({ dbh => $dbh, });
19             $multi->insert(
20             book => [
21             {
22             title => "Winnie the Pooh",
23             author => "Milne",
24             publication_date => DateTime->new(year => 1926)->ymd,
25             },
26             {
27             title => "Paddington",
28             author => "Bond",
29             publication_date => DateTime->new(year => 1958)->ymd,
30             },
31             ],
32             ); # die on error
33              
34             # Database specific INSERT statement
35             # MySQL: don't stop on errors
36             my $multi = DBIx::Insert::Multi->new({
37             ...
38             insert_sql_fragment => "INSERT IGNORE INTO",
39             });
40              
41             =head1 DESCRIPTION
42              
43             Bulk insert many db rows using a single INSERT INTO statement, e.g.
44              
45             INSERT INTO book (author, publication_date, title) VALUES
46             ( ?, ?, ? ),
47             ( ?, ?, ? );
48              
49             =head2 Restrictions
50              
51             All the hashrefs with row data should be shaped the same, i.e. have
52             the same keys.
53              
54             You should only use values that can be inserted into a database.
55              
56             That means no data structures (refs), and no objects. However, objects
57             will be stringified, so if they have overloaded stringification that
58             will work.
59              
60             Note that L<DateTime> objects are stringified to a format that is
61             unlikely to work correctly with your database date format (and without
62             a timezone), so make sure you construct strings manually before
63             inserting them.
64              
65             Undefs become NULL as usual.
66              
67              
68              
69             =head1 ISSUES
70              
71             =head2 last_insert_id
72              
73             It may be that you need to get hold of the PK ids of the inserted
74             rows. This is very non-standard and fiddly, so at this point this
75             module doesn't officially do any of that.
76              
77             You can do this yourself though, but I wouldn't bet it's very
78             reliable.
79              
80             $dbh->last_insert_id(undef, undef, $table, undef);
81              
82             Calling "$dbh->last_insert_id" returns a newly inserted row PK
83             value. It seems to vary between databases whether this is the id of
84             the first row or the last one. For instance:
85              
86             =over
87              
88             =item *
89              
90             MySQL: first
91              
92             =item *
93              
94             Postgres: last
95              
96             =back
97              
98             If the PK is an auto-increment / sequence, it is probably not
99             B<guaranteed> that these ids are in an unbroken series, but at least
100             MySQL B<seems> to do that.
101              
102             Read more about all the caveats here: L<DBI/"last_insert_id">.
103              
104              
105             =head3 Returning ids
106              
107             Some databases (Postgres) support INSERT INTO ... RETURNING, which can
108             be used to retrieve data from the inserted rows. This seems to be the
109             only reliable way to do this.
110              
111             This module can't do this at the moment, but patches are
112             welcome. Please submit a bug to open a discission about what the API
113             should look like.
114              
115             =cut
116              
117 2     2   3309 use DBIx::Insert::Multi::Batch;
  2         7  
  2         283  
118              
119              
120              
121             has dbh => ( is => "ro", required => 1 );
122              
123             has insert_sql_fragment => ( is => "lazy" );
124 0     0     sub _build_insert_sql_fragment { "INSERT INTO" }
125              
126             has is_last_insert_id_required => ( is => "lazy" );
127 0     0     sub _build_is_last_insert_id_required { 0 }
128              
129              
130              
131             =head1 METHODS
132              
133             =head2 insert($table_name, $records_arrayref)
134              
135             Perform the insert into $table_name of all the rows in
136             $records_arrayref (arrayref with hashrefs, where the hashref keys are
137             the column names, and the values are the column values).
138              
139             The return value not specified. If the query fails, die.
140              
141             =cut
142              
143             sub insert {
144 0     0 1   my $self = shift;
145 0           my ($table, $records) = @_;
146 0           return DBIx::Insert::Multi::Batch->new({
147             dbh => $self->dbh,
148             insert_sql_fragment => $self->insert_sql_fragment,
149             is_last_insert_id_required => $self->is_last_insert_id_required,
150             table => $table,
151             records => $records,
152             })->insert();
153             }
154              
155              
156              
157             1;
158              
159              
160             =head1 SEE ALSO
161              
162             =head2 DBIx::Class
163              
164             If you already have a L<DBIx::Class> schema, you can bulk insert rows
165             efficiently using the L<DBIx::Class::ResultSet/populate> method (note:
166             in void context!). You won't get back the new ids.
167              
168              
169              
170             =head1 DEVELOPMENT
171              
172             =head2 Author
173              
174             Johan Lindstrom, C<< <johanl [AT] cpan.org> >>
175              
176              
177             =head2 Source code
178              
179             L<https://github.com/jplindstrom/p5-DBIx-Insert-Multi>
180              
181              
182             =head2 Bug reports
183              
184             Please report any bugs or feature requests on GitHub:
185              
186             L<https://github.com/jplindstrom/p5-DBIx-Insert-Multi/issues>.
187              
188              
189              
190             =head1 COPYRIGHT & LICENSE
191              
192             Copyright 2019- Broadbean Technologies, All Rights Reserved.
193              
194             This program is free software; you can redistribute it and/or modify
195             it under the same terms as Perl itself.
196              
197              
198              
199             =head1 ACKNOWLEDGEMENTS
200              
201             Thanks to Broadbean for providing time to open source this module.
202              
203             =cut