From 6292d8a28025c70b94f012af1238e9aaa794cfc4 Mon Sep 17 00:00:00 2001 From: DS_Starter Date: Wed, 27 Dec 2017 09:19:30 +0000 Subject: [PATCH] 93_DbLog: V3.6.0, check global blockingCallMax in configCheck, configCheck available also for SQLITE now git-svn-id: https://svn.fhem.de/fhem/trunk@15702 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 + fhem/FHEM/93_DbLog.pm | 299 ++++++++++++++++++++++++++++-------------- 2 files changed, 205 insertions(+), 96 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 7ff946405..3cf5bf80e 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # 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. + - feature: 93_DbLog: V3.6.0, check global blockingCallMax in configCheck, + configCheck available also for SQLITE now - feature: 10_SOMFY: internal rework / prep for Alex / position command - feature: 70_BRAVIA: new command "text" to add text to an input field - changed: allowed.pm/fhem.pl: SecurityCheck cleanup, Forum #81509 diff --git a/fhem/FHEM/93_DbLog.pm b/fhem/FHEM/93_DbLog.pm index 52929315f..548c5603e 100644 --- a/fhem/FHEM/93_DbLog.pm +++ b/fhem/FHEM/93_DbLog.pm @@ -16,6 +16,7 @@ ############################################################################################################################################ # Versions History done by DS_Starter & DeeSPe: # +# 3.6.0 20.12.2017 check global blockingCallMax in configCheck, configCheck now available for SQLITE # 3.5.0 18.12.2017 importCacheFile, addCacheLine uses useCharfilter option, filter only $event by charfilter # 3.4.0 10.12.2017 avoid print out {RUNNING_PID} by "list device" # 3.3.0 07.12.2017 avoid print out the content of cache by "list device" @@ -171,7 +172,7 @@ use Blocking; use Time::HiRes qw(gettimeofday tv_interval); use Encode qw(encode_utf8); -my $DbLogVersion = "3.5.0"; +my $DbLogVersion = "3.6.0"; my %columns = ("DEVICE" => 64, "TYPE" => 64, @@ -436,7 +437,7 @@ sub DbLog_Set($@) { deleteOldDays deleteOldDaysNbl userCommand clearReadings:noArg eraseReadings:noArg addLog "; $usage .= "listCache:noArg addCacheLine purgeCache:noArg commitCache:noArg exportCache:nopurge,purgecache " if (AttrVal($name, "asyncMode", undef)); - $usage .= "configCheck:noArg " if($hash->{MODEL} =~ /MYSQL|POSTGRESQL/); + $usage .= "configCheck:noArg "; my (@logs,$dir); if (!AttrVal($name,"expimpdir",undef)) { @@ -2865,7 +2866,7 @@ sub DbLog_Get($@) { ########################################################################## # -# Ermittlung von DB-Parametern für configCheck +# Konfigurationscheck DbLog <-> Datenbank # ########################################################################## sub DbLog_configcheck($) { @@ -2876,7 +2877,8 @@ sub DbLog_configcheck($) { my $dbname = (split(/;|=/, $dbconn))[1]; my ($check, $rec); - # Connection und Encoding check + ### Connection und Encoding check + ####################################################################### my (@ce,@se); my ($chutf8mod,$chutf8dat); if($dbmodel =~ /MYSQL/) { @@ -2901,6 +2903,12 @@ sub DbLog_configcheck($) { $rec = "This is only an information. PostgreSQL supports automatic character set conversion between server and client for certain character set combinations. The conversion information is stored in the pg_conversion system catalog. PostgreSQL comes with some predefined conversions."; } } + if($dbmodel =~ /SQLITE/) { + @ce = DbLog_sqlget($hash,"PRAGMA encoding"); + $chutf8dat = @ce?uc($ce[0]):"no result"; + @se = DbLog_sqlget($hash,"PRAGMA table_info(history)"); + $rec = "This is only an information about text encoding used by the main database."; + } $check = ""; $check .= "Result of connection check

"; @@ -2912,17 +2920,17 @@ sub DbLog_configcheck($) { if(!@ce || !@se) { $check .= "Connection to database was not successful.
"; - $check .= "Recommendation: Plese see logfile for further information.

"; + $check .= "Recommendation: Plese check logfile for further information.

"; $check .= ""; return $check; } - $check .= "Result of encoding check

