- Fixed the QueryBuilder's escaping problem - adapters are now responsible for escaping identifiers.
- Added a MsSQL offset query fragment. There is still a problem with the way the Repository must act within another adapter.
This commit is contained in:
		
							parent
							
								
									3ff97f3bf0
								
							
						
					
					
						commit
						026a0f4f83
					
				| @ -7,7 +7,8 @@ use PDO, | |||||||
| 
 | 
 | ||||||
| class PdoObject extends PDO { | class PdoObject extends PDO { | ||||||
| 
 | 
 | ||||||
|     public function select(string $sql, array $parameters = []): PDOStatement { |     public function select(string $sql, array $parameters = []): PDOStatement  | ||||||
|  |     { | ||||||
|         try { |         try { | ||||||
|             if (false !== ( $statement = $this->prepare($sql) )) { |             if (false !== ( $statement = $this->prepare($sql) )) { | ||||||
|                 $statement = $this->execute($statement, $parameters, false); |                 $statement = $this->execute($statement, $parameters, false); | ||||||
| @ -21,7 +22,8 @@ class PdoObject extends PDO { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function runQuery(string $sql, array $parameters = []): ? PDOStatement { |     public function runQuery(string $sql, array $parameters = []): ? PDOStatement  | ||||||
|  |     { | ||||||
|         try { |         try { | ||||||
|             if (false !== ( $statement = $this->prepare($sql) )) { |             if (false !== ( $statement = $this->prepare($sql) )) { | ||||||
|                 return $this->execute($statement, $parameters, true); |                 return $this->execute($statement, $parameters, true); | ||||||
| @ -34,7 +36,8 @@ class PdoObject extends PDO { | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function execute(PDOStatement $statement, array $parameters = [], bool $commit = true): ? PDOStatement { |     public function execute(PDOStatement $statement, array $parameters = [], bool $commit = true): ? PDOStatement | ||||||
|  |     { | ||||||
|         try { |         try { | ||||||
|             if ( ! $this->inTransaction() ) { |             if ( ! $this->inTransaction() ) { | ||||||
|                 $this->beginTransaction(); |                 $this->beginTransaction(); | ||||||
| @ -56,10 +59,9 @@ class PdoObject extends PDO { | |||||||
|         catch (\PDOException $e) { |         catch (\PDOException $e) { | ||||||
|             $this->rollback(); |             $this->rollback(); | ||||||
|              |              | ||||||
|             throw new \PdoException($e->getMessage() . " `$sql` with data:" . json_encode($parameters)); |             throw $e; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -44,17 +44,13 @@ abstract class Sql { | |||||||
|     { |     { | ||||||
|         switch(true) { |         switch(true) { | ||||||
|             case is_object($value): |             case is_object($value): | ||||||
|                 # @TODO Make sure the object is a Field
 |  | ||||||
|                 return (string) $value; |                 return (string) $value; | ||||||
|             break; |  | ||||||
| 
 | 
 | ||||||
|             case is_string($value): |             case is_string($value): | ||||||
|                 $value = "\"$value\"";
 |                 return "'$value'"; | ||||||
|             break; |  | ||||||
| 
 | 
 | ||||||
|             case is_null($value): |             case is_null($value): | ||||||
|                 $value = "NULL"; |                 return "NULL"; | ||||||
|             break; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return $value; |         return $value; | ||||||
|  | |||||||
| @ -95,8 +95,8 @@ trait EntityTrait { | |||||||
|                     $relationAlias = uniqid("relation_"); |                     $relationAlias = uniqid("relation_"); | ||||||
| 
 | 
 | ||||||
|                     $repository->select("{$repository->alias}.*") |                     $repository->select("{$repository->alias}.*") | ||||||
|                         ->join(Query\Join::TYPE_INNER, $bridgeEntity->tableName() . " $bridgeAlias", $relation->bridge::field($relationRelation->key, $bridgeAlias), $relationRelation->entity::field($relationRelation->foreignKey)) |                         ->join(Query\Join::TYPE_INNER, $bridgeEntity->tableName(), $relation->bridge::field($relationRelation->key, $bridgeAlias), $relationRelation->entity::field($relationRelation->foreignKey), $bridgeAlias) | ||||||
|                         ->join(Query\Join::TYPE_INNER, $this->resolveEntity()->tableName() . " $relationAlias", $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias)) |                         ->join(Query\Join::TYPE_INNER, $this->resolveEntity()->tableName(), $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias), $relationAlias) | ||||||
|                         ->where( static::field($bridgeRelation->foreignKey, $relationAlias), $this->{$bridgeRelation->foreignKey} ); |                         ->where( static::field($bridgeRelation->foreignKey, $relationAlias), $this->{$bridgeRelation->foreignKey} ); | ||||||
| 
 | 
 | ||||||
|                     $this->$name = call_user_func([ $repository, $relationRelation->function ]); |                     $this->$name = call_user_func([ $repository, $relationRelation->function ]); | ||||||
| @ -105,8 +105,8 @@ trait EntityTrait { | |||||||
|                         $repository = $relationRelation->entity::repository(); |                         $repository = $relationRelation->entity::repository(); | ||||||
|                          |                          | ||||||
|                         $repository->select("$bridgeAlias.*") |                         $repository->select("$bridgeAlias.*") | ||||||
|                             ->join(Query\Join::TYPE_INNER, $bridgeEntity->tableName() . " $bridgeAlias", $relation->bridge::field($relationRelation->key, $bridgeAlias), $relationRelation->entity::field($relationRelation->foreignKey)) |                             ->join(Query\Join::TYPE_INNER, $bridgeEntity->tableName(), $relation->bridge::field($relationRelation->key, $bridgeAlias), $relationRelation->entity::field($relationRelation->foreignKey), $bridgeAlias) | ||||||
|                             ->join(Query\Join::TYPE_INNER, $this->resolveEntity()->tableName() . " $relationAlias", $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias)) |                             ->join(Query\Join::TYPE_INNER, $this->resolveEntity()->tableName(), $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias), $relationAlias) | ||||||
|                             ->where( static::field($bridgeRelation->foreignKey, $relationAlias), $this->{$bridgeRelation->foreignKey} ); |                             ->where( static::field($bridgeRelation->foreignKey, $relationAlias), $this->{$bridgeRelation->foreignKey} ); | ||||||
| 
 | 
 | ||||||
|                         $bridgeName = $relation->bridgeField; |                         $bridgeName = $relation->bridgeField; | ||||||
|  | |||||||
| @ -25,6 +25,8 @@ class Join extends Fragment { | |||||||
|      |      | ||||||
|     public /*string|QueryBuilder*/ $table; |     public /*string|QueryBuilder*/ $table; | ||||||
|      |      | ||||||
|  |     public ? string $alias; | ||||||
|  |      | ||||||
|     public string $field; |     public string $field; | ||||||
|      |      | ||||||
|     public /*string|QueryBuilder*/ $value; |     public /*string|QueryBuilder*/ $value; | ||||||
| @ -45,6 +47,6 @@ class Join extends Fragment { | |||||||
|      |      | ||||||
|     public function render() : string |     public function render() : string | ||||||
|     { |     { | ||||||
|         return $this->renderSegments([ $this->side, static::SQL_TOKEN, $this->table, $this->attachment, $this->field, "=", $this->value ]); |         return $this->renderSegments([ $this->side, static::SQL_TOKEN, $this->table, $this->alias ?? "", $this->attachment, $this->field, "=", $this->value ]); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										37
									
								
								src/Query/MsSQL/Offset.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/Query/MsSQL/Offset.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace Ulmus\Query\MsSQL; | ||||||
|  | 
 | ||||||
|  | class Offset extends \Ulmus\Query\Fragment { | ||||||
|  |      | ||||||
|  |     const SQL_TOKEN = "OFFSET %s ROWS FETCH NEXT %s ROWS ONLY"; | ||||||
|  |      | ||||||
|  |     public int $order = 95; | ||||||
|  | 
 | ||||||
|  |     public int $offset; | ||||||
|  |      | ||||||
|  |     public int $limit; | ||||||
|  | 
 | ||||||
|  |     public function set(int $offset, int $limit) : self | ||||||
|  |     { | ||||||
|  |         $this->offset = $offset; | ||||||
|  |         $this->limit = $limit; | ||||||
|  |          | ||||||
|  |         return $this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function render() : string | ||||||
|  |     { | ||||||
|  |         if ( $this->offset < 0 ) { | ||||||
|  |             throw new \Exception("An error occured trying to render the OFFSET fragment ; given value has to be > 0. Received {$this->offset}"); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |          if ( $this->limit < 0 ) { | ||||||
|  |             throw new \Exception("An error occured trying to render the LIMIT fragment ; given value has to be > 0. Received {$this->limit}"); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         return $this->renderSegments([ | ||||||
|  |             sprintf(static::SQL_TOKEN, $this->offset, $this->limit) | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -8,9 +8,11 @@ class Offset extends Fragment { | |||||||
|      |      | ||||||
|     public int $order = 95; |     public int $order = 95; | ||||||
| 
 | 
 | ||||||
|     protected int $offset = 0; |     public int $offset = 0; | ||||||
|  |      | ||||||
|  |     public string $rows = ""; | ||||||
| 
 | 
 | ||||||
|     public function set($offset) : self |     public function set(int $offset) : self | ||||||
|     { |     { | ||||||
|         $this->offset = $offset; |         $this->offset = $offset; | ||||||
|          |          | ||||||
| @ -24,7 +26,7 @@ class Offset extends Fragment { | |||||||
|         } |         } | ||||||
|          |          | ||||||
|         return $this->renderSegments([ |         return $this->renderSegments([ | ||||||
|             static::SQL_TOKEN, $this->offset, |             static::SQL_TOKEN, $this->offset, $this->rows | ||||||
|         ]); |         ]); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -79,11 +79,11 @@ class QueryBuilder | |||||||
|     { |     { | ||||||
|         if ( ! $this->getFragment(Query\Update::class) ) { |         if ( ! $this->getFragment(Query\Update::class) ) { | ||||||
|             if ( $schema ) { |             if ( $schema ) { | ||||||
|                 $table = "\"$schema\".$table";
 |                 $table = "$schema.$table"; | ||||||
|             } |             } | ||||||
|              |              | ||||||
|             if ( $database ) { |             if ( $database ) { | ||||||
|                 $table = "\"$database\".$table";
 |                 $table = "$database.$table"; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             $update = new Query\Update(); |             $update = new Query\Update(); | ||||||
| @ -121,7 +121,7 @@ class QueryBuilder | |||||||
|     public function from(string $table, ? string $alias = null, ? string $database = null, ? string $schema = null) : self |     public function from(string $table, ? string $alias = null, ? string $database = null, ? string $schema = null) : self | ||||||
|     { |     { | ||||||
|         if ( $schema ) { |         if ( $schema ) { | ||||||
|             $table = "\"$schema\".$table";
 |             $table = "$schema.$table"; | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         if ( $database ) { |         if ( $database ) { | ||||||
| @ -252,14 +252,18 @@ class QueryBuilder | |||||||
|         return $this; |         return $this; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function join(string $type, /*string | QueryBuilder*/ $table, $field, $value, bool $outer = false) : self |     public function join(string $type, /*string | QueryBuilder*/ $table, $field, $value, bool $outer = false, ? string $alias = null) : self | ||||||
|     { |     { | ||||||
|         $join = new Query\Join($this); |         $join = new Query\Join($this); | ||||||
|  |          | ||||||
|         $this->push($join); |         $this->push($join); | ||||||
|  |          | ||||||
|         $join->set($type, $table, $field, $value); |         $join->set($type, $table, $field, $value); | ||||||
|          |          | ||||||
|         $join->outer = $outer; |         $join->outer = $outer; | ||||||
|          |          | ||||||
|  |         $join->alias = $alias; | ||||||
|  |          | ||||||
|         return $this; |         return $this; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -181,9 +181,16 @@ class Repository | |||||||
|         return $this; |         return $this; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function join(string $type, $table, $field, $value) : self |     public function join(string $type, $table, $field, $value, ? string $alias = null) : self | ||||||
|     { |     { | ||||||
|         $this->queryBuilder->join($type, $this->escapeTable($table), $field, $value); |         $this->queryBuilder->join($type, $this->escapeTable($table), $field, $value, false, $alias); | ||||||
|  |          | ||||||
|  |         return $this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function outerJoin(string $type, $table, $field, $value, ? string $alias = null) : self | ||||||
|  |     { | ||||||
|  |         $this->queryBuilder->join($type, $this->escapeTable($table), $field, $value, true, $alias); | ||||||
|          |          | ||||||
|         return $this; |         return $this; | ||||||
|     } |     } | ||||||
| @ -455,7 +462,6 @@ class Repository | |||||||
|         $searchRequest->count = $searchRequest->filter( clone $this ) |         $searchRequest->count = $searchRequest->filter( clone $this ) | ||||||
|             ->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND) |             ->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND) | ||||||
|             ->likes($searchRequest->likes(), Query\Where::CONDITION_OR) |             ->likes($searchRequest->likes(), Query\Where::CONDITION_OR) | ||||||
|             ->orders($searchRequest->orders()) |  | ||||||
|             ->groups($searchRequest->groups()) |             ->groups($searchRequest->groups()) | ||||||
|             ->count(); |             ->count(); | ||||||
|          |          | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user