2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 12:49:34 +00:00
changed: migration moved from backend to frontend command
added: commands attr, migrate
updated: documentation

git-svn-id: https://svn.fhem.de/fhem/trunk@5216 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
betateilchen 2014-03-13 17:40:56 +00:00
parent 0ca892035c
commit 51188c02d6
2 changed files with 233 additions and 131 deletions

View File

@ -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 <device> <version>" 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 <version>" 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 <device> <version>\n".
" configdb uuid\n".
$ret = "\n Syntax:".
" configdb attr [attribute] [value]\n".
" configdb backup\n".
" configdb diff <device> <version>\n".
" configdb info\n".
" configdb list [device] [version]\n".
" configdb migrate\n".
" configdb recover <version>\n".
" configdb reorg [keepVersions]\n";
" configdb reorg [keepVersions]\n".
" configdb uuid\n".
"";
}
}
@ -200,6 +251,7 @@ sub CommandConfigdb($$) {
<br/>
<b>Prerequisits / Installation</b><br/>
<ul><br/>
<li>Please install perl package Text::Diff if not already installed on your system.</li><br/>
<li>You must have access to a SQL database. Supported database types are SQLITE, MYSQL and POSTGRESQL.</li><br/>
<li>The corresponding DBD module must be available in your perl environment,<br/>
e.g. sqlite3 running on a Debian systems requires package libdbd-sqlite3-perl</li><br/>
@ -276,7 +328,7 @@ sub CommandConfigdb($$) {
<ul><code>perl fhem.pl fhem.cfg</code></ul></li><br/>
<br/>
<li>transfer your existing configuration into the database<br/><br/>
<ul>enter <code>{use configDB;; cfgDB_Migrate}</code><br/>
<ul>enter<br/><br/><code>configdb migrate</code><br/>
<br/>
into frontend's command line</ul><br/></br>
Be patient! Migration can take some time, especially on mini-systems like RaspberryPi or Beaglebone.<br/>
@ -297,6 +349,43 @@ sub CommandConfigdb($$) {
This command can be used with different parameters.<br/>
<br/>
<li><code>configdb attr [attribute] [value]</code></li><br/>
Provides the possibility to pass attributes to backend and frontend.<br/>
<br/>
<code> configdb attr private 1</code> - set the attribute named 'private' to value 1.<br/>
<br/>
<code> configdb attr private</code> - delete the attribute named 'private'<br/>
<br/>
<code> configdb attr</code> - show all defined attributes.<br/>
<br/>
Currently, only one attribute is supported. If 'private' is set to 1 the user and password info<br/>
will not be shown in 'configdb info' output.<br/>
<br/>
<li><code>configdb backup</code></li><br/>
Replaces fhem's default backup process, since backup is no longer supported <br/>
with activated configDB.<br/>
<br/>
<b>Important:</b><br/>
Please be aware you are responsible for data backup of your database yourself!<br/>
The backup command can and will not do this job for you!<br/>
<br/>
<li><code>configdb diff &lt;device&gt; &lt;version&gt;</code></li><br/>
Compare configuration dataset for device &lt;device&gt;
from current version 0 with version &lt;version&gt;<br/>
Example for valid request:<br/>
<br/>
<code>get configDB telnetPort 1</code><br/>
<br/>
will show a result like this:
<pre>
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 * | |
+--+--------------------------------------+--+--------------------------------------+</pre>
<li><code>configdb info</code></li><br/>
Returns some database statistics<br/>
<pre>
@ -335,39 +424,6 @@ Ver 0 always indicates the currently running configuration.<br/>
<code>get configDB list global 1</code><br/>
<br/>
<li><code>configdb diff &lt;device&gt; &lt;version&gt;</code></li><br/>
Compare configuration dataset for device &lt;device&gt;
from current version 0 with version &lt;version&gt;<br/>
Example for valid request:<br/>
<br/>
<code>get configDB telnetPort 1</code><br/>
<br/>
will show a result like this:
<pre>
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 * | |
+--+--------------------------------------+--+--------------------------------------+</pre>
<li><code>configdb uuid</code></li><br/>
Returns a uuid that can be used for own purposes.<br/>
<br/>
<li><code>configdb backup</code></li><br/>
Replaces fhem's default backup process, since backup is no longer supported <br/>
with activated configDB.<br/>
<br/>
<b>Important:</b><br/>
Please be aware you are responsible for data backup of your database yourself!<br/>
The backup command can and will not do this job for you!<br/>
<br/>
<li><code>configdb reorg [keep]</code></li><br/>
Deletes all stored versions with version number higher than [keep].<br/>
Default value for optional parameter keep = 3.<br/>
This function can be used to create a nightly running job for<br/>
database reorganisation when called from an at-Definition.<br/>
<br/>
<li><code>configdb recover &lt;version&gt;</code></li><br/>
Restores an older version from database archive.<br/>
<code>set configDB recover 3</code> will <b>copy</b> version #3 from database
@ -376,6 +432,18 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right)
<b>Important!</b><br/>
The restored version will <b>NOT</b> be activated automatically!<br/>
You must do a <code>rereadcfg</code> or - even better - <code>shutdown restart</code> yourself.<br/>
<br/>
<li><code>configdb reorg [keep]</code></li><br/>
Deletes all stored versions with version number higher than [keep].<br/>
Default value for optional parameter keep = 3.<br/>
This function can be used to create a nightly running job for<br/>
database reorganisation when called from an at-Definition.<br/>
<br/>
<li><code>configdb uuid</code></li><br/>
Returns a uuid that can be used for own purposes.<br/>
<br/>
</ul>
<br/>
@ -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.<br/>
Finishing the save-process will be indicated by a corresponding message in frontend.</li>
<br/>
<li>You may need to install perl package Text::Diff to use cfgDB_Diff()</li>
<br/>
<li>There still will be some more (planned) development to this extension,
especially regarding some perfomance issues.</li>
<br/>
@ -418,6 +484,7 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right)
<br/>
<b>Voraussetzungen / Installation</b><br/>
<ul><br/>
<li>Bitte das perl Paket Text::Diff installieren, falls noch nicht auf dem System vorhanden.</li><br/>
<li>Es muss eine SQL Datenbank verf&uuml;gbar sein, untsrst&uuml;tzt werden SQLITE, MYSQL und POSTGRESQLL.</li><br/>
<li>Das zum Datenbanktype geh&ouml;rende DBD Modul muss in perl installiert sein,<br/>
f&uuml;r sqlite3 auf einem Debian System z.B. das Paket libdbd-sqlite3-perl</li><br/>
@ -494,7 +561,7 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right)
<ul><code>perl fhem.pl fhem.cfg</code></ul></li><br/>
<br/>
<li>Bestehende Konfiguration in die Datenbank &uuml;bertragen<br/><br/>
<ul><code>{use configDB;; cfgDB_Migrate}</code><br/>
<ul><code>configdb migrate</code><br/>
<br/>
in die Befehlszeile der fhem-Oberfl&auml;che eingeben</ul><br/></br>
Nicht die Geduld verlieren! Die Migration eine Weile dauern, speziell bei Mini-Systemen wie<br/>
@ -516,6 +583,46 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right)
Es wird ein neuer Befehl <code>configdb</code> bereitgestellt,<br/>
der mit verschiedenen Parametern aufgerufen werden kann.<br/>
<br/>
<li><code>configdb attr [attribute] [value]</code></li><br/>
Hiermit lassen sich attribute setzen, die das Verhalten von Front- und Backend beeinflussen.<br/>
<br/>
<code> configdb attr private 1</code> - setzt das Attribut 'private' auf den Wert 1.<br/>
<br/>
<code> configdb attr private</code> - l&ouml;scht das Attribut 'private'<br/>
<br/>
<code> configdb attr</code> - zeigt alle gespeicherten Attribute<br/>
<br/>
Im Moment ist nur ein Attribut definiert. Wenn 'private' auf 1 gesetzt wird, werden bei 'configdb info' <br/>
keine Benutzer- und Passwortdaten angezeigt.<br/>
<br/>
<br/>
<li><code>configdb backup</code></li><br/>
Ersetzt den Standard-Backup-Befehl von fhem, da dieser bei Verwendung von configDB nicht mehr<br/>
zur Verf&uuml;gung steht.<br/>
<br/>
<b>Wichtig:</b><br/>
F&uuml;r die Sicherung der Datenbank ist der Anwender selbst verantwortlich!<br/>
Der backup Befehl kann diese Aufgabe nicht &uuml;bernehmen.<br/>
Ausnahme: Nutzer einer im fhem Verzeichnis liegenden sqlite Datenbank profitieren von der Einfachheit<br/>
dieser Datenbank, denn das fhem Verzeichnis wird ohnehin komplett gesichert.<br/>
<br/>
<li><code>configdb diff &lt;device&gt; &lt;version&gt;</code></li><br/>
Vergleicht die Konfigurationsdaten des Ger&auml;tes &lt;device&gt; aus der aktuellen Version 0 mit den Daten aus Version &lt;version&gt;<br/>
Beispielaufruf:<br/>
<br/>
<code>configdb diff telnetPort 1</code><br/>
<br/>
liefert ein Ergebnis &auml;hnlich dieser Ausgabe:
<pre>
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 * | |
+--+--------------------------------------+--+--------------------------------------+</pre>
<li><code>configdb info</code></li><br/>
Liefert eine Datenbankstatistik<br/>
<pre>
@ -548,45 +655,10 @@ Ver 0 bezeichnet immer die aktuell verwendete Konfiguration.<br/>
Standardwert f&uuml;r [version] = 0 um Ger&auml;te in der aktuellen Version anzuzeigen.<br/>
Beispiele f&uuml;r g&uuml;ltige Aufrufe:<br/>
<br/>
<code>get configDB list</code><br/>
<code>get configDB list global</code><br/>
<code>get configDB list '' 1</code><br/>
<code>get configDB list global 1</code><br/>
<br/>
<li><code>configdb diff &lt;device&gt; &lt;version&gt;</code></li><br/>
Vergleicht die Konfigurationsdaten des Ger&auml;tes &lt;device&gt; aus der aktuellen Version 0 mit den Daten aus Version &lt;version&gt;<br/>
Beispielaufruf:<br/>
<br/>
<code>get configDB diff telnetPort 1</code><br/>
<br/>
liefert ein Ergebnis &auml;hnlich dieser Ausgabe:
<pre>
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 * | |
+--+--------------------------------------+--+--------------------------------------+</pre>
<li><code>configdb uuid</code></li><br/>
Liefert eine uuid, die man f&uuml;r eigene Zwecke verwenden kann.<br/>
<br/>
<li><code>configdb backup</code></li><br/>
Ersetzt den Standard-Backup-Befehl von fhem, da dieser bei Verwendung von configDB nicht mehr<br/>
zur Verf&uuml;gung steht.<br/>
<br/>
<b>Wichtig:</b><br/>
F&uuml;r die Sicherung der Datenbank ist der Anwender selbst verantwortlich!<br/>
Der backup Befehl kann diese Aufgabe nicht &uuml;bernehmen.<br/>
Ausnahme: Nutzer einer im fhem Verzeichnis liegenden sqlite Datenbank profitieren von der Einfachheit<br/>
dieser Datenbank, denn das fhem Verzeichnis wird ohnehin komplett gesichert.<br/>
<br/>
<li><code>configdb reorg [keep]</code></li><br/>
L&ouml;scht alle gespeicherten Konfigurationen mit Versionsnummern gr&ouml;&szlig;er als [keep].<br/>
Standardwert f&uuml;r den optionalen Parameter keep = 3.<br/>
Mit dieser Funktion l&auml;&szlig;t sich eine n&auml;chtliche Reorganisation per at umsetzen.<br/>
<code>configdb list</code><br/>
<code>configdb list global</code><br/>
<code>configdb list '' 1</code><br/>
<code>configdb list global 1</code><br/>
<br/>
<li><code>configdb recover &lt;version&gt;</code></li><br/>
@ -601,6 +673,16 @@ compare device: telnetPort in current version 0 (left) to version: 1 (right)
<br/>
<br/>
<li><code>configdb reorg [keep]</code></li><br/>
L&ouml;scht alle gespeicherten Konfigurationen mit Versionsnummern gr&ouml;&szlig;er als [keep].<br/>
Standardwert f&uuml;r den optionalen Parameter keep = 3.<br/>
Mit dieser Funktion l&auml;&szlig;t sich eine n&auml;chtliche Reorganisation per at umsetzen.<br/>
<br/>
<li><code>configdb uuid</code></li><br/>
Liefert eine uuid, die man f&uuml;r eigene Zwecke verwenden kann.<br/>
<br/>
<b>Hinweise</b><br/>
<br/>
<ul>

View File

@ -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($$) {
<a name="configDB"></a>
<h3>configDB</h3>
<ul>
This is the core library for configuration from SQL database.<br/>
This is the core backend library for configuration from SQL database.<br/>
See <a href="#configdb">configdb command documentation</a> for detailed info.<br/>
</ul>