"; - $check .= "Encoding used by Client (connection): $chutf8mod
"; + $check .= "Encoding used by Client (connection): $chutf8mod
" if($dbmodel !~ /SQLITE/); $check .= "Encoding used by DB $dbname: $chutf8dat
"; $check .= "Recommendation: $rec

"; - # Check Betriebsmodus + ### Check Betriebsmodus + ####################################################################### my $mode = $hash->{MODE}; my $sfx = AttrVal("global", "language", "EN"); $sfx = ($sfx eq "EN" ? "" : "_$sfx"); @@ -2930,19 +2938,27 @@ sub DbLog_configcheck($) { $check .= "Result of logmode check

"; $check .= "Logmode of DbLog-device $name is: $mode
"; if($mode =~ /asynchronous/) { - $rec = "settings o.k."; + my $max = AttrVal("global", "blockingCallMax", 0); + if(!$max || $max >= 6) { + $rec = "settings o.k."; + } else { + $rec = "WARNING - you are running asynchronous mode that is recommended, but the value of global device attribute \"blockingCallMax\" is set quite small.
"; + $rec .= "This may cause problems in operation. It is recommended to increase the global blockingCallMax attribute."; + } } else { $rec = "Switch $name to the asynchronous logmode by setting the 'asyncMode' attribute. The advantage of this mode is to log events non-blocking.
"; $rec .= "There are attributes 'syncInterval' and 'cacheLimit' relevant for this working mode.
"; - $rec .= "Please refer to Commandref attributes for further informations."; + $rec .= "Please refer to commandref for further informations about these attributes."; } $check .= "Recommendation: $rec

"; - # Check Spaltenbreite history + ### Check Spaltenbreite history + ####################################################################### my (@sr_dev,@sr_typ,@sr_evt,@sr_rdg,@sr_val,@sr_unt); my ($cdat_dev,$cdat_typ,$cdat_evt,$cdat_rdg,$cdat_val,$cdat_unt); my ($cmod_dev,$cmod_typ,$cmod_evt,$cmod_rdg,$cmod_val,$cmod_unt); - + + #if($dbmodel !~ /SQLITE/) { if($dbmodel =~ /MYSQL/) { @sr_dev = DbLog_sqlget($hash,"SHOW FIELDS FROM history where FIELD='DEVICE'"); @sr_typ = DbLog_sqlget($hash,"SHOW FIELDS FROM history where FIELD='TYPE'"); @@ -2959,20 +2975,31 @@ sub DbLog_configcheck($) { @sr_val = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_name='history' and column_name='value'"); @sr_unt = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_name='history' and column_name='unit'"); } - - $cdat_dev = @sr_dev?($sr_dev[1]):"no result"; - $cdat_dev =~ tr/varchar\(|\)//d if($cdat_dev ne "no result"); - $cdat_typ = @sr_typ?($sr_typ[1]):"no result"; - $cdat_typ =~ tr/varchar\(|\)//d if($cdat_typ ne "no result"); - $cdat_evt = @sr_evt?($sr_evt[1]):"no result"; - $cdat_evt =~ tr/varchar\(|\)//d if($cdat_evt ne "no result"); - $cdat_rdg = @sr_rdg?($sr_rdg[1]):"no result"; - $cdat_rdg =~ tr/varchar\(|\)//d if($cdat_rdg ne "no result"); - $cdat_val = @sr_val?($sr_val[1]):"no result"; - $cdat_val =~ tr/varchar\(|\)//d if($cdat_val ne "no result"); - $cdat_unt = @sr_unt?($sr_unt[1]):"no result"; - $cdat_unt =~ tr/varchar\(|\)//d if($cdat_unt ne "no result"); - + if($dbmodel =~ /SQLITE/) { + my $dev = (DbLog_sqlget($hash,"SELECT sql FROM sqlite_master WHERE name = 'history'"))[0]; + $cdat_dev = $dev?$dev:"no result"; + $cdat_typ = $cdat_evt = $cdat_rdg = $cdat_val = $cdat_unt = $cdat_dev; + $cdat_dev =~ s/.*DEVICE.varchar\(([\d]*)\).*/$1/e; + $cdat_typ =~ s/.*TYPE.varchar\(([\d]*)\).*/$1/e; + $cdat_evt =~ s/.*EVENT.varchar\(([\d]*)\).*/$1/e; + $cdat_rdg =~ s/.*READING.varchar\(([\d]*)\).*/$1/e; + $cdat_val =~ s/.*VALUE.varchar\(([\d]*)\).*/$1/e; + $cdat_unt =~ s/.*UNIT.varchar\(([\d]*)\).*/$1/e; + } + if ($dbmodel !~ /SQLITE/) { + $cdat_dev = @sr_dev?($sr_dev[1]):"no result"; + $cdat_dev =~ tr/varchar\(|\)//d if($cdat_dev ne "no result"); + $cdat_typ = @sr_typ?($sr_typ[1]):"no result"; + $cdat_typ =~ tr/varchar\(|\)//d if($cdat_typ ne "no result"); + $cdat_evt = @sr_evt?($sr_evt[1]):"no result"; + $cdat_evt =~ tr/varchar\(|\)//d if($cdat_evt ne "no result"); + $cdat_rdg = @sr_rdg?($sr_rdg[1]):"no result"; + $cdat_rdg =~ tr/varchar\(|\)//d if($cdat_rdg ne "no result"); + $cdat_val = @sr_val?($sr_val[1]):"no result"; + $cdat_val =~ tr/varchar\(|\)//d if($cdat_val ne "no result"); + $cdat_unt = @sr_unt?($sr_unt[1]):"no result"; + $cdat_unt =~ tr/varchar\(|\)//d if($cdat_unt ne "no result"); + } $cmod_dev = $hash->{HELPER}{DEVICECOL}; $cmod_typ = $hash->{HELPER}{TYPECOL}; $cmod_evt = $hash->{HELPER}{EVENTCOL}; @@ -2983,18 +3010,24 @@ sub DbLog_configcheck($) { if($cdat_dev >= $cmod_dev && $cdat_typ >= $cmod_typ && $cdat_evt >= $cmod_evt && $cdat_rdg >= $cmod_rdg && $cdat_val >= $cmod_val && $cdat_unt >= $cmod_unt) { $rec = "settings o.k."; } else { - $rec = "The relation between column width in table history and the field width used in device $name don't meet the requirements. "; - $rec .= "Please make sure that the width of database field definition is equal or larger than the field width used by the module. Compare the given results.
"; - $rec .= "Currently the default values for field width are:

