Skip to content

Commit 20985a4

Browse files
committed
[FEATURE] Added support for FOR UPDATE (issue #109).
- Cleanup
1 parent aa5a88d commit 20985a4

7 files changed

Lines changed: 48 additions & 49 deletions

File tree

src/Pecee/Pixie/Connection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public function getPdoInstance(): \PDO
131131
* Returns an instance of Query Builder
132132
*
133133
* @return QueryBuilderHandler
134-
* @throws \Pecee\Pixie\Exception
134+
* @throws Exception
135135
*/
136136
public function getQueryBuilder(): QueryBuilderHandler
137137
{

src/Pecee/Pixie/Exception.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function __construct(string $message = '', int $code = 0, Throwable $prev
3434
/**
3535
* @param \Exception $e
3636
* @param string|null $adapterName
37-
* @param \Pecee\Pixie\QueryBuilder\QueryObject|null $query
37+
* @param QueryObject|null $query
3838
*
3939
* @return static|ColumnNotFoundException|ConnectionException|DuplicateColumnException|DuplicateEntryException|DuplicateKeyException|ForeignKeyException|NotNullException|TableNotFoundException
4040
*
@@ -115,6 +115,7 @@ public static function create(\Exception $e, string $adapterName = null, QueryOb
115115
if ($errorCode === 14) {
116116
return new ConnectionException($errorMsg, 1, $e->getPrevious(), $query);
117117
}
118+
break;
118119
case 'HY000':
119120
case '23000':
120121
if (preg_match('/no such column:/', $errorMsg) === 1) {
@@ -149,4 +150,4 @@ public function getQuery(): ?QueryObject
149150
{
150151
return $this->query;
151152
}
152-
}
153+
}

src/Pecee/Pixie/QueryBuilder/Adapters/BaseAdapter.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ abstract class BaseAdapter
4040
*/
4141
protected const QUERY_PART_OFFSET = 'OFFSET';
4242

43+
/**
44+
* @var string
45+
*/
46+
protected const QUERY_PART_FOR = 'FOR';
47+
4348
/**
4449
* @var string
4550
*/
@@ -51,7 +56,7 @@ abstract class BaseAdapter
5156
protected const QUERY_PART_TOP = 'TOP';
5257

5358
/**
54-
* @var \Pecee\Pixie\Connection
59+
* @var Connection
5560
*/
5661
protected $connection;
5762

@@ -64,7 +69,7 @@ abstract class BaseAdapter
6469
/**
6570
* BaseAdapter constructor.
6671
*
67-
* @param \Pecee\Pixie\Connection $connection
72+
* @param Connection $connection
6873
*/
6974
public function __construct(Connection $connection)
7075
{
@@ -284,7 +289,7 @@ protected function buildJoin(array $statements): string
284289
$table = $joinArr['table'] instanceof Raw ? (string)$joinArr['table'] : $this->wrapSanitizer($joinArr['table']);
285290
}
286291

287-
/* @var $joinBuilder \Pecee\Pixie\QueryBuilder\QueryBuilderHandler */
292+
/* @var $joinBuilder QueryBuilderHandler */
288293
$joinBuilder = $joinArr['joinBuilder'];
289294

290295
$sqlArr = [
@@ -394,7 +399,7 @@ public function delete(array $statements, array $columns = null): array
394399
$this->buildQueryPart(static::QUERY_PART_GROUPBY, $statements),
395400
$this->buildQueryPart(static::QUERY_PART_ORDERBY, $statements),
396401
$this->buildQueryPart(static::QUERY_PART_LIMIT, $statements),
397-
$this->buildQueryPart(static::QUERY_PART_OFFSET, $statements),
402+
$this->buildQueryPart(static::QUERY_PART_OFFSET, $statements)
398403
]);
399404
$bindings = $whereBindings;
400405

@@ -559,7 +564,6 @@ public function select(array $statements): array
559564
if ($table instanceof Raw) {
560565
$t = $table;
561566
} else {
562-
$prefix = $statements['aliases'][$table] ?? null;
563567
$t = $this->buildAliasedTableName($table, $statements);
564568
}
565569

@@ -588,6 +592,7 @@ public function select(array $statements): array
588592
$this->buildQueryPart(static::QUERY_PART_ORDERBY, $statements),
589593
$this->buildQueryPart(static::QUERY_PART_LIMIT, $statements),
590594
$this->buildQueryPart(static::QUERY_PART_OFFSET, $statements),
595+
$this->buildQueryPart(static::QUERY_PART_FOR, $statements),
591596
]);
592597

