X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;ds=inline;f=SL%2FDBUtils.pm;h=c9c70c95a94fabd69881b6d8c79465925ff75af3;hb=e713c3142d8c603b31d25fff371da47f56976aae;hp=4a4ac25c19283c91c2765ed5d9c6c9cafdb15027;hpb=49ce0054e1fc4379b78b4d5dff506b1c5a03e548;p=kivitendo-erp.git diff --git a/SL/DBUtils.pm b/SL/DBUtils.pm index 4a4ac25c1..c9c70c95a 100644 --- a/SL/DBUtils.pm +++ b/SL/DBUtils.pm @@ -1,13 +1,16 @@ package SL::DBUtils; +use SL::Util qw(trim); + require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(conv_i conv_date conv_dateq do_query selectrow_query do_statement - dump_query quote_db_date + dump_query quote_db_date like selectfirst_hashref_query selectfirst_array_query selectall_hashref_query selectall_array_query selectall_as_map + selectall_ids prepare_execute_query prepare_query create_sort_spec does_table_exist add_token); @@ -19,9 +22,19 @@ sub conv_i { return (defined($value) && "$value" ne "") ? $value * 1 : $default; } +# boolean escape +sub conv_b { + my ($value, $default) = @_; + return !defined $value && defined $default ? $default + : $value ? 't' + : 'f'; +} + sub conv_date { my ($value) = @_; - return (defined($value) && "$value" ne "") ? $value : undef; + return undef if !defined $value; + $value = trim($value); + return $value eq "" ? undef : $value; } sub conv_dateq { @@ -213,11 +226,11 @@ sub selectall_as_map { my %hash; if ('' eq ref $value_col) { while (my $ref = $sth->fetchrow_hashref()) { - $hash{$ref->{$key_col}} = $ref->{$value_col}; + $hash{$ref->{$key_col} // ''} = $ref->{$value_col}; } } else { while (my $ref = $sth->fetchrow_hashref()) { - $hash{$ref->{$key_col}} = { map { $_ => $ref->{$_} } @{ $value_col } }; + $hash{$ref->{$key_col} // ''} = { map { $_ => $ref->{$_} } @{ $value_col } }; } } @@ -228,6 +241,25 @@ sub selectall_as_map { return %hash; } +sub selectall_ids { + $main::lxdebug->enter_sub(2); + + my ($form, $dbh, $query, $key_col) = splice(@_, 0, 4); + + my $sth = prepare_execute_query($form, $dbh, $query, @_); + + my @ids; + while (my $ref = $sth->fetchrow_arrayref()) { + push @ids, $ref->[$key_col]; + } + + $sth->finish; + + $main::lxdebug->leave_sub(2); + + return @ids; +} + sub create_sort_spec { $main::lxdebug->enter_sub(2); @@ -307,16 +339,29 @@ sub add_token { my %params = @_; my $col = $params{col}; my $val = $params{val}; - my $method = $params{method} || '='; my $escape = $params{esc} || sub { $_ }; + my $method = $params{esc} =~ /^start|end|substr$/ ? 'ILIKE' : $params{method} || '='; $val = [ $val ] unless ref $val eq 'ARRAY'; my %escapes = ( id => \&conv_i, + bool => \&conv_b, date => \&conv_date, + start => sub { trim($_[0]) . '%' }, + end => sub { '%' . trim($_[0]) }, + substr => sub { like($_[0]) }, ); + my $_long_token = sub { + my $op = shift; + sub { + my $col = shift; + return scalar @_ ? join ' OR ', ("$col $op ?") x scalar @_, + : undef; + } + }; + my %methods = ( '=' => sub { my $col = shift; @@ -324,6 +369,7 @@ sub add_token { : scalar @_ == 1 ? sprintf '%s = ?', $col : undef; }, + map({ $_ => $_long_token->($_) } qw(LIKE ILIKE >= <= > <)), ); $method = $methods{$method} || $method; @@ -340,14 +386,29 @@ sub add_token { return ($token, @vals); } +sub like { + my ($string) = @_; + + return "%" . SL::Util::trim($string // '') . "%"; +} + +sub role_is_superuser { + my ($dbh, $login) = @_; + my ($is_superuser) = $dbh->selectrow_array(qq|SELECT usesuper FROM pg_user WHERE usename = ?|, undef, $login); + + return $is_superuser; +} + 1; __END__ +=encoding utf-8 + =head1 NAME -SL::DBUTils.pm: All about Databaseconections in Lx +SL::DBUTils.pm: All about database connections in kivitendo =head1 SYNOPSIS @@ -374,23 +435,100 @@ SL::DBUTils.pm: All about Databaseconections in Lx =head1 DESCRIPTION -DBUtils is the attempt to reduce the amount of overhead it takes to retrieve information from the database in Lx-Office. Previously it would take about 15 lines of code just to get one single integer out of the database, including failure procedures and importing the necessary packages. Debugging would take even more. +DBUtils provides wrapper functions for low level database retrieval. It saves +you the trouble of mucking around with statement handles for small database +queries and does exception handling in the common cases for you. + +Query and retrieval function share the parameter scheme: + + query_or_retrieval(C