"; - $rec .= "DEVICE: $columns{DEVICE}
"; - $rec .= "TYPE: $columns{TYPE}
"; - $rec .= "EVENT: $columns{EVENT}
"; - $rec .= "READING: $columns{READING}
"; - $rec .= "VALUE: $columns{VALUE}
"; - $rec .= "UNIT: $columns{UNIT}

"; - $rec .= "You can change the column width in database by a statement like 'alter table history modify VALUE varchar(128);' (example for changing field 'VALUE'). "; - $rec .= "You can do it for example by executing 'sqlCMD' in DbRep or in a SQL-Editor of your choice. (switch $name to asynchron mode for non-blocking).
"; - $rec .= "The field width used by the module can be adjusted by attributes 'colEvent', 'colReading', 'colValue',"; + if ($dbmodel !~ /SQLITE/) { + $rec = "The relation between column width in table history and the field width used in device $name don't meet the requirements. "; + $rec .= "Please make sure that the width of database field definition is equal or larger than the field width used by the module. Compare the given results.
"; + $rec .= "Currently the default values for field width are:

"; + $rec .= "DEVICE: $columns{DEVICE}
"; + $rec .= "TYPE: $columns{TYPE}
"; + $rec .= "EVENT: $columns{EVENT}
"; + $rec .= "READING: $columns{READING}
"; + $rec .= "VALUE: $columns{VALUE}
"; + $rec .= "UNIT: $columns{UNIT}

"; + $rec .= "You can change the column width in database by a statement like 'alter table history modify VALUE varchar(128);' (example for changing field 'VALUE'). "; + $rec .= "You can do it for example by executing 'sqlCMD' in DbRep or in a SQL-Editor of your choice. (switch $name to asynchron mode for non-blocking).
"; + $rec .= "The field width used by the module can be adjusted by attributes 'colEvent', 'colReading', 'colValue'."; + } else { + $rec = "WARNING - The relation between column width in table history and the field width used by device $name should be equal but it differs. "; + $rec .= "The field width used by the module can be adjusted by attributes 'colEvent', 'colReading', 'colValue'. "; + $rec .= "Because you use SQLite this is only a warning. Normally the database can handle these differences. "; + } } $check .= "Result of table 'history' check

