diff --git a/src/DeleteQuery.php b/src/DeleteQuery.php index 9a4baa7..e1c548c 100644 --- a/src/DeleteQuery.php +++ b/src/DeleteQuery.php @@ -2,6 +2,7 @@ namespace ByJG\MicroOrm; +use ByJG\AnyDataset\Db\DbDriverInterface; use ByJG\AnyDataset\Db\DbFunctionsInterface; use ByJG\MicroOrm\Exception\InvalidArgumentException; use ByJG\MicroOrm\Interface\QueryBuilderInterface; @@ -13,7 +14,7 @@ public static function getInstance(): DeleteQuery return new DeleteQuery(); } - public function build(DbFunctionsInterface $dbHelper = null): SqlObject + public function build(DbFunctionsInterface|DbDriverInterface|null $dbDriverOrHelper = null): SqlObject { $whereStr = $this->getWhere(); if (is_null($whereStr)) { diff --git a/src/InsertBulkQuery.php b/src/InsertBulkQuery.php index 4f931bf..a41247e 100644 --- a/src/InsertBulkQuery.php +++ b/src/InsertBulkQuery.php @@ -2,6 +2,7 @@ namespace ByJG\MicroOrm; +use ByJG\AnyDataset\Db\DbDriverInterface; use ByJG\AnyDataset\Db\DbFunctionsInterface; use ByJG\MicroOrm\Exception\OrmInvalidFieldsException; use ByJG\MicroOrm\Interface\QueryBuilderInterface; @@ -60,19 +61,23 @@ public function values(array $values, bool $allowNonMatchFields = true): static } /** - * @param DbFunctionsInterface|null $dbHelper + * @param DbDriverInterface|DbFunctionsInterface|null $dbDriverOrHelper * @return SqlObject * @throws OrmInvalidFieldsException */ - public function build(DbFunctionsInterface $dbHelper = null): SqlObject + public function build(DbFunctionsInterface|DbDriverInterface|null $dbDriverOrHelper = null): SqlObject { if (empty($this->fields)) { throw new OrmInvalidFieldsException('You must specify the fields for insert'); } + if ($dbDriverOrHelper instanceof DbDriverInterface) { + $dbDriverOrHelper = $dbDriverOrHelper->getDbHelper(); + } + $tableStr = $this->table; - if (!is_null($dbHelper)) { - $tableStr = $dbHelper->delimiterTable($tableStr); + if (!is_null($dbDriverOrHelper)) { + $tableStr = $dbDriverOrHelper->delimiterTable($tableStr); } // Extract column names @@ -96,7 +101,7 @@ public function build(DbFunctionsInterface $dbHelper = null): SqlObject } else { $value = str_replace("'", "''", $this->fields[$col][$i]); if (!is_numeric($value)) { - $value = $dbHelper?->delimiterField($value) ?? "'{$value}'"; + $value = $dbDriverOrHelper?->delimiterField($value) ?? "'{$value}'"; } $params[$paramKey] = new Literal($value); // Map parameter key to value } @@ -104,8 +109,8 @@ public function build(DbFunctionsInterface $dbHelper = null): SqlObject $placeholders[] = '(' . implode(', ', $rowPlaceholders) . ')'; // Add row placeholders to query } - if (!is_null($dbHelper)) { - $columns = $dbHelper->delimiterField($columns); + if (!is_null($dbDriverOrHelper)) { + $columns = $dbDriverOrHelper->delimiterField($columns); } // Construct the final SQL query diff --git a/src/InsertQuery.php b/src/InsertQuery.php index 908a771..08b305b 100644 --- a/src/InsertQuery.php +++ b/src/InsertQuery.php @@ -2,6 +2,7 @@ namespace ByJG\MicroOrm; +use ByJG\AnyDataset\Db\DbDriverInterface; use ByJG\AnyDataset\Db\DbFunctionsInterface; use ByJG\MicroOrm\Exception\InvalidArgumentException; use ByJG\MicroOrm\Exception\OrmInvalidFieldsException; @@ -65,24 +66,28 @@ public function defineFields(array $fields): static } /** - * @param DbFunctionsInterface|null $dbHelper + * @param DbDriverInterface|DbFunctionsInterface|null $dbDriverOrHelper * @return SqlObject * @throws OrmInvalidFieldsException */ - public function build(DbFunctionsInterface $dbHelper = null): SqlObject + public function build(DbFunctionsInterface|DbDriverInterface|null $dbDriverOrHelper = null): SqlObject { if (empty($this->values)) { throw new OrmInvalidFieldsException('You must specify the fields for insert'); } + if ($dbDriverOrHelper instanceof DbDriverInterface) { + $dbDriverOrHelper = $dbDriverOrHelper->getDbHelper(); + } + $fieldsStr = array_keys($this->values); // get the fields from the first element only - if (!is_null($dbHelper)) { - $fieldsStr = $dbHelper->delimiterField($fieldsStr); + if (!is_null($dbDriverOrHelper)) { + $fieldsStr = $dbDriverOrHelper->delimiterField($fieldsStr); } $tableStr = $this->table; - if (!is_null($dbHelper)) { - $tableStr = $dbHelper->delimiterTable($tableStr); + if (!is_null($dbDriverOrHelper)) { + $tableStr = $dbDriverOrHelper->delimiterTable($tableStr); } $sql = 'INSERT INTO ' diff --git a/src/InsertSelectQuery.php b/src/InsertSelectQuery.php index c5c0fba..b8f3270 100644 --- a/src/InsertSelectQuery.php +++ b/src/InsertSelectQuery.php @@ -2,6 +2,7 @@ namespace ByJG\MicroOrm; +use ByJG\AnyDataset\Db\DbDriverInterface; use ByJG\AnyDataset\Db\DbFunctionsInterface; use ByJG\MicroOrm\Exception\OrmInvalidFieldsException; use ByJG\MicroOrm\Interface\QueryBuilderInterface; @@ -49,16 +50,20 @@ public function fromSqlObject(SqlObject $sqlObject): static } /** - * @param DbFunctionsInterface|null $dbHelper + * @param DbDriverInterface|DbFunctionsInterface|null $dbDriverOrHelper * @return SqlObject * @throws OrmInvalidFieldsException */ - public function build(DbFunctionsInterface $dbHelper = null): SqlObject + public function build(DbFunctionsInterface|DbDriverInterface|null $dbDriverOrHelper = null): SqlObject { if (empty($this->fields)) { throw new OrmInvalidFieldsException('You must specify the fields for insert'); } + if ($dbDriverOrHelper instanceof DbDriverInterface) { + $dbDriverOrHelper = $dbDriverOrHelper->getDbHelper(); + } + if (empty($this->query) && empty($this->sqlObject)) { throw new OrmInvalidFieldsException('You must specify the query for insert'); } elseif (!empty($this->query) && !empty($this->sqlObject)) { @@ -66,13 +71,13 @@ public function build(DbFunctionsInterface $dbHelper = null): SqlObject } $fieldsStr = $this->fields; - if (!is_null($dbHelper)) { - $fieldsStr = $dbHelper->delimiterField($fieldsStr); + if (!is_null($dbDriverOrHelper)) { + $fieldsStr = $dbDriverOrHelper->delimiterField($fieldsStr); } $tableStr = $this->table; - if (!is_null($dbHelper)) { - $tableStr = $dbHelper->delimiterTable($tableStr); + if (!is_null($dbDriverOrHelper)) { + $tableStr = $dbDriverOrHelper->delimiterTable($tableStr); } $sql = 'INSERT INTO ' diff --git a/src/Interface/UpdateBuilderInterface.php b/src/Interface/UpdateBuilderInterface.php index 56c76a8..699abbd 100644 --- a/src/Interface/UpdateBuilderInterface.php +++ b/src/Interface/UpdateBuilderInterface.php @@ -8,7 +8,7 @@ interface UpdateBuilderInterface { - public function build(?DbFunctionsInterface $dbHelper = null): SqlObject; + public function build(DbFunctionsInterface|DbDriverInterface|null $dbDriverOrHelper = null): SqlObject; public function buildAndExecute(DbDriverInterface $dbDriver, $params = [], ?DbFunctionsInterface $dbHelper = null); diff --git a/src/UpdateQuery.php b/src/UpdateQuery.php index 24f0a0e..d68172f 100644 --- a/src/UpdateQuery.php +++ b/src/UpdateQuery.php @@ -2,7 +2,9 @@ namespace ByJG\MicroOrm; +use ByJG\AnyDataset\Db\DbDriverInterface; use ByJG\AnyDataset\Db\DbFunctionsInterface; +use ByJG\AnyDataset\Db\SqlStatement; use ByJG\MicroOrm\Exception\InvalidArgumentException; use ByJG\MicroOrm\Interface\QueryBuilderInterface; use ByJG\MicroOrm\Literal\Literal; @@ -65,34 +67,58 @@ public function setLiteral(string $field, mixed $value): UpdateQuery return $this; } - protected function getJoinTables(DbFunctionsInterface $dbHelper = null): array + protected function getJoinTables(DbFunctionsInterface|DbDriverInterface $dbDriverOrHelper = null): array { + $dbDriver = null; + if ($dbDriverOrHelper instanceof DbDriverInterface) { + $dbDriver = $dbDriverOrHelper; + $dbHelper = $dbDriverOrHelper->getDbHelper(); + } else { + $dbHelper = $dbDriverOrHelper; + } + if (is_null($dbHelper)) { if (!empty($this->joinTables)) { throw new InvalidArgumentException('You must specify a DbFunctionsInterface to use join tables'); } return ['sql' => '', 'position' => 'before_set']; } + foreach ($this->joinTables as $key => $joinTable) { + if ($this->joinTables[$key]['table'] instanceof QueryBasic) { + if (is_null($dbDriver)) { + Throw new InvalidArgumentException('You must specify a DbDriverInterface to use Query join tables'); + } + $this->joinTables[$key]['table'] = new SqlStatement($this->joinTables[$key]['table']->build($dbDriver)->getSql()); + } + } return $dbHelper->getJoinTablesUpdate($this->joinTables); } - public function join(string $table, string $joinCondition): UpdateQuery + public function join(QueryBasic|string $table, string $joinCondition, ?string $alias = null): UpdateQuery { - $this->joinTables[] = ["table" => $table, "condition" => $joinCondition]; + $this->joinTables[] = ["table" => $table, "condition" => $joinCondition, "alias" => $alias]; return $this; } /** - * @param DbFunctionsInterface|null $dbHelper + * @param DbDriverInterface|DbFunctionsInterface|null $dbDriverOrHelper * @return SqlObject * @throws InvalidArgumentException */ - public function build(DbFunctionsInterface $dbHelper = null): SqlObject + public function build(DbFunctionsInterface|DbDriverInterface|null $dbDriverOrHelper = null): SqlObject { if (empty($this->set)) { throw new InvalidArgumentException('You must specify the fields for update'); } + + $dbDriver = null; + if ($dbDriverOrHelper instanceof DbDriverInterface) { + $dbHelper = $dbDriverOrHelper->getDbHelper(); + $dbDriver = $dbDriverOrHelper; + } else { + $dbHelper = $dbDriverOrHelper; + } $fieldsStr = []; $params = []; @@ -120,7 +146,7 @@ public function build(DbFunctionsInterface $dbHelper = null): SqlObject $tableName = $dbHelper->delimiterTable($tableName); } - $joinTables = $this->getJoinTables($dbHelper); + $joinTables = $this->getJoinTables($dbDriverOrHelper); $joinBeforeSet = $joinTables['position'] === 'before_set' ? $joinTables['sql'] : ''; $joinAfterSet = $joinTables['position'] === 'after_set' ? $joinTables['sql'] : ''; diff --git a/tests/UpdateQueryTest.php b/tests/UpdateQueryTest.php index 5e1be53..09a76c1 100644 --- a/tests/UpdateQueryTest.php +++ b/tests/UpdateQueryTest.php @@ -2,13 +2,18 @@ namespace Tests; +use ByJG\AnyDataset\Db\Factory; use ByJG\AnyDataset\Db\Helpers\DbMysqlFunctions; use ByJG\AnyDataset\Db\Helpers\DbPgsqlFunctions; use ByJG\AnyDataset\Db\Helpers\DbSqliteFunctions; +use ByJG\AnyDataset\Db\PdoMysql; +use ByJG\AnyDataset\Db\PdoObj; use ByJG\MicroOrm\Exception\InvalidArgumentException; +use ByJG\MicroOrm\Query; use ByJG\MicroOrm\SqlObject; use ByJG\MicroOrm\SqlObjectEnum; use ByJG\MicroOrm\UpdateQuery; +use ByJG\Util\Uri; use PHPUnit\Framework\TestCase; class UpdateQueryTest extends TestCase @@ -144,6 +149,58 @@ public function testUpdateJoinMySQl() ); } + public function testUpdateJoinMySQlAlias() + { + $this->object->table('test'); + $this->object->join('table2', 't2.id = test.id', 't2'); + $this->object->set('fld1', 'A'); + $this->object->set('fld2', 'B'); + $this->object->set('fld3', 'C'); + $this->object->where('fld1 = :id', ['id' => 10]); + + $sqlObject = $this->object->build(new DbMysqlFunctions()); + $this->assertEquals( + new SqlObject( + 'UPDATE `test` INNER JOIN `table2` AS t2 ON t2.id = test.id SET `fld1` = :fld1 , `fld2` = :fld2 , `fld3` = :fld3 WHERE fld1 = :id', + ['id' => 10, 'fld1' => 'A', 'fld2' => 'B', 'fld3' => 'C'], + SqlObjectEnum::UPDATE + ), + $sqlObject + ); + } + + public function testUpdateJoinMySQlSubqueryAlias() + { + $query = Query::getInstance() + ->table('table2') + ->where('id = 10'); + $this->object->table('test'); + $this->object->join($query, 't2.id = test.id', 't2'); + $this->object->set('fld1', 'A'); + $this->object->set('fld2', 'B'); + $this->object->set('fld3', 'C'); + $this->object->where('fld1 = :id', ['id' => 10]); + + + $dbDriver = new class extends PdoMysql + { + public function __construct() + { + $this->pdoObj = new PdoObj(new Uri('mysql://root:root@localhost/test')); + } + }; + + $sqlObject = $this->object->build($dbDriver); + $this->assertEquals( + new SqlObject( + 'UPDATE `test` INNER JOIN (SELECT * FROM table2 WHERE id = 10) AS t2 ON t2.id = test.id SET `fld1` = :fld1 , `fld2` = :fld2 , `fld3` = :fld3 WHERE fld1 = :id', + ['id' => 10, 'fld1' => 'A', 'fld2' => 'B', 'fld3' => 'C'], + SqlObjectEnum::UPDATE + ), + $sqlObject + ); + } + public function testUpdateJoinPostgres() { $this->object->table('test');