diff --git a/DataStorage/Database/BuilderAbstract.php b/DataStorage/Database/BuilderAbstract.php index e391224ab..5784c7dfd 100644 --- a/DataStorage/Database/BuilderAbstract.php +++ b/DataStorage/Database/BuilderAbstract.php @@ -68,7 +68,25 @@ abstract class BuilderAbstract public $raw = ''; /** - * {@inheritdoc} + * Get connection + * + * @return DataStorageConnectionInterface + * + * @since 1.0.0 + */ + public function getConnection() : DataStorageConnectionInterface + { + return $this->connection; + } + + /** + * Set table name prefix prefix + * + * @param string $prefix Table name prefix + * + * @return self + * + * @since 1.0.0 */ public function prefix(string $prefix) : self { diff --git a/DataStorage/Database/GrammarAbstract.php b/DataStorage/Database/GrammarAbstract.php index fa9077826..7083820e1 100644 --- a/DataStorage/Database/GrammarAbstract.php +++ b/DataStorage/Database/GrammarAbstract.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database; +use phpOMS\DataStorage\Database\Query\QueryType; + /** * Grammar. * @@ -106,15 +108,48 @@ abstract class GrammarAbstract } /** - * Compile query components. + * Compile components. * * @param BuilderAbstract $query Builder * - * @return array Parsed query components + * @return string[] + * + * @throws \InvalidArgumentException * * @since 1.0.0 */ - abstract protected function compileComponents(BuilderAbstract $query) : array; + protected function compileComponents(BuilderAbstract $query) : array + { + $sql = []; + + if ($query->getType() === QueryType::RAW) { + return [$query->raw]; + } + + $components = $this->getComponents($query->getType()); + + /* Loop all possible query components and if they exist compile them. */ + foreach ($components as $component) { + if (isset($query->{$component}) && !empty($query->{$component})) { + $sql[$component] = $this->{'compile' . \ucfirst($component)}($query, $query->{$component}); + } + } + + return $sql; + } + + /** + * Get query components based on query type. + * + * @param int $type Query type + * + * @return array Array of components to build query + * + * @throws \InvalidArgumentException Throws this exception if the query type is undefined + * + * @since 1.0.0 + */ + abstract protected function getComponents(int $type) : array; /** * Get date format. @@ -245,10 +280,18 @@ abstract class GrammarAbstract } // todo: move remaining * test also here not just if .* but also if * (should be done in else?) - if (\count($split = \explode('.', $system)) === 2) { - $system = $split[1] === '*' ? $split[1] : $this->compileSystem($split[1]); + if (\count($split = \explode('.', $system)) > 1) { + $fullSystem = ''; - return $this->compileSystem($prefix . $split[0]) . '.' . $system; + foreach ($split as $key => $system) { + if ($key === 0) { + $fullSystem .= $this->compileSystem($prefix . $system); + } else { + $fullSystem .= '.' . ($system === '*' ? '*' : $this->compileSystem($system)); + } + } + + return $fullSystem; } return $identifier . $prefix . $system . $identifier; diff --git a/DataStorage/Database/Query/Grammar/Grammar.php b/DataStorage/Database/Query/Grammar/Grammar.php index 3f4dbd8cd..9f85c9180 100644 --- a/DataStorage/Database/Query/Grammar/Grammar.php +++ b/DataStorage/Database/Query/Grammar/Grammar.php @@ -99,48 +99,9 @@ class Grammar extends GrammarAbstract ]; /** - * Compile components. - * - * @param BuilderAbstract $query Builder - * - * @return string[] - * - * @throws \InvalidArgumentException - * - * @since 1.0.0 + * {@inheritdoc} */ - protected function compileComponents(BuilderAbstract $query) : array - { - $sql = []; - - if ($query->getType() === QueryType::RAW) { - return [$query->raw]; - } - - $components = $this->getComponents($query->getType()); - - /* Loop all possible query components and if they exist compile them. */ - foreach ($components as $component) { - if (isset($query->{$component}) && !empty($query->{$component})) { - $sql[$component] = $this->{'compile' . \ucfirst($component)}($query, $query->{$component}); - } - } - - return $sql; - } - - /** - * Get query components based on query type. - * - * @param int $type Query type - * - * @return array Array of components to build query - * - * @throws \InvalidArgumentException Throws this exception if the query type is undefined - * - * @since 1.0.0 - */ - private function getComponents(int $type) : array + protected function getComponents(int $type) : array { switch ($type) { case QueryType::SELECT: @@ -401,7 +362,7 @@ class Grammar extends GrammarAbstract * * @since 1.0.0 */ - private function compileJoins(Builder $query, array $joins) : string + protected function compileJoins(Builder $query, array $joins) : string { $expression = ''; @@ -427,7 +388,7 @@ class Grammar extends GrammarAbstract * * @since 1.0.0 */ - private function compileOn(Builder $query, array $ons, bool $first = true) : string + protected function compileOn(Builder $query, array $ons, bool $first = true) : string { $expression = ''; @@ -494,7 +455,7 @@ class Grammar extends GrammarAbstract * * @since 1.0.0 */ - private function compileGroups(Builder $query, array $groups) + protected function compileGroups(Builder $query, array $groups) { $expression = ''; @@ -517,7 +478,7 @@ class Grammar extends GrammarAbstract * * @since 1.0.0 */ - private function compileOrders(Builder $query, array $orders) : string + protected function compileOrders(Builder $query, array $orders) : string { $expression = ''; @@ -539,12 +500,12 @@ class Grammar extends GrammarAbstract return 'ORDER BY ' . $expression; } - private function compileUnions() + protected function compileUnions() { return ''; } - private function compileLock() + protected function compileLock() { return ''; } diff --git a/DataStorage/Database/Schema/Builder.php b/DataStorage/Database/Schema/Builder.php index d84a67160..6889c6a07 100644 --- a/DataStorage/Database/Schema/Builder.php +++ b/DataStorage/Database/Schema/Builder.php @@ -29,6 +29,10 @@ class Builder extends QueryBuilder { public $drop = []; + public $selectTables = ['*']; + + public $selectFields = []; + /** * Constructor. * @@ -42,11 +46,29 @@ class Builder extends QueryBuilder $this->grammar = $connection->getSchemaGrammar(); } - public function drop(...$table) + public function drop(...$table) : Builder { $this->type = QueryType::DROP; $this->drop += $table; - $this->drop = array_unique($this->drop); + $this->drop = \array_unique($this->drop); + + return $this; + } + + public function selectTables() : Builder + { + $this->type = QueryType::TABLES; + + return $this; + } + + public function selectFields(string $table) : Builder + { + $this->type = QueryType::FIELDS; + + $this->selectFields[0] = $table; + + return $this; } public function create(string $table) diff --git a/DataStorage/Database/Schema/Grammar/Grammar.php b/DataStorage/Database/Schema/Grammar/Grammar.php index a415ce179..015d2386b 100644 --- a/DataStorage/Database/Schema/Grammar/Grammar.php +++ b/DataStorage/Database/Schema/Grammar/Grammar.php @@ -29,7 +29,7 @@ use phpOMS\DataStorage\Database\Schema\QueryType; class Grammar extends QueryGrammar { /** - * Select components. + * Drop components. * * @var string[] * @since 1.0.0 @@ -39,19 +39,37 @@ class Grammar extends QueryGrammar ]; /** - * Get query components based on query type. + * Select tables components. * - * @param int $type Query type - * - * @return array Array of components to build query - * - * @since 1.0.0 + * @var string[] + * @since 1.0.0 */ - private function getComponents(int $type) : array + protected $tablesComponents = [ + 'selectTables' + ]; + + /** + * Select field components. + * + * @var string[] + * @since 1.0.0 + */ + protected $fieldsComponents = [ + 'selectFields' + ]; + + /** + * {@inheritdoc} + */ + protected function getComponents(int $type) : array { switch ($type) { case QueryType::DROP: return $this->dropComponents; + case QueryType::TABLES: + return $this->tablesComponents; + case QueryType::FIELDS: + return $this->fieldsComponents; default: return parent::getComponents($type); } @@ -75,6 +93,6 @@ class Grammar extends QueryGrammar $expression = '*'; } - return 'DROP TABLE ' . $expression; + return 'DROP DATABASE ' . $expression; } } diff --git a/DataStorage/Database/Schema/Grammar/MysqlGrammar.php b/DataStorage/Database/Schema/Grammar/MysqlGrammar.php index 392345e38..cd79e5c47 100644 --- a/DataStorage/Database/Schema/Grammar/MysqlGrammar.php +++ b/DataStorage/Database/Schema/Grammar/MysqlGrammar.php @@ -35,24 +35,23 @@ class MysqlGrammar extends Grammar protected $systemIdentifier = '`'; /** - * Compile select. + * Compile from. * - * @param Builder $query Builder - * @param array $columns Columns + * @param Builder $query Builder + * @param array $table Tables * * @return string * * @since 1.0.0 */ - protected function compileSelects(Builder $query, array $columns) : string + protected function compileSelectTables(Builder $query, array $table) : string { - $expression = $this->expressionizeTableColumn($columns); + $builder = new Builder($query->getConnection()); + $builder->select('table_name') + ->from('information_schema.tables') + ->where('table_schema', '=', $query->getConnection()->getDatabase()); - if ($expression === '') { - $expression = '*'; - } - - return $expression; + return \rtrim($builder->toSql(), ';'); } /** @@ -65,10 +64,14 @@ class MysqlGrammar extends Grammar * * @since 1.0.0 */ - protected function compileFrom(Builder $query, array $table) : string + protected function compileSelectFields(Builder $query, array $table) : string { - $expression = $this->expressionizeTableColumn(['information_schema.tables']); + $builder = new Builder($query->getConnection()); + $builder->select('*') + ->from('information_schema.columns') + ->where('table_schema', '=', $query->getConnection()->getDatabase()) + ->andWhere('table_name', '=', 'test'); - return 'FROM ' . $expression; + return \rtrim($builder->toSql(), ';'); } } diff --git a/DataStorage/Database/Schema/QueryType.php b/DataStorage/Database/Schema/QueryType.php index 9ec09d47d..7b288a405 100644 --- a/DataStorage/Database/Schema/QueryType.php +++ b/DataStorage/Database/Schema/QueryType.php @@ -28,6 +28,8 @@ use phpOMS\DataStorage\Database\Query\QueryType as DefaultQueryType; */ abstract class QueryType extends DefaultQueryType { - public const DROP = 128; - public const ALTER = 129; + public const DROP = 128; + public const ALTER = 129; + public const TABLES = 130; + public const FIELDS = 131; } diff --git a/tests/DataStorage/Database/Schema/BuilderTest.php b/tests/DataStorage/Database/Schema/BuilderTest.php index 703e025e0..afc1c219f 100644 --- a/tests/DataStorage/Database/Schema/BuilderTest.php +++ b/tests/DataStorage/Database/Schema/BuilderTest.php @@ -13,6 +13,7 @@ namespace phpOMS\tests\DataStorage\Database\Schema; +use phpOMS\DataStorage\Database\Connection\MysqlConnection; use phpOMS\DataStorage\Database\Schema\Builder; class BuilderTest extends \PHPUnit\Framework\TestCase @@ -28,20 +29,20 @@ class BuilderTest extends \PHPUnit\Framework\TestCase { $query = new Builder($this->con); $sql = 'DROP DATABASE `test`;'; - self::assertEquals($sql, $query->drop('test')); + self::assertEquals($sql, $query->drop('test')->toSql()); } public function testMysqlShowTables() { $query = new Builder($this->con); - $sql = 'SELECT `table_name` FROM `information_schema`.`tables` WHERE `table_schema` = \'' . $GLOBALS['CONFIG']['db']['core']['masters']['admin']['database']. '\';'; - self::assertEquals($sql, $query->selectTables()); + $sql = 'SELECT `table_name` FROM `information_schema`.`tables` WHERE `information_schema`.`tables`.`table_schema` = \'' . $GLOBALS['CONFIG']['db']['core']['masters']['admin']['database']. '\';'; + self::assertEquals($sql, $query->selectTables()->toSql()); } public function testMysqlShowFields() { $query = new Builder($this->con); - $sql = 'SELECT * FROM `information_schema`.`columns` WHERE `table_schema` = \'' . $GLOBALS['CONFIG']['db']['core']['masters']['admin']['database']. '\' AND t`able_name` = \'test\';'; - self::assertEquals($sql, $query->selectFields('test')); + $sql = 'SELECT * FROM `information_schema`.`columns` WHERE `information_schema`.`columns`.`table_schema` = \'' . $GLOBALS['CONFIG']['db']['core']['masters']['admin']['database']. '\' AND `information_schema`.`columns`.`table_name` = \'test\';'; + self::assertEquals($sql, $query->selectFields('test')->toSql()); } } diff --git a/tests/DataStorage/Database/Schema/QueryTypeTest.php b/tests/DataStorage/Database/Schema/QueryTypeTest.php index 8748b581d..c9a3ad85d 100644 --- a/tests/DataStorage/Database/Schema/QueryTypeTest.php +++ b/tests/DataStorage/Database/Schema/QueryTypeTest.php @@ -19,10 +19,12 @@ class QueryTypeTest extends \PHPUnit\Framework\TestCase { public function testEnums() { - self::assertEquals(2, \count(QueryType::getConstants())); + self::assertEquals(11, \count(QueryType::getConstants())); self::assertEquals(QueryType::getConstants(), array_unique(QueryType::getConstants())); self::assertEquals(128, QueryType::DROP); self::assertEquals(129, QueryType::ALTER); + self::assertEquals(130, QueryType::TABLES); + self::assertEquals(131, QueryType::FIELDS); } }