SideBarMenu

1.  Grundlegendes zu Migrations

Unter Migrations versteht man den Umzug von Daten in eine andere Umgebung. Bei den Migrationen gibt es unterschiedliche Domänen. So ist eine Domäne "studip" vorhanden in der die Versionsprotokollierung von Stud.IP zu finden ist. Analog gibt es auch für jedes Plugin eine Migrationsdomäne.

1.1  Aufbau von Migrations-Skripten:

Migrationsskripte bestehen in der Grundlage aus mindestens zwei Funktionen, zu denen eine dritte, optionale, hinzu kommt.

Unbedingt erforderlich sind die Funktionen up() und down(). In up() werden die Änderungen durchgeführt und entsprechend in down() die Änderungen der up() Methode wieder rückgängig gemacht. (->siehe Irreversible Migrationen)

Die Funktion description() liefert eine Beschreibung der durchzuführenden Migration.

1.2  Basisklasse der Migrationsskripte

Grundsätzlich müssen alle Migrationsskripte die Klasse Migration erweitern. Die früher verwendete Klasse DBMigration existiert zwar noch, sollte aber nicht mehr verwendet werden.

1.3  Namensgebung

Die Migrations Klassen müssen fortlaufend nummeriert werden, beginnend bei 1 und sind immer ganzzahlig. Es dürfen keine Zahlensprünge größer als 1 in der Nummerierung vorhanden sein, führende Nullen dürfen verwendet werden. Für jede Domäne ist ein eigenes Verzeichnis vorhanden, in dem die Migrationsschritte abgespeichert werden müssen, damit auch nur die entsprechende Domäne darauf zugreifen kann.

1.4  Reversible und Irreversible Migrationen

Bei reversiblen Migrationen besteht die Möglichkeit über die up() und down() Methoden immer in eine andere Version zu springen. Bei irreversiblem Migrationen verändert die up() Funktion die vorhandenen Daten derart, dass ein Aufruf der down() Funktion diese nicht wieder herstellen kann. In solchen Fällen sollte unbedingt eine Fehlerbehandlung in der down() Funktion des Migrationsschrittes erfolgen.

1.5  Browser basierte Migration

Das web_migrate Skript unter /public/web_migrate.php benennt die Migrationsskripte eigenständig um insofern dass jeder Buchstabe der einen Unterstrich vor sich hatte in einen Großbuchstaben umgewandelt wird und die Dateiendung wird nicht mit angezeigt, Beispiel:

17_db_optimierung_kontingentierung.php --> 17 DbOptimierungKontingentierung

Außerdem ruft web_migrate automatisch die aktuelle Versionsnummer aus der Datenbank ab, vergleicht diese mit den vorhandenen Migrationsschrittnummern und listet ggfs. die noch nicht durchgeführten Schritte und die entsprechenden @@description()@ Methoden tabellarisch auf. (siehe Screenshot)

1.6  Kommandozeilen basierte Migration

In dem Ordner /cli/ befindet sich ein Skript, das die Migrationen statt per Web-Interface über die Kommandozeile durchführt. Hier ist auch Migration der Plugins möglich, die vom Webinterface nicht unterstützt werden.

Erforderliche Parameter

  • d: Domäne (default studip)
  • m: Dateipfad zu den migrations
  • l: Nur auflisten was getan werden soll nicht migrieren
  • t: Zielmigration (0 für komplettes Reset, andernfalls Zielversionsnummer)
  • v: verbose (empfohlen)

Beispiel: Stud.IP Migrationen von 6 rückgängig machen auf 5: ./migrate.php -d studip -m ../db/migrations/ -t 5 -v

