diff --git a/fhem/FHEM/98_configdb.pm b/fhem/FHEM/98_configdb.pm index 7d276a490..30f0de195 100644 --- a/fhem/FHEM/98_configdb.pm +++ b/fhem/FHEM/98_configdb.pm @@ -1,7 +1,11 @@ +# $Id $ +# + package main; use strict; use warnings; use feature qw/say switch/; +use configDB; sub CommandConfigdb($$); @@ -126,57 +130,104 @@ sub _configdb_backup { sub CommandConfigdb($$) { my ($cl, $param) = @_; - my $configfile = $attr{global}{configfile}; - return "\n error: configDB not used!" unless($configfile eq 'configDB'); - my @a = split(/ /,$param); - my ($ret,$usage); + my ($cmd, $param1, $param2) = @a; + $cmd = $cmd ? $cmd : ""; + $param1 = $param1 ? $param1 : ""; + $param2 = $param2 ? $param2 : ""; - given ($a[0]) { + my $configfile = $attr{global}{configfile}; + return "\n error: configDB not used!" unless($configfile eq 'configDB' || $cmd eq 'migrate'); - when ('info') { - $ret = cfgDB_Info; - } + my $ret; - when ('list') { - $a[1] = $a[1] ? $a[1] : '%'; - $a[2] = $a[2] ? $a[2] : 0; - $ret = cfgDB_List($a[1],$a[2]); - } + given ($cmd) { - when ('diff') { - $ret = cfgDB_Diff($a[1],$a[2]); - } - - when ('uuid') { - $ret = _cfgDB_Uuid; - } - - when ('reorg') { - $a[1] = $a[1] ? $a[1] : 3; - $ret = cfgDB_Reorg($a[1]); - } - - when ('recover') { - $a[1] = $a[1] ? $a[1] : 1; - $ret = cfgDB_Recover($a[1]); + when ('attr') { + Log3('configdb', 4, 'configdb: attr $param1 $param2 requested.'); + if ($param1 eq "" && $param2 eq "") { + # list attributes + foreach my $c (sort keys %{$attr{configdb}}) { + my $val = $attr{configdb}{$c}; + $val =~ s/;/;;/g; + $val =~ s/\n/\\\n/g; + $ret .= "attr configdb $c $val"; + } + } elsif($param2 eq "") { + # delete attribute + undef($attr{configdb}{$param1}); + $ret = " attribute $param1 deleted"; + } else { + # set attribute + $attr{configdb}{$param1} = $param2; + $ret = " attribute $param1 set to value $param2"; + } } when ('backup') { if($^O =~ m/Win/) { + Log3('configdb', 4, "configdb: error: backup requested on MS platform."); $ret = "\n error: backup not supported for Windows"; } else { + Log3('configdb', 4, "configdb: backup requested."); $ret = _configdb_backup; } } + + when ('diff') { + return "Syntax: configdb diff " if @a != 3; + Log3('configdb', 4, "configdb: diff requested for device: $param1 in version $param2."); + $ret = _cfgDB_Diff($param1, $param2); + } + + when ('info') { + Log3('configdb', 4, "info requested."); + $ret = _cfgDB_Info; + } + + when ('list') { + $param1 = $param1 ? $param1 : '%'; + $param2 = $param2 ? $param2 : 0; + Log3('configdb', 4, "configdb: list requested for device: $param1 in version $param2."); + $ret = _cfgDB_List($param1,$param2); + } + + when ('migrate') { + return "Migration not possible. Already running with configDB!" if $configfile eq 'configDB'; + Log3('configdb', 4, "configdb: migration requested."); + $ret = _cfgDB_Migrate; + } + + when ('recover') { + return "Syntax: configdb recover " if @a != 2; + Log3('configdb', 4, "configdb: recover for version $param1 requested."); + $ret = _cfgDB_Recover($param1); + } + + when ('reorg') { + $param1 = $param1 ? $param1 : 3; + Log3('configdb', 4, "configdb: reorg requested with keep: $param1."); + $ret = _cfgDB_Reorg($a[1]); + } + + when ('uuid') { + $param1 = _cfgDB_Uuid; + Log3('configdb', 4, "configdb: uuid requested: $param1"); + $ret = $param1; + } + default { - $ret = "\n Syntax: configdb info\n". - " configdb list [device] [version]\n". - " configdb diff \n". - " configdb uuid\n". + $ret = "\n Syntax:". + " configdb attr [attribute] [value]\n". " configdb backup\n". + " configdb diff \n". + " configdb info\n". + " configdb list [device] [version]\n". + " configdb migrate\n". " configdb recover \n". - " configdb reorg [keepVersions]\n"; + " configdb reorg [keepVersions]\n". + " configdb uuid\n". + ""; } } @@ -200,6 +251,7 @@ sub CommandConfigdb($$) {
Prerequisits / Installation

    +
  • Please install perl package Text::Diff if not already installed on your system.

  • You must have access to a SQL database. Supported database types are SQLITE, MYSQL and POSTGRESQL.

  • The corresponding DBD module must be available in your perl environment,
    e.g. sqlite3 running on a Debian systems requires package libdbd-sqlite3-perl

  • @@ -276,7 +328,7 @@ sub CommandConfigdb($$) {
      perl fhem.pl fhem.cfg


  • transfer your existing configuration into the database

    -
      enter {use configDB;; cfgDB_Migrate}
      +
        enter

        configdb migrate

        into frontend's command line


      Be patient! Migration can take some time, especially on mini-systems like RaspberryPi or Beaglebone.
      @@ -297,6 +349,43 @@ sub CommandConfigdb($$) { This command can be used with different parameters.

      +
    • configdb attr [attribute] [value]

    • + Provides the possibility to pass attributes to backend and frontend.
      +
      + configdb attr private 1 - set the attribute named 'private' to value 1.
      +
      + configdb attr private - delete the attribute named 'private'
      +
      + configdb attr - show all defined attributes.
      +
      + Currently, only one attribute is supported. If 'private' is set to 1 the user and password info
      + will not be shown in 'configdb info' output.
      +
      + +
    • configdb backup

    • + Replaces fhem's default backup process, since backup is no longer supported
      + with activated configDB.
      +
      + Important:
      + Please be aware you are responsible for data backup of your database yourself!
      + The backup command can and will not do this job for you!
      +
      + +
    • configdb diff <device> <version>

    • + Compare configuration dataset for device <device> + from current version 0 with version <version>
      + Example for valid request:
      +
      + get configDB telnetPort 1
      +
      + will show a result like this: +
      +compare device: telnetPort in current version 0 (left) to version: 1 (right)
      ++--+--------------------------------------+--+--------------------------------------+
      +| 1|define telnetPort telnet 7072 global  | 1|define telnetPort telnet 7072 global  |
      +* 2|attr telnetPort room telnet           *  |                                      |
      ++--+--------------------------------------+--+--------------------------------------+
      +
    • configdb info

    • Returns some database statistics
      @@ -335,39 +424,6 @@ Ver 0 always indicates the currently running configuration.
      get configDB list global 1

      -
    • configdb diff <device> <version>

    • - Compare configuration dataset for device <device> - from current version 0 with version <version>
      - Example for valid request:
      -
      - get configDB telnetPort 1
      -
      - will show a result like this: -
      -compare device: telnetPort in current version 0 (left) to version: 1 (right)
      -+--+--------------------------------------+--+--------------------------------------+
      -| 1|define telnetPort telnet 7072 global  | 1|define telnetPort telnet 7072 global  |
      -* 2|attr telnetPort room telnet           *  |                                      |
      -+--+--------------------------------------+--+--------------------------------------+
      - -
    • configdb uuid

    • - Returns a uuid that can be used for own purposes.
      -
      -
    • configdb backup

    • - Replaces fhem's default backup process, since backup is no longer supported
      - with activated configDB.
      -
      - Important:
      - Please be aware you are responsible for data backup of your database yourself!
      - The backup command can and will not do this job for you!
      -
      -
    • configdb reorg [keep]

    • - Deletes all stored versions with version number higher than [keep].
      - Default value for optional parameter keep = 3.
      - This function can be used to create a nightly running job for
      - database reorganisation when called from an at-Definition.
      -
      -
    • configdb recover <version>

    • Restores an older version from database archive.
      set configDB recover 3 will copy version #3 from database @@ -376,6 +432,18 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right) Important!
      The restored version will NOT be activated automatically!
      You must do a rereadcfg or - even better - shutdown restart yourself.
      +
      + +
    • configdb reorg [keep]

    • + Deletes all stored versions with version number higher than [keep].
      + Default value for optional parameter keep = 3.
      + This function can be used to create a nightly running job for
      + database reorganisation when called from an at-Definition.
      +
      + +
    • configdb uuid

    • + Returns a uuid that can be used for own purposes.
      +

    @@ -393,8 +461,6 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right) This will take some moments, due to writing version informations.
    Finishing the save-process will be indicated by a corresponding message in frontend.

  • -
  • You may need to install perl package Text::Diff to use cfgDB_Diff()
  • -
  • There still will be some more (planned) development to this extension, especially regarding some perfomance issues.

  • @@ -418,6 +484,7 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right)
    Voraussetzungen / Installation

      +
    • Bitte das perl Paket Text::Diff installieren, falls noch nicht auf dem System vorhanden.

    • Es muss eine SQL Datenbank verfügbar sein, untsrstützt werden SQLITE, MYSQL und POSTGRESQLL.

    • Das zum Datenbanktype gehörende DBD Modul muss in perl installiert sein,
      für sqlite3 auf einem Debian System z.B. das Paket libdbd-sqlite3-perl

    • @@ -494,7 +561,7 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right)
        perl fhem.pl fhem.cfg


    • Bestehende Konfiguration in die Datenbank übertragen

      -
        {use configDB;; cfgDB_Migrate}
        +
          configdb migrate

          in die Befehlszeile der fhem-Oberfläche eingeben


        Nicht die Geduld verlieren! Die Migration eine Weile dauern, speziell bei Mini-Systemen wie
        @@ -516,6 +583,46 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right) Es wird ein neuer Befehl configdb bereitgestellt,
        der mit verschiedenen Parametern aufgerufen werden kann.

        + +
      • configdb attr [attribute] [value]

      • + Hiermit lassen sich attribute setzen, die das Verhalten von Front- und Backend beeinflussen.
        +
        + configdb attr private 1 - setzt das Attribut 'private' auf den Wert 1.
        +
        + configdb attr private - löscht das Attribut 'private'
        +
        + configdb attr - zeigt alle gespeicherten Attribute
        +
        + Im Moment ist nur ein Attribut definiert. Wenn 'private' auf 1 gesetzt wird, werden bei 'configdb info'
        + keine Benutzer- und Passwortdaten angezeigt.
        +
        +
        + +
      • configdb backup

      • + Ersetzt den Standard-Backup-Befehl von fhem, da dieser bei Verwendung von configDB nicht mehr
        + zur Verfügung steht.
        +
        + Wichtig:
        + Für die Sicherung der Datenbank ist der Anwender selbst verantwortlich!
        + Der backup Befehl kann diese Aufgabe nicht übernehmen.
        + Ausnahme: Nutzer einer im fhem Verzeichnis liegenden sqlite Datenbank profitieren von der Einfachheit
        + dieser Datenbank, denn das fhem Verzeichnis wird ohnehin komplett gesichert.
        +
        + +
      • configdb diff <device> <version>

      • + Vergleicht die Konfigurationsdaten des Gerätes <device> aus der aktuellen Version 0 mit den Daten aus Version <version>
        + Beispielaufruf:
        +
        + configdb diff telnetPort 1
        +
        + liefert ein Ergebnis ähnlich dieser Ausgabe: +
        +compare device: telnetPort in current version 0 (left) to version: 1 (right)
        ++--+--------------------------------------+--+--------------------------------------+
        +| 1|define telnetPort telnet 7072 global  | 1|define telnetPort telnet 7072 global  |
        +* 2|attr telnetPort room telnet           *  |                                      |
        ++--+--------------------------------------+--+--------------------------------------+
        +
      • configdb info

      • Liefert eine Datenbankstatistik
        @@ -548,45 +655,10 @@ Ver 0 bezeichnet immer die aktuell verwendete Konfiguration.
        Standardwert für [version] = 0 um Geräte in der aktuellen Version anzuzeigen.
        Beispiele für gültige Aufrufe:

        - get configDB list
        - get configDB list global
        - get configDB list '' 1
        - get configDB list global 1
        -
        - -
      • configdb diff <device> <version>

      • - Vergleicht die Konfigurationsdaten des Gerätes <device> aus der aktuellen Version 0 mit den Daten aus Version <version>
        - Beispielaufruf:
        -
        - get configDB diff telnetPort 1
        -
        - liefert ein Ergebnis ähnlich dieser Ausgabe: -
        -compare device: telnetPort in current version 0 (left) to version: 1 (right)
        -+--+--------------------------------------+--+--------------------------------------+
        -| 1|define telnetPort telnet 7072 global  | 1|define telnetPort telnet 7072 global  |
        -* 2|attr telnetPort room telnet           *  |                                      |
        -+--+--------------------------------------+--+--------------------------------------+
        - -
      • configdb uuid

      • - Liefert eine uuid, die man für eigene Zwecke verwenden kann.
        -
        - -
      • configdb backup

      • - Ersetzt den Standard-Backup-Befehl von fhem, da dieser bei Verwendung von configDB nicht mehr
        - zur Verfügung steht.
        -
        - Wichtig:
        - Für die Sicherung der Datenbank ist der Anwender selbst verantwortlich!
        - Der backup Befehl kann diese Aufgabe nicht übernehmen.
        - Ausnahme: Nutzer einer im fhem Verzeichnis liegenden sqlite Datenbank profitieren von der Einfachheit
        - dieser Datenbank, denn das fhem Verzeichnis wird ohnehin komplett gesichert.
        -
        - -
      • configdb reorg [keep]

      • - Löscht alle gespeicherten Konfigurationen mit Versionsnummern größer als [keep].
        - Standardwert für den optionalen Parameter keep = 3.
        - Mit dieser Funktion läßt sich eine nächtliche Reorganisation per at umsetzen.
        + configdb list
        + configdb list global
        + configdb list '' 1
        + configdb list global 1

      • configdb recover <version>

      • @@ -601,6 +673,16 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right)

        +
      • configdb reorg [keep]

      • + Löscht alle gespeicherten Konfigurationen mit Versionsnummern größer als [keep].
        + Standardwert für den optionalen Parameter keep = 3.
        + Mit dieser Funktion läßt sich eine nächtliche Reorganisation per at umsetzen.
        +
        + +
      • configdb uuid

      • + Liefert eine uuid, die man für eigene Zwecke verwenden kann.
        +
        + Hinweise

          diff --git a/fhem/configDB.pm b/fhem/configDB.pm index 3f5a5c20a..0a7deaeed 100644 --- a/fhem/configDB.pm +++ b/fhem/configDB.pm @@ -169,6 +169,17 @@ sub cfgDB_GlobalAttr { $line[3] =~ s/ .*$//; $attr{global}{$line[2]} = $line[3]; } + + $sth = $fhem_dbh->prepare( "SELECT * FROM fhemconfig WHERE DEVICE = 'configdb'" ); + $sth->execute(); + + while (@line = $sth->fetchrow_array()) { + $row = "$line[0] $line[1] $line[2] $line[3]"; + $line[3] =~ s/#.*//; + $line[3] =~ s/ .*$//; + $attr{configdb}{$line[2]} = $line[3]; + } + $fhem_dbh->disconnect(); return; } @@ -233,7 +244,14 @@ sub cfgDB_SaveCfg { push @rowList, "attr $d $a $val"; } } - + + foreach my $a (sort keys %{$attr{configdb}}) { + my $val = $attr{configdb}{$a}; + $val =~ s/;/;;/g; + $val =~ s/\n/\\\n/g; + push @rowList, "attr configdb $a $val"; + } + # Insert @rowList into database table my $fhem_dbh = _cfgDB_Connect; my $uuid = _cfgDB_Rotate($fhem_dbh); @@ -400,32 +418,34 @@ sub _cfgDB_Uuid{ return $uuid; } -sub _cfgDB_backupdata { - my (undef, $cfgDB_dblocation) = split(/=/,$cfgDB_dbconn); - return ($cfgDB_dbtype,$cfgDB_dblocation); -} - ################################################## -# Tools / Additional functions +# Additional backend functions # not called from fhem.pl directly # # migrate existing fhem config into database -sub cfgDB_Migrate { +sub _cfgDB_Migrate { + my $ret; + $ret = "Starting migration...\n"; Log3('configDB',4,'Starting migration.'); + $ret .= "Processing: database initialization.\n"; Log3('configDB',4,'Processing: cfgDB_Init.'); cfgDB_Init; + $ret .= "Processing: save config.\n"; Log3('configDB',4,'Processing: cfgDB_SaveCfg.'); cfgDB_SaveCfg; + $ret .= "Processing: save state.\n"; Log3('configDB',4,'Processing: cfgDB_SaveState.'); cfgDB_SaveState; + $ret .= "Migration completed.\n\n"; Log3('configDB',4,'Migration finished.'); - return " Result after migration:\n".cfgDB_Info; + $ret .= _cfgDB_Info; + return $ret; } # show database statistics -sub cfgDB_Info { +sub _cfgDB_Info { my ($l, @r); for my $i (1..65){ $l .= '-';} # $l .= "\n"; @@ -435,8 +455,8 @@ sub cfgDB_Info { push @r, " ".cfgDB_svnId; push @r, $l; push @r, " dbconn: $cfgDB_dbconn"; - push @r, " dbuser: $cfgDB_dbuser" if !$attr{configDB}{private}; - push @r, " dbpass: $cfgDB_dbpass" if !$attr{configDB}{private}; + push @r, " dbuser: $cfgDB_dbuser" if !$attr{configdb}{private}; + push @r, " dbpass: $cfgDB_dbpass" if !$attr{configdb}{private}; push @r, " dbtype: $cfgDB_dbtype"; push @r, " Unknown dbmodel type in configuration file." if $dbtype eq 'unknown'; push @r, " Only Mysql, Postgresql, SQLite are fully supported." if $dbtype eq 'unknown'; @@ -482,7 +502,7 @@ sub cfgDB_Info { } # recover former config from database archive -sub cfgDB_Recover($) { +sub _cfgDB_Recover($) { my ($version) = @_; my ($cmd, $count, $ret); @@ -525,7 +545,7 @@ sub cfgDB_Recover($) { } # delete old configurations -sub cfgDB_Reorg(;$) { +sub _cfgDB_Reorg(;$) { my ($lastversion) = @_; $lastversion = ($lastversion > 0) ? $lastversion : 3; Log3('configDB', 4, "DB Reorg started, keeping last $lastversion versions."); @@ -534,11 +554,11 @@ sub cfgDB_Reorg(;$) { $fhem_dbh->do("delete from fhemversions where version > $lastversion"); $fhem_dbh->commit(); $fhem_dbh->disconnect(); - return " Result after database reorg:\n".cfgDB_Info; + return " Result after database reorg:\n"._cfgDB_Info; } # list device(s) from given version -sub cfgDB_List(;$$) { +sub _cfgDB_List(;$$) { my ($search,$searchversion) = @_; $search = $search ? $search : "%"; $searchversion = $searchversion ? $searchversion : 0; @@ -560,7 +580,7 @@ sub cfgDB_List(;$$) { } # called from cfgDB_Diff -sub _cfgDB_Diff($$$) { +sub __cfgDB_Diff($$$) { my ($fhem_dbh,$search,$searchversion) = @_; my ($sql, $sth, @line, $ret); $sql = "SELECT command, device, p1, p2 FROM fhemconfig as c join fhemversions as v ON v.versionuuid=c.versionuuid ". @@ -574,13 +594,13 @@ sub _cfgDB_Diff($$$) { } # compare device configurations from 2 versions -sub cfgDB_Diff($$) { +sub _cfgDB_Diff($$) { my ($search,$searchversion) = @_; use Text::Diff; my ($ret, $v0, $v1); my $fhem_dbh = _cfgDB_Connect; - $v0 = _cfgDB_Diff($fhem_dbh,$search,0); - $v1 = _cfgDB_Diff($fhem_dbh,$search,$searchversion); + $v0 = __cfgDB_Diff($fhem_dbh,$search,0); + $v1 = __cfgDB_Diff($fhem_dbh,$search,$searchversion); $fhem_dbh->disconnect(); $ret = diff \$v0, \$v1, { STYLE => "Table" }; $ret = "\nNo differences found!" if !$ret; @@ -597,7 +617,7 @@ sub cfgDB_Diff($$) {

          configDB

            - This is the core library for configuration from SQL database.
            + This is the core backend library for configuration from SQL database.
            See configdb command documentation for detailed info.