"; @@ -3002,7 +3035,8 @@ sub DbLog_configcheck($) { $check .= "Column width used by $name: 'DEVICE' = $cmod_dev, 'TYPE' = $cmod_typ, 'EVENT' = $cmod_evt, 'READING' = $cmod_rdg, 'VALUE' = $cmod_val, 'UNIT' = $cmod_unt
"; $check .= "Recommendation: $rec

"; - # Check Spaltenbreite current + ### Check Spaltenbreite current + ####################################################################### if($dbmodel =~ /MYSQL/) { @sr_dev = DbLog_sqlget($hash,"SHOW FIELDS FROM current where FIELD='DEVICE'"); @sr_typ = DbLog_sqlget($hash,"SHOW FIELDS FROM current where FIELD='TYPE'"); @@ -3020,50 +3054,69 @@ sub DbLog_configcheck($) { @sr_val = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_name='current' and column_name='value'"); @sr_unt = DbLog_sqlget($hash,"select column_name,character_maximum_length from information_schema.columns where table_name='current' and column_name='unit'"); } - - $cdat_dev = @sr_dev?($sr_dev[1]):"no result"; - $cdat_dev =~ tr/varchar\(|\)//d if($cdat_dev ne "no result"); - $cdat_typ = @sr_typ?($sr_typ[1]):"no result"; - $cdat_typ =~ tr/varchar\(|\)//d if($cdat_typ ne "no result"); - $cdat_evt = @sr_evt?($sr_evt[1]):"no result"; - $cdat_evt =~ tr/varchar\(|\)//d if($cdat_evt ne "no result"); - $cdat_rdg = @sr_rdg?($sr_rdg[1]):"no result"; - $cdat_rdg =~ tr/varchar\(|\)//d if($cdat_rdg ne "no result"); - $cdat_val = @sr_val?($sr_val[1]):"no result"; - $cdat_val =~ tr/varchar\(|\)//d if($cdat_val ne "no result"); - $cdat_unt = @sr_unt?($sr_unt[1]):"no result"; - $cdat_unt =~ tr/varchar\(|\)//d if($cdat_unt ne "no result"); - - $cmod_dev = $hash->{HELPER}{DEVICECOL}; - $cmod_typ = $hash->{HELPER}{TYPECOL}; - $cmod_evt = $hash->{HELPER}{EVENTCOL}; - $cmod_rdg = $hash->{HELPER}{READINGCOL}; - $cmod_val = $hash->{HELPER}{VALUECOL}; - $cmod_unt = $hash->{HELPER}{UNITCOL}; - - if($cdat_dev >= $cmod_dev && $cdat_typ >= $cmod_typ && $cdat_evt >= $cmod_evt && $cdat_rdg >= $cmod_rdg && $cdat_val >= $cmod_val && $cdat_unt >= $cmod_unt) { - $rec = "settings o.k."; - } else { - $rec = "The relation between column width in table current and the field width used in device $name don't meet the requirements. "; - $rec .= "Please make sure that the width of database field definition is equal or larger than the field width used by the module. Compare the given results.
"; - $rec .= "Currently the default values for field width are:

"; - $rec .= "DEVICE: $columns{DEVICE}
"; - $rec .= "TYPE: $columns{TYPE}
"; - $rec .= "EVENT: $columns{EVENT}
"; - $rec .= "READING: $columns{READING}
"; - $rec .= "VALUE: $columns{VALUE}
"; - $rec .= "UNIT: $columns{UNIT}

