From d4ec08179e472746be5c35c3d5ba0a8d4142284d Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 21 Dec 2018 20:16:33 +0100 Subject: [PATCH] Implrement create builder --- DataStorage/Database/Schema/Builder.php | 35 ++++++++-- .../Database/Schema/Grammar/Grammar.php | 48 +++++++++++++- .../Database/Schema/Grammar/MysqlGrammar.php | 64 +++++++++++++++++++ .../Database/Schema/Grammar/OracleGrammar.php | 20 ++++++ .../Database/Schema/Grammar/SQLiteGrammar.php | 8 ++- .../Schema/Grammar/SqlServerGrammar.php | 2 +- DataStorage/Database/Schema/QueryType.php | 9 +-- .../Database/Schema/BuilderTest.php | 13 ++++ .../Database/Schema/Grammar/GrammarTest.php | 10 ++- .../Schema/Grammar/MysqlGrammarTest.php | 7 +- .../Schema/Grammar/OracleGrammarTest.php | 25 ++++++++ .../Schema/Grammar/PostgresGrammarTest.php | 6 +- .../Schema/Grammar/SQLiteGrammarTest.php | 8 ++- .../Schema/Grammar/SqlServerGrammarTest.php | 6 +- .../Database/Schema/QueryTypeTest.php | 3 +- 15 files changed, 240 insertions(+), 24 deletions(-) create mode 100644 DataStorage/Database/Schema/Grammar/OracleGrammar.php create mode 100644 tests/DataStorage/Database/Schema/Grammar/OracleGrammarTest.php diff --git a/DataStorage/Database/Schema/Builder.php b/DataStorage/Database/Schema/Builder.php index 40b24532f..e293a06bf 100644 --- a/DataStorage/Database/Schema/Builder.php +++ b/DataStorage/Database/Schema/Builder.php @@ -27,12 +27,18 @@ use phpOMS\DataStorage\Database\Query\Builder as QueryBuilder; */ class Builder extends QueryBuilder { + public $createTable = ''; + + public $createFields = []; + public $drop = []; public $selectTables = ['*']; public $selectFields = []; + public $createTableSettings = true; + /** * Constructor. * @@ -64,21 +70,42 @@ class Builder extends QueryBuilder public function selectFields(string $table) : self { - $this->type = QueryType::FIELDS; - + $this->type = QueryType::FIELDS; $this->selectFields[0] = $table; return $this; } - public function create(string $table) + public function createTable(string $name) : self { + $this->type = QueryType::CREATE_TABLE; + $this->createTable = $name; + return $this; + } + + // todo: consider to work with flags instead of all these booleans + public function field( + string $name, string $type, $default = null, + bool $isNullable = true, bool $isPrimary = false, bool $autoincrement = false, + string $foreignTable = null, string $foreignKey = null + ) : self { + $this->createFields[$name] = [ + 'name' => $name, + 'type' => $type, + 'default' => $default, + 'null' => $isNullable, + 'primary' => $isPrimary, + 'autoincrement' => $autoincrement, + 'foreignTable' => $foreignTable, + 'foreignKey' => $foreignKey, + ]; + + return $this; } public function alter(array $column) { - } /** diff --git a/DataStorage/Database/Schema/Grammar/Grammar.php b/DataStorage/Database/Schema/Grammar/Grammar.php index 015d2386b..f422de118 100644 --- a/DataStorage/Database/Schema/Grammar/Grammar.php +++ b/DataStorage/Database/Schema/Grammar/Grammar.php @@ -38,6 +38,18 @@ class Grammar extends QueryGrammar 'drop', ]; + /** + * Select tables components. + * + * @var string[] + * @since 1.0.0 + */ + protected $createTablesComponents = [ + 'createTable', + 'createFields', + 'createTableSettings' + ]; + /** * Select tables components. * @@ -45,7 +57,7 @@ class Grammar extends QueryGrammar * @since 1.0.0 */ protected $tablesComponents = [ - 'selectTables' + 'selectTables', ]; /** @@ -55,7 +67,7 @@ class Grammar extends QueryGrammar * @since 1.0.0 */ protected $fieldsComponents = [ - 'selectFields' + 'selectFields', ]; /** @@ -70,11 +82,43 @@ class Grammar extends QueryGrammar return $this->tablesComponents; case QueryType::FIELDS: return $this->fieldsComponents; + case QueryType::CREATE_TABLE: + return $this->createTablesComponents; default: return parent::getComponents($type); } } + /** + * Compile create table query. + * + * @param BuilderAbstract $query Query + * @param string $table Tables to drop + * + * @return string + * + * @since 1.0.0 + */ + protected function compileCreateTable(BuilderAbstract $query, string $table) : string + { + return 'CREATE TABLE ' . $this->expressionizeTable([$table], $query->getPrefix()); + } + + /** + * Compile create table settings query. + * + * @param BuilderAbstract $query Query + * @param bool $settings Has settings + * + * @return string + * + * @since 1.0.0 + */ + protected function compileCreateTableSettings(BuilderAbstract $query, bool $settings) : string + { + return ''; + } + /** * Compile drop query. * diff --git a/DataStorage/Database/Schema/Grammar/MysqlGrammar.php b/DataStorage/Database/Schema/Grammar/MysqlGrammar.php index cd79e5c47..0fc862872 100644 --- a/DataStorage/Database/Schema/Grammar/MysqlGrammar.php +++ b/DataStorage/Database/Schema/Grammar/MysqlGrammar.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database\Schema\Grammar; +use phpOMS\DataStorage\Database\BuilderAbstract; use phpOMS\DataStorage\Database\Query\Builder; /** @@ -74,4 +75,67 @@ class MysqlGrammar extends Grammar return \rtrim($builder->toSql(), ';'); } + + /** + * Compile create table fields query. + * + * @param Builder $query Query + * @param array $tables Tables to drop + * + * @return string + * + * @since 1.0.0 + */ + protected function compileCreateFields(Builder $query, array $fields) : string + { + $fieldQuery = ''; + $keys = ''; + + foreach ($fields as $name => $field) { + $fieldQuery .= ' ' . $this->expressionizeTableColumn([$name], '') . ' ' . $field['type']; + + if (isset($field['default'])) { + $fieldQuery .= ' DEFAULT ' . $this->compileValue($query, $field['default']); + } + + if (isset($field['null'])) { + $fieldQuery .= ' ' . ($field['null'] ? '' : 'NOT ') . 'NULL'; + } + + if (isset($field['autoincrement']) && $field['autoincrement']) { + $fieldQuery .= ' AUTO_INCREMENT'; + } + + $fieldQuery .= ','; + + if (isset($field['primary']) && $field['primary']) { + $keys .= ' PRIMARY KEY (' . $this->expressionizeTableColumn([$name], '') . '),'; + } + + if (isset($field['foreignTable'], $field['foreignKey']) + && !empty($field['foreignTable']) && !empty($field['foreignKey']) + ) { + $keys .= ' FOREIGN KEY (' . $this->expressionizeTableColumn([$name], '') . ') REFERENCES ' + . $this->expressionizeTable([$field['foreignTable']], $query->getPrefix()) + . ' (' . $this->expressionizeTableColumn([$field['foreignKey']], '') . '),'; + } + } + + return '(' . \ltrim(\rtrim($fieldQuery . $keys, ','), ' ') . ')'; + } + + /** + * Compile create table settings query. + * + * @param BuilderAbstract $query Query + * @param bool $settings Has settings + * + * @return string + * + * @since 1.0.0 + */ + protected function compileCreateTableSettings(BuilderAbstract $query, bool $settings) : string + { + return 'ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1'; + } } diff --git a/DataStorage/Database/Schema/Grammar/OracleGrammar.php b/DataStorage/Database/Schema/Grammar/OracleGrammar.php new file mode 100644 index 000000000..7aa50a353 --- /dev/null +++ b/DataStorage/Database/Schema/Grammar/OracleGrammar.php @@ -0,0 +1,20 @@ +selectFields('test')->toSql()); } + + public function testMysqlCreateTable() + { + $query = new Builder($this->con); + $sql = 'CREATE TABLE `user_roles` (`user_id` INT NOT NULL AUTO_INCREMENT, `role_id` VARCHAR(10) DEFAULT \'1\' NULL, PRIMARY KEY (`user_id`), FOREIGN KEY (`user_id`) REFERENCES `users` (`ext1_id`), FOREIGN KEY (`role_id`) REFERENCES `roles` (`ext2_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;'; + self::assertEquals( + $sql, + $query->createTable('user_roles') + ->field('user_id', 'INT', null, false, true, true, 'users', 'ext1_id') + ->field('role_id', 'VARCHAR(10)', '1', true, false, false, 'roles', 'ext2_id') + ->toSql() + ); + } } diff --git a/tests/DataStorage/Database/Schema/Grammar/GrammarTest.php b/tests/DataStorage/Database/Schema/Grammar/GrammarTest.php index e62c75e27..15e59020a 100644 --- a/tests/DataStorage/Database/Schema/Grammar/GrammarTest.php +++ b/tests/DataStorage/Database/Schema/Grammar/GrammarTest.php @@ -13,11 +13,17 @@ namespace phpOMS\tests\DataStorage\Database\Schema\Grammar; +use phpOMS\DataStorage\Database\Schema\Grammar\Grammar; class GrammarTest extends \PHPUnit\Framework\TestCase { - public function testPlaceholder() + public function testDefault() { - self::markTestIncomplete(); + $grammar = new Grammar(); + self::assertEquals('Y-m-d H:i:s', $grammar->getDateFormat()); + self::assertEquals('', $grammar->getTablePrefix()); + + $grammar->setTablePrefix('oms_'); + self::assertEquals('oms_', $grammar->getTablePrefix()); } } diff --git a/tests/DataStorage/Database/Schema/Grammar/MysqlGrammarTest.php b/tests/DataStorage/Database/Schema/Grammar/MysqlGrammarTest.php index a2037064c..0959601ee 100644 --- a/tests/DataStorage/Database/Schema/Grammar/MysqlGrammarTest.php +++ b/tests/DataStorage/Database/Schema/Grammar/MysqlGrammarTest.php @@ -13,11 +13,14 @@ namespace phpOMS\tests\DataStorage\Database\Schema\Grammar; +use phpOMS\DataStorage\Database\Schema\Grammar\MysqlGrammar; +use phpOMS\Utils\TestUtils; class MysqlGrammarTest extends \PHPUnit\Framework\TestCase { - public function testPlaceholder() + public function testDefault() { - self::markTestIncomplete(); + self::assertInstanceOf('\phpOMS\DataStorage\Database\Schema\Grammar\Grammar', new MysqlGrammar()); + self::assertEquals('`', TestUtils::getMember(new MysqlGrammar(), 'systemIdentifier')); } } diff --git a/tests/DataStorage/Database/Schema/Grammar/OracleGrammarTest.php b/tests/DataStorage/Database/Schema/Grammar/OracleGrammarTest.php new file mode 100644 index 000000000..558116a67 --- /dev/null +++ b/tests/DataStorage/Database/Schema/Grammar/OracleGrammarTest.php @@ -0,0 +1,25 @@ +