-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add selectConcat method to query builder (#434)
Replaces Laravel's Grammar classes with October Rain versions, and sets the DB connections to use these new Grammars. Instead of copying over the entire grammars for the different database types, we'll just replace and amend what is necessary, so we should be safe with updates.
- Loading branch information
1 parent
ac0215b
commit d72caf0
Showing
12 changed files
with
322 additions
and
6 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
namespace October\Rain\Database\Capsule; | ||
|
||
use Illuminate\Database\DatabaseManager; | ||
use Illuminate\Database\Capsule\Manager as BaseManager; | ||
use October\Rain\Database\Connectors\ConnectionFactory; | ||
|
||
class Manager extends BaseManager | ||
{ | ||
/** | ||
* Build the database manager instance. | ||
* | ||
* @return void | ||
*/ | ||
protected function setupManager() | ||
{ | ||
$factory = new ConnectionFactory($this->container); | ||
|
||
$this->manager = new DatabaseManager($this->container, $factory); | ||
} | ||
} |
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
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
67 changes: 67 additions & 0 deletions
67
src/Database/Query/Grammars/Concerns/SelectConcatenations.php
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 |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php namespace October\Rain\Database\Query\Grammars\Concerns; | ||
|
||
use \Illuminate\Database\Query\Builder; | ||
use Illuminate\Database\Query\Expression; | ||
|
||
trait SelectConcatenations | ||
{ | ||
/** | ||
* Compile the "select *" portion of the query. | ||
* | ||
* This particular method will call the original compileColumns() method provided by the grammar, then append | ||
* the concatenated columns to the query. | ||
* | ||
* @param \Illuminate\Database\Query\Builder $query | ||
* @param array $columns | ||
* @return string|null | ||
*/ | ||
protected function compileColumns(Builder $query, $columns) | ||
{ | ||
$select = parent::compileColumns($query, $columns); | ||
|
||
if (count($query->concats)) { | ||
$select .= $this->compileConcats($query); | ||
} | ||
|
||
return $select; | ||
} | ||
|
||
/** | ||
* Compiles the concatenated columns and adds them to the "select" portion of the query. | ||
* | ||
* @param \Illuminate\Database\Query\Builder $query | ||
* @return string | ||
*/ | ||
protected function compileConcats(Builder $query) | ||
{ | ||
$columns = []; | ||
|
||
foreach ($query->concats as $as => $parts) { | ||
$columns[] = $this->compileConcat($parts, $as); | ||
} | ||
|
||
return ', ' . implode(', ', $columns); | ||
} | ||
|
||
/** | ||
* Compiles a single CONCAT value. | ||
* | ||
* @param array $parts The concatenation parts. | ||
* @param string $as The alias to return the entire concatenation as. | ||
* @return string | ||
*/ | ||
protected function compileConcat(array $parts, string $as) | ||
{ | ||
$compileParts = []; | ||
|
||
foreach ($parts as $part) { | ||
if (preg_match('/^[a-z_@#][a-z0-9@$#_]*$/', $part)) { | ||
$compileParts[] = $this->wrap($part); | ||
} else { | ||
$compileParts[] = $this->wrap(new Expression('\'' . trim($part, '\'"') . '\'')); | ||
} | ||
} | ||
|
||
return 'concat(' . implode(', ', $compileParts) . ') as ' . $this->wrap($as); | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php namespace October\Rain\Database\Query\Grammars; | ||
|
||
use Illuminate\Database\Query\Grammars\MySqlGrammar as BaseMysqlGrammer; | ||
use October\Rain\Database\Query\Grammars\Concerns\SelectConcatenations; | ||
|
||
class MySqlGrammar extends BaseMysqlGrammer | ||
{ | ||
use SelectConcatenations; | ||
} |
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 |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php namespace October\Rain\Database\Query\Grammars; | ||
|
||
use Illuminate\Database\Query\Grammars\PostgresGrammar as BasePostgresGrammer; | ||
use October\Rain\Database\Query\Grammars\Concerns\SelectConcatenations; | ||
|
||
class PostgresGrammar extends BasePostgresGrammer | ||
{ | ||
use SelectConcatenations; | ||
} |
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 |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php namespace October\Rain\Database\Query\Grammars; | ||
|
||
use Illuminate\Database\Query\Expression; | ||
use Illuminate\Database\Query\Grammars\SQLiteGrammar as BaseSQLiteGrammar; | ||
use October\Rain\Database\Query\Grammars\Concerns\SelectConcatenations; | ||
|
||
class SQLiteGrammar extends BaseSQLiteGrammar | ||
{ | ||
use SelectConcatenations; | ||
|
||
/** | ||
* Compiles a single CONCAT value. | ||
* | ||
* SQLite uses slightly different concatenation syntax. | ||
* | ||
* @param array $parts The concatenation parts. | ||
* @param string $as The alias to return the entire concatenation as. | ||
* @return string | ||
*/ | ||
protected function compileConcat(array $parts, string $as) | ||
{ | ||
$compileParts = []; | ||
|
||
foreach ($parts as $part) { | ||
if (preg_match('/^[a-z_@#][a-z0-9@$#_]*$/', $part)) { | ||
$compileParts[] = $this->wrap($part); | ||
} else { | ||
$compileParts[] = $this->wrap(new Expression('\'' . trim($part, '\'"') . '\'')); | ||
} | ||
} | ||
|
||
return implode(' || ', $compileParts) . ' as ' . $this->wrap($as); | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php namespace October\Rain\Database\Query\Grammars; | ||
|
||
use Illuminate\Database\Query\Grammars\SqlServerGrammar as BaseSqlServerGrammar; | ||
use October\Rain\Database\Query\Grammars\Concerns\SelectConcatenations; | ||
|
||
class SqlServerGrammar extends BaseSqlServerGrammar | ||
{ | ||
use SelectConcatenations; | ||
} |
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 |
---|---|---|
@@ -0,0 +1,145 @@ | ||
<?php | ||
use October\Rain\Database\Models\Revision; | ||
|
||
class SelectConcatTest extends TestCase | ||
{ | ||
public function testMySqlConcat() | ||
{ | ||
$capsule = new October\Rain\Database\Capsule\Manager; | ||
$capsule->addConnection([ | ||
'driver' => 'mysql', | ||
'database' => ':memory:', | ||
'prefix' => '' | ||
]); | ||
$capsule->setAsGlobal(); | ||
$capsule->bootEloquent(); | ||
|
||
$model = new Revision; | ||
|
||
$query = $model | ||
->newQuery() | ||
->select(['id']) | ||
->selectConcat(['field', ' ', 'cast'], 'full_cast') | ||
->selectConcat(['field2', ' ', 'cast2'], 'full_cast2'); | ||
|
||
$this->assertEquals( | ||
'select `id`, concat(`field`, \' \', `cast`) as `full_cast`, concat(`field2`, \' \', `cast2`) as `full_cast2` from `revisions`', | ||
$query->toSql() | ||
); | ||
|
||
$query = $model | ||
->newQuery() | ||
->select(['id']) | ||
->selectConcat(['"field"', ' ', 'cast'], 'full_cast'); | ||
|
||
$this->assertEquals( | ||
'select `id`, concat(\'field\', \' \', `cast`) as `full_cast` from `revisions`', | ||
$query->toSql() | ||
); | ||
} | ||
|
||
public function testSQLiteConcat() | ||
{ | ||
$capsule = new October\Rain\Database\Capsule\Manager; | ||
$capsule->addConnection([ | ||
'driver' => 'sqlite', | ||
'database' => ':memory:', | ||
'prefix' => '' | ||
]); | ||
$capsule->setAsGlobal(); | ||
$capsule->bootEloquent(); | ||
|
||
$model = new Revision; | ||
|
||
$query = $model | ||
->newQuery() | ||
->select(['id']) | ||
->selectConcat(['field', ' ', 'cast'], 'full_cast') | ||
->selectConcat(['field2', ' ', 'cast2'], 'full_cast2'); | ||
|
||
$this->assertEquals( | ||
'select "id", "field" || \' \' || "cast" as "full_cast", "field2" || \' \' || "cast2" as "full_cast2" from "revisions"', | ||
$query->toSql() | ||
); | ||
|
||
$query = $model | ||
->newQuery() | ||
->select(['id']) | ||
->selectConcat(['"field"', ' ', 'cast'], 'full_cast'); | ||
|
||
$this->assertEquals( | ||
'select "id", \'field\' || \' \' || "cast" as "full_cast" from "revisions"', | ||
$query->toSql() | ||
); | ||
} | ||
|
||
public function testPostgresqlConcat() | ||
{ | ||
$capsule = new October\Rain\Database\Capsule\Manager; | ||
$capsule->addConnection([ | ||
'driver' => 'pgsql', | ||
'database' => ':memory:', | ||
'prefix' => '' | ||
]); | ||
$capsule->setAsGlobal(); | ||
$capsule->bootEloquent(); | ||
|
||
$model = new Revision; | ||
|
||
$query = $model | ||
->newQuery() | ||
->select(['id']) | ||
->selectConcat(['field', ' ', 'cast'], 'full_cast') | ||
->selectConcat(['field2', ' ', 'cast2'], 'full_cast2'); | ||
|
||
$this->assertEquals( | ||
'select "id", concat("field", \' \', "cast") as "full_cast", concat("field2", \' \', "cast2") as "full_cast2" from "revisions"', | ||
$query->toSql() | ||
); | ||
|
||
$query = $model | ||
->newQuery() | ||
->select(['id']) | ||
->selectConcat(['"field"', ' ', 'cast'], 'full_cast'); | ||
|
||
$this->assertEquals( | ||
'select "id", concat(\'field\', \' \', "cast") as "full_cast" from "revisions"', | ||
$query->toSql() | ||
); | ||
} | ||
|
||
public function testSqlServerConcat() | ||
{ | ||
$capsule = new October\Rain\Database\Capsule\Manager; | ||
$capsule->addConnection([ | ||
'driver' => 'sqlsrv', | ||
'database' => ':memory:', | ||
'prefix' => '' | ||
]); | ||
$capsule->setAsGlobal(); | ||
$capsule->bootEloquent(); | ||
|
||
$model = new Revision; | ||
|
||
$query = $model | ||
->newQuery() | ||
->select(['id']) | ||
->selectConcat(['field', ' ', 'cast'], 'full_cast') | ||
->selectConcat(['field2', ' ', 'cast2'], 'full_cast2'); | ||
|
||
$this->assertEquals( | ||
'select [id], concat([field], \' \', [cast]) as [full_cast], concat([field2], \' \', [cast2]) as [full_cast2] from [revisions]', | ||
$query->toSql() | ||
); | ||
|
||
$query = $model | ||
->newQuery() | ||
->select(['id']) | ||
->selectConcat(['"field"', ' ', 'cast'], 'full_cast'); | ||
|
||
$this->assertEquals( | ||
'select [id], concat(\'field\', \' \', [cast]) as [full_cast] from [revisions]', | ||
$query->toSql() | ||
); | ||
} | ||
} |