"; - $rec .= "You can change the column width in database by a statement like 'alter table current modify VALUE varchar(128);' (example for changing field 'VALUE'). "; - $rec .= "You can do it for example by executing 'sqlCMD' in DbRep or in a SQL-Editor of your choice. (switch $name to asynchron mode for non-blocking).
"; - $rec .= "The field width used by the module can be adjusted by attributes 'colEvent', 'colReading', 'colValue',"; + if($dbmodel =~ /SQLITE/) { + my $dev = (DbLog_sqlget($hash,"SELECT sql FROM sqlite_master WHERE name = 'current'"))[0]; + $cdat_dev = $dev?$dev:"no result"; + $cdat_typ = $cdat_evt = $cdat_rdg = $cdat_val = $cdat_unt = $cdat_dev; + $cdat_dev =~ s/.*DEVICE.varchar\(([\d]*)\).*/$1/e; + $cdat_typ =~ s/.*TYPE.varchar\(([\d]*)\).*/$1/e; + $cdat_evt =~ s/.*EVENT.varchar\(([\d]*)\).*/$1/e; + $cdat_rdg =~ s/.*READING.varchar\(([\d]*)\).*/$1/e; + $cdat_val =~ s/.*VALUE.varchar\(([\d]*)\).*/$1/e; + $cdat_unt =~ s/.*UNIT.varchar\(([\d]*)\).*/$1/e; } + if ($dbmodel !~ /SQLITE/) { + $cdat_dev = @sr_dev?($sr_dev[1]):"no result"; + $cdat_dev =~ tr/varchar\(|\)//d if($cdat_dev ne "no result"); + $cdat_typ = @sr_typ?($sr_typ[1]):"no result"; + $cdat_typ =~ tr/varchar\(|\)//d if($cdat_typ ne "no result"); + $cdat_evt = @sr_evt?($sr_evt[1]):"no result"; + $cdat_evt =~ tr/varchar\(|\)//d if($cdat_evt ne "no result"); + $cdat_rdg = @sr_rdg?($sr_rdg[1]):"no result"; + $cdat_rdg =~ tr/varchar\(|\)//d if($cdat_rdg ne "no result"); + $cdat_val = @sr_val?($sr_val[1]):"no result"; + $cdat_val =~ tr/varchar\(|\)//d if($cdat_val ne "no result"); + $cdat_unt = @sr_unt?($sr_unt[1]):"no result"; + $cdat_unt =~ tr/varchar\(|\)//d if($cdat_unt ne "no result"); + } + $cmod_dev = $hash->{HELPER}{DEVICECOL}; + $cmod_typ = $hash->{HELPER}{TYPECOL}; + $cmod_evt = $hash->{HELPER}{EVENTCOL}; + $cmod_rdg = $hash->{HELPER}{READINGCOL}; + $cmod_val = $hash->{HELPER}{VALUECOL}; + $cmod_unt = $hash->{HELPER}{UNITCOL}; - $check .= "Result of table 'current' check

"; - $check .= "Column width set in DB $dbname.current: 'DEVICE' = $cdat_dev, 'TYPE' = $cdat_typ, 'EVENT' = $cdat_evt, 'READING' = $cdat_rdg, 'VALUE' = $cdat_val, 'UNIT' = $cdat_unt
"; - $check .= "Column width used by $name: 'DEVICE' = $cmod_dev, 'TYPE' = $cmod_typ, 'EVENT' = $cmod_evt, 'READING' = $cmod_rdg, 'VALUE' = $cmod_val, 'UNIT' = $cmod_unt
"; - $check .= "Recommendation: $rec

"; + if($cdat_dev >= $cmod_dev && $cdat_typ >= $cmod_typ && $cdat_evt >= $cmod_evt && $cdat_rdg >= $cmod_rdg && $cdat_val >= $cmod_val && $cdat_unt >= $cmod_unt) { + $rec = "settings o.k."; + } else { + if ($dbmodel !~ /SQLITE/) { + $rec = "The relation between column width in table current and the field width used in device $name don't meet the requirements. "; + $rec .= "Please make sure that the width of database field definition is equal or larger than the field width used by the module. Compare the given results.
"; + $rec .= "Currently the default values for field width are:

"; + $rec .= "DEVICE: $columns{DEVICE}
"; + $rec .= "TYPE: $columns{TYPE}
"; + $rec .= "EVENT: $columns{EVENT}
"; + $rec .= "READING: $columns{READING}
"; + $rec .= "VALUE: $columns{VALUE}
"; + $rec .= "UNIT: $columns{UNIT}

"; + $rec .= "You can change the column width in database by a statement like 'alter table current modify VALUE varchar(128);' (example for changing field 'VALUE'). "; + $rec .= "You can do it for example by executing 'sqlCMD' in DbRep or in a SQL-Editor of your choice. (switch $name to asynchron mode for non-blocking).
"; + $rec .= "The field width used by the module can be adjusted by attributes 'colEvent', 'colReading', 'colValue',"; + } else { + $rec = "WARNING - The relation between column width in table current and the field width used by device $name should be equal but it differs. "; + $rec .= "The field width used by the module can be adjusted by attributes 'colEvent', 'colReading', 'colValue'. "; + $rec .= "Because you use SQLite this is only a warning. Normally the database can handle these differences. "; + } + } - # Check Vorhandensein Search_Idx mit den empfohlenen Spalten + $check .= "Result of table 'current' check

