<?php /** * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; under version 2 * of the License (non-upgradable). * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (c) 2013-2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); * */ namespace oat\taoDelivery\scripts\install; use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Type; use oat\oatbox\extension\AbstractAction; use oat\taoDelivery\model\execution\rds\RdsDeliveryExecutionService; class GenerateRdsDeliveryExecutionTable extends AbstractAction { public function __invoke($params) { /** @var \common_persistence_SqlPersistence $service */ $persistence = $this->getServiceLocator()->get(\common_persistence_Manager::SERVICE_ID)->getPersistenceById("default"); $this->generateTable($persistence); } /** * @param \common_persistence_SqlPersistence $persistence * @throws \common_ext_InstallationException */ public function generateTable(\common_persistence_SqlPersistence $persistence) { $tableName = RdsDeliveryExecutionService::TABLE_NAME; $schemaManager = $persistence->getSchemaManager(); $updatedSchema = $schemaManager->createSchema(); $currentSchema = clone $updatedSchema; $isTableExist = $this->isTableExist($schemaManager); $areColumnsExist = $this->areColumnsExist($schemaManager); if ($isTableExist && !$areColumnsExist) { throw new \common_ext_InstallationException( sprintf("'%s' table is already exist, but with the wrong Schema", $tableName) ); } if (!$isTableExist) { $this->createTable($updatedSchema); } $queries = $persistence->getPlatForm()->getMigrateSchemaSql($currentSchema, $updatedSchema); foreach ($queries as $query) { $persistence->exec($query); } } /** * Returns that the delivery_executions table is already exist in the database or not * * @param \common_persistence_sql_SchemaManager $schemaManager * @return bool */ private function isTableExist(\common_persistence_sql_SchemaManager $schemaManager) { return in_array(RdsDeliveryExecutionService::TABLE_NAME, $schemaManager->getTables()); } /** * Returns that the delivery_executions table columns are already exist in the table or not * * @param \common_persistence_sql_SchemaManager $schemaManager * @return bool */ private function areColumnsExist(\common_persistence_sql_SchemaManager $schemaManager) { $columnNames = [ RdsDeliveryExecutionService::COLUMN_ID, RdsDeliveryExecutionService::COLUMN_USER_ID, RdsDeliveryExecutionService::COLUMN_DELIVERY_ID, RdsDeliveryExecutionService::COLUMN_LABEL, RdsDeliveryExecutionService::COLUMN_STATUS, RdsDeliveryExecutionService::COLUMN_STARTED_AT, RdsDeliveryExecutionService::COLUMN_FINISHED_AT, ]; $tableColumns = array_map(function (Column $column) { return $column->getName(); }, $schemaManager->getColumnNames(RdsDeliveryExecutionService::TABLE_NAME)); return array_reduce($columnNames, function ($areColumnsExist, $column) use ($tableColumns) { $areColumnsExist = $areColumnsExist && in_array($column, $tableColumns); return $areColumnsExist; }, true); } /** * Creates the table in the database for the Delivery * * @param Schema $schema * @return void */ private function createTable(Schema $schema) { $table = $schema->createTable(RdsDeliveryExecutionService::TABLE_NAME); $table->addOption("engine", "InnoDB"); $table->addOption("charset", "utf8"); $table->addOption("collate", "utf8_unicode_ci"); $this->createColumns($table); /** * Create index for the following methods * @see RdsDeliveryExecutionService::getExecutionsByDelivery() * @see RdsDeliveryExecutionService::getUserExecutions() */ $this->createIndex($table, [ RdsDeliveryExecutionService::COLUMN_DELIVERY_ID, RdsDeliveryExecutionService::COLUMN_USER_ID, ]); /** * Create index for the following methods * @see RdsDeliveryExecutionService::getDeliveryExecutionsByStatus() */ $this->createIndex($table, [ RdsDeliveryExecutionService::COLUMN_USER_ID, ]); } /** * Generates columns * * @param Table $table * @return void */ private function createColumns(Table $table) { $table->addColumn(RdsDeliveryExecutionService::COLUMN_ID, Type::STRING, ["length" => 255, "notnull" => true]); $table->addColumn(RdsDeliveryExecutionService::COLUMN_DELIVERY_ID, Type::STRING, ["length" => 255, "notnull" => true]); $table->addColumn(RdsDeliveryExecutionService::COLUMN_USER_ID, Type::STRING, ["length" => 255, "notnull" => true]); $table->addColumn(RdsDeliveryExecutionService::COLUMN_LABEL, Type::STRING, ["length" => 255, "notnull" => true]); $table->addColumn(RdsDeliveryExecutionService::COLUMN_STATUS, Type::STRING, ["length" => 255, "notnull" => true]); $table->addColumn(RdsDeliveryExecutionService::COLUMN_STARTED_AT, Type::DATETIME, ["notnull" => true]); $table->addColumn(RdsDeliveryExecutionService::COLUMN_FINISHED_AT, Type::DATETIME, ["notnull" => false]); $table->setPrimaryKey([RdsDeliveryExecutionService::COLUMN_ID]); } /** * Generates index for the given columns * * @param Table $table * @param array $columns * @return void */ private function createIndex(Table $table, array $columns) { if (count($columns) > 0) { $indexPrefix = "idx_" . RdsDeliveryExecutionService::TABLE_NAME . "_"; // Index names are limited to 63 characters in PostgreSQL (64 in MySQL) $indexName = substr($indexPrefix . implode("_", $columns), 0, 63); $table->addIndex($columns, $indexName); } } }