2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-25 16:05:19 +00:00

93_DbLog: contrib 5.3.0

git-svn-id: https://svn.fhem.de/fhem/trunk@26804 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2022-12-06 19:43:01 +00:00
parent 935a4d6c34
commit 1666d3c6f9

View File

@ -40,7 +40,7 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
# Version History intern by DS_Starter: # Version History intern by DS_Starter:
my %DbLog_vNotesIntern = ( my %DbLog_vNotesIntern = (
"5.3.0" => "05.12.2022 activate func _DbLog_SBP_onRun_Log, implement count command non blocking with SBP ", "5.3.0" => "05.12.2022 activate func _DbLog_SBP_onRun_Log, implement commands with SBP: count(Nbl), deleteOldDays(Nbl) ",
"5.2.0" => "05.12.2022 LONGRUN_PID, \$hash->{prioSave}, rework SetFn ", "5.2.0" => "05.12.2022 LONGRUN_PID, \$hash->{prioSave}, rework SetFn ",
"5.1.0" => "03.12.2022 implement SubProcess for logging data in synchron Mode ", "5.1.0" => "03.12.2022 implement SubProcess for logging data in synchron Mode ",
"5.0.0" => "02.12.2022 implement SubProcess for logging data in asynchron Mode, delete attr traceHandles ", "5.0.0" => "02.12.2022 implement SubProcess for logging data in asynchron Mode, delete attr traceHandles ",
@ -269,19 +269,21 @@ my %DbLog_vNotesIntern = (
############### ###############
my %DbLog_hset = ( # Hash der Set-Funktion my %DbLog_hset = ( # Hash der Set-Funktion
listCache => { fn => \&_DbLog_setlistCache }, listCache => { fn => \&_DbLog_setlistCache },
clearReadings => { fn => \&_DbLog_setclearReadings }, clearReadings => { fn => \&_DbLog_setclearReadings },
eraseReadings => { fn => \&_DbLog_seteraseReadings }, eraseReadings => { fn => \&_DbLog_seteraseReadings },
stopSubProcess => { fn => \&_DbLog_setstopSubProcess }, stopSubProcess => { fn => \&_DbLog_setstopSubProcess },
purgeCache => { fn => \&_DbLog_setpurgeCache }, purgeCache => { fn => \&_DbLog_setpurgeCache },
commitCache => { fn => \&_DbLog_setcommitCache }, commitCache => { fn => \&_DbLog_setcommitCache },
configCheck => { fn => \&_DbLog_setconfigCheck }, configCheck => { fn => \&_DbLog_setconfigCheck },
reopen => { fn => \&_DbLog_setreopen }, reopen => { fn => \&_DbLog_setreopen },
rereadcfg => { fn => \&_DbLog_setrereadcfg }, rereadcfg => { fn => \&_DbLog_setrereadcfg },
addLog => { fn => \&_DbLog_setaddLog }, addLog => { fn => \&_DbLog_setaddLog },
addCacheLine => { fn => \&_DbLog_setaddCacheLine }, addCacheLine => { fn => \&_DbLog_setaddCacheLine },
count => { fn => \&_DbLog_setcount }, count => { fn => \&_DbLog_setcount },
countNbl => { fn => \&_DbLog_setcount }, countNbl => { fn => \&_DbLog_setcount },
deleteOldDays => { fn => \&_DbLog_setdeleteOldDays },
deleteOldDaysNbl => { fn => \&_DbLog_setdeleteOldDays },
); );
my %DbLog_columns = ("DEVICE" => 64, my %DbLog_columns = ("DEVICE" => 64,
@ -462,8 +464,6 @@ sub DbLog_Undef {
delete $hash->{HELPER}{LONGRUN_PID}; delete $hash->{HELPER}{LONGRUN_PID};
BlockingKill($hash->{HELPER}{REDUCELOG_PID}) if($hash->{HELPER}{REDUCELOG_PID}); BlockingKill($hash->{HELPER}{REDUCELOG_PID}) if($hash->{HELPER}{REDUCELOG_PID});
BlockingKill($hash->{HELPER}{COUNT_PID}) if($hash->{HELPER}{COUNT_PID});
BlockingKill($hash->{HELPER}{DELDAYS_PID}) if($hash->{HELPER}{DELDAYS_PID});
$dbh->disconnect() if(defined($dbh)); $dbh->disconnect() if(defined($dbh));
@ -575,7 +575,7 @@ sub DbLog_Attr {
InternalTimer(gettimeofday()+1.5, 'DbLog_attrForSQLite', $hash, 0); # muß zweimal ausgeführt werden - Grund unbekannt :-( InternalTimer(gettimeofday()+1.5, 'DbLog_attrForSQLite', $hash, 0); # muß zweimal ausgeführt werden - Grund unbekannt :-(
DbLog_SBP_dbDisconnect ($hash, 1); # DB Verbindung und Verbindungsdaten im SubProzess löschen DbLog_SBP_sendDbDisconnect ($hash, 1); # DB Verbindung und Verbindungsdaten im SubProzess löschen
InternalTimer(gettimeofday()+2.0, 'DbLog_SBP_sendConnectionData', $hash, 0); # neue Verbindungsdaten an SubProzess senden InternalTimer(gettimeofday()+2.0, 'DbLog_SBP_sendConnectionData', $hash, 0); # neue Verbindungsdaten an SubProzess senden
} }
@ -611,7 +611,7 @@ sub DbLog_Attr {
} }
if ($init_done == 1) { if ($init_done == 1) {
DbLog_SBP_dbDisconnect ($hash, 1); # DB Verbindung und Verbindungsdaten im SubProzess löschen DbLog_SBP_sendDbDisconnect ($hash, 1); # DB Verbindung und Verbindungsdaten im SubProzess löschen
InternalTimer(gettimeofday()+2.0, 'DbLog_SBP_sendConnectionData', $hash, 0); # neue Verbindungsdaten an SubProzess senden InternalTimer(gettimeofday()+2.0, 'DbLog_SBP_sendConnectionData', $hash, 0); # neue Verbindungsdaten an SubProzess senden
} }
@ -676,7 +676,7 @@ sub DbLog_Attr {
} }
if ($init_done == 1) { if ($init_done == 1) {
DbLog_SBP_dbDisconnect ($hash, 1); # DB Verbindung und Verbindungsdaten im SubProzess löschen DbLog_SBP_sendDbDisconnect ($hash, 1); # DB Verbindung und Verbindungsdaten im SubProzess löschen
InternalTimer(gettimeofday()+2.0, 'DbLog_SBP_sendConnectionData', $hash, 0); # neue Verbindungsdaten an SubProzess senden InternalTimer(gettimeofday()+2.0, 'DbLog_SBP_sendConnectionData', $hash, 0); # neue Verbindungsdaten an SubProzess senden
} }
@ -784,6 +784,7 @@ sub DbLog_Set {
my $params = { my $params = {
hash => $hash, hash => $hash,
name => $name, name => $name,
dbname => $db,
argsref => \@args, argsref => \@args,
opt => $opt, opt => $opt,
prop => $prop, prop => $prop,
@ -960,62 +961,6 @@ sub DbLog_Set {
return; return;
} }
elsif ($opt eq 'deleteOldDays') {
Log3 ($name, 2, qq{DbLog $name - WARNING - "$opt" is outdated. Please consider use of DbRep "set <Name> delEntries" instead.});
Log3 ($name, 3, "DbLog $name - Deletion of records older than $prop days in database $db requested");
my ($c, $cmd);
$dbh = _DbLog_ConnectNewDBH($hash);
if(!$dbh) {
Log3($name, 1, "DbLog $name: DBLog_Set - deleteOldDays - DB connect not possible");
return;
}
else {
$cmd = "delete from $history where TIMESTAMP < ";
if ($hash->{MODEL} eq 'SQLITE') { $cmd .= "datetime('now', '-$prop days')"; }
elsif ($hash->{MODEL} eq 'MYSQL') { $cmd .= "DATE_SUB(CURDATE(),INTERVAL $prop DAY)"; }
elsif ($hash->{MODEL} eq 'POSTGRESQL') { $cmd .= "NOW() - INTERVAL '$prop' DAY"; }
else { $cmd = undef; $ret = 'Unknown database type. Maybe you can try userCommand anyway.'; }
if(defined($cmd)) {
$c = $dbh->do($cmd);
$c = 0 if($c == 0E0);
eval {$dbh->commit() if(!$dbh->{AutoCommit});};
$dbh->disconnect();
Log3 ($name, 3, "DbLog $name - deleteOldDays finished. $c entries of database $db deleted.");
readingsSingleUpdate($hash, 'lastRowsDeleted', $c ,1);
}
InternalTimer(gettimeofday()+5, 'DbLog_execMemCacheAsync', $hash, 0);
}
}
elsif ($opt eq 'deleteOldDaysNbl') {
Log3($name, 2, qq{DbLog $name - WARNING - "$opt" is outdated. Please consider use of DbRep "set <Name> delEntries" instead.});
if (defined $prop && $prop =~ /^\d+$/) {
if ($hash->{HELPER}{DELDAYS_PID} && $hash->{HELPER}{DELDAYS_PID}{pid} !~ m/DEAD/) {
$ret = "deleteOldDaysNbl already in progress. Please wait until the running process is finished.";
}
else {
delete $hash->{HELPER}{DELDAYS_PID};
$hash->{HELPER}{DELDAYS} = $prop;
Log3 ($name, 3, "DbLog $name - Deletion of records older than $prop days in database $db requested");
$hash->{HELPER}{DELDAYS_PID} = BlockingCall("DbLog_deldaysNbl","$name","DbLog_deldaysNbl_done");
return;
}
}
else {
Log3($name, 1, "DbLog $name: deleteOldDaysNbl error, no <days> given.");
$ret = "deleteOldDaysNbl error, no <days> given.";
}
}
elsif ($opt eq 'userCommand') { elsif ($opt eq 'userCommand') {
Log3 ($name, 2, qq{DbLog $name - WARNING - "$opt" is outdated. Please consider use of DbRep "set <Name> sqlCmd" instead.}); Log3 ($name, 2, qq{DbLog $name - WARNING - "$opt" is outdated. Please consider use of DbRep "set <Name> sqlCmd" instead.});
$dbh = _DbLog_ConnectNewDBH($hash); $dbh = _DbLog_ConnectNewDBH($hash);
@ -1181,7 +1126,7 @@ sub _DbLog_setreopen { ## no critic "not used"
$dbh->disconnect(); $dbh->disconnect();
} }
DbLog_SBP_dbDisconnect ($hash); DbLog_SBP_sendDbDisconnect ($hash);
if (!$prop) { if (!$prop) {
Log3 ($name, 3, "DbLog $name - Reopen requested"); Log3 ($name, 3, "DbLog $name - Reopen requested");
@ -1205,12 +1150,8 @@ sub _DbLog_setreopen { ## no critic "not used"
$hash->{HELPER}{REOPEN_RUNS} = $prop; # Statusbit "Kein Schreiben in DB erlauben" wenn reopen mit Zeitangabe $hash->{HELPER}{REOPEN_RUNS} = $prop; # Statusbit "Kein Schreiben in DB erlauben" wenn reopen mit Zeitangabe
BlockingKill($hash->{HELPER}{REDUCELOG_PID}) if($hash->{HELPER}{REDUCELOG_PID}); BlockingKill($hash->{HELPER}{REDUCELOG_PID}) if($hash->{HELPER}{REDUCELOG_PID});
BlockingKill($hash->{HELPER}{COUNT_PID}) if($hash->{HELPER}{COUNT_PID});
BlockingKill($hash->{HELPER}{DELDAYS_PID}) if($hash->{HELPER}{DELDAYS_PID});
delete $hash->{HELPER}{LONGRUN_PID}; delete $hash->{HELPER}{LONGRUN_PID};
delete $hash->{HELPER}{COUNT_PID};
delete $hash->{HELPER}{DELDAYS_PID};
delete $hash->{HELPER}{REDUCELOG_PID}; delete $hash->{HELPER}{REDUCELOG_PID};
my $ts = (split " ",FmtDateTime(gettimeofday()+$prop))[1]; my $ts = (split " ",FmtDateTime(gettimeofday()+$prop))[1];
@ -1246,7 +1187,7 @@ sub _DbLog_setrereadcfg { ## no critic "not used"
return $ret if $ret; return $ret if $ret;
_DbLog_ConnectPush ($hash); _DbLog_ConnectPush ($hash);
DbLog_SBP_dbDisconnect ($hash, 1); # DB Verbindung und Verbindungsdaten im SubProzess löschen DbLog_SBP_sendDbDisconnect ($hash, 1); # DB Verbindung und Verbindungsdaten im SubProzess löschen
my $rst = DbLog_SBP_sendConnectionData ($hash); # neue Verbindungsdaten an SubProzess senden my $rst = DbLog_SBP_sendConnectionData ($hash); # neue Verbindungsdaten an SubProzess senden
@ -1378,7 +1319,31 @@ sub _DbLog_setcount { ## no critic "not used"
Log3 ($name, 4, "DbLog $name - Records count requested."); Log3 ($name, 4, "DbLog $name - Records count requested.");
DbLog_SBP_sendCommand ($hash, 'count', 'count'); DbLog_SBP_sendCommand ($hash, 'count');
return;
}
################################################################
# Setter deleteOldDays
################################################################
sub _DbLog_setdeleteOldDays { ## no critic "not used"
my $paref = shift;
my $hash = $paref->{hash};
my $name = $paref->{name};
my $db = $paref->{dbname};
my $opt = $paref->{opt};
my $prop = $paref->{prop};
if (defined $hash->{HELPER}{LONGRUN_PID}) {
return 'Another operation is in progress, try again a little later.';
}
Log3 ($name, 2, qq{DbLog $name - WARNING - "$opt" is outdated. Please consider use of DbRep "set <Name> delEntries" instead.});
Log3 ($name, 3, "DbLog $name - Deletion of records older than $prop days in database $db requested");
DbLog_SBP_sendCommand ($hash, 'deleteOldDays', $prop);
return; return;
} }
@ -2747,15 +2712,7 @@ sub DbLog_execMemCacheAsync {
delete $hash->{HELPER}{REDUCELOG_PID}; delete $hash->{HELPER}{REDUCELOG_PID};
} }
if($hash->{HELPER}{DELDAYS_PID} && $hash->{HELPER}{DELDAYS_PID}{pid} =~ m/DEAD/) {
delete $hash->{HELPER}{DELDAYS_PID};
}
if($hash->{MODEL} eq "SQLITE") { # bei SQLite Sperrverwaltung Logging wenn andere schreibende Zugriffe laufen if($hash->{MODEL} eq "SQLITE") { # bei SQLite Sperrverwaltung Logging wenn andere schreibende Zugriffe laufen
if($hash->{HELPER}{DELDAYS_PID}) {
$error = "deleteOldDaysNbl is running - resync at NextSync";
$dolog = 0;
}
if($hash->{HELPER}{REDUCELOG_PID}) { if($hash->{HELPER}{REDUCELOG_PID}) {
$error = "reduceLogNbl is running - resync at NextSync"; $error = "reduceLogNbl is running - resync at NextSync";
$dolog = 0; $dolog = 0;
@ -2791,7 +2748,7 @@ sub DbLog_execMemCacheAsync {
} }
else { else {
if($hash->{HELPER}{LONGRUN_PID}) { if($hash->{HELPER}{LONGRUN_PID}) {
$error = 'Cache execution already running - resync at NextSync'; $error = 'Another operation is in progress - resync at NextSync';
DbLog_writeFileIfCacheOverflow ($params); # Cache exportieren bei Overflow DbLog_writeFileIfCacheOverflow ($params); # Cache exportieren bei Overflow
} }
else { else {
@ -2925,6 +2882,7 @@ sub DbLog_SBP_onRun {
Log3 ($name, 3, "DbLog $name - DB connection parameters are stored in SubProcess ..."); Log3 ($name, 3, "DbLog $name - DB connection parameters are stored in SubProcess ...");
$store->{dbparams}{dbconn} = $memc->{dbconn}; $store->{dbparams}{dbconn} = $memc->{dbconn};
$store->{dbparams}{dbname} = (split /;|=/, $memc->{dbconn})[1];
$store->{dbparams}{dbuser} = $memc->{dbuser}; $store->{dbparams}{dbuser} = $memc->{dbuser};
$store->{dbparams}{dbpassword} = $memc->{dbpassword}; $store->{dbparams}{dbpassword} = $memc->{dbpassword};
$store->{dbparams}{utf8} = $memc->{utf8}; # Database UTF8 0|1 $store->{dbparams}{utf8} = $memc->{utf8}; # Database UTF8 0|1
@ -3080,6 +3038,18 @@ sub DbLog_SBP_onRun {
} }
); );
} }
## Kommando: count
#########################################################
if ($operation =~ /deleteOldDays/xs) {
_DbLog_SBP_onRun_deleteOldDays ( { subprocess => $subprocess,
name => $name,
memc => $memc,
store => $store,
bst => $bst
}
);
}
} }
usleep(300000); # reduziert CPU Last usleep(300000); # reduziert CPU Last
@ -3298,30 +3268,30 @@ sub _DbLog_SBP_onRun_Log {
$error = __DbLog_SBP_beginTransaction ($name, $dbh, $useta); $error = __DbLog_SBP_beginTransaction ($name, $dbh, $useta);
eval { $sth_ih = $dbh->prepare($sqlins); eval { $sth_ih = $dbh->prepare($sqlins);
$sth_ih->{TraceLevel} = "$tl|$tf" if($tl); # Tracelevel setzen $sth_ih->{TraceLevel} = "$tl|$tf" if($tl); # Tracelevel setzen
$ins_hist = $sth_ih->execute(); $ins_hist = $sth_ih->execute();
1; 1;
} }
or do { or do { $errorh = $@;
$errorh = $@;
Log3 ($name, 2, "DbLog $name - Error table $history - $errorh"); Log3 ($name, 2, "DbLog $name - Error table $history - $errorh");
$dbh->disconnect(); $dbh->disconnect();
delete $store->{dbh};
$rowlback = $cdata if($useta); # nicht gespeicherte Datensätze nur zurück geben wenn Transaktion ein $rowlback = $cdata if($useta); # nicht gespeicherte Datensätze nur zurück geben wenn Transaktion ein
$ret = { $ret = {
name => $name, name => $name,
msg => $@, msg => $@,
ot => 0, ot => 0,
oper => $operation, oper => $operation,
rowlback => $rowlback rowlback => $rowlback
}; };
$retjson = eval { encode_json($ret) }; $retjson = eval { encode_json($ret) };
$subprocess->writeToParent ($retjson); $subprocess->writeToParent ($retjson);
return; return;
}; };
$ins_hist = 0 if($ins_hist eq "0E0"); $ins_hist = 0 if($ins_hist eq "0E0");
@ -3353,6 +3323,7 @@ sub _DbLog_SBP_onRun_Log {
Log3 ($name, 2, "DbLog $name - Error: $error"); Log3 ($name, 2, "DbLog $name - Error: $error");
$dbh->disconnect(); $dbh->disconnect();
delete $store->{dbh};
$ret = { $ret = {
name => $name, name => $name,
@ -3477,6 +3448,7 @@ sub _DbLog_SBP_onRun_Log {
Log3 ($name, 2, "DbLog $name - Error: $error"); Log3 ($name, 2, "DbLog $name - Error: $error");
$dbh->disconnect(); $dbh->disconnect();
delete $store->{dbh};
$ret = { $ret = {
name => $name, name => $name,
@ -3582,6 +3554,7 @@ sub _DbLog_SBP_onRun_Log {
Log3 ($name, 2, "DbLog $name - Error: $error"); Log3 ($name, 2, "DbLog $name - Error: $error");
$dbh->disconnect(); $dbh->disconnect();
delete $store->{dbh};
$ret = { $ret = {
name => $name, name => $name,
@ -3756,6 +3729,97 @@ sub _DbLog_SBP_onRun_Count {
return; return;
} }
#################################################################
# SubProcess - deleteOldDays-Routine
#################################################################
sub _DbLog_SBP_onRun_deleteOldDays {
my $paref = shift;
my $subprocess = $paref->{subprocess};
my $name = $paref->{name};
my $memc = $paref->{memc};
my $store = $paref->{store}; # Datenspeicher
my $bst = $paref->{bst};
my $dbh = $store->{dbh};
my $history = $store->{dbparams}{history};
my $model = $store->{dbparams}{model};
my $db = $store->{dbparams}{dbname};
my $operation = $memc->{operation} // 'unknown'; # aktuell angeforderte Operation (log, etc.)
my $args = $memc->{arguments};
my $error = q{};
my $errorh = q{};
my $numdel = 0;
my $ret;
my $retjson;
my $cmd = "delete from $history where TIMESTAMP < ";
if ($model eq 'SQLITE') {
$cmd .= "datetime('now', '-$args days')";
}
elsif ($model eq 'MYSQL') {
$cmd .= "DATE_SUB(CURDATE(),INTERVAL $args DAY)";
}
elsif ($model eq 'POSTGRESQL') {
$cmd .= "NOW() - INTERVAL '$args' DAY";
}
else {
$cmd = undef;
$error = 'Unknown database type. Maybe you can try userCommand anyway';
}
my $st = [gettimeofday]; # SQL-Startzeit
if(defined ($cmd)) {
eval { $numdel = $dbh->do($cmd);
1;
}
or do { $errorh = $@;
Log3 ($name, 2, "DbLog $name - Error table $history - $errorh");
$dbh->disconnect();
delete $store->{dbh};
$ret = {
name => $name,
msg => $@,
ot => 0,
oper => $operation
};
$retjson = eval { encode_json($ret) };
$subprocess->writeToParent ($retjson);
return;
};
$numdel = 0 if($numdel == 0E0);
$error = __DbLog_SBP_commitOnly ($name, $dbh, $history);
Log3 ($name, 3, "DbLog $name - deleteOldDays finished. $numdel entries of database $db deleted.");
}
my $rt = tv_interval($st); # SQL-Laufzeit ermitteln
my $brt = tv_interval($bst); # Background-Laufzeit ermitteln
my $ot = $rt.",".$brt;
$ret = {
name => $name,
msg => $error,
ot => $ot,
oper => $operation,
numdel => $numdel
};
my $retjson = eval { encode_json($ret) };
$subprocess->writeToParent ($retjson);
return;
}
#################################################################################################### ####################################################################################################
# nur Datenbank "begin transaction" # nur Datenbank "begin transaction"
#################################################################################################### ####################################################################################################
@ -3955,7 +4019,7 @@ return $err;
# Datenbankverbindung im SubProcess # Datenbankverbindung im SubProcess
# beenden # beenden
##################################################### #####################################################
sub DbLog_SBP_dbDisconnect { sub DbLog_SBP_sendDbDisconnect {
my $hash = shift; my $hash = shift;
my $delpars = shift // 0; # 1 - die im SubProzess gespeicherten Daten sollen gelöscht werden my $delpars = shift // 0; # 1 - die im SubProzess gespeicherten Daten sollen gelöscht werden
@ -4085,11 +4149,13 @@ return;
# $oper = count # $oper = count
# $oper = deleteOldDays # $oper = deleteOldDays
# etc. # etc.
#
# $arg -> Argumente von $oper
##################################################### #####################################################
sub DbLog_SBP_sendCommand { sub DbLog_SBP_sendCommand {
my $hash = shift; my $hash = shift;
my $oper = shift; # angeforderte Operation my $oper = shift; # angeforderte Operation
my $cmd = shift // q{}; my $arg = shift // q{};
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $subprocess = $hash->{".fhem"}{subprocess}; my $subprocess = $hash->{".fhem"}{subprocess};
@ -4103,7 +4169,7 @@ sub DbLog_SBP_sendCommand {
$memc->{verbose} = AttrVal ($name, 'verbose', 3); $memc->{verbose} = AttrVal ($name, 'verbose', 3);
$memc->{operation} = $oper; $memc->{operation} = $oper;
$memc->{command} = $cmd; $memc->{arguments} = $arg;
my $json = eval { encode_json($memc); my $json = eval { encode_json($memc);
} }
@ -4116,7 +4182,7 @@ sub DbLog_SBP_sendCommand {
$hash->{HELPER}{LONGRUN_PID} = time(); # Statusbit laufende Verarbeitung mit Startzeitstempel; $hash->{HELPER}{LONGRUN_PID} = time(); # Statusbit laufende Verarbeitung mit Startzeitstempel;
DbLog_setReadingstate ($hash, "command '$cmd' is running"); DbLog_setReadingstate ($hash, "operation '$oper' is running");
return; return;
} }
@ -4271,6 +4337,12 @@ sub DbLog_SBP_Read {
readingsEndUpdate ($hash, 1); readingsEndUpdate ($hash, 1);
} }
## deleteOldDays - Read
#########################
if ($oper =~ /deleteOldDays/xs) {
readingsSingleUpdate($hash, 'lastRowsDeleted', $ret->{numdel}, 1);
}
if(AttrVal($name, 'showproctime', 0) && $ot) { if(AttrVal($name, 'showproctime', 0) && $ot) {
my ($rt,$brt) = split(",", $ot); my ($rt,$brt) = split(",", $ot);
@ -7266,139 +7338,6 @@ sub DbLog_reduceLogNbl_finished {
return; return;
} }
#########################################################################################
# DBLog - deleteOldDays non-blocking
#########################################################################################
sub DbLog_deldaysNbl {
my ($name) = @_;
my $hash = $defs{$name};
my $dbconn = $hash->{dbconn};
my $dbuser = $hash->{dbuser};
my $dbpassword = $attr{"sec$name"}{secret};
my $days = delete($hash->{HELPER}{DELDAYS});
my $history = $hash->{HELPER}{TH};
my $current = $hash->{HELPER}{TC};
my ($cmd,$dbh,$rows,$error,$sth,$ret,$bst,$brt,$st,$rt);
Log3 ($name, 5, "DbLog $name - Start DbLog_deldaysNbl $days");
# Background-Startzeit
$bst = [gettimeofday];
my ($useac,$useta) = DbLog_commitMode ($name, AttrVal($name, 'commitMode', $dblog_cmdef));
if(!$useac) {
eval {$dbh = DBI->connect("dbi:$dbconn", $dbuser, $dbpassword, { PrintError => 0, RaiseError => 1, AutoCommit => 0, AutoInactiveDestroy => 1 });};
}
elsif($useac == 1) {
eval {$dbh = DBI->connect("dbi:$dbconn", $dbuser, $dbpassword, { PrintError => 0, RaiseError => 1, AutoCommit => 1, AutoInactiveDestroy => 1 });};
}
else {
# Server default
eval {$dbh = DBI->connect("dbi:$dbconn", $dbuser, $dbpassword, { PrintError => 0, RaiseError => 1, AutoInactiveDestroy => 1 });};
}
if ($@) {
$error = encode_base64($@,"");
Log3 ($name, 2, "DbLog $name - Error: $@");
Log3 ($name, 5, "DbLog $name - DbLog_deldaysNbl finished");
return "$name|0|0|$error";
}
my $ac = ($dbh->{AutoCommit})?"ON":"OFF";
my $tm = ($useta)?"ON":"OFF";
Log3 $name, 4, "DbLog $name - AutoCommit mode: $ac, Transaction mode: $tm";
$cmd = "delete from $history where TIMESTAMP < ";
if ($hash->{MODEL} eq 'SQLITE') {
$cmd .= "datetime('now', '-$days days')";
}
elsif ($hash->{MODEL} eq 'MYSQL') {
$cmd .= "DATE_SUB(CURDATE(),INTERVAL $days DAY)";
}
elsif ($hash->{MODEL} eq 'POSTGRESQL') {
$cmd .= "NOW() - INTERVAL '$days' DAY";
}
else {
$ret = 'Unknown database type. Maybe you can try userCommand anyway.';
$error = encode_base64($ret,"");
Log3 ($name, 2, "DbLog $name - Error: $ret");
Log3 ($name, 5, "DbLog $name - DbLog_deldaysNbl finished");
return "$name|0|0|$error";
}
# SQL-Startzeit
$st = [gettimeofday];
eval {
$sth = $dbh->prepare($cmd);
$sth->execute();
};
if ($@) {
$error = encode_base64($@,"");
Log3 ($name, 2, "DbLog $name - $@");
$dbh->disconnect;
Log3 ($name, 4, "DbLog $name - BlockingCall DbLog_deldaysNbl finished");
return "$name|0|0|$error";
}
else {
$rows = $sth->rows;
$dbh->commit() if(!$dbh->{AutoCommit});
$dbh->disconnect;
}
$rt = tv_interval($st); # SQL-Laufzeit ermitteln
$brt = tv_interval($bst); # Background-Laufzeit ermitteln
$rt = $rt.",".$brt;
Log3 ($name, 5, "DbLog $name - DbLog_deldaysNbl finished");
return "$name|$rows|$rt|0";
}
#########################################################################################
# DBLog - deleteOldDays non-blocking Rückkehrfunktion
#########################################################################################
sub DbLog_deldaysNbl_done {
my $string = shift;
my @a = split("\\|",$string);
my $name = $a[0];
my $hash = $defs{$name};
my $rows = $a[1];
my($bt,$err);
$bt = $a[2] if ($a[2]);
$err = decode_base64($a[3]) if ($a[3]);
Log3 ($name, 5, "DbLog $name - Start DbLog_deldaysNbl_done");
if ($err) {
DbLog_setReadingstate ($hash, $err);
delete $hash->{HELPER}{DELDAYS_PID};
Log3 ($name, 5, "DbLog $name - DbLog_deldaysNbl_done finished");
return;
}
else {
if(AttrVal($name, "showproctime", undef) && $bt) {
my ($rt,$brt) = split(",", $bt);
readingsBeginUpdate($hash);
readingsBulkUpdate ($hash, "background_processing_time", sprintf("%.4f",$brt));
readingsBulkUpdate ($hash, "sql_processing_time", sprintf("%.4f",$rt));
readingsEndUpdate ($hash, 1);
}
readingsSingleUpdate($hash, "lastRowsDeleted", $rows ,1);
}
my $db = (split(/;|=/, $hash->{dbconn}))[1];
Log3 ($name, 3, "DbLog $name - deleteOldDaysNbl finished. $rows entries of database $db deleted.");
delete $hash->{HELPER}{DELDAYS_PID};
Log3 ($name, 5, "DbLog $name - DbLog_deldaysNbl_done finished");
return;
}
################################################################ ################################################################
# benutzte DB-Feldlängen in Helper und Internals setzen # benutzte DB-Feldlängen in Helper und Internals setzen
################################################################ ################################################################
@ -7809,12 +7748,13 @@ sub DbLog_chartQuery {
if ($sql eq "error") { if ($sql eq "error") {
return DbLog_jsonError("Could not setup SQL String. Maybe the Database is busy, please try again!"); return DbLog_jsonError("Could not setup SQL String. Maybe the Database is busy, please try again!");
} elsif ($sql eq "errordb") { }
elsif ($sql eq "errordb") {
return DbLog_jsonError("The Database Type is not supported!"); return DbLog_jsonError("The Database Type is not supported!");
} }
my ($hash, @a) = @_; my ($hash, @a) = @_;
my $dbhf = _DbLog_ConnectNewDBH($hash); my $dbhf = _DbLog_ConnectNewDBH($hash);
return if(!$dbhf); return if(!$dbhf);
my $totalcount; my $totalcount;
@ -7854,7 +7794,6 @@ sub DbLog_chartQuery {
my $jsonstring = '{"data":['; my $jsonstring = '{"data":[';
while ( my @data = $query_handle->fetchrow_array()) { while ( my @data = $query_handle->fetchrow_array()) {
if($i == 0) { if($i == 0) {
$jsonstring .= '{'; $jsonstring .= '{';
} }
@ -7869,6 +7808,7 @@ sub DbLog_chartQuery {
if (defined $data[$i]) { if (defined $data[$i]) {
my $fragment = substr($data[$i],0,1); my $fragment = substr($data[$i],0,1);
if ($fragment eq "{") { if ($fragment eq "{") {
$jsonstring .= $data[$i]; $jsonstring .= $data[$i];
} }
@ -7884,8 +7824,10 @@ sub DbLog_chartQuery {
$jsonstring .= ','; $jsonstring .= ',';
} }
} }
$jsonstring .= '}'; $jsonstring .= '}';
} }
$dbhf->disconnect(); $dbhf->disconnect();
$jsonstring .= ']'; $jsonstring .= ']';
if (defined $totalcount && $totalcount ne "") { if (defined $totalcount && $totalcount ne "") {
@ -8300,18 +8242,19 @@ return;
<br> <br>
<li><b>set &lt;name&gt; deleteOldDays &lt;n&gt; </b> <br><br> <li><b>set &lt;name&gt; deleteOldDays &lt;n&gt; </b> <br><br>
<ul> <ul>
Delete records from history older than &lt;n&gt; days. Number of deleted records will be written into reading Deletes records older than &lt;n&gt; days in table history.
lastRowsDeleted. The number of deleted records is logged in Reading lastRowsDeleted.
</li>
</ul> </ul>
</li>
<br> <br>
<li><b>set &lt;name&gt; deleteOldDaysNbl &lt;n&gt; </b> <br><br> <li><b>set &lt;name&gt; deleteOldDaysNbl &lt;n&gt; </b> <br><br>
<ul> <ul>
Is identical to function "deleteOldDays" whereupon deleteOldDaysNbl will be executed non-blocking. The function is identical to "set &lt;name&gt; deleteOldDays" and will be removed soon.
</li> <br>
</ul> </ul>
</li>
<br> <br>
<li><b>set &lt;name&gt; eraseReadings </b> <br><br> <li><b>set &lt;name&gt; eraseReadings </b> <br><br>
@ -9857,18 +9800,19 @@ attr SMA_Energymeter DbLogValueFn
<br> <br>
<li><b>set &lt;name&gt; deleteOldDays &lt;n&gt; </b> <br><br> <li><b>set &lt;name&gt; deleteOldDays &lt;n&gt; </b> <br><br>
<ul>Löscht Datensätze in Tabelle history, die älter sind als &lt;n&gt; Tage sind. <ul>
Die Anzahl der gelöschten Datens&auml;tze wird in das Reading lastRowsDeleted geschrieben. Löscht Datensätze älter als &lt;n&gt; Tage in Tabelle history.
</li> Die Anzahl der gelöschten Datens&auml;tze wird im Reading lastRowsDeleted protokolliert.
</ul> </ul>
</li>
<br> <br>
<li><b>set &lt;name&gt; deleteOldDaysNbl &lt;n&gt; </b> <br><br> <li><b>set &lt;name&gt; deleteOldDaysNbl &lt;n&gt; </b> <br><br>
<ul> <ul>
Identisch zu Funktion "deleteOldDays" wobei deleteOldDaysNbl nicht blockierend ausgeführt wird. Die Funktion ist identisch zu "set &lt;name&gt; deleteOldDays" und wird demnächst entfernt.
<br> <br>
</li>
</ul> </ul>
</li>
<br> <br>
<a id="DbLog-set-exportCache"></a> <a id="DbLog-set-exportCache"></a>