"; + $check .= "Column width set in DB $dbname.current: 'DEVICE' = $cdat_dev, 'TYPE' = $cdat_typ, 'EVENT' = $cdat_evt, 'READING' = $cdat_rdg, 'VALUE' = $cdat_val, 'UNIT' = $cdat_unt
"; + $check .= "Column width used by $name: 'DEVICE' = $cmod_dev, 'TYPE' = $cmod_typ, 'EVENT' = $cmod_evt, 'READING' = $cmod_rdg, 'VALUE' = $cmod_val, 'UNIT' = $cmod_unt
"; + $check .= "Recommendation: $rec

"; +#} + + ### Check Vorhandensein Search_Idx mit den empfohlenen Spalten + ####################################################################### my (@six,@six_dev,@six_rdg,@six_tsp); my ($idef,$idef_dev,$idef_rdg,$idef_tsp); $check .= "Result of check 'Search_Idx' availability

"; @@ -3072,7 +3125,7 @@ sub DbLog_configcheck($) { @six = DbLog_sqlget($hash,"SHOW INDEX FROM history where Key_name='Search_Idx'"); if (!@six) { $check .= "The index 'Search_Idx' is missing.
"; - $rec = "You can create the index by executing statement 'CREATE INDEX Search_Idx ON `history` (DEVICE, READING, TIMESTAMP) USING BTREE;'
"; + $rec = "You can create the index by executing statement 'CREATE INDEX Search_Idx ON `history` (DEVICE, READING, TIMESTAMP) USING BTREE;'
"; $rec .= "Depending on your database size this command may running a long time.
"; $rec .= "Please make sure the device '$name' is operating in asynchronous mode to avoid FHEM from blocking when creating the index.
"; $rec .= "Note: If you have just created another index which covers the same fields and order as suggested (e.g. a primary key) you don't need to create the 'Search_Idx' as well !
"; @@ -3089,7 +3142,7 @@ sub DbLog_configcheck($) { $check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'TIMESTAMP'.
" if (!@six_tsp); $rec = "The index should contain the fields 'DEVICE', 'READING', 'TIMESTAMP'. "; $rec .= "You can change the index by executing e.g.
"; - $rec .= "'ALTER TABLE `history` DROP INDEX `Search_Idx`, ADD INDEX `Search_Idx` (`DEVICE`, `READING`, `TIMESTAMP`) USING BTREE;'
"; + $rec .= "'ALTER TABLE `history` DROP INDEX `Search_Idx`, ADD INDEX `Search_Idx` (`DEVICE`, `READING`, `TIMESTAMP`) USING BTREE;'
"; $rec .= "Depending on your database size this command may running a long time.
"; } } @@ -3098,7 +3151,7 @@ sub DbLog_configcheck($) { @six = DbLog_sqlget($hash,"SELECT * FROM pg_indexes WHERE tablename='history' and indexname ='Search_Idx'"); if (!@six) { $check .= "The index 'Search_Idx' is missing.
"; - $rec = "You can create the index by executing statement 'CREATE INDEX \"Search_Idx\" ON history USING btree (device, reading, \"timestamp\")'
"; + $rec = "You can create the index by executing statement 'CREATE INDEX \"Search_Idx\" ON history USING btree (device, reading, \"timestamp\")'
"; $rec .= "Depending on your database size this command may running a long time.
"; $rec .= "Please make sure the device '$name' is operating in asynchronous mode to avoid FHEM from blocking when creating the index.
"; $rec .= "Note: If you have just created another index which covers the same fields and order as suggested (e.g. a primary key) you don't need to create the 'Search_Idx' as well !
"; @@ -3116,7 +3169,34 @@ sub DbLog_configcheck($) { $check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'TIMESTAMP'.
" if (!$idef_tsp); $rec = "The index should contain the fields 'DEVICE', 'READING', 'TIMESTAMP'. "; $rec .= "You can change the index by executing e.g.
"; - $rec .= "'DROP INDEX \"Search_Idx\"; CREATE INDEX \"Search_Idx\" ON history USING btree (device, reading, \"timestamp\")'
"; + $rec .= "'DROP INDEX \"Search_Idx\"; CREATE INDEX \"Search_Idx\" ON history USING btree (device, reading, \"timestamp\")'
"; + $rec .= "Depending on your database size this command may running a long time.
"; + } + } + } + if($dbmodel =~ /SQLITE/) { + @six = DbLog_sqlget($hash,"SELECT name,sql FROM sqlite_master WHERE type='index' AND name='Search_Idx'"); + if (!$six[0]) { + $check .= "The index 'Search_Idx' is missing.
"; + $rec = "You can create the index by executing statement 'CREATE INDEX Search_Idx ON `history` (DEVICE, READING, TIMESTAMP)'
"; + $rec .= "Depending on your database size this command may running a long time.
"; + $rec .= "Please make sure the device '$name' is operating in asynchronous mode to avoid FHEM from blocking when creating the index.
"; + $rec .= "Note: If you have just created another index which covers the same fields and order as suggested (e.g. a primary key) you don't need to create the 'Search_Idx' as well !
"; + } else { + $idef = $six[1]; + $idef_dev = 1 if(lc($idef) =~ /device/); + $idef_rdg = 1 if(lc($idef) =~ /reading/); + $idef_tsp = 1 if(lc($idef) =~ /timestamp/); + if ($idef_dev && $idef_rdg && $idef_tsp) { + $check .= "Index 'Search_Idx' exists and contains the recommended fields 'DEVICE', 'READING', 'TIMESTAMP'.
"; + $rec = "settings o.k."; + } else { + $check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'DEVICE'.
" if (!$idef_dev); + $check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'READING'.
" if (!$idef_rdg); + $check .= "Index 'Search_Idx' exists but doesn't contain recommended field 'TIMESTAMP'.
" if (!$idef_tsp); + $rec = "The index should contain the fields 'DEVICE', 'READING', 'TIMESTAMP'. "; + $rec .= "You can change the index by executing e.g.
"; + $rec .= "'DROP INDEX \"Search_Idx\"; CREATE INDEX Search_Idx ON `history` (DEVICE, READING, TIMESTAMP)'
"; $rec .= "Depending on your database size this command may running a long time.
"; } } @@ -3124,7 +3204,8 @@ sub DbLog_configcheck($) { $check .= "Recommendation: $rec

