[GORM] PMA-Relations automatisiert erstellen

Dieser Bereich dient dazu, eure Tricks und Erweiterungen vorzustellen, damit diese auch andere Anwender nutzen können. // This area can be used to publish your tricks and extensions to the APF to be used by other developers.
Antworten
Benutzeravatar
MrNiceGuy
Beiträge: 749
Registriert: 03.02.2009, 16:49:42
Wohnort: Nienburg / Weser

[GORM] PMA-Relations automatisiert erstellen

Beitrag von MrNiceGuy » 12.02.2011, 14:23:50

Moin moin!

Ich habe mir heute mal wieder ein paar Gedanken zum APF gemacht, nachdem ich die letzten Monate vornehmlich mit der Verwendung des Selbigen verbrachte und kaum konstruktives hier im Forum anbringen konnte.

Aber das soll sich heute mal wieder ein bisschen ändern :)

Bei der Erweiterung geht es um folgendes: Ich nutze exzessiv phpMyAdmin als Administrations-Interface für die Datenbank. Die Datenbanken meiner APF-Projekte habe ich immer mit dem mitgelieferten GORM-Setup erstellt, was aber auch gleichzeitig einen großen Nachteil mit sich bringt: Bei Änderungen an der Datenbank-Struktur funktioniert es in manchen Fällen nicht das Update-Tool zu benutzen (z.B. Umbenennung von Feldern), wenn Daten in der DB vorhanden sind. Damit ich nicht ewig viel mit Datenleichen herumhantieren muss arbeite ich in meinem Test-System meist auf diese Weise: Löschen der Tabellen und neu Anlegen der gesamten Datenbank mittels GORM-Setup.

Wie ich ja aber schon sagte nutze ich PMA sehr exzessiv, was auch die zusätzlichen Funktionen beinhaltet. In diesem Fall geht es um die Relations, die man bei MyISAM-Tabellen über PMA erstellen kann. Bei den meisten meiner Projekte geht es hierbei um weit über 100 Tabellen. Sollte ich nun für alle Relations die Verbindung manuell angeben müssen hätte ich viel zu tun, denn: Jede ASS- oder CMP-Tabelle benötigt 2 Relations!

Um dieses Problem ebenfalls zu automatisieren habe ich eine kleine Erweiterung für den GORM geschrieben, die vom Setup abgeleitet wurde und die Einträge in die Datenbank automatisch erledigen soll:

Code: Alles auswählen

<?php
import
  ( 'modules::genericormapper::data',
    'BaseMapper'
   );

class GenericORMapperPMARelation extends BaseMapper
{
  protected $__RowTypeMappingFrom = array
    ( '/^VARCHAR\(([0-9]+)\)$/i',
      '/^TEXT$/i',
      '/^DATE$/i'
     );

  protected $__RowTypeMappingTo = array
    ( 'VARCHAR($1) character set utf8 NOT NULL default \'\'',
      'TEXT character set utf8 NOT NULL',
      'DATE NOT NULL default \'0000-00-00\''
     );

  protected $__StorageEngine = 'MyISAM';
  protected $__PMARelation   = 'pma_relation';

  function GenericORMapperPMARelation ()
  {
  }

  public function setupRelation
    ( $configNamespace,
      $configNameAffix,
      $connectionName,
      $connectionPMA = NULL
     )
  {
    $this->__ConfigNamespace = $configNamespace;
    $this->__ConfigNameAffix = $configNameAffix;

    // get connection manager
    $cM = $this->__getServiceObject
      ( 'core::database',
        'connectionManager'
       );

    // initialize connection
    $this->__DBDriver = $cM->getConnection ($connectionName);

    // setup relation layout
    $relations = $this->__generateRelationLayout ($this->__DBDriver->get ('dbName'));

    // display only
    if ($connectionPMA === NULL)
    {
      // display relation structure
      foreach ($relations AS $relation)
      {
        echo PHP_EOL.PHP_EOL.$relation;
      }
      echo '</pre>';
    }
    else
    {
      // initialize connection
      $this->__DBDriver = $cM->getConnection ($connectionPMA);

      // create relation structure
      foreach ($relations AS $relation)
      {
        $this->__DBDriver->executeTextStatement ($relation);
      }
    }
  }

