From d80c38ecfb306825f7aa20d3cc28328b01ba9ad5 Mon Sep 17 00:00:00 2001 From: nasseeder1 <> Date: Mon, 17 Oct 2016 21:50:40 +0000 Subject: [PATCH] 93_DbRep: get data of dbstatus, dbvars, tableinfo, svrinfo (database dependend) git-svn-id: https://svn.fhem.de/fhem/trunk@12368 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 + fhem/FHEM/93_DbRep.pm | 409 +++++++++++++++++++++++++++++++++++------- 2 files changed, 343 insertions(+), 68 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 20c6d2b33..0595f883a 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_DbRep: get data of dbstatus, dbvars, tableinfo, svrinfo + (database dependend) - added: 70_Pushsafer: new module to send push notifications via www.pushsafer.com - feature: 93_DbRep: allow SQL-Wildcards (% _) in attr reading & attr device diff --git a/fhem/FHEM/93_DbRep.pm b/fhem/FHEM/93_DbRep.pm index a3fd78c1d..cee97c988 100644 --- a/fhem/FHEM/93_DbRep.pm +++ b/fhem/FHEM/93_DbRep.pm @@ -37,7 +37,7 @@ ########################################################################################################### # Versions History: # -# 4.5 14.10.2016 get dbstatus, dbvars, tableinfo +# 4.5 17.10.2016 get data of dbstatus, dbvars, tableinfo, svrinfo (database dependend) # 4.4 13.10.2016 get function prepared # 4.3 11.10.2016 Preparation of get metadata # 4.2 10.10.2016 allow SQL-Wildcards (% _) in attr reading & attr device @@ -133,9 +133,10 @@ use POSIX qw(strftime); use Time::HiRes qw(gettimeofday tv_interval); use Scalar::Util qw(looks_like_number); use DBI; +use DBI::Const::GetInfoType; use Blocking; use Time::Local; -no if $] >= 5.017011, warnings => 'experimental'; +# no if $] >= 5.017011, warnings => 'experimental'; my %dbrep_col_postgre = ("DEVICE" => 64, "TYPE" => 64, @@ -162,7 +163,7 @@ sub DbRep_Initialize($) { $hash->{UndefFn} = "DbRep_Undef"; $hash->{NotifyFn} = "DbRep_Notify"; $hash->{SetFn} = "DbRep_Set"; -# $hash->{GetFn} = "DbRep_Get"; + $hash->{GetFn} = "DbRep_Get"; $hash->{AttrFn} = "DbRep_Attr"; $hash->{AttrList} = "disable:1,0 ". @@ -175,8 +176,10 @@ sub DbRep_Initialize($) { "aggregation:hour,day,week,month,no ". "role:Client,Agent ". "showproctime:1,0 ". + "showSvrInfo ". "showVariables ". "showStatus ". + "showTableInfo ". "timestamp_begin ". "timestamp_end ". "timeDiffToNow ". @@ -373,6 +376,7 @@ sub DbRep_Get($@) { my $to = AttrVal($name, "timeout", "60"); my $getlist = "Unknown argument $opt, choose one of ". + "svrinfo:noArg ". (($dbmodel eq "MYSQL")?"dbstatus:noArg ":""). (($dbmodel eq "MYSQL")?"tableinfo:noArg ":""). (($dbmodel eq "MYSQL")?"dbvars:noArg ":"") @@ -382,9 +386,14 @@ sub DbRep_Get($@) { if ($opt eq "dbvars" || $opt eq "dbstatus" || $opt eq "tableinfo") { return "The operation \"$opt\" isn't available with database type $dbmodel" if ($dbmodel ne 'MYSQL'); + readingsSingleUpdate($hash, "state", "running", 1); delread($hash); # Readings löschen die nicht in der Ausnahmeliste (Attr readingPreventFromDel) stehen $hash->{HELPER}{RUNNING_PID} = BlockingCall("dbmeta_DoParse", "$name|$opt", "dbmeta_ParseDone", $to, "ParseAborted", $hash); - } + } elsif ($opt eq "svrinfo") { + delread($hash); + readingsSingleUpdate($hash, "state", "running", 1); + $hash->{HELPER}{RUNNING_PID} = BlockingCall("dbmeta_DoParse", "$name|$opt", "dbmeta_ParseDone", $to, "ParseAborted", $hash); + } else { return "$getlist"; @@ -909,7 +918,7 @@ sub delread($) { my $name = $hash->{NAME}; my @rdpfdel = split(",", $hash->{HELPER}{RDPFDEL}) if($hash->{HELPER}{RDPFDEL}); if (@rdpfdel) { - my @allrds = keys($defs{$name}{READINGS}); + my @allrds = keys%{$defs{$name}{READINGS}}; foreach my $key(@allrds) { # Log3 ($name, 3, "DbRep $name - Reading Schlüssel: $key"); my $dodel = 1; @@ -3009,6 +3018,7 @@ sub dbmeta_DoParse($) { my $dbuser = $dbloghash->{dbuser}; my $dblogname = $dbloghash->{NAME}; my $dbpassword = $attr{"sec$dblogname"}{secret}; + my $dbmodel = $dbloghash->{DBMODEL}; my $err; # Background-Startzeit @@ -3026,10 +3036,14 @@ sub dbmeta_DoParse($) { return "$name|''|''|''|$err"; } + # only for this block because of warnings if details of readings are not set + no warnings 'uninitialized'; + # Liste der anzuzeigenden Parameter erzeugen, sonst alle ("%"), abhängig von $opt my $param = AttrVal($name, "showVariables", "%") if($opt eq "dbvars"); + $param = AttrVal($name, "showSvrInfo", "[A-Z_]") if($opt eq "svrinfo"); $param = AttrVal($name, "showStatus", "%") if($opt eq "dbstatus"); - $param = "1" if($opt eq "tableinfo"); # Dummy-Eintrag für einen Schleifenabdruck + $param = "1" if($opt eq "tableinfo"); # Dummy-Eintrag für einen Schleifendurchlauf my @parlist = split(",",$param); # SQL-Startzeit @@ -3039,29 +3053,70 @@ sub dbmeta_DoParse($) { my $sth; my $sql; - foreach my $ple (@parlist) { - if ($opt eq "dbvars") { - $sql = "show global variables like '$ple';"; - } elsif ($opt eq "dbstatus") { - $sql = "show global status like '$ple';"; - } elsif ($opt eq "tableinfo") { - $sql = "select - table_schema, - round(sum(data_length+index_length)/1024/1024,2), - round(data_free/1024/1024,2), - row_format, - table_collation, - engine, - table_type, - create_time, - from information_schema.tables group by table_schema;"; - } + if ($opt ne "svrinfo") { + foreach my $ple (@parlist) { + if ($opt eq "dbvars") { + $sql = "show global variables like '$ple';"; + } elsif ($opt eq "dbstatus") { + $sql = "show global status like '$ple';"; + } elsif ($opt eq "tableinfo") { + $sql = "select + table_name, + table_schema, + round(sum(data_length+index_length)/1024/1024,2), + round(data_free/1024/1024,2), + row_format, + table_collation, + engine, + table_type, + create_time + from information_schema.tables group by table_name;"; + } - Log3($name, 4, "DbRep $name - SQL execute: $sql"); + Log3($name, 4, "DbRep $name - SQL execute: $sql"); - $sth = $dbh->prepare($sql); - eval {$sth->execute();}; + $sth = $dbh->prepare($sql); + eval {$sth->execute();}; + if ($@) { + $err = encode_base64($@,""); + Log3 ($name, 2, "DbRep $name - $@"); + $dbh->disconnect; + Log3 ($name, 4, "DbRep $name -> BlockingCall dbmeta_DoParse finished"); + return "$name|''|''|''|$err"; + } else { + while (my @line = $sth->fetchrow_array()) { + Log3 ($name, 5, "DbRep $name - SQL result: @line"); + my $row = join("§", @line); + $row =~ s/ /_/g; + @line = split("§", $row); + if ($opt eq "tableinfo") { + $param = AttrVal($name, "showTableInfo", "[A-Z_]"); + $param =~ s/,/\|/g; + $param =~ tr/%//d; + if($line[0] =~ m/($param)/i) { + push(@row_array, $line[0].".table_schema ".$line[1]); + push(@row_array, $line[0].".data_index_lenth_MB ".$line[2]); + push(@row_array, $line[0].".table_name ".$line[1]); + push(@row_array, $line[0].".data_free_MB ".$line[3]); + push(@row_array, $line[0].".row_format ".$line[4]); + push(@row_array, $line[0].".table_collation ".$line[5]); + push(@row_array, $line[0].".engine ".$line[6]); + push(@row_array, $line[0].".table_type ".$line[7]); + push(@row_array, $line[0].".create_time ".$line[8]); + } + } else { + push(@row_array, $line[0]." ".$line[1]); + } + } + } + $sth->finish; + } + } else { + $param =~ s/,/\|/g; + $param =~ tr/%//d; + # Log3 ($name, 5, "DbRep $name - showDbInfo: $param"); + my $sf = $dbh->sqlite_db_filename() if($dbmodel eq 'SQLITE'); if ($@) { $err = encode_base64($@,""); Log3 ($name, 2, "DbRep $name - $@"); @@ -3069,34 +3124,31 @@ sub dbmeta_DoParse($) { Log3 ($name, 4, "DbRep $name -> BlockingCall dbmeta_DoParse finished"); return "$name|''|''|''|$err"; } else { - while (my @line = $sth->fetchrow_array()) { - Log3 ($name, 5, "DbRep $name - SQL result: @line"); - my $rowlist = join("§", @line); - $rowlist =~ s/ /_/g; - @line = split("§", $rowlist); - if ($opt eq "tableinfo") { - push(@row_array, $line[0]."___data_index_lenth_MB ".$line[1]); - push(@row_array, $line[0]."___data_free_MB ".$line[2]); - push(@row_array, $line[0]."___row_format ".$line[3]); - push(@row_array, $line[0]."___table_collation ".$line[4]); - push(@row_array, $line[0]."___engine ".$line[5]); - push(@row_array, $line[0]."___table_type ".$line[6]); - push(@row_array, $line[0]."___create_time ".$line[7]); - } else { - push(@row_array, $line[0]." ".$line[1]); - } - } - } + my $key = "SQLITE_DB_FILENAME"; + push(@row_array, $key." ".$sf) if($key =~ m/($param)/i); + } + my $info; + while( my ($key,$value) = each(%GetInfoType) ) { + eval { $info = $dbh->get_info($GetInfoType{"$key"}) }; + if ($@) { + $err = encode_base64($@,""); + Log3 ($name, 2, "DbRep $name - $@"); + $dbh->disconnect; + Log3 ($name, 4, "DbRep $name -> BlockingCall dbmeta_DoParse finished"); + return "$name|''|''|''|$err"; + } else { + push(@row_array, $key." ".$info) if($key =~ m/($param)/i); + } + } } # SQL-Laufzeit ermitteln my $rt = tv_interval($st); - $sth->finish; $dbh->disconnect; my $rowlist = join('§', @row_array); - Log3 ($name, 5, "DbRep $name -> row_array: \n@row_array"); + Log3 ($name, 5, "DbRep $name -> row_array: \n@row_array"); # Daten müssen als Einzeiler zurückgegeben werden $rowlist = encode_base64($rowlist,""); @@ -3148,6 +3200,7 @@ sub dbmeta_ParseDone($) { my $pre = "VAR_" if($opt eq "dbvars"); $pre = "STAT_" if($opt eq "dbstatus"); $pre = "INFO_" if($opt eq "tableinfo"); + $pre = "" if($opt eq "svrinfo"); foreach my $row (@row_array) { my @a = split(" ", $row); @@ -3161,6 +3214,7 @@ sub dbmeta_ParseDone($) { readingsBulkUpdate($hash, "state", "done"); readingsEndUpdate($hash, 1); + # InternalTimer(time+0.5, "browser_refresh", $hash, 0); delete($hash->{HELPER}{RUNNING_PID}); Log3 ($name, 4, "DbRep $name -> BlockingCall dbmeta_ParseDone finished"); @@ -3183,8 +3237,6 @@ my $name = $hash->{NAME}; # Browser Refresh nach DB-Abfrage #################################################################################################### sub browser_refresh($) { - return; - my ($hash) = @_; RemoveInternalTimer($hash, "browser_refresh"); # FW_directNotify("#FHEMWEB:$name", "location.reload(true);","" ); @@ -3377,29 +3429,37 @@ my $name = $hash->{NAME}; return; } else { my $dbh = $hash->{DBH}; - my $i = 1; - # $dbh->table_info( $catalog, $schema, $table) - # my $sth = $dbh->table_info('', '', ''); - # my $tables = $dbh->selectcol_arrayref($sth, {Columns => [3]}); - # my $table = join ', ', @$tables; - # Log3 ($name, 3, "DbRep $name - SQL_TABLES : $table"); + Log3 ($name, 3, "DbRep $name - --------------- FILE INFO --------------"); + my $sqlfile = $dbh->sqlite_db_filename(); + Log3 ($name, 3, "DbRep $name - FILE : $sqlfile "); +# # $dbh->table_info( $catalog, $schema, $table) +# my $sth = $dbh->table_info('', '%', '%'); +# my $tables = $dbh->selectcol_arrayref($sth, {Columns => [3]}); +# my $table = join ', ', @$tables; +# Log3 ($name, 3, "DbRep $name - SQL_TABLES : $table"); - Log3 ($name, 3, "DbRep $name - $i\--------------- COMMON SERVER INFO --------------"); - my %InfoTypes = ( SQL_DATA_SOURCE_NAME => 2 , - SQL_SERVER_NAME => 13 , - SQL_DBMS_NAME => 17 , - SQL_DBMS_VERSION => 18 , - SQL_TRANSACTION_CAPABLE => 46 , - ); - $i++; - while ((my $key, my $val) = each(%InfoTypes) ) { - my $d = $dbh->get_info( $val ); - Log3 ($name, 3, "DbRep $name - $i\_$key : $d"); - $i++; - } + Log3 ($name, 3, "DbRep $name - --------------- PRAGMA --------------"); + my @InfoTypes = ('sqlite_db_status'); + + foreach my $row (@InfoTypes) { + # my @linehash = $dbh->$row; + + my $array= $dbh->$row ; + # push(@row_array, @array); + while ((my $key, my $val) = each %{$array}) { + Log3 ($name, 3, "DbRep $name - PRAGMA : $key : ".%{$val}); + } + + } - # $sth->finish; + + # $sth->finish; + + + + + $dbh->disconnect; } return; @@ -3590,6 +3650,84 @@ return; + +Get +