Eigenes Model / Datenbanktabelle

Hallo an Alle!

Ich versuche gerade in unserem Modul eine neue Datenbanktabelle für Shipping Labels anzulegen. Bin dabei auf folgende Problematik gestoßen:

  1. DatabseProvider ist deprecated. Man soll das QueryBuilderInterface nutzen. Alles gut, jedoch kann der QueryBuilder keine neuen Datenbanktabellen erstellen, oder irre ich mich? Wie erstelle ich dann eine neue Datenbanktabelle?

  2. Ich hätte gern ein eigenes, Custom, Model für die Datenbanktabelle. Muss ich hierfür die \OxidEsales\Eshop\Core\Model\BaseModel Klasse extenden? Muss ich sonst noch was tun damit mein Model vom System erkannt wird und mit oxNew() verwendet werden kann?

Entschuldigt bitte falls die Fragen bereits irgendwo gestellt/beantwortet wurden. Ich konnte bisher noch nichts finden.

Puh, hoffentlich lehne ich mich jetzt nicht zu weit aus dem Fenster…
Das hier habe ich für Dich gefunden: https://docs.oxid-esales.com/developer/en/6.2/development/modules_components_themes/module/using_database.html. Und wenn ich das richtig sehe, kann man mit insert($tableName) auch eine DB-Tabelle anlegen: https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/query-builder.html

@marco.steinhaeuser danke für die schnelle Antwort!

Die von Dir angegebenen Links habe ich auch schon gefunden. Ich habe es auch soeben ausprobiert, leider geht das nicht. Es macht ja auch Sinn, da die insert() Methode ja nur für das Einfügen der Daten in eine bestehende Datenbanktabelle gedacht ist.

An exception occurred while executing 'INSERT INTO shipping_labels () VALUES()': SQLSTATE[42S02]: Base table or view not found: 1146 Table 'oxid.shipping_labels' doesn't exist

Soll ich dann einfach die Deprecated Methode nutzen? Ich sehe zurzeit keine andere Möglichkeit.

EDIT: Die Model-Klasse funktioniert super. Ich müsste jetzt nur noch die Datenbanktabelle richtig erstellen.

Die Doctrine Dokumentation Schema unter https://www.doctrine-project.org/projects/doctrine-dbal/en/2.10/reference/schema-manager.html#createschema sollte der Weg sein. In der Dokumentation selber sieht man nur dropTable() erwähnt, aber wenn man sich den PHP Code anguckt gibt es auch createTable()

Wenn man sich an Doctrine orientieren möchte könnten man folgendes Beispiel probieren

use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;

$container = ContainerFactory::getInstance()->getContainer();
$queryBuilderFactory = $container->get(QueryBuilderFactoryInterface::class);
$schemaManager = $queryBuilderFactory->getSchemaManager;
$schemaManager->createTable('shipping_labels');
$schemaManager->addColumn('name', 'string');

Ja, wenn Du auf OXID Framework Funktionalitäten zurückgreifen möchtest.

Nein, wenn Du OXID Framework Funktionalitäten nicht benötigst und es lieber selbst managen möchtest.

Nein, Models im Modul werden vom OXID Framework normalerweise von selbst erkannt. Dies wirst aber merken ob oxNew() fehlschlägt mit Deinem Model oder nicht.

@indianer3c

Danke für die Hilfe! Leider funktioniert der getSchemaManager() Aufruf auf der $queryBuilderFactory nicht. Die Methode gibt es dort nicht:

Uncaught Error: Call to undefined method OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactory::getSchemaManager()

Das mit der Model-Klasse habe ich mittlerweile hinbekommen. Die Datenbanktabelle kann ich auch erstellen, halt nur mit der deprecated DatabaseProvider Klasse:

$db = \OxidEsales\Eshop\Core\DatabaseProvider\DatabaseProvider::getDb();
$db->execute("CREATE TABLE IF NOT EXISTS ...");

Funktioniert auch super, jedoch hätte ich es gerne richtig gemacht, und nicht mit einer Klasse die demnächst entfernt wird.

das Problem hatte ich auch kürzlich, habe mich für den MetadataHändler entschieden.
Hier einer meiner onActivate Events:

/** @var \OxidEsales\Eshop\Core\DbMetaDataHandler $dbMetaDataHandler */
$dbMetaDataHandler = oxNew(\OxidEsales\Eshop\Core\DbMetaDataHandler::class);

$aQueries = [];

if (!$dbMetaDataHandler->fieldExists("my_column","tablename"))
{
    $aQueries[] = "ALTER TABLE `tablename` ADD  `my_column` INT( 11 ) UNSIGNED NULL;";
}

if (!$dbMetaDataHandler->tableExists("meine_tabelle"))
{
    $aQueries[] = "CREATE TABLE `meine_tabelle` ( "
               ." `CustomerNo` int(11) NOT NULL COMMENT 'Customer Number', "
               ." `ItemNo` varchar(16) NOT NULL COMMENT 'Item Number', "
               ." `Price` double NOT NULL COMMENT 'netto price', "
               ." `PriceVAT` double NOT NULL COMMENT 'brutto price', "
               ." `CurrencyCode` varchar(3) NOT NULL COMMENT 'currency code', "
               ." `Timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'timestamp for caching' "
               ." ) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
    $aQueries[] = "ALTER TABLE `meine_tabelle` ADD PRIMARY KEY (`CustomerNo`, `ItemNo`);";
}

if(count($aQueries) === 0) return true;

$dbMetaDataHandler->executeSql($aQueries);
$dbMetaDataHandler->updateViews();
1 Like