Tom: String-Auswertung

Hello,

bingerade dabei, ein paar älterte Funktionen in meiner Librairy zu überarbeiten.

Es geht dabei um die Aufsplittung des Typenstrings von MySQL

[Type] => bigint(20) unsigned
[Type] => bigint(20)
[Type] => decimal(10,2)
[Type] => set('rot','gelb','grün','blau')
[Type] => datetime

gilt es sinnvoll zu splitten und zu erkennen
Ich habe nur die Muster abgebildet, nicht alle Möglichkeiten!

Wie würdet Ihr da vorgehen?

Diejenigen, die "more Input" benötigen, bitte ich um Eingabe von "category:PHP author:Tom get_info" ind die Suche.

Harzliche Grüße vom Berg
http://www.annerschbarrich.de

Tom

--
Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
Nur selber lernen macht schlau

  1. Hello,

    Es geht dabei um die Aufsplittung des Typenstrings von MySQL

    [Type] => bigint(20) unsigned
    [Type] => bigint(20)
    [Type] => decimal(10,2)
    [Type] => set('rot','gelb','grün','blau')
    [Type] => datetime

    gilt es sinnvoll zu splitten und zu erkennen
    Ich habe nur die Muster abgebildet, nicht alle Möglichkeiten!

    Wie würdet Ihr da vorgehen?

    bisher war das so geregelt:

    $_colinfo["Type"]      = $_split["type"];             # Nominaltyp
      $_colinfo["TypeClass"] = $_types[$_split["type"]][0]; # Typoberklasse
      $_colinfo["Len"]       = $_split["len"];              # Länge des Feldes gesamt
      $_colinfo["Dec"]       = $_split["dec"];              # Dezimalstellen
      $_colinfo["Rem"]       = $_split["rem"];              # REMARK, bisher nur 'unsigned'
      $_colinfo["Set"]       = $_split["set"];              # Wertearray  für enum und set

    Mir geht es darum, wie man am effektivsten, sichersteren  und zukunftsorientiertesten die atomaren Informationen aus dem Type-String extrhieren kann.

    Harzliche Grüße vom Berg
    http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau

    1. Hello,

      Wie bekomme ich es hin, dass der zweite Wert der dezimalen Angabe (also hinter dem Komma) in einem eigenen Match auftritt, wenn er vorhanden ist.

      Also bei "decimal(10,2)" sollten die 10 und die 2 jeweils in einem eigenen match auftreten

      Formatbeispiele:

      #   bigint(20) unsigned
      #   timestamp(14)
      #   varchar(30)
      #   set('EINS','ZWEI','DREI','VIER','FÜNF')
      #   float(11,10)
      #   double(11,5)
      #   decimal(10,2)
      #   year(2)
      #   char(2)
      #   enum('eins','zwei','sieben','12')

      $metasum = "bigint(20) unsigned";
      #$metasum = "set('EINS','ZWEI','DREI','VIER','FÜNF')";
      #$metasum = "double(11,5)";
      #$metasum = "timestamp(14)";
      #$metasum = "time";

      #$type="([a-z]{3,})";
      $type="tinyint|smallint|mediumint|int|bigint|float|double|decimal|".
            "date|datetime|timestamp|time|year|char|varchar|tinyblob|".
            "tinytext|text|blob|mediumblob|mediumtext|longblob|longtext|".
            "enum|set";

      #$len="([0-9]{1,3})";
      #$dec=",([0-9]{1,3})";

      preg_match("#^($type){1}(({1}([^)]+)){1})*(\s(unsigned){1})*#i",
         $metasum, $matches);

      Harzliche Grüße vom Berg
      http://www.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau

      1. gudn tach!

        Wie bekomme ich es hin, dass der zweite Wert der dezimalen Angabe (also hinter dem Komma) in einem eigenen Match auftritt, wenn er vorhanden ist.

        Also bei "decimal(10,2)" sollten die 10 und die 2 jeweils in einem eigenen match auftreten

        preg_match("#^($type){1}(({1}([^)]+)){1})*(\s(unsigned){1})*#i",
           $metasum, $matches);

        {1} ist an allen stellen ueberfluessig.

        * = {0,} du meinst aber wahrscheinlich eher {0,1} und das ist einfach das "?".

        bei deinen nicht-benoetigten geklammerten teilausdruecken, kannst du das speichern (als $1, $2, ...) unterdruecken, indem du der oeffnenden klammer ?: nachstellst, also statt (foo) (?:foo).

        vorschlag:
        preg_match("#^($type)(?:\((?:(\d+)|(\d+),(\d+)|('.*'))\))?(?:\s(unsigned))?$#i", $metasum, $matches);

        in $matches steht dann (falls gefunden)
         [0] => alles gematchte
         [1] => der typ ($type)
         [2] => eine zahl, wenn sie der einzige parameter ist
         [3] => eine zahl, wenn sie der erste von zwei parametern ist
         [4] => eine zahl, wenn sie der zweite von zwei parametern ist
         [5] => string-parameter (alle zusammen als ein string)
         [6] => "unsigned"

        prost
        seth

        1. Hello seth,

          bei deinen nicht-benoetigten geklammerten teilausdruecken, kannst du das speichern (als $1, $2, ...) unterdruecken, indem du der oeffnenden klammer ?: nachstellst, also statt (foo) (?:foo).

          Ok, irgendwann wusste ich das sogar schon mal. ;-)

          vorschlag:
          preg_match("#^($type)(?:\((?:(\d+)|(\d+),(\d+)|('.*'))\))?(?:\s(unsigned))?$#i", $metasum, $matches);

          in $matches steht dann (falls gefunden)
          [0] => alles gematchte
          [1] => der typ ($type)
          [2] => eine zahl, wenn sie der einzige parameter ist
          [3] => eine zahl, wenn sie der erste von zwei parametern ist
          [4] => eine zahl, wenn sie der zweite von zwei parametern ist
          [5] => string-parameter (alle zusammen als ein string)
          [6] => "unsigned"

          Das sieht gut aus. Scheint sicher zu funktionieren.
          Ich hatte versucht, dass der erste und der einzige Größenparameter ([3] oder [2]) immer in demselben Match-Element landen sollte. Aber das bekommt man wohl nicht hin?

          Vielen Dank für die Hilfe.

          Harzliche Grüße vom Berg
          http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau

          1. gudn tach Tom!

            Das sieht gut aus. Scheint sicher zu funktionieren.

            "sicher" allerdings nur, wenn damit nicht syntaktische richtigkeit ueberprueft werden soll, denn dann duerfte z.b. sowies wie ".*" da nicht stehen. ich ging bei dem regexp davon aus, dass die syntax streng mit dem uebereinstimmt, was du als vorgabe genannt hast.

            Ich hatte versucht, dass der erste und der einzige Größenparameter ([3] oder [2]) immer in demselben Match-Element landen sollte. Aber das bekommt man wohl nicht hin?

            doch, und es ist sogar *huestel* kuerzer:
            statt /(?:(\d+)|(\d+),(\d+)|...)/
                  /(?:(\d+)(?:,(\d+))?|...)/

            preg_match("#^($type)(?:\((?:(\d+)(?:,(\d+))?|('.*'))\))?(?:\s(unsigned))?$#i", $metasum, $matches);

            prost
            seth

            1. Hello Seth,

              Das sieht gut aus. Scheint sicher zu funktionieren.

              "sicher" allerdings nur, wenn damit nicht syntaktische richtigkeit ueberprueft werden soll, denn dann duerfte z.b. sowies wie ".*" da nicht stehen. ich ging bei dem regexp davon aus, dass die syntax streng mit dem uebereinstimmt, was du als vorgabe genannt hast.

              Ich will einfach mal annehmen, dass ich aus "show columns from $table" aus dem MySQL-DBMS entweder eine gültige oder keine Antwort bekomme. Allerdings habe ich mich vorhin auch gefragt, wie paranoid man programmieren muss, oder wann man sich auf Ergebnisse einer anderen Funktion verlassen darf.

              Ich hatte versucht, dass der erste und der einzige Größenparameter ([3] oder [2]) immer in demselben Match-Element landen sollte. Aber das bekommt man wohl nicht hin?

              doch, und es ist sogar *huestel* kuerzer:
              statt /(?:(\d+)|(\d+),(\d+)|...)/
                    /(?:(\d+)(?:,(\d+))?|...)/

              preg_match("#^($type)(?:\((?:(\d+)(?:,(\d+))?|('.*'))\))?(?:\s(unsigned))?$#i", $metasum, $matches);

              Danke nochmal.
              Das bau ich gleich um :-)

              Bei der Gelegenheit noch eine Frage zur Philosophie:

              Ich signiere über die Namen der Spalten, ob es sich beim Feldinhalt z.B. um einen Hyperlink oder um einen eMailnamen handeln soll. Die gerade in der mache befindliche Funktion trägt dann in eines der Informationsfelder ( ['func_view'] ) die Referenz zur passenden Darstellungsfunktion für HTML ein.

              Bei den Typen

              enum      "select_single"   oder "radio"
                set       "select_multiple" oder "checkbox"

              könnte man nun zweifeln, welche der Varianten die passende ist.

              Da ich ihn nicht benutze ...  Wie macht das der phpMyAdmin? nimmt der immer selects oder auch mal Radio/checkbox?

              Harzliche Grüße vom Berg
              http://www.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau