diff --git a/contrib/DS_Starter/93_DbRep.pm b/contrib/DS_Starter/93_DbRep.pm index 47ed01166..ae51c5955 100644 --- a/contrib/DS_Starter/93_DbRep.pm +++ b/contrib/DS_Starter/93_DbRep.pm @@ -1,5 +1,5 @@ ########################################################################################################## -# $Id: 93_DbRep.pm 22678 2020-08-27 17:05:24Z DS_Starter $ +# $Id: 93_DbRep.pm 22733 2020-09-04 19:33:12Z DS_Starter $ ########################################################################################################## # 93_DbRep.pm # @@ -57,6 +57,7 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch'; # Version History intern our %DbRep_vNotesIntern = ( + "8.40.8" => "17.09.2020 sqlCmd supports PREPARE statament, commandRef revised ", "8.40.7" => "03.09.2020 rename getter dbValue to sqlCmdBlocking, consider attr timeout in function DbRep_sqlCmdBlocking (blocking function), commandRef revised ", "8.40.6" => "27.08.2020 commandRef revised ", "8.40.5" => "29.07.2020 fix crash if delEntries startet without any time limits, Forum:#113202 ", @@ -6189,17 +6190,20 @@ sub sqlCmd_DoParse { # only for this block because of warnings if details of readings are not set no warnings 'uninitialized'; - my $sql = ($cmd =~ m/\;$/)?$cmd:$cmd.";"; + $cmd =~ s/\;\;/ESC_ESC_ESC/gx; # ersetzen von escapeten ";" (;;) + + my $sql = ($cmd =~ m/\;$/) ? $cmd : $cmd.";"; # Set Session Variablen "SET" oder PRAGMA aus Attribut "sqlCmdVars" my $vars = AttrVal($name, "sqlCmdVars", ""); if ($vars) { @pms = split(";",$vars); - foreach my $pm (@pms) { + for my $pm (@pms) { if($pm !~ /PRAGMA|SET/i) { next; } $pm = ltrim($pm).";"; + $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";" Log3($name, 4, "DbRep $name - Set VARIABLE or PRAGMA: $pm"); eval {$dbh->do($pm);}; if ($@) { @@ -6213,15 +6217,24 @@ sub sqlCmd_DoParse { # Abarbeitung von Session Variablen vor einem SQL-Statement # z.B. SET @open:=NULL, @closed:=NULL; Select ... - if($cmd =~ /^\s*SET.*;/i) { + if($cmd =~ /^\s*(SET|PREPARE).*;/i) { @pms = split(";",$cmd); - foreach my $pm (@pms) { - if($pm !~ /SET/i) { + for my $pm (@pms) { + + if($pm !~ /SET|PREPARE/i) { $sql = $pm.";"; next; } + $pm = ltrim($pm).";"; - Log3($name, 4, "DbRep $name - Set SQL session variable: $pm"); + $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";" + + if($pm =~ /SET/i) { + Log3($name, 4, "DbRep $name - Set SQL session variable: $pm"); + } else { + Log3($name, 4, "DbRep $name - Exec PREPARE statement: $pm"); + } + eval {$dbh->do($pm);}; if ($@) { $err = encode_base64($@,""); @@ -6234,15 +6247,24 @@ sub sqlCmd_DoParse { # Abarbeitung aller Pragmas vor einem SQLite Statement, SQL wird extrahiert # wenn Pragmas im SQL vorangestellt sind - if($cmd =~ /^\s*PRAGMA.*;/i) { + if($cmd =~ /^\s*(PRAGMA|PREPARE).*;/i) { @pms = split(";",$cmd); - foreach my $pm (@pms) { - if($pm !~ /PRAGMA/i) { + for my $pm (@pms) { + + if($pm !~ /PRAGMA|PREPARE/i) { $sql = $pm.";"; next; } + $pm = ltrim($pm).";"; - Log3($name, 4, "DbRep $name - Exec PRAGMA Statement: $pm"); + $pm =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";" + + if($pm =~ /PRAGMA/i) { + Log3($name, 4, "DbRep $name - Exec PRAGMA Statement: $pm"); + } else { + Log3($name, 4, "DbRep $name - Exec PREPARE statement: $pm"); + } + eval {$dbh->do($pm);}; if ($@) { $err = encode_base64($@,""); @@ -6257,6 +6279,8 @@ sub sqlCmd_DoParse { $sql =~ s/§timestamp_begin§/'$runtime_string_first'/g; $sql =~ s/§timestamp_end§/'$runtime_string_next'/g; + $sql =~ s/ESC_ESC_ESC/;/gx; # wiederherstellen von escapeten ";" -> umwandeln von ";;" in ";" + Log3($name, 4, "DbRep $name - SQL execute: $sql"); # SQL-Startzeit @@ -6265,7 +6289,7 @@ sub sqlCmd_DoParse { my ($sth,$r); eval {$sth = $dbh->prepare($sql); - $r = $sth->execute(); + $r = $sth->execute(); }; if ($@) { @@ -6295,6 +6319,7 @@ sub sqlCmd_DoParse { # Anzahl der Datensätze $nrows++; } + } else { $nrows = $sth->rows; eval {$dbh->commit() if(!$dbh->{AutoCommit});}; @@ -6312,17 +6337,16 @@ sub sqlCmd_DoParse { $sth->finish; - # SQL-Laufzeit ermitteln - my $rt = tv_interval($st); + my $rt = tv_interval($st); # SQL-Laufzeit ermitteln $dbh->disconnect; - # Daten müssen als Einzeiler zurückgegeben werden - my $rowstring = join("§", @rows); - $rowstring = encode_base64($rowstring,""); - - # Background-Laufzeit ermitteln - my $brt = tv_interval($bst); + my $rowstring = join("§", @rows); # Daten müssen als Einzeiler zurückgegeben werden + $rowstring = encode_base64($rowstring,""); + + $cmd =~ s/ESC_ESC_ESC/;;/gx; # wiederherstellen der escapeten ";" -> ";;" + + my $brt = tv_interval($bst); # Background-Laufzeit ermitteln $rt = $rt.",".$brt; @@ -11499,12 +11523,12 @@ sub DbRep_setVersionInfo { if($modules{$type}{META}{x_prereqs_src} && !$hash->{HELPER}{MODMETAABSENT}) { # META-Daten sind vorhanden $modules{$type}{META}{version} = "v".$v; # Version aus META.json überschreiben, Anzeige mit {Dumper $modules{SMAPortal}{META}} - if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 93_DbRep.pm 22678 2020-08-27 17:05:24Z DS_Starter $ im Kopf komplett! vorhanden ) + if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 93_DbRep.pm 22733 2020-09-04 19:33:12Z DS_Starter $ im Kopf komplett! vorhanden ) $modules{$type}{META}{x_version} =~ s/1.1.1/$v/g; } else { $modules{$type}{META}{x_version} = $v; } - return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 93_DbRep.pm 22678 2020-08-27 17:05:24Z DS_Starter $ im Kopf komplett! vorhanden ) + return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 93_DbRep.pm 22733 2020-09-04 19:33:12Z DS_Starter $ im Kopf komplett! vorhanden ) if(__PACKAGE__ eq "FHEM::$type" || __PACKAGE__ eq $type) { # es wird mit Packages gearbeitet -> Perl übliche Modulversion setzen # mit {->VERSION()} im FHEMWEB kann Modulversion abgefragt werden @@ -12815,15 +12839,19 @@ return; The used database user needs the ALTER, CREATE and INDEX privilege.

- -
  • insert - use it to insert data ito table "history" manually. Input values for Date, Time and Value are mandatory. The database fields for Type and Event will be filled in with "manual" automatically and the values of Device, Reading will be get from set attributes.

    + + +
  • insert - data are inserted into table "history" manually. Input values for Date, Time and Value are + mandatory. The database fields for Type and Event will be filled in with "manual" automatically. + The values of device, reading use the + attribute settings .