package DBtank; # # SPDX-License-Identifier: AGPL-3.0-or-later # Copyright (c) Rainer Gümpelein, TeilRad GmbH # use strict; use warnings; use POSIX; use DBI; use DBI::Const::GetInfoType; use CGI ':standard'; use Lib::Config; use Mod::Basework; use Scalar::Util qw(looks_like_number); use Config::General; use Data::Dumper; my $cf = new Config; my $bw = new Basework; my $q = new CGI; $q->import_names('R'); my $debug = 1; sub new { my $class = shift; my $self = {}; my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg"; my $conf = Config::General->new($globalconf_file); my %globalconf = $conf->getall; $self = \%globalconf; bless($self,$class); return $self; } my $today = strftime("%d.%m.%Y",localtime(time)); my $date_time = strftime("%d.%m.%Y %H:%M",localtime(time)); my %varenv = $cf->envonline(); #dbconnect_intern, on default $dbh_intern will be used my $dbh_intern = &dbconnect(""); sub dbconnect { my $self = shift; my $options =""; my $database = "dbi:Pg:dbname=$varenv{dbname};host=$varenv{dbhost};port=5432;options='$options'"; my $dbh = DBI->connect($database, $varenv{dbuser}, $varenv{dbpassw},{ RaiseError => 1, AutoCommit => 1 }) or die "Can't connect to $varenv{dbname}: $DBI::errstr"; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); $bw->log("--> dbconnect_intern --> $varenv{syshost} $source",$database,""); return $dbh if($dbh); } #dbconnect_extern for copri operator instance sub dbconnect_extern { my $self = shift; my $dbname = shift; my $instance_type = "operator"; $instance_type = "primary" if($dbname eq "sharee_primary"); my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg"; my $conf = Config::General->new($globalconf_file); my %globalconf = $conf->getall; $bw->log("dbconnect_extern call with instance_type:$instance_type and copri_instance:",$dbname,""); #keep in mind, only one DB can be returned by this way #while (my ($key, $value) = each %{ $self->{$instance_type} }) { while (my ($key, $value) = each %{ $globalconf{$instance_type} }) { if($key eq $dbname){ $bw->log("dbconnect_XX",$value->{database},""); my $database = "dbi:Pg:dbname=$value->{database}->{dbname};host=$value->{database}->{host};port=$value->{database}->{port};options='$value->{database}->{options}'"; $database .= ";sslmode=$value->{database}->{sslmode}" if($value->{database}->{sslmode} && $value->{database}->{host} ne "localhost"); my $dbh = DBI->connect($database, $value->{database}->{user}, $value->{database}->{passwd},{ RaiseError => 0, AutoCommit => 1 }); $bw->log("--> dbconnect_extern success --> $database, $value->{database}->{user}, $value->{database}->{passwd}",$database,""); return $dbh if($dbh); } } $bw->log("ERROR, dbconnect_extern call with dbname: $dbname |instance_type:$instance_type","",""); return ""; } #get operator conf by oprefix sub get_operator_conf { my $self = shift; my $oprefix = shift || ""; my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg"; my $conf = Config::General->new($globalconf_file); my %globalconf = $conf->getall; while (my ($key, $operator) = each %{ $globalconf{operator} }) { if($oprefix && $oprefix eq $operator->{oprefix}){ $bw->log("get operator conf by oprefix: $oprefix",$operator->{oprefix},""); return $operator; } } $bw->log("Cannot get operator conf by oprefix: $oprefix","",""); return 0; } #get dbname because varenv{dbname} seems not stable sub get_dbname { my $self = shift; my $dbh = shift || $dbh_intern; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); return $source; } #loop extern operator db's for specific tablefield sync sub update_operatorsloop { my $self = shift; my $dbname = shift || ""; my $adrc_id = shift || 0; my $todo = shift || "update"; use DBI::Const::GetInfoType; my $authref = { table => "contentadr", fetch => "one", template_id => "202", c_id => "$adrc_id", }; my $dbh_primary = $self->dbconnect_extern("sharee_primary"); my $source_primary = $dbh_primary->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $record_primary = { c_id => 0 }; $record_primary = $self->fetch_record($dbh_primary,$authref) if($adrc_id && $adrc_id > 0); $bw->log("update_operatorsloop by copri_instance-dbname: $dbname | owner: $record_primary->{owner} | get_info-dbname: $source_primary","",""); my $rows = 0; if($record_primary->{c_id}){ my %operator_hash = (); #keep in mind, shareedms-operators updates sharee_primary, that's because we have to also loop #if($dbname eq "sharee_primary"){ if($record_primary->{txt17}){ if($record_primary->{txt17} =~ /\w\s\w/){ %operator_hash = map { $_ => "$self->{operator}{$_}->{operatorApp}" } split(/\s+/,$record_primary->{txt17}); }else{ %operator_hash = ( "$record_primary->{txt17}" => "$self->{operator}{$record_primary->{txt17}}->{operatorApp}" ); } foreach my $sharee_operator (keys (%operator_hash)){ if($sharee_operator =~ /sharee_/){ $sharee_operator =~ s/\s//g; my $dbh_operator = $self->dbconnect_extern("$sharee_operator"); if($todo eq "update"){ #this will be saved by operator DMS and have to keep intividual $bw->log("disabled condition: if($sharee_operator ne $dbname || $record_primary->{owner} == 197 || $dbname eq \"sharee_primary\"","",""); #if($sharee_operator ne "$dbname" || $record_primary->{owner} == 197 || $dbname eq "sharee_primary"){ delete $record_primary->{txt17};#operators delete $record_primary->{txt30} if($dbname ne "sharee_lv" && $record_primary->{txt30} ne "5511");#Tarif, exception sharee_lv;#Tarif delete $record_primary->{txt15};#Bonusnr delete $record_primary->{int07};#Rabatt delete $record_primary->{txt18};#Service tour delete $record_primary->{int05};#Web-Login delete $record_primary->{int16};#payone-cron-interval delete $record_primary->{int19};#Ilockit Admin #delete $record_primary->{int12};#Vde (remove delete for global setting) delete $record_primary->{int23};#mini_answer count will be saved on operator delete $record_primary->{txt29};#Sonstiges #} my $update = { %$record_primary, table => "contentadr", }; $bw->log("--> save_account update_operatorsloop $sharee_operator by $source_primary",$update->{c_id},""); $bw->log("UPDATE adr from record_primary to operator on loop $sharee_operator",$record_primary->{c_id},""); $rows = $self->update_record($dbh_operator,$update,$record_primary); if($rows != 1){ $bw->log("INSERT adr from record_primary to operator on loop $sharee_operator",$record_primary->{c_id},""); my $insert = { %$record_primary, table => "contentadr", mtime => 'now()', }; #owner => "198", my $c_id = $self->insert_contentoid($dbh_operator,$insert,""); $rows = 1 if($c_id); #pseudo code copied fom net_booking. have to be done elsewehre because of $apif if(1==2){ my $ctadr = { c_id => $c_id }; my ($bike_group,$user_group,$tariff_content,$user_tour);# = $apif->fetch_tariff($ctadr,""); foreach my $id (keys (%$tariff_content)){ # #int18 # # 2 = "public" # 3 = "private" # 4 = "hidden-lv" # my $update_op = { table => "contentadr", }; if($tariff_content->{$id}->{int18} && ($tariff_content->{$id}->{int18} == 2 || $tariff_content->{$id}->{int18} == 3 || $tariff_content->{$id}->{int18} == 4)){ #if($tariff_content->{$id}->{int12} && $tariff_content->{$id}->{int12} == $ct->{main_id} && $tariff_content->{$id}->{barcode}){ $update_op->{txt30} = $tariff_content->{$id}->{barcode}; $rows = $self->update_record($dbh_operator,$update,$ctadr); #} } } } } }elsif($todo eq "delete"){ $bw->log("DELETE adr from operators and at last primary $sharee_operator",$record_primary,""); $rows += $self->delete_content($dbh_operator,"contentadr",$record_primary->{c_id}); } } } } #} } return $rows; } #return system and contentadr username by c_id (owner last change) sub sys_username { my $self = shift; my $dbh = shift || $dbh_intern; my $owner = shift || ""; my $u_name = ""; if(looks_like_number($owner)){ my $channel_map = $self->channel_map(); foreach my $id (sort { $channel_map->{$a} cmp $channel_map->{$b} } keys (%$channel_map)){ if($id == $owner){ $u_name = $channel_map->{$id}; } } if(!$u_name){ my $users_pref = { table => "contentadr", fetch => "one", c_id => $owner, }; my $ct_users = $self->fetch_tablerecord($dbh,$users_pref); $u_name = $ct_users->{txt01}; } } return $u_name; } #collect serviceapp and DMS users for search select username u_id mapping sub users_map(){ my $self = shift; my $dbh = shift || $dbh_intern; my $mapref = shift || ""; my $and = ""; if(ref($mapref) eq "HASH"){ foreach my $key (keys (%$mapref)){ $and = " and u.$key=$mapref->{$key}" if($key =~ /int/); } } my $sql = "SELECT ct.* FROM contentadr ct, users u WHERE ct.c_id=u.u_id $and"; my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); my $users_rec = $sth->fetchall_hashref('c_id'); $bw->log("DBtank users_map:",$sql,"") if($debug); return $users_rec; } #booking channel id's #TODO migrate all to global.cfg sub channel_map(){ my $self = shift; my $channel = { 173 => "merchant fallback",#mig 175 => "example App",#mig 176 => "Mein konrad App",#mig 177 => "LastenradBay App",#mig 179 => "cronjob", 178 => "payone API", 181 => "SMS API", 182 => "velofactur API", 183 => "Ilockit API", 184 => "web App",#mig 185 => "konstanz App",#mig 186 => "sharee App",#mig 187 => "shareetool App",#mig 188 => "sys API", 192 => "Web Bayern", 193 => "Web Demo",#mig 194 => "Web Example",#mig 195 => "Web KN",#mig and import 196 => "DMS Form std",#mig 197 => "Web Form std",#mig 198 => "primary",#mig 199 => "LV API",#mig }; return $channel; } #get tpl sub get_tpl { my $self = shift; my $dbh = shift || $dbh_intern; my $tpl_id = shift || 0; my $sth = $dbh->prepare("SELECT * FROM template WHERE tpl_id='$tpl_id'"); my $rc = $sth->execute(); my $tpl = $sth->fetchrow_hashref(); return $tpl; } #get uri_path and meta data like tpl_order by menue path sub get_node_meta { my $self = shift; my $dbh = shift || $dbh_intern; my $viewsel = shift; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $node_name1 = $q->escapeHTML(@{$viewsel}[-1]); my @node_path = ("$node_name1"); my $where = "WHERE n.main_id=rel.main_id and rel.template_id=tpl.tpl_id and node_name = '$node_name1'"; pop @{$viewsel}; my @reverse_viewsel = reverse(@{$viewsel}); #print Dumper(@reverse_viewsel) . "
\n"; #bsp #SELECT * FROM nodes n,relation rel, template tpl WHERE n.main_id=rel.main_id and rel.template_id=tpl.tpl_id and n.node_name = 'Firma' and n.parent_id IN (SELECT n.main_id from nodes n where n.node_name='Einstellung' and n.parent_id IN (SELECT n.main_id from nodes n where n.node_name='JBW')); foreach(@reverse_viewsel){ #print $_ . "
\n"; my $node_nameX = $q->escapeHTML($_); push(@node_path, $node_nameX); $where .= " and n.parent_id IN (SELECT n.main_id from nodes n where n.node_name='$node_nameX'"; } foreach(@reverse_viewsel){ $where .= ")"; } my $sql = "SELECT * FROM nodes n,relation rel, template tpl $where"; my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); my $nrt = $sth->fetchrow_hashref(); my @reverse_node_path = reverse(@node_path); my $uri_path = ""; foreach(@reverse_node_path){ $uri_path .= "$_/"; } $uri_path =~ s/\/$//; $bw->log("get_node_meta $uri_path | $source",$sql,"") if($debug); #print Dumper($nrt); return $nrt; } sub get_node { my $self = shift; my $dbh = shift || $dbh_intern; my $main_id = shift; my $sth = $dbh->prepare("SELECT * FROM nodes WHERE main_id=$main_id"); my $rc = $sth->execute(); my $node = $sth->fetchrow_hashref(); return $node; } # Nodes einer Ebene sub collect_node { my $self = shift; my $dbh = shift || $dbh_intern; my $main_id = shift; my $sth = $dbh->prepare("SELECT * FROM nodes WHERE parent_id=$main_id"); my $rc = $sth->execute(); my $nodes = $sth->fetchall_hashref("main_id"); my $rows = $sth->rows; return ($nodes,$rows); } # Nodes einer Ebene mit relation sub collect_noderel { my $self = shift; my $dbh = shift || $dbh_intern; my $main_id = shift; my $template_id = shift || ""; my $where = "WHERE n.main_id=rel.main_id and rel.content_id=0 and n.parent_id=$main_id"; $where .= " and rel.template_id=$template_id" if($template_id); my $sth = $dbh->prepare("SELECT * FROM nodes n, relation rel $where"); my $rc = $sth->execute(); my $nodes = $sth->fetchall_hashref("main_id"); my $rows = $sth->rows; return ($nodes,$rows); } #recursive node runner to get node path sub recurse_select { my $self = shift; my $dbh = shift || $dbh_intern; my $main_id = shift || ""; my $sth = $dbh->prepare("SELECT parent_id,node_name FROM nodes where main_id=$main_id"); my $rc = $sth->execute(); my $node = $sth->fetchrow_hashref(); return ($node->{parent_id},$node->{node_name}); } sub recurse_node { my $self = shift; my $dbh = shift || $dbh_intern; my $main_id = shift || ""; my $depth=$1 if($main_id =~ /^(\d)/); my $uri_path = "?failure=recurse_node"; my @nodes = (); if($main_id && $main_id > 20000){ $uri_path = ""; for(my $i=0; $i<$depth;$i++){ ($main_id,my $node_name) = $self->recurse_select($dbh,$main_id) if($main_id); push(@nodes, $node_name); #print $main_id . "|$node_name\n"; } my @node_path = reverse(@nodes); foreach(@node_path){ $uri_path .= "$_/"; } $uri_path =~ s/\/$//; } return $uri_path; } ############################### #get one subnode #ex. get contentpos template_id from subnode #select n.n_id,n.parent_id,n.main_id,rel.template_id from nodes n, relation rel where n.main_id=rel.main_id and n.parent_id=300029; # n_id | parent_id | main_id | template_id #------+-----------+---------+------------- # 431 | 300029 | 400004 | 401 sub get_subrelnode { my $self = shift; my $dbh = shift || $dbh_intern; my $main_id = shift; my $template_id = shift || ""; my $node_name = shift || ""; my $where = ""; $where .= " and rel.template_id = $template_id" if($template_id); $where .= " and n.node_name = '$node_name'" if($node_name); my $sql = "SELECT * FROM nodes n, relation rel where n.main_id=rel.main_id and n.parent_id=$main_id $where"; my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); my $node = $sth->fetchrow_hashref(); $bw->log("get_subrelnode",$sql,""); return $node; } #because of different and dynamic pos templates we need template grouping sub pos_template_group { my $self = shift; my $dbh = shift || $dbh_intern; my $fetch = shift; my $ctcp_where = "1=1"; if($fetch->{table} eq "content" && $fetch->{table_pos} eq "contentpos"){ $ctcp_where .= " and ct.c_id=cp.cc_id"; }elsif($fetch->{table} eq "contentadr" && $fetch->{table_pos} eq "contentadrpos"){ $ctcp_where .= " and ct.c_id=cp.ca_id"; } my $sql = "SELECT tpl_id,tpl_order from template where tpl_id IN (SELECT cp.template_id from $fetch->{table_pos} cp, $fetch->{table} ct where $ctcp_where group by cp.template_id)"; my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); my $templates = $sth->fetchall_hashref("tpl_id"); $bw->log("pos_template_group",$sql,""); return $templates; } #fetch relation, template, nodes sub fetch_rel4tpl4nd(){ my $self = shift; my $dbh = shift || $dbh_intern; my $fetch = shift; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); $fetch->{content_id}=0 if($fetch->{content_id} eq "null"); my $where = "WHERE nodes.main_id=relation.main_id and relation.template_id=template.tpl_id"; $where .= " and nodes.parent_id=$fetch->{parent_id}" if($fetch->{parent_id}); $where .= " and relation.main_id=$fetch->{main_id}" if($fetch->{main_id}); $where .= " and relation.content_id=$fetch->{content_id}" if($fetch->{content_id}); $where .= " and relation.template_id=$fetch->{template_id}" if($fetch->{template_id}); if($fetch->{template_id1} && $fetch->{template_id2}){ $where .= " and relation.template_id >= $fetch->{template_id1} and relation.template_id <= $fetch->{template_id2}"; } $where .= " and relation.rel_id=$fetch->{rel_id}" if($fetch->{rel_id}); $where .= " order by content_id $fetch->{ascdesc}" if($fetch->{ascdesc}); my $sql = "SELECT * FROM relation,template,nodes $where"; my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); my $rel = { main_id => 0 }; if($fetch->{fetch} eq "all" && $fetch->{keyfield}){ $rel = $sth->fetchall_hashref($fetch->{keyfield}); }else{ $rel = $sth->fetchrow_hashref(); } $bw->log("fetch_rel4tpl4nd $source",$sql,"") if($debug); return $rel; } #azn time worktime from Von Bis sub select_worktime { my $self = shift; my $dbh = shift || $dbh_intern; my $fetch = shift; my $sql = "SELECT $fetch->{end_at} - $fetch->{start_at} AS worktime FROM $fetch->{table} where ct_id = $fetch->{ct_id} and barcode = $fetch->{barcode} and $fetch->{end_at} is not null and $fetch->{start_at} is not null"; my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); my $record = $sth->fetchrow_hashref(); $bw->log("DBtank select_worktime: ",$sql,"") if($debug); return $record; } #Collect table ...post sub collect_post(){ my $self = shift; my $dbh = shift || $dbh_intern; my $fetch = shift; my $count = shift || ""; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $table; my $table_pos; my $ct_where = "1=1"; my $cp_where = "1=1"; my $ctcp_where = "1=1"; my $poscid; if($fetch->{table} eq "content" && $fetch->{table_pos} eq "contentpos"){ #*2 $ctcp_where .= " and ct.c_id=cp.cc_id"; $poscid = "cp.cc_id"; }elsif($fetch->{table} eq "contentadr" && $fetch->{table_pos} eq "contentadrpos"){ #*1 $ctcp_where .= " and ct.c_id=cp.ca_id"; $poscid = "cp.ca_id"; }elsif(($fetch->{table} eq "contenttrans" && $fetch->{table_pos} eq "contenttranspos") || ($fetch->{table} eq "contenttver" && $fetch->{table_pos} eq "contenttverpos")){ #*3 $ctcp_where .= " and ct.c_id=cp.ct_id"; $poscid = "cp.ct_id"; }else{ return; } foreach my $key (keys %$fetch){ if($fetch->{$key}){ $fetch->{$key} =~ s/^\s//g; $fetch->{$key} =~ s/\s$//g; my $op = "="; my $value = $fetch->{$key}; ($op, $value) = split(/::/, $fetch->{$key}) if($fetch->{$key} =~ /::/); if($key =~ /^(ct_name|txt\d+)$/ && $value){ if($op eq "IN"){ $cp_where .= " and cp.$key $op $value"; }else{ if($key eq "txt01" && $value =~ /NaN/){ $cp_where .= " and $value"; }else{ $cp_where .= " and cp.$key $op '$value'"; } } }elsif($key =~ /ct\.close_time|ct\.state|ct\.int14/ && $value){#used to get open invoices $ct_where .= " and $key $op $value"; }elsif($key =~ /time/ && $value){ if($value =~ /interval/){ $cp_where .= " and cp.$key $op $value";#format like (now() - integer '7 day') }elsif($key eq "time_range"){ $cp_where .= " and $value";#look at only_first_free }else{ $cp_where .= " and cp.$key $op '$value'"; } }elsif($varenv{systype} && $varenv{systype} eq "azn"){ if($key =~ /^ct\.(contentadr_id|owner|barcode|int\d+)$/ && $value){ $ct_where .= " and $key $op $value"; }elsif($key eq "barcode" && $fetch->{fetch} eq "all"){ if($value =~ /\d-\d/){ my ($start_val,$end_val) = split(/-/, $value); $cp_where .= " and (cp.$key >= $start_val AND cp.$key <= $end_val)"; }else{ my $start_val = $value . "01"; my $end_val = $value . "31"; $cp_where .= " and (cp.$key >= $start_val AND cp.$key <= $end_val)"; } }elsif($key =~ /^(c_id|ca_id|ct_id|owner|barcode|int\d+)$/ && $value){ $cp_where .= " and cp.$key $op $value"; } }elsif($key =~ /^(c_id|ca_id|ct_id|owner|barcode|int\d+)$/ && $value){ $cp_where .= " and cp.$key $op $value"; }elsif($fetch->{catch} && $key eq "template_id" && $value){ $cp_where .= " and cp.$key $op $value"; }elsif(!$fetch->{catch} && $key =~ /main_id|template_id/ && $value){ $ct_where .= " and rel.$key $op $value"; } } } my $sth; my $sql; my $limit = ""; $limit = "LIMIT $count" if(looks_like_number($count)); if($fetch->{catch} && $fetch->{catch} eq "content_contentpos"){ $sql = "SELECT cp.* from $fetch->{table_pos} cp, $fetch->{table} ct where $ctcp_where and $cp_where and $ct_where order by cp.mtime DESC $limit"; $sth = $dbh->prepare($sql); #+3 }else{ #adapated from search_content3 to get Category-Menue $sql = "SELECT cp.* FROM $fetch->{table_pos} cp WHERE $cp_where and $poscid IN (SELECT ct.c_id FROM relation rel, $fetch->{table} ct WHERE rel.content_id=ct.c_id and $ct_where) order by cp.mtime ASC";#mtime aufsteigend get last (newest) entry $sth = $dbh->prepare($sql); } my $rc = $sth->execute(); $bw->log("DBtank collect_post $source",$sql,"") if($debug); my $record = { c_id => 0 }; if($fetch->{fetch} eq "all" && $fetch->{keyfield}){ $record = $sth->fetchall_hashref($fetch->{keyfield}); }elsif($fetch->{fetch} eq "one"){ $record = $sth->fetchrow_hashref(); } return $record; } #fetch all|one content + relation + nodes sub fetch_record(){ my $self = shift; my $dbh = shift || $dbh_intern; my $fetch = shift; my $fetch_sql = shift || ""; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $where = "where ct.c_id=rel.content_id and nd.main_id=rel.main_id"; $where .= "$fetch_sql" if($fetch_sql);#enhancement to get bike_group OR my $order = ""; foreach my $key (keys %$fetch){ if($fetch->{$key}){ $fetch->{$key} =~ s/^\s//g; $fetch->{$key} =~ s/\s$//g; my $op = "="; my $value = $fetch->{$key}; ($op, $value) = split(/::/, $fetch->{$key}) if($fetch->{$key} =~ /::/); #$value = $q->escapeHTML($value);#In DB context will always done by API #can also be "rel.main_id IN (300005,300024)" $where .= " and rel.$key $op $value" if($key =~ /^(parent_id|main_id|template_id|rel_id)$/ && $value); if($key =~ /^(ct_name$|txt\d+|uri\d+|state)$/ && $value){ if($value =~ /length/){ $where .= " and $value"; }elsif($value eq "null"){ $where .= " and (ct.$key is null OR ct.$key = '')"; }else{ $where .= " and ct.$key $op '$value'"; } } if($key =~ /^(c_id|barcode|int\d+|owner|contentadr_id)$/){ if(looks_like_number($value) || $value eq "null"){ if($value eq "null"){ $where .= " and (ct.$key is null OR ct.$key = 0)"; }else{ $where .= " and ct.$key $op $value"; } }elsif($op eq "IN"){ $where .= " and ct.$key $op $value"; } } if($varenv{systype} && $varenv{systype} eq "azn" && $key =~ /start_time|end_time/){ if($key =~ /start_time/){ $where .= " and (ct.end_time >= '$fetch->{start_time}' AND ct.start_time <= '$fetch->{end_time}')"; $order = " order by ct.start_time DESC";#because to get ct_id for contenttverpos Übertrag } }elsif($key =~ /close_time$/ && $value){ $where .= " and ct.$key $op $value"; }elsif($key =~ /time$/ && $value){ if($value =~ /interval/){ $where .= " and ct.$key $op $value"; }else{ $where .= " and ct.$key $op '$value'"; } } } } #ct.* because of nd.txt01 and ct.txt01 . my $sql = "SELECT ct.*,rel.*,nd.node_name,nd.parent_id FROM $fetch->{table} ct, relation rel, nodes nd $where $order"; my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); $bw->log("DBtank fetch_record $source: $rc",$sql,"") if($debug); my $record = { c_id => 0 }; if($fetch->{fetch} eq "all" && $fetch->{keyfield}){ $record = $sth->fetchall_hashref($fetch->{keyfield}); }elsif($fetch->{fetch} eq "one"){ $record = $sth->fetchrow_hashref(); } return $record; } #fetch just in one table --> without relation ... sub fetch_tablerecord(){ my $self = shift; my $dbh = shift || $dbh_intern; my ($fetch) = @_; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $where = "where 1=1"; foreach my $key (keys %$fetch){ if($fetch->{$key}){ $fetch->{$key} =~ s/^\s//g; $fetch->{$key} =~ s/\s$//g; my $op = "="; my $value = $fetch->{$key}; ($op, $value) = split(/::/, $fetch->{$key}) if($fetch->{$key} =~ /::/); #print "$key: $fetch->{$key}|$op, $value\n"; #$value = $q->escapeHTML($value);#In DB context will always done by API if($key =~ /ct_name/ && $value =~ /CAST/){#CAST(c_id AS text) $where .= " and $key $op $value"; }elsif($key =~ /^(ct_name$|txt\d+|uri\d+|state)$/ && $value){ $where .= " and $key $op '$value'"; }elsif($key =~ /_itime$/ && $value){ $where .= " and itime $op '$value'"; }elsif($key =~ /time$/ && $value && $value =~ /interval/){#<= (now() - interval '15 minutes') $where .= " and $key $op $value"; }elsif($key =~ /time$/ && $value){ $where .= " and $key $op '$value'"; }elsif($key =~ /^(c_id|u_id|ct_id|ca_id|barcode|int\d+|owner|template_id)$/ && $value){ if($value eq "null"){ $where .= " and ($key is null OR $key = 0)"; }else{ $where .= " and $key $op $value"; } } } } $where .= " order by end_time DESC" if($fetch->{table} eq "contenttranspos");#prio data with newest end_time my $sql = "SELECT * FROM $fetch->{table} $where"; my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); $bw->log("DBtank fetch_tablerecord $source:",$sql,"") if($debug); my $record = { c_id => 0 }; if($fetch->{fetch} eq "all" && $fetch->{keyfield}){ $record = $sth->fetchall_hashref($fetch->{keyfield}); }elsif($fetch->{fetch} eq "one"){ $record = $sth->fetchrow_hashref(); } return $record; } #update sql sub update_sql(){ my $self = shift; my $dbh = shift || $dbh_intern; my $update_sql = shift; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $rows = 0; my $sql = "$update_sql"; my $sth = $dbh->prepare($sql); $rows = $sth->execute(); $bw->log("DBtank update_sql $source: $rows",$sql,"") if($debug); return $rows; } #update one value sub update_one(){ my $self = shift; my $dbh = shift || $dbh_intern; my $update = shift; my $one = shift; my $c_id = shift || ""; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $rows = 0; my $where = ""; if($c_id){ $where = "where c_id = $c_id"; }elsif($update->{c_id}){ $where = "where c_id = $update->{c_id}"; } if($update->{table} eq "users" && $update->{u_id}){ $where = "where u_id = $update->{u_id}"; } if($update->{table} eq "nodes" && $update->{main_id}){ $where = "where main_id = $update->{main_id}"; } if($update->{table} eq "relation" && $update->{main_id}){ $where = "where main_id = $update->{main_id} and content_id=0"; } if($update->{table} eq "relation" && $update->{rel_id}){ $where = "where rel_id = $update->{rel_id}"; } if($update->{table} =~ /^users|relation|node/){ $one .= ",change='now()'"; }else{ $one .= ",mtime='now()'"; } $one .= ",owner=$update->{owner}" if($update->{owner}); if($where){ my $sql = "UPDATE $update->{table} set $one $where"; my $sth = $dbh->prepare($sql); $rows = $sth->execute(); $bw->log("DBtank update_one $source: $rows",$sql,"") if($debug); } return $rows; } #update all sub update_record(){ my $self = shift; my $dbh = shift || $dbh_intern; my $update = shift; my $record = shift; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $where = ""; my $set = "set"; my $rows = 0; #print Dumper($update); if(looks_like_number($record->{c_id})){ $where = "where c_id = $record->{c_id}"; foreach my $key (keys %$update){ $update->{$key} =~ s/^\s//g if($update->{$key}); $update->{$key} =~ s/\s$//g if($update->{$key}); my $value = $update->{$key} || ""; $value = "$update->{$key}" if(looks_like_number($update->{$key})); #my $value = $q->escapeHTML($update->{$key});#In DB context will always done by API #print "$key=$value|$update->{$key}
\n"; if($key =~ /^(ct_name$|txt\d+|state|start_time|end_time|byte)/){ if($value && $value eq "null"){ $set .= " $key=$value,"; }else{ $set .= " $key='$value',"; } } if($key =~ /^(barcode|contentadr_id|int\d+|owner|owner_end|start_at\d+|end_at\d+)$/){ $value =~ s/,/\./ if($value); if($key =~ /int\d+|start_at\d+|end_at\d+/ && $value && $value =~ /\d+:\d+/){#azn time format $set .= " $key='$value',"; }elsif(looks_like_number($value) || ($value && $value eq "null")){ $set .= " $key=$value,"; }elsif($key =~ /int\d+/ && !$value){ $set .= " $key=null,";#we need this for null values in operators loop } } if($key =~ /(mtime|atime)$/){ if($value && $value =~ /^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}$/){ $set .= " $key='$value',"; }else{ $set .= " $key='now()',"; } } } } $set =~ s/,$//; my $sql = "UPDATE $update->{table} $set $where"; my $sth = $dbh->prepare($sql); $rows = $sth->execute(); $bw->log("DBtank update_record $source: $rows",$sql,"") if($debug); return $rows; }#update_record #insert content sub insert_users { my $self = shift; my $dbh = shift || $dbh_intern; my $u_id = shift; my $owner = shift; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $sql = "INSERT INTO users (u_id,itime,mtime,owner) VALUES ('$u_id','now()','now()','$owner')"; my $sth = $dbh->prepare($sql); my $rows = $sth->execute(); $bw->log("DBtank INSERT DMS users $source $rows",$sql,"") if($debug); return $u_id; } sub select_users(){ my $self = shift; my $dbh = shift || $dbh_intern; my $u_id = shift || 0; my $sqlcon = shift || "";#used with "and int09=1" my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $sql = "SELECT * FROM users WHERE u_id=$u_id $sqlcon"; my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); my $users = $sth->fetchrow_hashref(); $bw->log("DBtank SELECT DMS users $source u_id: $users->{u_id}",$sql,"") if($debug); return $users; } #insert content sub insert_contentoid { my $self = shift; my $dbh = shift || $dbh_intern; my $insert = shift; my $reset_keys = shift || ""; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); if($reset_keys eq "reset_adropkeys"){ delete $insert->{txt17};#operators delete $insert->{txt30} if($source ne "sharee_lv" && $insert->{txt30} ne "5511");#Tarif, exception sharee_lv delete $insert->{txt15};#Bonusnr delete $insert->{int07};#Rabatt delete $insert->{txt18};#Service tour delete $insert->{int05};#Web-Login delete $insert->{int16};#payone-cron-interval delete $insert->{int19};#Ilockit Admin #delete $insert->{int12};#Vde (remove delete for global setting) delete $insert->{txt29};#Sonstiges } my $columns = ""; my $values = ""; foreach my $key (keys(%$insert)){ $insert->{$key} =~ s/^\s//g if($insert->{$key}); $insert->{$key} =~ s/\s$//g if($insert->{$key}); #because of time format without of looks_like_number if($varenv{systype} && $varenv{systype} eq "azn" && $insert->{table} eq "contenttverpos" && $key =~ /start_at|end_at|int/){ $columns .= "$key,"; if(!$insert->{$key} || $insert->{$key} eq "null"){ $values .= "null,"; }else{ $values .= "'$insert->{$key}',"; } } #elsif($key =~ /contentadr_id|cc_id|ct_id|barcode|txt|int|time|owner/){ #2021-03-04 changed with c_id, ct_name and only insert if value elsif($key =~ /^c_id|ct_name|barcode|txt|int|time|owner/ && ($insert->{$key} || looks_like_number($insert->{$key}))){ $columns .= "$key,"; if($key =~ /_id|barcode|int|owner/ && !looks_like_number($insert->{$key})){ $values .= "null,"; }else{ $values .= "'$insert->{$key}',"; } } elsif($key =~ /template_id|cc_id|ct_id|ca_id/ && $insert->{table} =~ /contentpos|contentadrpos|contenttranspos/){ $columns .= "$key,"; $values .= "'$insert->{$key}',"; } } $columns =~ s/,$//; $values =~ s/,$//; my $sql = "INSERT INTO $insert->{table} ($columns) VALUES ($values) RETURNING c_id"; my $sth = $dbh->prepare($sql); my $rows = $sth->execute(); my $last_id; $sth->bind_columns(\$last_id); my $c_id = $sth->fetchrow_array(); $bw->log("insert_contentoid $source c_id: $c_id",$sql,"") if($debug); if($insert->{table} =~ /content$|contentadr|contenttrans$|contenttver$|contentusers$/ && $insert->{main_id} && $insert->{template_id}){ my $foreignkey = ""; $foreignkey = "ca_id" if($insert->{table} eq "contentadr"); $foreignkey = "cc_id" if($insert->{table} eq "content"); $foreignkey = "ct_id" if($insert->{table} eq "contenttrans"); $foreignkey = "cu_id" if($insert->{table} eq "contentusers"); $foreignkey = "cv_id" if($insert->{table} eq "contenttver"); my $sql_rel = "INSERT INTO relation (main_id,content_id,template_id,change,$foreignkey) VALUES('$insert->{main_id}','$c_id','$insert->{template_id}','now()','$c_id')"; my $sth3 = $dbh->prepare($sql_rel); $sth3->execute(); $bw->log("insert_contentoid relation $source c_id: $c_id",$sql_rel,"") if($debug); } return $c_id; } #delete content sub delete_content(){ my $self = shift; my $dbh = shift || $dbh_intern; my $table = shift; my $c_id = shift || 0; my $template_id = shift || ""; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $rows = 0; if($c_id){ my $where = "c_id=$c_id"; $where = "template_id = $template_id" if($table eq "contentpos" && $template_id && $c_id eq "all"); $where = "u_id=$c_id" if($table eq "users"); my $sql = "DELETE FROM $table WHERE $where"; my $sth = $dbh->prepare($sql); $rows = $sth->execute(); $bw->log("delete_content $source: $rows",$sql,"") if($debug); } return $rows; } #collect contenttranspos with contenttrans sub collect_transpos { my $self = shift; my $dbh = shift || $dbh_intern; my $search = shift; $search->{offset} = 0 if(!$search->{offset}); my $updown = "ASC"; $updown = "DESC" if($search->{cal_sort_updown} eq "down"); my $where = "where cp.ct_id=ct.c_id"; foreach my $key (%$search){ $search->{$key} =~ s/\s//g; $where .= " and cp.c_id = $search->{$key}" if($key eq "cttpos_id" && $search->{$key}); $where .= " and cp.end_time >= '$search->{$key}'" if($key eq "start_date_time"); $where .= " and cp.end_time <= '$search->{$key}'" if($key eq "end_date_time"); $where .= " and cp.start_time <= '$search->{$key}'" if($key eq "end_date_time"); $where .= " and cp.$key ilike '%$search->{$key}%'" if($key eq "txt08" && $search->{$key}); $where .= " and (cp.int04 = $search->{$key} OR cp.int06 = $search->{$key})" if($key eq "int04" && looks_like_number($search->{$key})); $where .= " and cp.ct_name = '$search->{$key}'" if($key eq "cp_ct_name" && $search->{$key}); $where .= " and ct.ct_name = '$search->{$key}'" if($key eq "ct_ct_name" && $search->{$key}); $where .= " and ct.txt06 ilike '$search->{$key}%'" if($key eq "ct_txt06" && $search->{$key});#PLZ $where .= " and cp.$key = $search->{$key}" if($key eq "int10" && looks_like_number($search->{$key}));#bike_state $where .= " and cp.$key = $search->{$key}" if($key eq "int20" && looks_like_number($search->{$key}));#lock_state $where .= " and cp.$key = $search->{$key}" if($key eq "barcode" && looks_like_number($search->{$key})); $where .= " and cp.$key = $search->{$key}" if($key eq "int12" && looks_like_number($search->{$key}));#bike_group $where .= " and cp.$key = $search->{$key}" if($key eq "owner" && looks_like_number($search->{$key})); } $where .= " ORDER BY cp.end_time $updown LIMIT $search->{limit} OFFSET $search->{offset}" if($search->{limit}); my $sth = $dbh->prepare("SELECT cp.* from $search->{table} cp, contenttrans ct $where"); my $rc = $sth->execute(); my $ct = $sth->fetchall_hashref("c_id"); $sth->finish; return $ct; } #collect contenttheftpos sub collect_theftpos { my $self = shift; my $dbh = shift || $dbh_intern; my $search = shift; $search->{offset} = 0 if(!$search->{offset}); my $updown = "ASC"; $updown = "DESC" if($search->{cal_sort_updown} eq "down"); my $where = "where 1=1"; foreach my $key (%$search){ $search->{$key} =~ s/\s//g; $where .= " and cp.c_id = $search->{$key}" if($key eq "cttpos_id" && $search->{$key}); $where .= " and cp.end_time >= '$search->{$key}'" if($key eq "start_date_time"); $where .= " and cp.end_time <= '$search->{$key}'" if($key eq "end_date_time"); $where .= " and cp.start_time <= '$search->{$key}'" if($key eq "end_date_time"); $where .= " and cp.$key ilike '%$search->{$key}%'" if($key eq "txt06" && $search->{$key}); $where .= " and cp.$key = $search->{$key}" if($key eq "int10" && looks_like_number($search->{$key}));#bike_state $where .= " and cp.$key = $search->{$key}" if($key eq "int20" && looks_like_number($search->{$key}));#lock_state $where .= " and cp.$key = $search->{$key}" if($key eq "barcode" && looks_like_number($search->{$key})); $where .= " and cp.$key = $search->{$key}" if($key eq "int12" && looks_like_number($search->{$key}));#bike_group $where .= " and cp.$key = $search->{$key}" if($key eq "int13" && looks_like_number($search->{$key}));#deviceId $where .= " and cp.$key = $search->{$key}" if($key eq "owner" && looks_like_number($search->{$key})); } $where .= " ORDER BY cp.end_time $updown LIMIT $search->{limit} OFFSET $search->{offset}" if($search->{limit}); my $sth = $dbh->prepare("SELECT cp.* from $search->{table} cp $where"); my $rc = $sth->execute(); my $ct = $sth->fetchall_hashref("c_id"); $sth->finish; return $ct; } # new node sub insert_nodeoid(){ my $self = shift; my $dbh = shift || $dbh_intern; my $insert = shift; #my ($parent_id,$main_id,$node_name,$lang,$sort,$template_id,$c_id,$owner) = @_; my $node_name = $insert->{node_name}; my $node_path = $insert->{node_name}; ($node_name,$node_path) = split(/\|/,$node_name) if($node_name =~ /\|/); my $sth2 = $dbh->prepare("INSERT INTO nodes (main_id,parent_id,lang,node_name,node_path,n_sort,owner) VALUES('$insert->{main_id}','$insert->{parent_id}','$insert->{lang}','$node_name','$node_path','$insert->{n_sort}','$insert->{owner}')"); my $rc = $sth2->execute(); $sth2 = $dbh->prepare("INSERT INTO relation (main_id,template_id,content_id,lang,change) VALUES('$insert->{main_id}','$insert->{template_id}','$insert->{content_id}','$insert->{lang}','now()') RETURNING rel_id"); $rc = $sth2->execute(); my $last_id; $sth2->bind_columns(\$last_id); my $rel_id = $sth2->fetchrow_array(); return $rel_id; } # Delete node and relation! (without content) sub delete_noderel(){ my $self = shift; my $dbh = shift || $dbh_intern; my $main_id = shift; my $sth = $dbh->prepare("DELETE FROM relation WHERE main_id=$main_id and content_id=0"); my $rc = $sth->execute(); $sth = $dbh->prepare("DELETE FROM nodes WHERE main_id=$main_id"); $rc = $sth->execute(); $sth->finish(); return $rc; } sub delete_template(){ my $self = shift; my $dbh = shift || $dbh_intern; my $tpl_id = shift; my $sth = $dbh->prepare("DELETE FROM template WHERE tpl_id=$tpl_id"); my $rc = $sth->execute(); return $rc; } # get next free node sub get_freenode(){ my $self = shift; my $dbh = shift || $dbh_intern; my $prefix_id = shift; my $s_id = "$prefix_id"; my $e_id = "$prefix_id"; $s_id .= "00001"; $e_id .= "99999"; my $main_id = ""; for (my $x_id=$s_id; $x_id < $e_id; $x_id++){ my $sth1 = $dbh->prepare("SELECT main_id from nodes where main_id='$x_id'"); my $rc1 = $sth1->execute(); $main_id = $sth1->fetchrow_array(); if(!$main_id){ return $x_id; } } } # # get next free template id sub get_freetpl(){ my $self = shift; my $dbh = shift || $dbh_intern; my ($s_id,$e_id) = @_; my $tpl_id = ""; for (my $x_id=$s_id; $x_id < $e_id; $x_id++){ my $sth1 = $dbh->prepare("SELECT tpl_id from template where tpl_id='$x_id'"); my $rc1 = $sth1->execute(); $tpl_id = $sth1->fetchrow_array(); if(!$tpl_id){ return $x_id; } } } # # copy template sub copy_template(){ my $self = shift; my $dbh = shift || $dbh_intern; my $master_tpl_id = shift; my $new_tpl_id = shift; my $owner = shift; my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} ); my $columns = "tpl_name,tpl_order,ct_table,tpl_height,tpl_width,bg_color"; my $sql = "INSERT INTO template ($columns) SELECT $columns from template where tpl_id=$master_tpl_id RETURNING tpl_id"; my $sth = $dbh->prepare($sql); my $rows = $sth->execute(); my $last_id; $sth->bind_columns(\$last_id); my $auto_tpl_id = $sth->fetchrow_array(); $bw->log("DBtank copy_template $source: $rows",$sql,"") if($debug); my $sth2 = $dbh->prepare("UPDATE template set tpl_id=$new_tpl_id, change='now()',owner=$owner where tpl_id=$auto_tpl_id"); $rows = $sth2->execute(); return $new_tpl_id; } #content of txt08 changed to ctadr->{txt01} Name sub insert_pos(){ my $self = shift; my $dbh = shift || $dbh_intern; my $ctt_id = shift; my $ct = shift; my $ctadr = shift; my $ct_tariff = shift || ""; my $endRental = shift || "0000-00-00"; my $artikelnr = shift; my $status = shift; my $owner = shift; $artikelnr = $ct->{barcode} if(!$artikelnr);#RadID my $user_name = $ctadr->{txt01}; $user_name = $ctadr->{txt08} if(!$user_name || $user_name eq "no name"); my $deviceId = $ct->{int13} || 0; my $bike_charge = $ct->{int19} || 0; my $trackon = $ct->{int25} || 0; my $from_main_id = $ct->{main_id} || 0; my $station = $ct->{int04} || 0; my $rabatt = 0; my $unit_price = $ct->{int02} || 0; my $day_maxprice = 0; my $abo_price = 0; my $tariff_nr = 0; my $tariff_desc; my $free_hours = 0; my $sharing_type = 0; my $menge = 0; if(ref($ct_tariff) eq "HASH"){ $rabatt = $ctadr->{int07} || 0; $unit_price = $ct_tariff->{int02} || 0; $tariff_nr = $ct_tariff->{barcode} || 0; $tariff_desc = $ct_tariff->{ct_name}; $day_maxprice = $ct_tariff->{int17} || 0; $abo_price = $ct_tariff->{int15} || 0; $free_hours = $ct_tariff->{int16} || 0; $sharing_type = $ct_tariff->{int18} || 0; } my $sth; #Verleihräder if($ct->{template_id} && $ct->{template_id} == 205){#Leihrad_list $sth = $dbh->prepare("INSERT INTO contenttranspos (ct_id,cc_id,ca_id,ct_name,barcode,txt01,txt08,txt02,txt09,itime,start_time,end_time,int02,int03,int06,int04,txt05,txt06,txt07,int10,int12,int13,owner,int07,txt04,int09,int17,int15,int16,int11,int18,int19,txt17,txt18,int20,int25) VALUES ('$ctt_id','$ct->{c_id}','$ctadr->{c_id}','$artikelnr','$ct->{barcode}','$ct->{txt01}','$user_name','$ct->{txt02}','$ctadr->{txt09}',now(),now(),'$endRental','$unit_price','$menge','$station','$station','$ct->{txt06}','$ct->{txt06}','$ct->{txt07}','$status','$from_main_id','$deviceId','$owner','$rabatt','$tariff_desc','$tariff_nr','$day_maxprice','$abo_price','$free_hours','$ct->{int11}','$sharing_type','$bike_charge','$ct->{txt17}','$ct->{txt18}','$ct->{int20}','$trackon') RETURNING c_id"); }else{ $sth = $dbh->prepare("INSERT INTO contenttranspos (ct_id,cc_id,ca_id,ct_name,barcode,txt08,txt09,itime,int02,int03,txt01,txt06,txt07,int10,int12,owner) VALUES ('$ctt_id','$ct->{c_id}','$ctadr->{c_id}','$artikelnr','0','$user_name','$ctadr->{txt09}',now(),'$unit_price','1','$ct->{txt01}','$ct->{txt06}','$ct->{txt07}','0','$from_main_id','$owner') RETURNING c_id"); } my $rows = $sth->execute(); my $last_id; $sth->bind_columns(\$last_id); my $c_id = $sth->fetchrow_array(); if($c_id && $status){ #update Leihräder in Stammdaten my $set2 = "owner=$owner" if($owner); $set2 .= ",int10='$status'" if($status); $set2 .= ",mtime='now()'"; my $sth2 = $dbh->prepare("UPDATE content SET $set2 where barcode='$ct->{barcode}'"); my $rows2 = $sth2->execute(); } return $c_id; } # insert contenttrans sub insert_contenttrans(){ my $self = shift; my $dbh = shift || $dbh_intern; my $ctadr = shift; my $main_id = shift; my $tpl_id = shift; my $invoice_nr = shift || "----"; my $owner = shift || 0; $owner="199" if(!$owner); my $sth = $dbh->prepare("INSERT INTO contenttrans (ct_name,txt00,int10,int03,txt02,txt01,txt03,txt06,txt07,txt08,txt09,txt15,txt17,txt18,txt19,owner,itime) VALUES('$invoice_nr','Rechnung','$ctadr->{c_id}','$ctadr->{int03}','$ctadr->{txt02}','$ctadr->{txt01}','$ctadr->{txt03}','$ctadr->{txt06}','$ctadr->{txt07}','$ctadr->{txt08}','$ctadr->{txt09}','$ctadr->{txt15}','$ctadr->{txt17}','$ctadr->{txt18}','$ctadr->{txt19}','$owner','now()') RETURNING c_id"); my $rows = $sth->execute(); my $last_id; $sth->bind_columns(\$last_id); my $c_id = $sth->fetchrow_array(); my $sth3 = $dbh->prepare("INSERT INTO relation (ca_id,main_id,content_id,template_id,change) VALUES('$ctadr->{c_id}','$main_id','$c_id','$tpl_id','now()')"); $sth3->execute(); return $c_id; } #compute amount of wawi content sub update_content4comp(){ my $self = shift; my $dbh = shift || $dbh_intern; my $c_id = shift || 0; my $op = shift; my $amount = shift; my $where = "c_id=$c_id"; my $ct_set = "int03=(int03 $op $amount)"; my $sth = $dbh->prepare("UPDATE content SET $ct_set where $where"); my $rows = $sth->execute(); return $rows; } 1;