-
Notifications
You must be signed in to change notification settings - Fork 170
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for QueryBuilder upsert() method. (#531)
Pulls in the work by @paras-malhotra in https:ithub.com/laravel/framework/pull/34698 & laravel/framework#34712 for use in October CMS. Co-authored-by: Ben Thomson <[email protected]>
- Loading branch information
Luke Towers
and
Ben Thomson
authored
Oct 20, 2020
1 parent
d72caf0
commit 05d3e90
Showing
9 changed files
with
497 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,32 @@ | ||
<?php namespace October\Rain\Database\Query\Grammars; | ||
|
||
use October\Rain\Database\QueryBuilder; | ||
use Illuminate\Database\Query\Grammars\MySqlGrammar as BaseMysqlGrammer; | ||
use October\Rain\Database\Query\Grammars\Concerns\SelectConcatenations; | ||
|
||
class MySqlGrammar extends BaseMysqlGrammer | ||
{ | ||
use SelectConcatenations; | ||
|
||
/** | ||
* Compile an "upsert" statement into SQL. | ||
* | ||
* @param \October\Rain\Database\QueryBuilder $query | ||
* @param array $values | ||
* @param array $uniqueBy | ||
* @param array $update | ||
* @return string | ||
*/ | ||
public function compileUpsert(QueryBuilder $query, array $values, array $uniqueBy, array $update) | ||
{ | ||
$sql = $this->compileInsert($query, $values) . ' on duplicate key update '; | ||
|
||
$columns = collect($update)->map(function ($value, $key) { | ||
return is_numeric($key) | ||
? $this->wrap($value) . ' = values(' . $this->wrap($value) . ')' | ||
: $this->wrap($key) . ' = ' . $this->parameter($value); | ||
})->implode(', '); | ||
|
||
return $sql . $columns; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,34 @@ | ||
<?php namespace October\Rain\Database\Query\Grammars; | ||
|
||
use October\Rain\Database\QueryBuilder; | ||
use Illuminate\Database\Query\Grammars\PostgresGrammar as BasePostgresGrammer; | ||
use October\Rain\Database\Query\Grammars\Concerns\SelectConcatenations; | ||
|
||
class PostgresGrammar extends BasePostgresGrammer | ||
{ | ||
use SelectConcatenations; | ||
|
||
/** | ||
* Compile an "upsert" statement into SQL. | ||
* | ||
* @param \October\Rain\Database\QueryBuilder $query | ||
* @param array $values | ||
* @param array $uniqueBy | ||
* @param array $update | ||
* @return string | ||
*/ | ||
public function compileUpsert(QueryBuilder $query, array $values, array $uniqueBy, array $update) | ||
{ | ||
$sql = $this->compileInsert($query, $values); | ||
|
||
$sql .= ' on conflict (' . $this->columnize($uniqueBy) . ') do update set '; | ||
|
||
$columns = collect($update)->map(function ($value, $key) { | ||
return is_numeric($key) | ||
? $this->wrap($value) . ' = ' . $this->wrapValue('excluded') . '.' . $this->wrap($value) | ||
: $this->wrap($key) . ' = ' . $this->parameter($value); | ||
})->implode(', '); | ||
|
||
return $sql . $columns; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,52 @@ | ||
<?php namespace October\Rain\Database\Query\Grammars; | ||
|
||
use October\Rain\Database\QueryBuilder; | ||
use Illuminate\Database\Query\Grammars\SqlServerGrammar as BaseSqlServerGrammar; | ||
use October\Rain\Database\Query\Grammars\Concerns\SelectConcatenations; | ||
|
||
class SqlServerGrammar extends BaseSqlServerGrammar | ||
{ | ||
use SelectConcatenations; | ||
|
||
/** | ||
* Compile an "upsert" statement into SQL. | ||
* | ||
* @param \October\Rain\Database\QueryBuilder $query | ||
* @param array $values | ||
* @param array $uniqueBy | ||
* @param array $update | ||
* @return string | ||
*/ | ||
public function compileUpsert(QueryBuilder $query, array $values, array $uniqueBy, array $update) | ||
{ | ||
$columns = $this->columnize(array_keys(reset($values))); | ||
|
||
$sql = 'merge ' . $this->wrapTable($query->from) . ' '; | ||
|
||
$parameters = collect($values)->map(function ($record) { | ||
return '(' . $this->parameterize($record) . ')'; | ||
})->implode(', '); | ||
|
||
$sql .= 'using (values ' . $parameters . ') ' . $this->wrapTable('laravel_source') . ' (' . $columns . ') '; | ||
|
||
$on = collect($uniqueBy)->map(function ($column) use ($query) { | ||
return $this->wrap('laravel_source.' . $column) . ' = ' . $this->wrap($query->from . '.' . $column); | ||
})->implode(' and '); | ||
|
||
$sql .= 'on ' . $on . ' '; | ||
|
||
if ($update) { | ||
$update = collect($update)->map(function ($value, $key) { | ||
return is_numeric($key) | ||
? $this->wrap($value) . ' = ' . $this->wrap('laravel_source.' . $value) | ||
: $this->wrap($key) . ' = ' . $this->parameter($value); | ||
})->implode(', '); | ||
|
||
$sql .= 'when matched then update set ' . $update . ' '; | ||
} | ||
|
||
$sql .= 'when not matched then insert (' . $columns . ') values (' . $columns . ')'; | ||
|
||
return $sql; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.