Skip to content

insertBatch updateBatch upsertBatch deleteBatch from query #6689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 40 commits into from
Dec 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
78a4fca
Add fromQuery() and fieldsFromQuery() methods
sclubricants Oct 14, 2022
ad9210c
Add fromQuery() logic to updateBatch()
sclubricants Oct 14, 2022
00bb907
Add updateBatch test
sclubricants Oct 14, 2022
8017493
Add fromQuery() logic to insertBatch()
sclubricants Oct 14, 2022
d22b0e7
Add InsertBatch() test
sclubricants Oct 14, 2022
cc7bf57
Add fromQuery() logic to upsertBatch()
sclubricants Oct 14, 2022
4aac862
Add upsertBatch() test
sclubricants Oct 14, 2022
5ef39cb
Fix CS
sclubricants Oct 14, 2022
cb5c33b
Add documentation and change log
sclubricants Oct 14, 2022
cd14f28
CS Fix
sclubricants Oct 15, 2022
d0a0b10
Change example to use fromQuery()
sclubricants Oct 15, 2022
dd7eaaa
Fix CS
sclubricants Oct 15, 2022
0fd7e34
Add note to documentation
sclubricants Oct 20, 2022
672366e
Fixes from review
sclubricants Oct 25, 2022
b3d932d
Refactor fromQuery()
sclubricants Oct 25, 2022
66829a8
Added fromQuery() test
sclubricants Oct 25, 2022
113e8be
Fix testMode()
sclubricants Oct 26, 2022
f29d253
Comment fieldsFromQuery()
sclubricants Oct 26, 2022
b5a2837
Add more comments
sclubricants Oct 26, 2022
8335990
Remove type string from fromQuery()
sclubricants Oct 26, 2022
d8dbc91
CS Fixer
sclubricants Oct 26, 2022
134aeb6
Change fieldsFromQuery() method
sclubricants Oct 27, 2022
fc4e890
Add $columns parameter
sclubricants Oct 27, 2022
62055ae
Fix logic
sclubricants Oct 27, 2022
b9119a5
Add test for RawSql and manual columns
sclubricants Oct 27, 2022
a345821
Update documentation
sclubricants Oct 27, 2022
1e3d73a
Change to getFieldNames()
sclubricants Oct 28, 2022
3e5a8d6
CS Fixer
sclubricants Oct 28, 2022
a535ca5
Change fromQuery() to setQuery()
sclubricants Oct 28, 2022
2f8d9dc
Throw exception if $query parameter is string
sclubricants Oct 31, 2022
e1855f6
Remove use of setAlias()
sclubricants Nov 18, 2022
70d25ed
Rename setQuery() to setQueryAsData()
sclubricants Nov 21, 2022
055c580
Add query to deleteBatch()
sclubricants Nov 21, 2022
bc02c21
Add delete from query documentation
sclubricants Nov 21, 2022
5979c98
Update user_guide_src/source/changelogs/v4.3.0.rst
sclubricants Dec 8, 2022
91c1a20
Update user_guide_src/source/database/query_builder.rst
sclubricants Dec 8, 2022
a586e4d
Remove query input from $set in *Batch() methods
sclubricants Dec 8, 2022
bb50984
Add notes for version added
sclubricants Dec 8, 2022
e3fd379
Clean up a few things
sclubricants Dec 8, 2022
2154e87
Fix tests to not use query as set parameter
sclubricants Dec 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 132 additions & 14 deletions system/Database/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class BaseBuilder
* tableIdentity?: string,
* updateFields?: array,
* constraints?: array,
* fromQuery?: string,
* setQueryAsData?: string,
* sql?: string,
* alias?: string
* }
Expand Down Expand Up @@ -1925,6 +1925,22 @@ public function upsert($set = null, ?bool $escape = null)
*/
public function upsertBatch($set = null, ?bool $escape = null, int $batchSize = 100)
{
if (isset($this->QBOptions['setQueryAsData'])) {
$sql = $this->_upsertBatch($this->QBFrom[0], $this->QBKeys, []);

if ($sql === '') {
return false; // @codeCoverageIgnore
}

if ($this->testMode === false) {
$this->db->query($sql, null, false);
}

$this->resetWrite();

return $this->testMode ? $sql : $this->db->affectedRows();
}

if ($set !== null) {
$this->setData($set, $escape);
}
Expand Down Expand Up @@ -1965,8 +1981,8 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = 'VALUES ' . implode(', ', $this->formatValues($values)) . "\n";
}
Expand Down Expand Up @@ -2067,6 +2083,60 @@ public function onConstraint($set)
return $this;
}