593598
$sql = $this->buildUnion($statements, $sql);
@@ -639,6 +644,8 @@ protected function buildQueryPart(string $section, array $statements): string
639644
}
640645

641646
return $groupBys;
647+
case static::QUERY_PART_FOR:
648+
return isset($statements['for']) ? ' FOR ' . $statements['for'][0] : '';
642649
}
643650

644651
return '';

src/Pecee/Pixie/QueryBuilder/Adapters/Sqlserver.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
use Pecee\Pixie\Exception;
55
use Pecee\Pixie\QueryBuilder\Raw;
6-
use Pecee\Pixie\QueryBuilder\Adapters\BaseAdapter;
76

87
/**
98
* Class Sqlserver
@@ -195,4 +194,4 @@ public function wrapSanitizer($value)
195194
// Join these back with "." and return
196195
return implode('.', $valueArr);
197196
}
198-
}
197+
}

src/Pecee/Pixie/QueryBuilder/QueryBuilderHandler.php

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class QueryBuilderHandler implements IQueryBuilderHandler
7070
*
7171
* @var array
7272
*/
73-
protected $fetchParameters = [\PDO::FETCH_OBJ];
73+
protected $fetchParameters = [PDO::FETCH_OBJ];
7474

7575
/**
7676
* If true calling from, select etc. will overwrite any existing values from previous calls in query.
@@ -80,9 +80,9 @@ class QueryBuilderHandler implements IQueryBuilderHandler
8080
protected $overwriteEnabled = false;
8181

8282
/**
83-
* @param \Pecee\Pixie\Connection|null $connection
83+
* @param Connection|null $connection
8484
*
85-
* @throws \Pecee\Pixie\Exception
85+
* @throws Exception
8686
*/
8787
public function __construct(Connection $connection = null)
8888
{
@@ -228,7 +228,7 @@ public function first()
228228
public function get(): array
229229
{
230230
/**
231-
* @var $queryObject \Pecee\Pixie\QueryBuilder\QueryObject
231+
* @var $queryObject QueryObject
232232
* @var $executionTime float
233233
* @var $start float
234234
* @var $result array
@@ -340,7 +340,7 @@ public function fireEvents(string $name, QueryObject $queryObject, array $eventA
340340
* @throws \Pecee\Pixie\Exceptions\TableNotFoundException
341341
* @throws \Pecee\Pixie\Exceptions\ConnectionException
342342
* @throws \Pecee\Pixie\Exceptions\ColumnNotFoundException
343-
* @throws \Pecee\Pixie\Exception
343+
* @throws Exception
344344
* @throws \Pecee\Pixie\Exceptions\DuplicateColumnException
345345
* @throws \Pecee\Pixie\Exceptions\DuplicateEntryException
346346
* @throws \Pecee\Pixie\Exceptions\DuplicateKeyException
@@ -453,7 +453,7 @@ public function fetchNext(int $fetchNext): IQueryBuilderHandler
453453
*
454454
* Example: ['field' => 'alias'] will become `field` AS `alias`
455455
*
456-
* @param string|array $fields,...
456+
* @param string|array|Raw $fields,...
457457
*
458458
* @return static
459459
*/
@@ -661,7 +661,7 @@ public function subQuery(QueryBuilderHandler $queryBuilder, $alias = null): Raw
661661
{
662662
$sql = '(' . $queryBuilder->getQuery()->getRawSql() . ')';
663663
if ($alias !== null) {
664-
$sql = $sql . ' AS ' . $this->adapterInstance->wrapSanitizer($alias);
664+
$sql .= ' AS ' . $this->adapterInstance->wrapSanitizer($alias);
665665
}
666666

667667
return $queryBuilder->raw($sql);
@@ -927,7 +927,7 @@ public function join($table, $key = null, $operator = null, $value = null, $type
927927
* in the closure should reflect here
928928
*/
929929
if ($key instanceof \Closure === false) {
930-
$key = function (JoinBuilder $joinBuilder) use ($key, $operator, $value) {
930+
$key = static function (JoinBuilder $joinBuilder) use ($key, $operator, $value) {
931931
$joinBuilder->on($key, $operator, $value);
932932
};
933933
}
@@ -1028,12 +1028,6 @@ private function doInsert(array $data, string $type)
10281028
*/
10291029
public function transaction(\Closure $callback): Transaction
10301030
{
1031-
/**
1032-
* Get the Transaction class
1033-
*
1034-
* @var \Pecee\Pixie\QueryBuilder\Transaction $queryTransaction
1035-
* @throws \Exception
1036-
*/
10371031
$queryTransaction = new Transaction($this->connection);
10381032
$queryTransaction->statements = $this->statements;
10391033

@@ -1074,7 +1068,7 @@ public function transaction(\Closure $callback): Transaction
10741068
* @return static
10751069
* @throws Exception
10761070
*/
1077-
public function joinUsing($table, $fields, $joinType = '')
1071+
public function joinUsing($table, $fields, $joinType = ''): IQueryBuilderHandler
10781072
{
10791073
if (\is_array($fields) === false) {
10801074
$fields = [$fields];
@@ -1414,7 +1408,7 @@ public function rightJoin($table, $key, ?string $operator = null, $value = null)
14141408
*
14151409
* @return static
14161410
*/
1417-
public function selectDistinct($fields)
1411+
public function selectDistinct($fields): IQueryBuilderHandler
14181412
{
14191413
if ($this->overwriteEnabled === true) {
14201414
$this->statements['distincts'] = $fields;
@@ -1466,7 +1460,7 @@ public function getStatements(): array
14661460
*
14671461
* @return static $this
14681462
*/
1469-
public function setStatements(array $statements)
1463+
public function setStatements(array $statements): IQueryBuilderHandler
14701464
{
14711465
$this->statements = $statements;
14721466

@@ -1615,6 +1609,17 @@ public function whereNull($key): IQueryBuilderHandler
16151609
return $this->whereNullHandler($key);
16161610
}
16171611

1612+
/**
1613+
* Will add FOR statement to the end of the SELECT statement, like FOR UPDATE, FOR SHARE etc.
1614+
* @param $statement string
1615+
* @return static
1616+
*/
1617+
public function for(string $statement): IQueryBuilderHandler
1618+
{
1619+
$this->addStatement('for', $statement);
1620+
return $this;
1621+
}
1622+
16181623
/**
16191624
* Returns all columns in current query
16201625
*
@@ -1655,7 +1660,7 @@ public function isOverwriteEnabled(): bool
16551660
* @param bool $enabled
16561661
* @return static
16571662
*/
1658-
public function setOverwriteEnabled(bool $enabled)
1663+
public function setOverwriteEnabled(bool $enabled): IQueryBuilderHandler
16591664
{
16601665
$this->overwriteEnabled = $enabled;
16611666

src/Pecee/Pixie/QueryBuilder/QueryObject.php

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,24 +94,6 @@ protected function interpolateQuery($query, $params): string
9494
// Try to parse object-types
9595
if(\is_object($value) === true) {
9696
$value = (string)$value;
97-
98-
// Test if value is nummeric
99-
if(\is_numeric($value) === true) {
100-
101-
// Parse integer values
102-
if(\is_int($value) === true) {
103-
$value = (int)$value;
104-
continue;
105-
}
106-
107-
// Parse float values
108-
if(\is_float($value) === true) {
109-
$value = (float)$value;
110-
continue;
111-
}
112-
113-
// Otherwise continue
114-
}
11597
}
11698

11799
if (\is_string($value) === true) {

tests/Pecee/Pixie/QueryBuilderTest.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,10 @@ public function testNullableWhere()
9696

9797
public function testWhereBetween()
9898
{
99-
10099
$qb = $this->builder;
101100
$query = $qb->table('animals')->whereBetween('created_date', $qb->raw('NOW()'), '27-05-2017');
102101

103102
$this->assertEquals('SELECT * FROM `cb_animals` WHERE `created_date` BETWEEN NOW() AND \'27-05-2017\'', $query->getQuery()->getRawSql());
104-
105103
}
106104

107105
public function testUnion()
@@ -183,4 +181,11 @@ public function testGetColumns(){
183181
],$query->getColumns());
184182
}
185183

186-
}
184+
public function testQueryPartFor()
185+
{
186+
$query = $this->builder->newQuery()->select(['id'])->table('users')->for('UPDATE');
187+
188+
$this->assertEquals('SELECT * FROM `cb_users` FOR UPDATE', $query->getQuery()->getRawSql());
189+
}
190+
191+
}

0 commit comments

Comments
 (0)