[patch] fhem.pl - Neue Funktion FileDelete()

Begonnen von betateilchen, 16 September 2017, 13:31:54

Vorheriges Thema - Nächstes Thema

betateilchen

Analog zu FileWrite() und FileRead() schlage ich folgende neue Funktion vor.


Index: fhem.pl
===================================================================
--- fhem.pl     (revision 15072)
+++ fhem.pl     (working copy)
@@ -59,6 +59,7 @@
sub DoTrigger($$@);
sub EvalSpecials($%);
sub Each($$;$);
+sub FileDelete($);
sub FileRead($);
sub FileWrite($@);
sub FmtDateTime($);
@@ -4830,6 +4831,25 @@
}

sub
+FileDelete($)
+{
+  my ($param) = @_;
+  my ($fileName, $forceType);
+  if(ref($param) eq "HASH") {
+    $fileName = $param->{FileName};
+    $forceType = $param->{ForceType};
+  } else {
+    $fileName = $param;
+  }
+  $forceType //= '';
+  if(configDBUsed() && lc($forceType) ne "file") {
+    return _cfgDB_Filedelete($fileName);
+  } else {
+    return unlink($fileName);
+  }
+}
+
+sub
getUniqueId()
{
   my ($err, $uniqueID) = getKeyValue("uniqueID");

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig


betateilchen

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Markus Bloch

Hallo zusammen,

ich bin gerade dabei die Funktion FileDelete() ins Wiki aufzunehmen. Dabei bin ich bei der Recherche, was der Return-Wert genau bedeutet etwas arg verwirrt, was damit bezweckt werden soll.

Generell muss man dabei zwischen Filesystem-Löschen und configDB-Löschen unterscheiden:

Filesystem:

Rückgabewert von undef() => https://perldoc.perl.org/functions/unlink.html wobei die Anzahl der gelöschten Dateien zurückgegeben wird oder undef im Fehlerfall. Die eigentliche Fehlermeldung steht dann in $!, welche man selber auswerten müsste.

configDB:

Hier gibts folgendes if-Konstrukt:


        if($ret > 0) {
                $ret = "File $filename deleted from database.";
        } else {
                $ret = "File $filename not found in database.";
        }
        return $ret;


Sowohl im Erfolgs-, als auch Fehlerfall wird ein String zurückgegeben.

Könnte man das ganze nicht harmonisieren mit den Error-Rückgabewerten der anderen File-Funktionen? Also nur im Fehlerfall wird eine Fehlermeldung als String zurückgegeben? Aktuell ist das ein sehr kruder Rückgabewert wo ich etwas Probleme habe zu beschreiben, was dieser Rückgabewert in welchem Fall genau bedeutet.

Danke

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

betateilchen

configDB liefert in beiden Fällen einen String zurück, weil es schon sehr lange den Frontend-Befehl "configdb filedelete <fileName>" gibt und der Anwender an dieser Stelle - zurecht - eine aussagekräftige Rückantwort haben möchte.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Markus Bloch

Das ist mir natürlich klar.

Mein Vorschlag daher:

FileDelete($)
{
  my ($param) = @_;
  my ($fileName, $forceType);
  if(ref($param) eq "HASH") {
    $fileName = $param->{FileName};
    $forceType = $param->{ForceType};
  } else {
    $fileName = $param;
  }
  $forceType //= '';
  if(configDBUsed() && lc($forceType) ne "file") {
    my $r = _cfgDB_Filedelete($fileName);
    return $r if($r !~ /deleted from database/);
  } else {
    return $! unless(defined(unlink($fileName)));
  }
  return undef;
}


Damit ist der Rückgabewert klar ein String im Falle eines Fehlers. Bei Erfolg wird undef zurückgegeben.
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

betateilchen

Ab morgen (ab sofort in SVN) gilt folgende Regel:


  • Rückgabewert aus _cfgDB_Filedelete() = undef wenn eine Datei nicht gelöscht werden konnte (aus welchen Gründen auch immer)
  • Rückgabewert aus _cfgDB_Filedelete() = 1 wenn die Datei gelöscht wurde
  • Die Textausgabe für den Benutzer bei "configdb filedelete ..." wird an anderer Stelle erzeugt.

Das hier:

return $! unless(defined(unlink($fileName)));

halte ich übrigens für fragwürdig, weil unlink() eine (definierte) 0 zurückliefert, wenn eine vorhandene Datei wegen fehlender Berechtigung nicht gelöscht werden konnte. Eigentlich ist das aber ein Fehlerfall.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Markus Bloch

Neuer Vorschlag:

FileDelete($)
{
  my ($param) = @_;
  my ($fileName, $forceType);
  if(ref($param) eq "HASH") {
    $fileName = $param->{FileName};
    $forceType = $param->{ForceType};
  } else {
    $fileName = $param;
  }
  $forceType //= '';
  if(configDBUsed() && lc($forceType) ne "file") {
    my $r = _cfgDB_Filedelete($fileName);
    return "unable to delete file from configDB: $fileName" unless($r);
  } else {
    return $! unless(unlink($fileName));
  }
  return undef;
}
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

betateilchen

Das ist ja noch schlimmer als der vorhergehende. Lies bitte nochmal meinen letzten Beitrag.

Ich würde an dieser Stelle gar keinen String zurückgeben, sondern einfach nur einen logischen Wert für den Fehler- und den Erfolgsfall.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Markus Bloch

Von mir aus gerne, nur dann aber sollten wir das bei allen File*()-Funktionen machen. Jede Funktion gibt da unterschiedliche Sachen zurück und schlimmer möchte ich es ehrlich gesagt nicht machen:

($err,@content) = FileRead(...)

-> $err ist im Fehlerfall mit einer Fehlermeldung als Zeichenkette befüllt. Im Erfolgsfall ist $err = undef oder "" (Leerstring von configDB)

$err = FileWrite(...)

-> $err ist im Fehlerfall mit einer Fehlermeldung als Zeichenkette befüllt. Im Erfolgsfall ist undef (sowohl regulär als auch configDB)

$ret = FileDelete(...)
-> $ret ist im Fehlerfall 0 und im Erfolgsfall 1 (so?)



Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

betateilchen

Wenn Du in Deinem jetzigen Job mal keinen Spaß mehr hast, kannst Du jederzeit bei der EU in der Abteilung anfangen, die Gurkengrößen normieren will...

mann mann mann...
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

Meiner Erfahrung nach werden Entwickler von nicht genormten "Gurken" schnell frustriert.

betateilchen

ich finde nicht genormte Gurken sind einfach "natürlich" und quasi 100% BIO :)

Darüber hinaus sind sie auch noch vegetarisch & vegan. Was wollen wir mehr?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Markus Bloch

Ich seh das eher unter gutes Handwerk.  ;)

Rudi darf entscheiden.

Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

betateilchen

Ich finde das alles gut so, wie es jetzt ist.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!