Skip to content

Commit 9e37fa5

Browse files
committed
Add fromQuery() and fieldsFromQuery() methods
fromQuery() sets a query as a datasource. fieldsFromQuery() parses a select query and retrieves the field names. These will be used to define QBKeys.
1 parent 603239c commit 9e37fa5

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

system/Database/BaseBuilder.php

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,72 @@ public function onConstraint($set)
20512051
return $this;
20522052
}
20532053

2054+
/**
2055+
* Sets data source as a query for insert/update/upsert
2056+
*
2057+
* @param BaseBuilder|string $query
2058+
*/
2059+
public function fromQuery($query): BaseBuilder
2060+
{
2061+
if (! empty($query)) {
2062+
if ($query instanceof BaseBuilder) {
2063+
$query = $query->getCompiledSelect();
2064+
}
2065+
2066+
if (is_string($query)) {
2067+
$this->QBOptions['fromQuery'] = $query;
2068+
$this->QBKeys = $this->db->protectIdentifiers($this->fieldsFromQuery($query));
2069+
$this->QBSet = [];
2070+
}
2071+
}
2072+
2073+
return $this;
2074+
}
2075+
2076+
/**
2077+
* Gets column names from a select query
2078+
*
2079+
* @param string $sql
2080+
*/
2081+
protected function fieldsFromQuery(string $sql): array
2082+
{
2083+
$sql = preg_replace('/\\(([^()]*+|(?R))*\\)/', '', $sql); // remove everything in parenthesis - removes "FROM" and commas
2084+
$d = ['`', "'", '"'];
2085+
2086+
$o = ' ';
2087+
$r = '$';
2088+
$sql = preg_replace_callback("~{$d[0]}([^{$d[0]}]*){$d[0]}~", static fn ($s) => str_replace($o, $r, "{$d[0]}{$s[1]}{$d[0]}"), $sql);
2089+
$sql = preg_replace_callback("~{$d[1]}([^{$d[1]}]*){$d[1]}~", static fn ($s) => str_replace($o, $r, "{$d[1]}{$s[1]}{$d[1]}"), $sql);
2090+
$sql = preg_replace_callback("~{$d[2]}([^{$d[2]}]*){$d[2]}~", static fn ($s) => str_replace($o, $r, "{$d[2]}{$s[1]}{$d[2]}"), $sql);
2091+
2092+
$o = ',';
2093+
$r = '';
2094+
$sql = preg_replace_callback("~{$d[0]}([^{$d[0]}]*){$d[0]}~", static fn ($s) => str_replace($o, $r, "{$d[0]}{$s[1]}{$d[0]}"), $sql);
2095+
$sql = preg_replace_callback("~{$d[1]}([^{$d[1]}]*){$d[1]}~", static fn ($s) => str_replace($o, $r, "{$d[1]}{$s[1]}{$d[1]}"), $sql);
2096+
$sql = preg_replace_callback("~{$d[2]}([^{$d[2]}]*){$d[2]}~", static fn ($s) => str_replace($o, $r, "{$d[2]}{$s[1]}{$d[2]}"), $sql);
2097+
$sql = preg_replace("/[\n\r]/", ' ', $sql);
2098+
2099+
// pull out main select fields
2100+
preg_match('/select(.*?) from /is', $sql, $matches);
2101+
2102+
$sql = $matches[1];
2103+
2104+
$columnsStrings = explode(',', $sql);
2105+
2106+
$newColumns = [];
2107+
2108+
foreach ($columnsStrings as $string) {
2109+
$words = preg_replace('/\.+/', ' ', $string);
2110+
$words = explode(' ', trim($words));
2111+
$word = trim(str_replace('$', ' ', trim(end($words))));
2112+
$word = trim(str_replace($d, '', $word));
2113+
2114+
$newColumns[] = $word;
2115+
}
2116+
2117+
return $newColumns;
2118+
}
2119+
20542120
/**
20552121
* Converts value array of array to array of strings
20562122
*/
@@ -2399,7 +2465,7 @@ protected function validateUpdate(): bool
23992465
/**
24002466
* Sets data and calls batchExecute to run queryies
24012467
*
2402-
* @param array|object|null $set a dataset or select query
2468+
* @param array|BaseBuilder|RawSqwl|object|null $set a dataset or select query
24032469
* @param array|RawSql|string|null $constraints
24042470
*
24052471
* @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode

0 commit comments

Comments
 (0)