/**
* Sets data source as a query for insertBatch()/updateBatch()/upsertBatch()/deleteBatch()
*
* @param BaseBuilder|RawSql $query
* @param array|string|null $columns an array or comma delimited string of columns
*/
public function setQueryAsData($query, ?string $alias = null, $columns = null): BaseBuilder
{
if (is_string($query)) {
throw new InvalidArgumentException('$query parameter must be BaseBuilder or RawSql class.');
}

if ($query instanceof BaseBuilder) {
$query = $query->getCompiledSelect();
} elseif ($query instanceof RawSql) {
$query = $query->__toString();
}

if (is_string($query)) {
if ($columns !== null && is_string($columns)) {
$columns = explode(',', $columns);
$columns = array_map(static fn ($key) => trim($key), $columns);
}

$columns = (array) $columns;

if ($columns === []) {
$columns = $this->fieldsFromQuery($query);
}

if ($alias !== null) {
$this->setAlias($alias);
}

foreach ($columns as $key => $value) {
$columns[$key] = $this->db->escapeChar . $value . $this->db->escapeChar;
}

$this->QBOptions['setQueryAsData'] = $query;
$this->QBKeys = $columns;
$this->QBSet = [];
}

return $this;
}

/**
* Gets column names from a select query
*/
protected function fieldsFromQuery(string $sql): array
{
return $this->db->query('SELECT * FROM (' . $sql . ') _u_ LIMIT 1')->getFieldNames();
}

/**
* Converts value array of array to array of strings
*/
Expand All @@ -2084,6 +2154,22 @@ protected function formatValues(array $values): array
*/
public function insertBatch($set = null, ?bool $escape = null, int $batchSize = 100)
{
if (isset($this->QBOptions['setQueryAsData'])) {
$sql = $this->_insertBatch($this->QBFrom[0], $this->QBKeys, []);

if ($sql === '') {
return false; // @codeCoverageIgnore
}

if ($this->testMode === false) {
$this->db->query($sql, null, false);
}

$this->resetWrite();

return $this->testMode ? $sql : $this->db->affectedRows();
}

if ($set !== null && $set !== []) {
$this->setData($set, $escape);
}
Expand Down Expand Up @@ -2114,8 +2200,8 @@ protected function _insertBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = 'VALUES ' . implode(', ', $this->formatValues($values));
}
Expand Down Expand Up @@ -2427,9 +2513,9 @@ protected function validateUpdate(): bool
}