"; - # Check Index Report_Idx für DbRep-Device falls DbRep verwendet wird + ### Check Index Report_Idx für DbRep-Device falls DbRep verwendet wird + ####################################################################### my ($dbrp,$irep,); my (@dix,@dix_rdg,@dix_tsp,$irep_rdg,$irep_tsp); my $isused = 0; @@ -3148,7 +3229,7 @@ sub DbLog_configcheck($) { @dix = DbLog_sqlget($hash,"SHOW INDEX FROM history where Key_name='Report_Idx'"); if (!@dix) { $check .= "You use at least one DbRep-device assigned to $name, but the recommended index 'Report_Idx' is missing.
"; - $rec = "You can create the index by executing statement 'CREATE INDEX Report_Idx ON `history` (TIMESTAMP, READING) USING BTREE;'
"; + $rec = "You can create the index by executing statement 'CREATE INDEX Report_Idx ON `history` (TIMESTAMP, READING) USING BTREE;'
"; $rec .= "Depending on your database size this command may running a long time.
"; $rec .= "Please make sure the device '$name' is operating in asynchronous mode to avoid FHEM from blocking when creating the index.
"; $rec .= "Note: If you have just created another index which covers the same fields and order as suggested (e.g. a primary key) you don't need to create the 'Report_Idx' as well !
"; @@ -3165,7 +3246,7 @@ sub DbLog_configcheck($) { $check .= "Index 'Report_Idx' exists but doesn't contain recommended field 'TIMESTAMP'.
" if (!@dix_tsp); $rec = "The index should contain the fields 'TIMESTAMP', 'READING'. "; $rec .= "You can change the index by executing e.g.
"; - $rec .= "'ALTER TABLE `history` DROP INDEX `Report_Idx`, ADD INDEX `Report_Idx` (`TIMESTAMP`, `READING`) USING BTREE'
"; + $rec .= "'ALTER TABLE `history` DROP INDEX `Report_Idx`, ADD INDEX `Report_Idx` (`TIMESTAMP`, `READING`) USING BTREE'
"; $rec .= "Depending on your database size this command may running a long time.
"; } } @@ -3174,7 +3255,7 @@ sub DbLog_configcheck($) { @dix = DbLog_sqlget($hash,"SELECT * FROM pg_indexes WHERE tablename='history' and indexname ='Report_Idx'"); if (!@dix) { $check .= "You use at least one DbRep-device assigned to $name, but the recommended index 'Report_Idx' is missing.
"; - $rec = "You can create the index by executing statement 'CREATE INDEX \"Report_Idx\" ON history USING btree (\"timestamp\", reading)'
"; + $rec = "You can create the index by executing statement 'CREATE INDEX \"Report_Idx\" ON history USING btree (\"timestamp\", reading)'
"; $rec .= "Depending on your database size this command may running a long time.
"; $rec .= "Please make sure the device '$name' is operating in asynchronous mode to avoid FHEM from blocking when creating the index.
"; $rec .= "Note: If you have just created another index which covers the same fields and order as suggested (e.g. a primary key) you don't need to create the 'Report_Idx' as well !
"; @@ -3190,7 +3271,32 @@ sub DbLog_configcheck($) { $check .= "Index 'Report_Idx' exists but doesn't contain recommended field 'TIMESTAMP'.
" if (!$irep_tsp); $rec = "The index should contain the fields 'TIMESTAMP', 'READING'. "; $rec .= "You can change the index by executing e.g.
"; - $rec .= "'DROP INDEX \"Report_Idx\"; CREATE INDEX \"Report_Idx\" ON history USING btree (\"timestamp\", reading)'
"; + $rec .= "'DROP INDEX \"Report_Idx\"; CREATE INDEX \"Report_Idx\" ON history USING btree (\"timestamp\", reading)'
"; + $rec .= "Depending on your database size this command may running a long time.
"; + } + } + } + if($dbmodel =~ /SQLITE/) { + @dix = DbLog_sqlget($hash,"SELECT name,sql FROM sqlite_master WHERE type='index' AND name='Report_Idx'"); + if (!$dix[0]) { + $check .= "The index 'Report_Idx' is missing.
"; + $rec = "You can create the index by executing statement 'CREATE INDEX Report_Idx ON `history` (TIMESTAMP, READING)'
"; + $rec .= "Depending on your database size this command may running a long time.
"; + $rec .= "Please make sure the device '$name' is operating in asynchronous mode to avoid FHEM from blocking when creating the index.
"; + $rec .= "Note: If you have just created another index which covers the same fields and order as suggested (e.g. a primary key) you don't need to create the 'Search_Idx' as well !
"; + } else { + $irep = $dix[1]; + $irep_rdg = 1 if(lc($irep) =~ /reading/); + $irep_tsp = 1 if(lc($irep) =~ /timestamp/); + if ($irep_rdg && $irep_tsp) { + $check .= "Index 'Report_Idx' exists and contains the recommended fields 'TIMESTAMP', 'READING'.
"; + $rec = "settings o.k."; + } else { + $check .= "Index 'Report_Idx' exists but doesn't contain recommended field 'READING'.
" if (!$irep_rdg); + $check .= "Index 'Report_Idx' exists but doesn't contain recommended field 'TIMESTAMP'.
" if (!$irep_tsp); + $rec = "The index should contain the fields 'TIMESTAMP', 'READING'. "; + $rec .= "You can change the index by executing e.g.
"; + $rec .= "'DROP INDEX \"Report_Idx\"; CREATE INDEX Report_Idx ON `history` (TIMESTAMP, READING)'
"; $rec .= "Depending on your database size this command may running a long time.
"; } } @@ -4929,8 +5035,8 @@ sub checkUsePK ($$){
- This check reports some important settings and gives recommendations back to you if proposals are indentified. - (Available for MySQL, PostgreSQL)

+ This check reports some important settings and gives recommendations back to you if proposals are indentified. +

DbLog distinguishes between the synchronous (default) and asynchronous logmode. The logmode is adjustable by the attribute asyncMode. Since version 2.13.5 DbLog is supporting primary key (PK) set in table @@ -5001,8 +5107,8 @@ sub checkUsePK ($$){ point of time into the database.
set <name> configCheck

-
+
set <name> count


@@ -5865,7 +5971,7 @@ sub checkUsePK ($$){
Dieser Check prüft einige wichtige Einstellungen des DbLog-Devices und gibt Empfehlungen für potentielle Verbesserungen. - (verfügbar für MySQL, PostgreSQL)

+


DbLog unterscheidet den synchronen (Default) und asynchronen Logmodus. Der Logmodus ist über das @@ -5941,8 +6047,9 @@ sub checkUsePK ($$){ Datenbank zu schreiben.
set <name> configCheck

-
+
set <name> count