Beispiel: Ausgabe mit l Parameter: @@ ./migrate.php -d studip -l ../db/migrations/ -t 18

  3 Step87ExternConfigurations Extends table extern_config and converts configurations for the external pages from 
    INI-style files to serialised arrays stored in the database.
  4 Step116ParticipantView creates table necessary for StEP116
  5 Step25RaumzeitMigrations modify db schema for StEP00025; see logfile in $TMP_PATH
  6 Step25RaumzeitDbConversion convert dates for StEP00025; see logfile in $TMP_PATH
  7 TableTokenClass      creates table for Token class
  8 Step117StudienModule modify db schema StEP00117 Studienmodulstrukturen; 
  9 StEP00111Admission   creates table admission groups
 10 ImageProxy           creates table image_proxy_cache and config entry EXTERNAL_IMAGE_EMBEDDING
 11 LockRules            creates table for lock rules
 12 Step120Userpic       modify existing user pictures according to Step00120
 13 RemoveFieldsFromExtermine removes expire|repeat|color|priority from table ex_termine
 14 StEP00123Admission2  modifies table seminare, adds field `admission_enable_quota`
 15 Step00129EmailRestriction Adds the new Value EMAIL_DOMAIN_RESTRICTION to table config.
 16 Step00126EmbeddingFlashMovies Adds the new values EXTERNAL_
    FLASH_MOVIE_EMBEDDING and DOCUMENTS_EMBEDD_FLASH_MOVIES to table config.
 17 DbOptimierungKontingentierung adds keys in admission_seminar_studiengang, admission_seminar_user and seminar_user
 18 Step00139UploadFileReorg reorganize uploaded files into sub-folders@@

2.  Beispielplugin mit Migration

Elmar hat einfach mal ein kleines Beispiel fertiggemacht: das "DummyPlugin" (ein Plugin, da die Verwendung für die Plugin-Schnittstelle vorrangig von Interesse ist). Die Katalogstruktur des Plugins sieht folgendermaßen aus:

  DummyPlugin.class.php 
  plugin.manifest 
  sql/ 
    sql/dummy_install.sql 
    sql/dummy_uninstall.sql 
  migrations/ 
    migrations/1_test.php 
    migrations/2_foo.php 

Die SQL-Dateien unter sql definieren wie gehabt das "Grundlayout" für das Plugin und sind entsprechend als "dbscheme" (bzw. "uninstalldbscheme") im Manifest eingetragen, soweit also nichts neues. Neu hingekommen ist der Katalog migrations, der die einzelnen Deltas enthält, die von Plugin-Version zu Plugin-Version nachgezogen werden müssen (diese werden also nicht mehr in sql/dummy_install.sql abgebildet). Jeder Versionsschritt des Plugins kann beliebig viele solche Deltas ( = Migrations) besitzen. Alle Migrations sind aufsteigend numeriert, die Dateinamen folgen dabei der Konvention nummer_klassenname.php.

Jede Migration ist eine PHP-Klasse mit den Operationen up() und down(), die die jeweiligen Änderungen durchführen bzw. wieder zurücknehmen können. Als Beispiel hier der Inhalt von migrations/1_test.php:

  <? 
  class Test extends Migration { 
      function up () {
          $db = DBManager::get();
          $db->exec("INSERT INTO dummy VALUES (42, 'axel')"); 
      } 

      function down () {
          $db = DBManager::get();
          $db->exec("DELETE FROM dummy WHERE id = 42"); 
      } 
  } 
  ?> 

Anstatt Werte in eine Tabelle einzutragen könnte man natürlich ebenfalls neue Tabellen anlegen, Felder hinzufügen oder entfernen, Daten umwandeln oder in eine andere Tabelle kopieren, Dateien oder Kataloge anlegen, Rechte setzen usw. (es muß nichts mit der DB zu tun haben). Der Zugriff auf die Datenbank erfolgt dabei wie üblich über die DBManager-Klasse. Alles weitere passiert (bei Plugins) automatisch, d.h. beim Update eines Plugins werden - ausgehend vom aktuellen Versionsstand - alle notwendigen Änderungen (d.h. Migrations) durchgeführt bzw. bei einem Downgrade eines Plugins entsprechend wieder zurückgenommen.

PS: Wenn man möchte, kann man natürlich auch "dbscheme" und "uninstalldbscheme" im Manifest weglassen und das Anlegen der kompletten DB-Struktur für das Plugin über Migrations erledigen.

Für ein Beispiel für die Migration eines Plugins gibt es hier ein kleines Zip file:

Attach:dummy_plugin-v0.3.zip

Letzte Änderung am 24.11.2014 15:11 Uhr von eludwig.