/**
* Sets data and calls batchExecute to run queryies
* Sets data and calls batchExecute to run queries
*
* @param array|object|null $set a dataset or select query
* @param array|object|null $set a dataset
* @param array|RawSql|string|null $constraints
*
* @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode
Expand All @@ -2438,6 +2524,22 @@ public function updateBatch($set = null, $constraints = null, int $batchSize = 1
{
$this->onConstraint($constraints);

if (isset($this->QBOptions['setQueryAsData'])) {
$sql = $this->_updateBatch($this->QBFrom[0], $this->QBKeys, []);

if ($sql === '') {
return false; // @codeCoverageIgnore
}

if ($this->testMode === false) {
$this->db->query($sql, null, false);
}

$this->resetWrite();

return $this->testMode ? $sql : $this->db->affectedRows();
}

if ($set !== null && $set !== []) {
$this->setData($set, true);
}
Expand Down Expand Up @@ -2521,8 +2623,8 @@ protected function _updateBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = implode(
" UNION ALL\n",
Expand Down Expand Up @@ -2677,7 +2779,7 @@ public function delete($where = '', ?int $limit = null, bool $resetData = true)
/**
* Sets data and calls batchExecute to run queries
*
* @param array|object|null $set a dataset or select query
* @param array|object|null $set a dataset
* @param array|RawSql|null $constraints
*
* @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode
Expand All @@ -2686,6 +2788,22 @@ public function deleteBatch($set = null, $constraints = null, int $batchSize = 1
{
$this->onConstraint($constraints);

if (isset($this->QBOptions['setQueryAsData'])) {
$sql = $this->_deleteBatch($this->QBFrom[0], $this->QBKeys, []);

if ($sql === '') {
return false; // @codeCoverageIgnore
}

if ($this->testMode === false) {
$this->db->query($sql, null, false);
}

$this->resetWrite();

return $this->testMode ? $sql : $this->db->affectedRows();
}

if ($set !== null && $set !== []) {
$this->setData($set, true);
}
Expand Down Expand Up @@ -2757,8 +2875,8 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = trim($sql);
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = implode(
" UNION ALL\n",
Expand Down Expand Up @@ -3156,7 +3274,7 @@ protected function isLiteral(string $str): bool
*
* @return $this
*/
public function resetQuery()
public function resetQueryAsData()
{
$this->resetSelect();
$this->resetWrite();
Expand Down Expand Up @@ -3311,7 +3429,7 @@ protected function setBind(string $key, $value = null, bool $escape = true): str
*/
protected function cleanClone()
{
return (clone $this)->from([], true)->resetQuery();
return (clone $this)->from([], true)->resetQueryAsData();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions system/Database/MySQLi/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ protected function _updateBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = implode(
" UNION ALL\n",
Expand Down
24 changes: 16 additions & 8 deletions system/Database/OCI8/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ protected function _insertBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = implode(
" FROM DUAL UNION ALL\n",
Expand Down Expand Up @@ -307,8 +307,8 @@ protected function _updateBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = implode(
" UNION ALL\n",
Expand Down Expand Up @@ -416,8 +416,8 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = implode(
" FROM DUAL UNION ALL\n",
Expand Down Expand Up @@ -495,8 +495,8 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = implode(
" FROM DUAL UNION ALL\n",
Expand All @@ -513,4 +513,12 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri

return str_replace('{:_table_:}', $data, $sql);
}

/**
* Gets column names from a select query
*/
protected function fieldsFromQuery(string $sql): array
{
return $this->db->query('SELECT * FROM (' . $sql . ') "_u_" WHERE ROWNUM = 1')->getFieldNames();
}
}
12 changes: 6 additions & 6 deletions system/Database/Postgre/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ protected function _insertBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = 'VALUES ' . implode(', ', $this->formatValues($values));
}
Expand Down Expand Up @@ -400,8 +400,8 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = 'VALUES ' . implode(', ', $this->formatValues($values)) . "\n";
}
Expand Down Expand Up @@ -469,8 +469,8 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = implode(
" UNION ALL\n",
Expand Down
16 changes: 12 additions & 4 deletions system/Database/SQLSRV/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ protected function _insertBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = 'VALUES ' . implode(', ', $this->formatValues($values));
}
Expand Down Expand Up @@ -756,12 +756,20 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
$this->QBOptions['sql'] = $sql;
}

if (isset($this->QBOptions['fromQuery'])) {
$data = $this->QBOptions['fromQuery'];
if (isset($this->QBOptions['setQueryAsData'])) {
$data = $this->QBOptions['setQueryAsData'];
} else {
$data = 'VALUES ' . implode(', ', $this->formatValues($values)) . "\n";
}

return str_replace('{:_table_:}', $data, $sql);
}

/**
* Gets column names from a select query
*/
protected function fieldsFromQuery(string $sql): array
{
return $this->db->query('SELECT TOP 1 * FROM (' . $sql . ') _u_')->getFieldNames();
}
}
Loading