DBIx-UpdateTable-FromHoH
view release on metacpan or search on metacpan
lib/DBIx/UpdateTable/FromHoH.pm view on Meta::CPAN
this code:
my $res = update_table_from_hoh(
dbh => $dbh,
table => 't1',
key_column => 'id',
hoh => {
1 => {col1=>'a', col2=>'b'},
2 => {col1=>'c', col2=>'d'},
4 => {col1=>'e', col2=>'f'},
},
);
will perform these SQL queries:
UPDATE TABLE t1 SET col2='d' WHERE id='2';
INSERT INTO t1 (id,col1,col2) VALUES (4,'e','f');
DELETE FROM t1 WHERE id='3';
to make table `t1` become like this:
id col1 col2 col3
-- ---- ---- ----
1 a b foo
2 c d bar
4 e f qux
_
args => {
dbh => {
schema => ['obj*'],
req => 1,
},
table => {
schema => 'str*',
req => 1,
},
hoh => {
schema => 'hoh*',
req => 1,
},
key_column => {
schema => 'str*',
req => 1,
},
data_columns => {
schema => ['array*', of=>'str*'],
},
use_tx => {
schema => 'bool*',
default => 1,
},
extra_insert_columns => {
schema => ['hos*'], # XXX or code
},
extra_update_columns => {
schema => ['hos*'], # XXX or code
},
},
};
sub update_table_from_hoh {
my %args = @_;
my $dbh = $args{dbh};
my $table = $args{table};
my $hoh = $args{hoh};
my $key_column = $args{key_column};
my $data_columns = $args{data_columns};
my $use_tx = $args{use_tx} // 1;
unless ($data_columns) {
my %columns;
for my $key (keys %$hoh) {
my $row = $hoh->{$key};
$columns{ $_ }++ for keys %$row;
}
$data_columns = [sort keys %columns];
}
my @columns = @$data_columns;
push @columns, $key_column unless grep { $_ eq $key_column } @columns;
my $columns_str = join(",", @columns);
$dbh->begin_work if $use_tx;
my $hoh_table = {};
GET_ROWS: {
my $sth = $dbh->prepare("SELECT $columns_str FROM $table");
$sth->execute;
while (my $row = $sth->fetchrow_hashref) {
$hoh_table->{ $row->{$key_column} } = $row;
}
}
my $num_rows_unchanged = keys %$hoh_table;
my $num_rows_deleted = 0;
DELETE: {
for my $key (sort keys %$hoh_table) {
unless (exists $hoh->{$key}) {
$dbh->do("DELETE FROM $table WHERE $key_column=?", {}, $key);
$num_rows_deleted++;
$num_rows_unchanged--;
}
}
}
my $num_rows_updated = 0;
UPDATE: {
for my $key (sort keys %$hoh) {
next unless exists $hoh_table->{$key};
my @update_columns;
my @values;
for my $column (@columns) {
next if $column eq $key_column;
unless (_eq($hoh_table->{$key}{$column}, $hoh->{$key}{$column})) {
push @update_columns, $column;
push @values, $hoh->{$key}{$column};
}
}
next unless @update_columns;
( run in 1.134 second using v1.01-cache-2.11-cpan-39bf76dae61 )