2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

93_DbRep: prepare client - server communication compression support

git-svn-id: https://svn.fhem.de/fhem/trunk@28636 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2024-03-11 21:02:09 +00:00
parent 6105ecec85
commit 45e323a5cc
2 changed files with 236 additions and 193 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it. # Do not insert empty lines here, update check depends on it.
- feature: 93_DbRep: prepare client - server communication compression support
- feature: 76_SMAInverter: add GridConection reading (SI only) - feature: 76_SMAInverter: add GridConection reading (SI only)
- bugfix: 88_HMCCU: Fixed syntax errors in HMCCUConf.pm - bugfix: 88_HMCCU: Fixed syntax errors in HMCCUConf.pm
- change: 93_DbLog: META.json data corrected - change: 93_DbLog: META.json data corrected

View File

@ -59,6 +59,8 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
# Version History intern # Version History intern
my %DbRep_vNotesIntern = ( my %DbRep_vNotesIntern = (
"8.53.5" => "11.03.2024 some changes for MariaDB Perl driver usage, change DbRep_dbConnect".
"support compression between client and server ",
"8.53.4" => "09.03.2024 Ready for support of MariaDB Perl driver ", "8.53.4" => "09.03.2024 Ready for support of MariaDB Perl driver ",
"8.53.3" => "06.03.2024 delete attribute allowDeletion, multiCmd: executeBeforeProc, executeAfterProc as attributes ". "8.53.3" => "06.03.2024 delete attribute allowDeletion, multiCmd: executeBeforeProc, executeAfterProc as attributes ".
"Set: all commands are executable even if \$dbloghash->{HELPER}{REOPEN_RUNS_UNTIL}is set ". "Set: all commands are executable even if \$dbloghash->{HELPER}{REOPEN_RUNS_UNTIL}is set ".
@ -377,77 +379,77 @@ my $dbrep_deftobl = 10;
################################################################################### ###################################################################################
sub DbRep_Initialize { sub DbRep_Initialize {
my ($hash) = @_; my ($hash) = @_;
$hash->{DefFn} = "DbRep_Define"; $hash->{DefFn} = "DbRep_Define";
$hash->{UndefFn} = "DbRep_Undef"; $hash->{UndefFn} = "DbRep_Undef";
$hash->{DeleteFn} = "DbRep_Delete"; $hash->{DeleteFn} = "DbRep_Delete";
$hash->{ShutdownFn} = "DbRep_Shutdown"; $hash->{ShutdownFn} = "DbRep_Shutdown";
$hash->{NotifyFn} = "DbRep_Notify"; $hash->{NotifyFn} = "DbRep_Notify";
$hash->{SetFn} = "DbRep_Set"; $hash->{SetFn} = "DbRep_Set";
$hash->{GetFn} = "DbRep_Get"; $hash->{GetFn} = "DbRep_Get";
$hash->{AttrFn} = "DbRep_Attr"; $hash->{AttrFn} = "DbRep_Attr";
$hash->{FW_deviceOverview} = 1; $hash->{FW_deviceOverview} = 1;
$hash->{AttrList} = "aggregation:minute,hour,day,week,month,year,no ". $hash->{AttrList} = "aggregation:minute,hour,day,week,month,year,no ".
"allowDeletion:obsolete ". "allowDeletion:obsolete ".
"disable:1,0 ". "disable:1,0 ".
"reading ". "reading ".
"autoForward:textField-long ". "autoForward:textField-long ".
"averageCalcForm:avgArithmeticMean,avgDailyMeanGWS,avgDailyMeanGWSwithGTS,avgTimeWeightMean ". "averageCalcForm:avgArithmeticMean,avgDailyMeanGWS,avgDailyMeanGWSwithGTS,avgTimeWeightMean ".
"countEntriesDetail:1,0 ". "countEntriesDetail:1,0 ".
"device " . "device " .
"dumpComment ". "dumpComment ".
"dumpCompress:1,0 ". "dumpCompress:1,0 ".
"dumpDirLocal ". "dumpDirLocal ".
"dumpDirRemote ". "dumpDirRemote ".
"dumpMemlimit ". "dumpMemlimit ".
"dumpSpeed ". "dumpSpeed ".
"dumpFilesKeep:0,1,2,3,4,5,6,7,8,9,10 ". "dumpFilesKeep:0,1,2,3,4,5,6,7,8,9,10 ".
"executeBeforeProc:textField-long ". "executeBeforeProc:textField-long ".
"executeAfterProc:textField-long ". "executeAfterProc:textField-long ".
"expimpfile ". "expimpfile ".
"fastStart:0,1 ". "fastStart:0,1 ".
"fetchRoute:ascent,descent ". "fetchRoute:ascent,descent ".
"fetchMarkDuplicates:red,blue,brown,green,orange ". "fetchMarkDuplicates:red,blue,brown,green,orange ".
"fetchValueFn:textField-long ". "fetchValueFn:textField-long ".
"ftpDebug:1,0 ". "ftpDebug:1,0 ".
"ftpDir ". "ftpDir ".
"ftpDumpFilesKeep:1,2,3,4,5,6,7,8,9,10 ". "ftpDumpFilesKeep:1,2,3,4,5,6,7,8,9,10 ".
"ftpPassive:1,0 ". "ftpPassive:1,0 ".
"ftpPwd ". "ftpPwd ".
"ftpPort ". "ftpPort ".
"ftpServer ". "ftpServer ".
"ftpTimeout ". "ftpTimeout ".
"ftpUse:1,0 ". "ftpUse:1,0 ".
"ftpUser ". "ftpUser ".
"ftpUseSSL:1,0 ". "ftpUseSSL:1,0 ".
"diffAccept ". "diffAccept ".
"limit ". "limit ".
"numDecimalPlaces:0,1,2,3,4,5,6,7 ". "numDecimalPlaces:0,1,2,3,4,5,6,7 ".
"optimizeTablesBeforeDump:1,0 ". "optimizeTablesBeforeDump:1,0 ".
"readingNameMap ". "readingNameMap ".
"readingPreventFromDel ". "readingPreventFromDel ".
"role:Client,Agent ". "role:Client,Agent ".
"seqDoubletsVariance ". "seqDoubletsVariance ".
"showproctime:1,0 ". "showproctime:1,0 ".
"showSvrInfo ". "showSvrInfo ".
"showVariables ". "showVariables ".
"showStatus ". "showStatus ".
"showTableInfo ". "showTableInfo ".
"sqlCmdHistoryLength:slider,0,1,200 ". "sqlCmdHistoryLength:slider,0,1,200 ".
"sqlCmdVars ". "sqlCmdVars ".
"sqlFormatService:https://sqlformat.org,none ". "sqlFormatService:https://sqlformat.org,none ".
"sqlResultFormat:separated,mline,sline,table,json ". "sqlResultFormat:separated,mline,sline,table,json ".
"sqlResultFieldSep:|,:,\/ ". "sqlResultFieldSep:|,:,\/ ".
"timeYearPeriod ". "timeYearPeriod ".
"timestamp_begin ". "timestamp_begin ".
"timestamp_end ". "timestamp_end ".
"timeDiffToNow ". "timeDiffToNow ".
"timeOlderThan ". "timeOlderThan ".
"timeout ". "timeout ".
"useAdminCredentials:1,0 ". "useAdminCredentials:1,0 ".
"userExitFn:textField-long ". "userExitFn:textField-long ".
"valueFilter ". "valueFilter ".
$readingFnAttributes; $readingFnAttributes;
my %hash = ( my %hash = (
Fn => 'CommandDbReadingsVal', Fn => 'CommandDbReadingsVal',
@ -498,7 +500,6 @@ sub DbRep_Define {
$hash->{NOTIFYDEV} = "global,".$name; # nur Events dieser Devices an DbRep_Notify weiterleiten $hash->{NOTIFYDEV} = "global,".$name; # nur Events dieser Devices an DbRep_Notify weiterleiten
my $dbconn = $defs{$a[2]}{dbconn}; my $dbconn = $defs{$a[2]}{dbconn};
$hash->{DATABASE} = (split(/;|=/, $dbconn))[1]; $hash->{DATABASE} = (split(/;|=/, $dbconn))[1];
$hash->{UTF8} = defined($defs{$a[2]}{UTF8}) ? $defs{$a[2]}{UTF8} : 0; # wird in DbRep_getInitData aus DB abgefragt und neu gesetzt
DbRep_setVersionInfo ($hash); # Versionsinformationen setzen DbRep_setVersionInfo ($hash); # Versionsinformationen setzen
DbRep_initSQLcmdCache ($name); # SQL Kommando Cache initialisieren DbRep_initSQLcmdCache ($name); # SQL Kommando Cache initialisieren
@ -1465,7 +1466,7 @@ sub DbRep_Get {
return $ret; return $ret;
} }
else { else {
return "$getlist"; return $getlist;
} }
return; return;
@ -2010,12 +2011,18 @@ sub DbRep_firstconnect {
RemoveInternalTimer ($hash, "DbRep_firstconnect"); RemoveInternalTimer ($hash, "DbRep_firstconnect");
return if(IsDisabled($name)); return if(IsDisabled($name));
if ($init_done == 1) { if ($init_done) {
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}}; my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
my $dbconn = $dbloghash->{dbconn}; my $dbconn = $dbloghash->{dbconn};
my $dbuser = $dbloghash->{dbuser}; my $dbuser = $dbloghash->{dbuser};
my $fadef = $hash->{MODEL} eq "Client" ? 1 : 0; # fastStart default immer 1 für Clients (0 für Agenten) my $fadef = $hash->{MODEL} eq "Client" ? 1 : 0; # fastStart default immer 1 für Clients (0 für Agenten)
delete $hash->{COMPRESSION};
delete $hash->{UTF8};
$hash->{COMPRESSION} = $dbloghash->{COMPRESSION} if(defined $dbloghash->{COMPRESSION});
$hash->{UTF8} = $dbloghash->{UTF8} if(defined $dbloghash->{UTF8});
if (AttrVal($name, "fastStart", $fadef) && $prop eq "onBoot" ) { if (AttrVal($name, "fastStart", $fadef) && $prop eq "onBoot" ) {
DbRep_setLastCmd ($name, "initial database connect stopped due to attribute 'fastStart'"); DbRep_setLastCmd ($name, "initial database connect stopped due to attribute 'fastStart'");
@ -2073,7 +2080,7 @@ sub DbRep_getInitData {
my $bst = [gettimeofday]; # Background-Startzeit my $bst = [gettimeofday]; # Background-Startzeit
my ($err,$dbh,$dbmodel) = DbRep_dbConnect ($name, 0); my ($err, $dbh, $dbmodel) = DbRep_dbConnect ($name, 0);
return "$name|$err" if ($err); return "$name|$err" if ($err);
my $st = [gettimeofday]; # SQL-Startzeit my $st = [gettimeofday]; # SQL-Startzeit
@ -2089,17 +2096,17 @@ sub DbRep_getInitData {
my $encc = qq{}; my $encc = qq{};
my (@se,@sec); my (@se,@sec);
if($dbmodel =~ /MYSQL|MARIADB/xs) { if ($dbmodel =~ /MYSQL|MARIADB/xs) {
eval { @se = $dbh->selectrow_array("SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = '$database'") }; eval { @se = $dbh->selectrow_array("SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = '$database'") };
$enc = $se[0] // $enc; $enc = $se[0] // $enc;
eval { @sec = $dbh->selectrow_array("SHOW VARIABLES LIKE 'character_set_connection'") }; eval { @sec = $dbh->selectrow_array("SHOW VARIABLES LIKE 'character_set_connection'") };
$encc = $sec[1] // $encc; $encc = $sec[1] // $encc;
} }
elsif($dbmodel =~ /SQLITE/xs) { elsif ($dbmodel =~ /SQLITE/xs) {
eval { @se = $dbh->selectrow_array("PRAGMA encoding;") }; eval { @se = $dbh->selectrow_array("PRAGMA encoding;") };
$enc = $se[0] // $enc; $enc = $se[0] // $enc;
} }
elsif($dbmodel =~ /POSTGRESQL/xs) { elsif ($dbmodel =~ /POSTGRESQL/xs) {
eval { @se = $dbh->selectrow_array("SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = '$database'") }; eval { @se = $dbh->selectrow_array("SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = '$database'") };
$enc = $se[0] // $enc; $enc = $se[0] // $enc;
eval { @sec = $dbh->selectrow_array("SHOW CLIENT_ENCODING") }; eval { @sec = $dbh->selectrow_array("SHOW CLIENT_ENCODING") };
@ -2115,13 +2122,13 @@ sub DbRep_getInitData {
my ($ava,$sqlava); my ($ava,$sqlava);
if($dbmodel =~ /MYSQL|MARIADB/xs) { if ($dbmodel =~ /MYSQL|MARIADB/xs) {
$sqlava = "SHOW INDEX FROM history where Key_name='$idx';"; $sqlava = "SHOW INDEX FROM history where Key_name='$idx';";
} }
elsif($dbmodel =~ /SQLITE/xs) { elsif ($dbmodel =~ /SQLITE/xs) {
$sqlava = "SELECT name FROM sqlite_master WHERE type='index' AND name='$idx';"; $sqlava = "SELECT name FROM sqlite_master WHERE type='index' AND name='$idx';";
} }
elsif($dbmodel =~ /POSTGRESQL/xs) { elsif ($dbmodel =~ /POSTGRESQL/xs) {
$sqlava = "SELECT indexname FROM pg_indexes WHERE tablename='history' and indexname ='$idx';"; $sqlava = "SELECT indexname FROM pg_indexes WHERE tablename='history' and indexname ='$idx';";
} }
@ -2173,7 +2180,7 @@ sub DbRep_getInitData {
$err = q{}; $err = q{};
return "$name|$err|$mints|$rt|$opt|$prop|$fret|$idxstate|$grants|$enc|$encc"; return "$name|$err|$mints|$rt|$opt|$prop|$fret|$idxstate|$grants|$enc|$encc|$dbmodel";
} }
#################################################################################################### ####################################################################################################
@ -2268,6 +2275,7 @@ sub DbRep_getInitDataDone {
my $grants = $a[8] ? decode_base64($a[8]) : ''; my $grants = $a[8] ? decode_base64($a[8]) : '';
my $enc = $a[9] ? decode_base64($a[9]) : ''; my $enc = $a[9] ? decode_base64($a[9]) : '';
my $encc = $a[10] ? decode_base64($a[10]) : ''; my $encc = $a[10] ? decode_base64($a[10]) : '';
my $dbmodel = $a[11];
my $hash = $defs{$name}; my $hash = $defs{$name};
@ -2296,15 +2304,16 @@ sub DbRep_getInitDataDone {
readingsBeginUpdate ($hash); readingsBeginUpdate ($hash);
if($hash->{LASTCMD} eq "minTimestamp") { if ($hash->{LASTCMD} eq "minTimestamp") {
ReadingsBulkUpdateValue ($hash, "timestamp_oldest_dataset", $mints); ReadingsBulkUpdateValue ($hash, "timestamp_oldest_dataset", $mints);
} }
else { else {
ReadingsBulkUpdateValue ($hash, "dbEncoding", $enc); ReadingsBulkUpdateValue ($hash, "dbEncoding", $enc);
ReadingsBulkUpdateValue ($hash, "connectionEncoding", $encc) if($encc); ReadingsBulkUpdateValue ($hash, "dbModel", $dbmodel);
ReadingsBulkUpdateValue ($hash, "connectionEncoding", $encc) if($encc);
ReadingsBulkUpdateValue ($hash, "indexState", $idxstate); ReadingsBulkUpdateValue ($hash, "indexState", $idxstate);
ReadingsBulkUpdateValue ($hash, "timestamp_oldest_dataset", $mints); ReadingsBulkUpdateValue ($hash, "timestamp_oldest_dataset", $mints);
ReadingsBulkUpdateValue ($hash, "userRights", $grants) if($grants); ReadingsBulkUpdateValue ($hash, "userRights", $grants) if($grants);
} }
ReadingsBulkUpdateTimeState ($hash,$brt,$rt,$state); ReadingsBulkUpdateTimeState ($hash,$brt,$rt,$state);
@ -2314,7 +2323,6 @@ sub DbRep_getInitDataDone {
$hash->{HELPER}{MINTS} = $mints; $hash->{HELPER}{MINTS} = $mints;
$hash->{HELPER}{GRANTS} = $grants if($grants); $hash->{HELPER}{GRANTS} = $grants if($grants);
$hash->{UTF8} = $enc =~ /utf-?8/xi ? 1 : 0;
} }
return if(!$fret); return if(!$fret);
@ -8281,8 +8289,6 @@ sub DbRep_mysql_DumpClientSide {
my $bst = [gettimeofday]; # Background-Startzeit my $bst = [gettimeofday]; # Background-Startzeit
Log3 ($name, 3, "DbRep $name - Starting dump of database '$dbname'");
## Beginn Dump ## Beginn Dump
################# #################
undef %db_tables; undef %db_tables;
@ -8300,9 +8306,11 @@ sub DbRep_mysql_DumpClientSide {
my ($err, $dbh, $dbmodel) = DbRep_dbConnect($name, 0); my ($err, $dbh, $dbmodel) = DbRep_dbConnect($name, 0);
return "$name|$err" if($err); return "$name|$err" if($err);
Log3 ($name, 3, "DbRep $name - Starting dump of database '$dbname' (model: $dbmodel)");
$dbh->{mysql_enable_utf8} = 0 if($dbmodel =~ /MYSQL/xs); # Dump Performance !!! Forum: https://forum.fhem.de/index.php/topic,53584.msg1204535.html#msg1204535 $dbh->{mysql_enable_utf8} = 0 if($dbmodel =~ /MYSQL/xs); # Dump Performance !!! Forum: https://forum.fhem.de/index.php/topic,53584.msg1204535.html#msg1204535
my $st = [gettimeofday]; # SQL-Startzeit my $st = [gettimeofday]; # SQL-Startzeit
($err, $sth) = DbRep_prepareExecuteQuery ($name, $dbh, "SELECT VERSION()"); # Mysql-Version ermitteln ($err, $sth) = DbRep_prepareExecuteQuery ($name, $dbh, "SELECT VERSION()"); # Mysql-Version ermitteln
@ -8649,7 +8657,7 @@ sub DbRep_mysql_DumpClientSide {
($err, $sth) = DbRep_prepareExecuteQuery ($name, $dbh, $sql_daten); ($err, $sth) = DbRep_prepareExecuteQuery ($name, $dbh, $sql_daten);
return "$name|$err" if($err); return "$name|$err" if($err);
while ( @ar = $sth->fetchrow) { # Start the insert while (@ar = $sth->fetchrow) { # Start the insert
if ($first_insert == 0) { if ($first_insert == 0) {
$part = "\n$insert"; $part = "\n$insert";
} }
@ -8666,8 +8674,7 @@ sub DbRep_mysql_DumpClientSide {
if ($memory_limit > 0 && length($sql_text) > $memory_limit) { if ($memory_limit > 0 && length($sql_text) > $memory_limit) {
($err, $filesize) = DbRep_WriteToDumpFile ($sql_text, $sql_file); ($err, $filesize) = DbRep_WriteToDumpFile ($sql_text, $sql_file);
# Log3 ($name, 5, "DbRep $name - Memory limit '$memory_limit' exceeded. Wrote to '$sql_file'. Filesize: '"._DbRep_byteOutput($filesize)."'"); $sql_text = "";
$sql_text = "";
} }
} }
@ -8755,7 +8762,7 @@ sub DbRep_mysql_DumpServerSide {
my $bst = [gettimeofday]; # Background-Startzeit my $bst = [gettimeofday]; # Background-Startzeit
my ($err,$dbh,$dbmodel) = DbRep_dbConnect($name, 0); my ($err, $dbh, $dbmodel) = DbRep_dbConnect($name, 0);
return "$name|$err" if ($err); return "$name|$err" if ($err);
my $value = 0; my $value = 0;
@ -8808,7 +8815,7 @@ sub DbRep_mysql_DumpServerSide {
return "$name|$err" if ($err); return "$name|$err" if ($err);
} }
Log3 ($name, 3, "DbRep $name - Starting dump of database '$dbname', table '$table'"); Log3 ($name, 3, "DbRep $name - Starting dump of database '$dbname', table '$table' (model: $dbmodel)");
# Startzeit ermitteln # Startzeit ermitteln
my ($Sekunden, $Minuten, $Stunden, $Monatstag, $Monat, $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) = localtime(time); my ($Sekunden, $Minuten, $Stunden, $Monatstag, $Monat, $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) = localtime(time);
@ -8892,7 +8899,7 @@ sub DbRep_sqlite_Dump {
my ($err,$dbh,$dbmodel) = DbRep_dbConnect($name, 0); my ($err,$dbh,$dbmodel) = DbRep_dbConnect($name, 0);
return "$name|$err" if ($err); return "$name|$err" if ($err);
if($optimize_tables_beforedump) { # Vacuum vor Dump # Anfangsgröße ermitteln if ($optimize_tables_beforedump) { # Vacuum vor Dump # Anfangsgröße ermitteln
$fsBytes = _DbRep_fsizeInBytes ($dbname); $fsBytes = _DbRep_fsizeInBytes ($dbname);
$db_MB = _DbRep_byteOutput ($fsBytes); $db_MB = _DbRep_byteOutput ($fsBytes);
@ -8913,7 +8920,7 @@ sub DbRep_sqlite_Dump {
$dbname = (split /[\/]/, $dbname)[-1]; $dbname = (split /[\/]/, $dbname)[-1];
Log3 ($name, 3, "DbRep $name - Starting dump of database '$dbname'"); Log3 ($name, 3, "DbRep $name - Starting dump of database '$dbname' (model: $dbmodel)");
# Startzeit ermitteln # Startzeit ermitteln
my ($Sekunden, $Minuten, $Stunden, $Monatstag, $Monat, $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) = localtime(time); my ($Sekunden, $Minuten, $Stunden, $Monatstag, $Monat, $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) = localtime(time);
@ -11660,20 +11667,20 @@ return $sql;
# 1 - adminCredentials werden immer verwendet # 1 - adminCredentials werden immer verwendet
###################################################################################### ######################################################################################
sub DbRep_dbConnect { sub DbRep_dbConnect {
my $name = shift; my $name = shift;
my $uac = shift // AttrVal($name, "useAdminCredentials", 0); my $uac = shift // AttrVal ($name, "useAdminCredentials", 0);
my $hash = $defs{$name};
my $hash = $defs{$name}; my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}};
my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}}; my $dbconn = $dbloghash->{dbconn};
my $dbconn = $dbloghash->{dbconn}; my $dbuser = $dbloghash->{dbuser};
my $dbuser = $dbloghash->{dbuser}; my $dblogname = $dbloghash->{NAME};
my $dblogname = $dbloghash->{NAME}; my $model = $dbloghash->{MODEL};
my $dbmodel = $dbloghash->{MODEL}; my $compression = $dbloghash->{COMPRESSION};
my $dbpassword = $attr{"sec$dblogname"}{secret}; my $dbpassword = $attr{"sec$dblogname"}{secret};
my $utf8 = $hash->{UTF8} // 0; my $utf8 = $dbloghash->{UTF8};
my $err = q{};
my $dbh; my $dbh;
my $err = q{};
if ($uac) { if ($uac) {
my ($success,$admusername,$admpassword) = DbRep_getcredentials ($hash, "adminCredentials"); my ($success,$admusername,$admpassword) = DbRep_getcredentials ($hash, "adminCredentials");
@ -11689,8 +11696,12 @@ sub DbRep_dbConnect {
} }
} }
Log3 ($name, 4, "DbRep $name - Database Model: $model");
Log3 ($name, 4, "DbRep $name - Database connect - user: ".($dbuser ? $dbuser : 'no').", UTF-8 option set: ".($utf8 ? 'yes' : 'no')); Log3 ($name, 4, "DbRep $name - Database connect - user: ".($dbuser ? $dbuser : 'no').", UTF-8 option set: ".($utf8 ? 'yes' : 'no'));
$dbconn .= ';mysql_compression=1' if($compression && $model eq 'MYSQL');
$dbconn .= ';mariadb_compression=1' if($compression && $model eq 'MARIADB');
eval { $dbh = DBI->connect("dbi:$dbconn", $dbuser, $dbpassword, { PrintError => 0, eval { $dbh = DBI->connect("dbi:$dbconn", $dbuser, $dbpassword, { PrintError => 0,
RaiseError => 1, RaiseError => 1,
AutoCommit => 1, AutoCommit => 1,
@ -11702,33 +11713,55 @@ sub DbRep_dbConnect {
Log3 ($name, 2, "DbRep $name - ERROR: $@"); Log3 ($name, 2, "DbRep $name - ERROR: $@");
return $err; return $err;
}; };
return $DBI::errstr if($DBI::errstr);
if ($model =~ /MYSQL/xs) {
$dbh->{mysql_enable_utf8} = 1 if($utf8);
if ($utf8) { if ($compression) {
if ($dbmodel =~ /MYSQL|MARIADB/xs) { Log3 ($name, 4, "DbRep $name - Communication between Client and Server will be compressed");
$dbh->{mysql_enable_utf8} = 1 if($dbmodel =~ /MYSQL/xs); # MariaDB kennt kein mysql_enable_utf8 }
($err, my @se) = DbRep_prepareExec2Array ($name, $dbh, "SHOW VARIABLES LIKE 'collation_database'"); ($err, my @se) = DbRep_prepareExec2Array ($name, $dbh, "SHOW VARIABLES LIKE 'collation_database'");
return $err if ($err);
my $dbcharset = @se ? $se[1] : 'noresult';
Log3 ($name, 4, "DbRep $name - Database Character set is >$dbcharset<");
if ($dbcharset !~ /noresult|ucs2|utf16|utf32/ixs) { # Impermissible Client Character Sets -> https://dev.mysql.com/doc/refman/8.0/en/charset-connection.html
my $collation = $dbcharset;
$dbcharset = (split '_', $collation, 2)[0];
($err, undef) = DbRep_dbhDo ($name, $dbh, qq(set names "$dbcharset" collate "$collation"));
return $err if ($err); return $err if ($err);
my $dbcharset = @se ? $se[1] : 'noresult';
Log3 ($name, 4, "DbRep $name - Database Character set is >$dbcharset<");
if ($dbcharset !~ /noresult|ucs2|utf16|utf32/ixs) { # Impermissible Client Character Sets -> https://dev.mysql.com/doc/refman/8.0/en/charset-connection.html
my $collation = $dbcharset;
$dbcharset = (split '_', $collation, 2)[0];
($err, undef) = DbRep_dbhDo ($name, $dbh, qq(set names "$dbcharset" collate "$collation"));
return $err if ($err);
}
} }
}
if ($model =~ /MARIADB/xs) {
if ($compression) {
Log3 ($name, 4, "DbRep $name - Communication between Client and Server will be compressed");
}
}
if ($dbmodel eq "SQLITE") { if ($model eq 'SQLITE') {
$dbh->do('PRAGMA encoding="UTF-8"'); if ($utf8) {
($err, undef) = DbRep_dbhDo ($name, $dbh, 'PRAGMA encoding="UTF-8"');
return $err if ($err);
}
my @dos = ("PRAGMA temp_store=MEMORY",
"PRAGMA synchronous=FULL",
);
for my $do (@dos) {
($err, undef) = DbRep_dbhDo ($name, $dbh, $do);
return $err if ($err);
} }
} }
return ($err, $dbh, $dbmodel); return ($err, $dbh, $model);
} }
#################################################################################################### ####################################################################################################
@ -16550,47 +16583,51 @@ return;
<ul><ul> <ul><ul>
<a id="DbRep-get-blockinginfo"></a> <a id="DbRep-get-blockinginfo"></a>
<li><b> blockinginfo </b> - list the current system wide running background processes (BlockingCalls) together with their informations. <li><b> blockinginfo </b> <br>
If character string is too long (e.g. arguments) it is reported shortened. List the current system wide running background processes (BlockingCalls) together with their informations.
</li> If character string is too long (e.g. arguments) it is reported shortened.
<br><br> </li>
<br><br>
<a id="DbRep-get-dbstatus"></a> <a id="DbRep-get-dbstatus"></a>
<li><b> dbstatus </b> - lists global information about MySQL server status (e.g. informations related to cache, threads, bufferpools, etc. ). <li><b> dbstatus </b> <br>
Initially all available informations are reported. Using the attribute <a href="#DbRep-attr-showStatus">showStatus</a> the quantity of Lists global information about MySQL server status (e.g. informations related to cache, threads, bufferpools, etc. ).
results can be limited to show only the desired values. Further detailed informations of items meaning are Initially all available informations are reported. Using the attribute <a href="#DbRep-attr-showStatus">showStatus</a> the quantity of
explained <a href="http://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html">here</a>. <br><br> results can be limited to show only the desired values. Further detailed informations of items meaning are
explained <a href="http://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html">here</a>. <br><br>
<ul> <ul>
<b>Example</b> <br> <b>Example</b> <br>
attr &lt;name&gt; showStatus %uptime%,%qcache% <br> attr &lt;name&gt; showStatus %uptime%,%qcache% <br>
get &lt;name&gt; dbstatus <br> get &lt;name&gt; dbstatus <br>
# Only readings containing "uptime" and "qcache" in name will be created # Only readings containing "uptime" and "qcache" in name will be created
</ul> </ul>
</li> </li>
<br><br> <br><br>
<a id="DbRep-get-dbvars"></a> <a id="DbRep-get-dbvars"></a>
<li><b> dbvars </b> - lists global informations about MySQL system variables. Included are e.g. readings related to InnoDB-Home, datafile path, <li><b> dbvars </b> <br>
memory- or cache-parameter and so on. The Output reports initially all available informations. Using the Lists global informations about MySQL system variables. Included are e.g. readings related to InnoDB-Home, datafile path,
attribute <a href="#DbRep-attr-showVariables">showVariables</a> the quantity of results can be limited to show only the desired values. memory- or cache-parameter and so on. The Output reports initially all available informations. Using the
Further detailed informations of items meaning are explained attribute <a href="#DbRep-attr-showVariables">showVariables</a> the quantity of results can be limited to show only the desired values.
<a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html">here</a>. <br><br> Further detailed informations of items meaning are explained
<a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html">here</a>. <br><br>
<ul> <ul>
<b>Example</b> <br> <b>Example</b> <br>
attr &lt;name&gt; showVariables %version%,%query_cache% <br> attr &lt;name&gt; showVariables %version%,%query_cache% <br>
get &lt;name&gt; dbvars <br> get &lt;name&gt; dbvars <br>
# Only readings containing "version" and "query_cache" in name will be created # Only readings containing "version" and "query_cache" in name will be created
</ul> </ul>
</li> </li>
<br><br> <br><br>
<a id="DbRep-get-initData"></a> <a id="DbRep-get-initData"></a>
<li><b> initData </b> - Determines some database properties relevant for the module function. <li><b> initData </b> <br>
The command is executed implicitly at the first database connection. Determines some database properties relevant for the module function.
</li> The command is executed implicitly at the first database connection.
<br><br> </li>
<br><br>
<a id="DbRep-get-minTimestamp"></a> <a id="DbRep-get-minTimestamp"></a>
<li><b> minTimestamp </b> - Identifies the oldest timestamp in the database (will be executed implicitely at FHEM start). <li><b> minTimestamp </b> - Identifies the oldest timestamp in the database (will be executed implicitely at FHEM start).
@ -19678,47 +19715,52 @@ return;
<ul><ul> <ul><ul>
<a id="DbRep-get-blockinginfo"></a> <a id="DbRep-get-blockinginfo"></a>
<li><b> blockinginfo </b> - Listet die aktuell systemweit laufenden Hintergrundprozesse (BlockingCalls) mit ihren Informationen auf. <li><b> blockinginfo </b> <br>
Zu lange Zeichenketten (z.B. Argumente) werden gekürzt ausgeschrieben. Listet die aktuell systemweit laufenden Hintergrundprozesse (BlockingCalls) mit ihren Informationen auf.
</li> Zu lange Zeichenketten (z.B. Argumente) werden gekürzt ausgeschrieben.
<br><br> </li>
<br><br>
<a id="DbRep-get-dbstatus"></a> <a id="DbRep-get-dbstatus"></a>
<li><b> dbstatus </b> - Listet globale Informationen zum MySQL Serverstatus (z.B. Informationen zum Cache, Threads, Bufferpools, etc. ). <li><b> dbstatus </b> <br>
Es werden zunächst alle verfügbaren Informationen berichtet. Mit dem Attribut <a href="#DbRep-attr-showStatus">showStatus</a> kann die Listet globale Informationen zum MySQL Serverstatus (z.B. Informationen zum Cache, Threads, Bufferpools, etc. ).
Ergebnismenge eingeschränkt werden, um nur gewünschte Ergebnisse abzurufen. Detailinformationen zur Bedeutung der einzelnen Readings Es werden zunächst alle verfügbaren Informationen berichtet. Mit dem Attribut <a href="#DbRep-attr-showStatus">showStatus</a> kann die
sind <a href="http://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html">hier</a> verfügbar. <br><br> Ergebnismenge eingeschränkt werden, um nur gewünschte Ergebnisse abzurufen. Detailinformationen zur Bedeutung der einzelnen Readings
sind <a href="http://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html">hier</a> verfügbar.
<br><br>
<ul> <ul>
<b>Beispiel</b> <br> <b>Beispiel</b> <br>
attr &lt;name&gt; showStatus %uptime%,%qcache% <br> attr &lt;name&gt; showStatus %uptime%,%qcache% <br>
get &lt;name&gt; dbstatus <br> get &lt;name&gt; dbstatus <br>
# Es werden nur Readings erzeugt die im Namen "uptime" und "qcache" enthaltenen # Es werden nur Readings erzeugt die im Namen "uptime" und "qcache" enthaltenen
</ul> </ul>
</li> </li>
<br><br> <br><br>
<a id="DbRep-get-dbvars"></a> <a id="DbRep-get-dbvars"></a>
<li><b> dbvars </b> - Zeigt die globalen Werte der MySQL Systemvariablen. Enthalten sind zum Beispiel Angaben zum InnoDB-Home, dem Datafile-Pfad, <li><b> dbvars </b> <br>
Memory- und Cache-Parameter, usw. Die Ausgabe listet zunächst alle verfügbaren Informationen auf. Mit dem Attribut Zeigt die globalen Werte der MySQL Systemvariablen. Enthalten sind zum Beispiel Angaben zum InnoDB-Home, dem Datafile-Pfad,
<a href="#DbRep-attr-showVariables">showVariables</a> kann die Ergebnismenge eingeschränkt werden um nur gewünschte Ergebnisse Memory- und Cache-Parameter, usw. Die Ausgabe listet zunächst alle verfügbaren Informationen auf. Mit dem Attribut
abzurufen. Weitere Informationen zur Bedeutung der ausgegebenen Variablen sind <a href="#DbRep-attr-showVariables">showVariables</a> kann die Ergebnismenge eingeschränkt werden um nur gewünschte Ergebnisse
<a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html">hier</a> verfügbar. <br><br> abzurufen. Weitere Informationen zur Bedeutung der ausgegebenen Variablen sind
<a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html">hier</a> verfügbar. <br><br>
<ul> <ul>
<b>Beispiel</b> <br> <b>Beispiel</b> <br>
attr &lt;name&gt; showVariables %version%,%query_cache% <br> attr &lt;name&gt; showVariables %version%,%query_cache% <br>
get &lt;name&gt; dbvars <br> get &lt;name&gt; dbvars <br>
# Es werden nur Readings erzeugt die im Namen "version" und "query_cache" enthalten # Es werden nur Readings erzeugt die im Namen "version" und "query_cache" enthalten
</ul> </ul>
</li> </li>
<br><br> <br><br>
<a id="DbRep-get-initData"></a> <a id="DbRep-get-initData"></a>
<li><b> initData </b> - Ermittelt einige für die Funktion des Moduls relevante Datenbankeigenschaften. <li><b> initData </b> <br>
Der Befehl wird bei der ersten Datenbankverbindung implizit ausgeführt. Ermittelt einige für die Funktion des Moduls relevante Datenbankeigenschaften.
</li> Der Befehl wird bei der ersten Datenbankverbindung implizit ausgeführt.
<br><br> </li>
<br><br>
<a id="DbRep-get-minTimestamp"></a> <a id="DbRep-get-minTimestamp"></a>
<li><b> minTimestamp </b> - Ermittelt den Zeitstempel des ältesten Datensatzes in der Datenbank (wird implizit beim Start von <li><b> minTimestamp </b> - Ermittelt den Zeitstempel des ältesten Datensatzes in der Datenbank (wird implizit beim Start von