  protected function __generateRelationLayout ($sDB)
  {
    // create relation table
    $this->__createRelationTable();

    // generate tables for objects
    $setup = array();
    foreach ($this->__RelationTable AS $name => $attributes)
    {
      $setup[] = $this->__generateRelationTableLayout
        ( $sDB,
          $this->__RelationTable[$name]
         ).PHP_EOL.PHP_EOL;
    }

    return $setup;
  }

  protected function __generateRelationTableLayout
    ( $sDB,
      $tableAttributes
     )
  {
    return
      'INSERT INTO '.
        '`'.$this->__PMARelation.'` '.
      '('.
        '`master_db`,'.
        '`master_table`,'.
        '`master_field`,'.
        '`foreign_db`,'.
        '`foreign_table`,'.
        '`foreign_field`'.
      ') '.
      'VALUES '.
      '('.
        '\''.$sDB.'\','.
        '\''.$tableAttributes['Table'].'\','.
        '\''.$tableAttributes['SourceID'].'\','.
        '\''.$sDB.'\','.
        '\'ent_'.strtolower ($tableAttributes['SourceObject']).'\','.
        '\''.$tableAttributes['SourceID'].'\''.
      '),'.PHP_EOL.'('.
        '\''.$sDB.'\','.
        '\''.$tableAttributes['Table'].'\','.
        '\''.$tableAttributes['TargetID'].'\','.
        '\''.$sDB.'\','.
        '\'ent_'.strtolower ($tableAttributes['TargetObject']).'\','.
        '\''.$tableAttributes['TargetID'].'\''.
      ');'.PHP_EOL;
  }
}
Aufgerufen wird das Ganze dann ähnlich wie das Setup selbst, nur dass in diesem Fall eine Verbindung definitiv angegeben werden muss udn eine optional ist. Grund hierfür: Ich brauche den Datenbank-Namen für die Relations von PMA. Die erste Verbindung ist also lediglich für den Datenbank-Namen relevant, die zweite (optionale) Verbindung entscheidet dann zwischen Ausgabe oder direkter Ausführung in der Datenbank:

Code: Alles auswählen

<?php
require ('Apf/core/pagecontroller/pagecontroller.php');

import
  ( 'extensions::PMA_Relation::data::tools',
    'GenericORMapperPMARelation'
   );

// Registry laden
$objectRegistry = Singleton::getInstance ('Registry');

$objectRegistry->register
  ( 'apf::core',
    'Environment',
    'DEFAULT'
   );

$oMapper = new GenericORMapperPMARelation ();

$oMapper->set
  ( 'Context',
    'sites::app'
   );

//$oMapper->setupRelation
//  ( '3rdparty::app',
//    'appconfig',
//    'AppConnection',
//    'PMAConnection'
//   );

$oMapper->setupRelation
  ( '3rdparty::app',
    'appconfig',
    'AppConnection'
   );
Vielleicht findet der Eine oder Andere das ja auch noch sinnvoll!?

Eien Diskussion, sowie Kritiken sind erwünscht!

MfG
Lutz
There are only 10 Types of people in the world:
Those who understand binary and those who don't.

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [GORM] PMA-Relations automatisiert erstellen

Beitrag von Screeze » 21.02.2011, 15:06:21

Nachdem sich hier keiner zu äußert, mach ich mal den Anfang:
Was genau bringen diese PMA relations eigentlich? Habe davon noch nie was gehört :D

Benutzeravatar
MrNiceGuy
Beiträge: 749
Registriert: 03.02.2009, 16:49:42
Wohnort: Nienburg / Weser

Re: [GORM] PMA-Relations automatisiert erstellen

Beitrag von MrNiceGuy » 21.02.2011, 18:01:17

Innerhalb des PMA kannst du damit die Eingabe von Daten vereinfachen. Dabei wird in einer PMA-Tabelle in einer eigenen Datenbank (für die Erweiterungen) eine Verknüpfung als Fremdschlüssel gespeichert und im PMA dann anstelle eines Eingabefeldes eine Auswahlliste angezeigt.

Nehmen wir mal an, du hast die Tabellen ent_application und ent_user. Diese sind über cmp_application2user verbunden. Du kannst nun in PMA angeben, dass der Inhalt in cmp_application2user.ApplicationID sich auf ent_application.ApplicationID bezieht. Das gleiche im Übrigen auch für die UserID zur Tabelle ent_user.

Wenn du nun einen Datensatz in PMA hinzufügen willst (in cmp_application2user), erhälst du kein Text-Feld mehr, sondern ein Select-Feld (oder bei zu vielen Daten irgendwann ein Text-Feld mit einem Button daneben, um aus einer Tabelle den entsprechenden Wert auszuwählen), über den du den Wert auswählen kannst.

