Kennt Ihr einen Weg das SchemaTool so zu nützen, dass Tabellen nur neu angelegt werden, wenn Sie noch nicht existieren?
/**
* Creates the schemas for the additional models
*/
public static function createSchemas()
{
$tool = new SchemaTool(Shopware()->Container()->get('models'));
$classes = [
Shopware()->Container()->get('models')->getClassMetadata(Discount::class),
Shopware()->Container()->get('models')->getClassMetadata(AccessCode::class)
];
$tool->createSchema($classes);
}
Wenn ich die Tabellen beim Uninstall nicht löschen möchte führt das beim erneuten Install des Plugins aktuell zu einer Exception.
Eine $tool->hasTable() Methode oder einen entsprechenden Parameter beim Anlegen habe ich bislang leider nicht gefunden.
Durch dropSchema würde der Table gelöscht werden, was Synonymous vermutlich auch bei der Installation nicht möchte („Wenn ich die Tabellen beim Uninstall nicht löschen möchte…“).
Ich habe ebenfalls ein Plugin, dessen Daten ich nicht verlieren möchte, wenn das Plugin deinstalliert oder neuinstalliert wird.
Ich habe das derzeit so gelöst, dass ich bei der Installation eine eigene PDO Connection öffne und das „CREATE TABLE IF NOT EXISTS“ statement absetze.
Falls es einen bessere Lösung dafür gibt, wäre ich für Feedback dankbar.
Deine Methode könnte damit in etwa so aussehen (ungetestet):
/**
* Creates the schemas for the additional models
*/
public static function createSchemas() {
$tool = new SchemaTool(Shopware()->Container()->get('models'));
$classes = [
Shopware()->Container()->get('models')->getClassMetadata(Discount::class),
Shopware()->Container()->get('models')->getClassMetadata(AccessCode::class)
];
// you could (and should) also implement a method which dynamically returns an array of
// table names based on the ClassMetadata in $classes
$tableNames = array("table1", "table2");
$schemaManager = Shopware()->Container()->get('models')->getConnection()->getSchemaManager();
if (!$schemaManager->tablesExist($tableNames)) {
$tool->createSchema($classes);
}
}
Deine Methode könnte damit in etwa so aussehen (ungetestet):
/**
Creates the schemas for the additional models
*/
public static function createSchemas() {
$tool = new SchemaTool(Shopware()->Container()->get(‚models‘));
$classes = [
Shopware()->Container()->get(‚models‘)->getClassMetadata(Discount::class),
Shopware()->Container()->get(‚models‘)->getClassMetadata(AccessCode::class)
];
// you could (and should) also implement a method which dynamically returns an array of
// table names based on the ClassMetadata in $classes
$tableNames = array(„table1“, „table2“);
$schemaManager = Shopware()->Container()->get(‚models‘)->getConnection()->getSchemaManager();
if (!$schemaManager->tablesExist($tableNames)) {
$tool->createSchema($classes);
}
}
Viele Grüße
Man braucht vlt. eine Mischung von createSchema mit updateSchema. Wenn in der Zwischen eine neue Version des Plugins gibt, würde diese Funktion nicht mehr richtig funktionieren.
Deine Methode könnte damit in etwa so aussehen (ungetestet):
/**
* Creates the schemas for the additional models
*/
public static function createSchemas() {
$tool = new SchemaTool(Shopware()->Container()->get('models'));
$tables = [
"table1" => Shopware()->Container()->get('models')->getClassMetadata(Discount::class),
"table2" => Shopware()->Container()->get('models')->getClassMetadata(AccessCode::class)
];
$schemaManager = Shopware()->Container()->get('models')->getConnection()->getSchemaManager();
foreach($tables as $tableName => $class){
if (!$schemaManager->tablesExist($tableName)) {
$tool->createSchema([$class]);
}else{
$tool->updateSchema([$class], true); //true - saveMode and not delete other schemas
}
}
}
Eine ifTableExists Methode habe ich eigentlich gesucht. Die gibt es in meiner Version des SchemaTools (Doctrine\ORM\Tools) aber leider nicht!?
Möglicherweise gibt es die in einer anderen Doctrine Version - in jener die bei Shopware genutzt wird fehlt sie aber. Oder ich bin gerade völlig am falschen Dampfer…
Ansonsten tut sie aus meiner Sicht genau das, wonach Du gesucht hast: Man kann damit vor dem Erstellen von Schemata prüfen, ob die Tabellennamen schon existieren.
Vielen Dank für eure Ideen @kcon und @alexxxbing. Mit “getTableName” kann man sich einfach den Tabellennamen aus der Klasse holen und muss diesen nicht manuell im Installer hinterlegen:
private function createSchema()
{
$tool = new SchemaTool($this->modelManager);
$classes = [
$this->modelManager->getClassMetadata(Confirmation::class),
$this->modelManager->getClassMetadata(Shipment::class),
$this->modelManager->getClassMetadata(ShipmentDetail::class),
$this->modelManager->getClassMetadata(StockList::class)
];
/** @var \Doctrine\DBAL\Schema\AbstractSchemaManager $schemaManager */
$schemaManager = $this->modelManager->getConnection()->getSchemaManager();
/** @var \Doctrine\ORM\Mapping\ClassMetadata $class */
foreach ($classes as $class) {
if (!$schemaManager->tablesExist([$class->getTableName()])) {
$tool->createSchema([$class]);
} else {
$tool->updateSchema([$class], true); //true - saveMode and not delete other schemas
}
}
}