Zusätzlich zu dieser Verknüpfung kann man dann noch angeben, welches Feld einer Tabelle als Anzeigefeld dienen soll, dieser Name wird dann in der Auswahlliste neben dem Wert, auf den es sich bezieht angezeigt. Diese Funktion deckt meine Erweiterung zwar noch nicht ab, aber die ist auch erstmal nebensächlich. Praktisch wird es aber, wenn man die IDs nicht mehr behalten kann. In ent_user würde man zum Beispiel den Usernamen als das Feld angeben, das angezeigt werden soll und in ent_application den Namen der Applikation. Dadurch wird die Verwaltung der Daten innerhalb von PMA meiner Meinung nach erheblich vereinfacht - zumindest in der Entwicklungsphase, bis man irgendwann sein Backend fertig hat.
There are only 10 Types of people in the world:
Those who understand binary and those who don't.

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [GORM] PMA-Relations automatisiert erstellen

Beitrag von Screeze » 21.02.2011, 18:07:14

Hast du evtl. Links parat wo das gut dokumentiert ist? Würde mir das demnächst wenn ich Zeit hab mal ansehen wollen die Funktion, dann muss ich nicht suchen wenn du was kennst.

Benutzeravatar
MrNiceGuy
Beiträge: 749
Registriert: 03.02.2009, 16:49:42
Wohnort: Nienburg / Weser

Re: [GORM] PMA-Relations automatisiert erstellen

Beitrag von MrNiceGuy » 21.02.2011, 19:08:30

Direkt weiß ich da keinen Link, außer zur Homepage von PMA und den entsprechenden Wiki-Eintrag.
There are only 10 Types of people in the world:
Those who understand binary and those who don't.

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: [GORM] PMA-Relations automatisiert erstellen

Beitrag von dr.e. » 22.02.2011, 00:04:30

Hallo Lutz,

ich kannte die PMA-Erweiterung nur aus einer Fehlermeldung, wenn die relevanten Tabellen im PHPMyAdmin-Schema nicht angelegt waren. Für mich klingt das aber grundsätzlich sinnvoll auch wenn ich bisher deine Vorgehensweise mit Löschen, Setup und Import immer als ausreichend empfunden habe. Im Fall von Spalten-Umbenennungen ist es theoretisch mit dem Update-Tool getan, sofern du Datentyp-Konvertierungen hast, wird es natürlich schwierig. Und genau da - so wie ich dich verstehe - kann das ja helfen.
Viele Grüße,
Christian

Benutzeravatar
MrNiceGuy
Beiträge: 749
Registriert: 03.02.2009, 16:49:42
Wohnort: Nienburg / Weser

Re: [GORM] PMA-Relations automatisiert erstellen

Beitrag von MrNiceGuy » 22.02.2011, 07:20:23

Mich üebrrascht ein wenig, dass diese Zusatzfunktionen von PMA scheinbar nicht genutzt werden - ich liebe sie! Sie machen einem das Arbeiten mit der Datenbank auch in Datenbank-Typen != 'InnoDB' erheblich einfacher - vor Allem wenn es irgendwann weit über hundert Tabellen mit weit über tausend Datensätzen sind.

Persönlich habe ich mich noch nicht wieder mit dem Update-Tool auseinandergesetzt, da ich bisher immer befürchte, dass da irgendwas nicht richtig funktionieren könnte und um dem vorzubeugen nutze ich halt immer: "Löschen, neu anlegen". Aber auch bei neuen Projekten, bei denen man schon zum Anfang 10, 20, 50 oder 100 Tabellen "mal eben schnell" in die Kofniguration gehackt hat ist diese Erweiterung sinnvoll, da sie einem auch hier schon die Arbeit abnimmt die Verknüpfungen selber einzupflegen.

Im Übriegn solltet ihr euch im Zuge der Verknüpfung auch mal den Designer anschauen, da kann man dann die Verbindungen zwischen den Tabellen sehen und diese per Drag&Drop anordnen und eine kleine Datenbank-Übersicht ähnlich der Entwurfsansicht in Access erhalten. Mag manchmal ganz hilfreich sein davon einen Ausdruck an der Wand hängen zu haben :)
There are only 10 Types of people in the world:
Those who understand binary and those who don't.

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast