- 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 { | ||||
| 
 | ||||
|     public function select(string $sql, array $parameters = []): PDOStatement { | ||||
|     public function select(string $sql, array $parameters = []): PDOStatement  | ||||
|     { | ||||
|         try { | ||||
|             if (false !== ( $statement = $this->prepare($sql) )) { | ||||
|                 $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 { | ||||
|             if (false !== ( $statement = $this->prepare($sql) )) { | ||||
|                 return $this->execute($statement, $parameters, true); | ||||
| @ -34,7 +36,8 @@ class PdoObject extends PDO { | ||||
|         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 { | ||||
|             if ( ! $this->inTransaction() ) { | ||||
|                 $this->beginTransaction(); | ||||
| @ -56,10 +59,9 @@ class PdoObject extends PDO { | ||||
|         catch (\PDOException $e) { | ||||
|             $this->rollback(); | ||||
|              | ||||
|             throw new \PdoException($e->getMessage() . " `$sql` with data:" . json_encode($parameters)); | ||||
|             throw $e; | ||||
|         } | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -44,17 +44,13 @@ abstract class Sql { | ||||
|     { | ||||
|         switch(true) { | ||||
|             case is_object($value): | ||||
|                 # @TODO Make sure the object is a Field
 | ||||
|                 return (string) $value; | ||||
|             break; | ||||
| 
 | ||||
|             case is_string($value): | ||||
|                 $value = "\"$value\"";
 | ||||
|             break; | ||||
|                 return "'$value'"; | ||||
| 
 | ||||
|             case is_null($value): | ||||
|                 $value = "NULL"; | ||||
|             break; | ||||
|                 return "NULL"; | ||||
|         } | ||||
| 
 | ||||
|         return $value; | ||||
|  | ||||
| @ -95,8 +95,8 @@ trait EntityTrait { | ||||
|                     $relationAlias = uniqid("relation_"); | ||||
| 
 | ||||
|                     $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, $this->resolveEntity()->tableName() . " $relationAlias", $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias)) | ||||
|                         ->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(), $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias), $relationAlias) | ||||
|                         ->where( static::field($bridgeRelation->foreignKey, $relationAlias), $this->{$bridgeRelation->foreignKey} ); | ||||
| 
 | ||||
|                     $this->$name = call_user_func([ $repository, $relationRelation->function ]); | ||||
| @ -105,8 +105,8 @@ trait EntityTrait { | ||||
|                         $repository = $relationRelation->entity::repository(); | ||||
|                          | ||||
|                         $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, $this->resolveEntity()->tableName() . " $relationAlias", $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias)) | ||||
|                             ->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(), $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias), $relationAlias) | ||||
|                             ->where( static::field($bridgeRelation->foreignKey, $relationAlias), $this->{$bridgeRelation->foreignKey} ); | ||||
| 
 | ||||
|                         $bridgeName = $relation->bridgeField; | ||||
|  | ||||
| @ -25,6 +25,8 @@ class Join extends Fragment { | ||||
|      | ||||
|     public /*string|QueryBuilder*/ $table; | ||||
|      | ||||
|     public ? string $alias; | ||||
|      | ||||
|     public string $field; | ||||
|      | ||||
|     public /*string|QueryBuilder*/ $value; | ||||
| @ -45,6 +47,6 @@ class Join extends Fragment { | ||||
|      | ||||
|     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; | ||||
| 
 | ||||
|     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; | ||||
|          | ||||
| @ -24,7 +26,7 @@ class Offset extends Fragment { | ||||
|         } | ||||
|          | ||||
|         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 ( $schema ) { | ||||
|                 $table = "\"$schema\".$table";
 | ||||
|                 $table = "$schema.$table"; | ||||
|             } | ||||
|              | ||||
|             if ( $database ) { | ||||
|                 $table = "\"$database\".$table";
 | ||||
|                 $table = "$database.$table"; | ||||
|             } | ||||
| 
 | ||||
|             $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 | ||||
|     { | ||||
|         if ( $schema ) { | ||||
|             $table = "\"$schema\".$table";
 | ||||
|             $table = "$schema.$table"; | ||||
|         } | ||||
|          | ||||
|         if ( $database ) { | ||||
| @ -252,14 +252,18 @@ class QueryBuilder | ||||
|         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); | ||||
|          | ||||
|         $this->push($join); | ||||
|          | ||||
|         $join->set($type, $table, $field, $value); | ||||
|          | ||||
|         $join->outer = $outer; | ||||
|          | ||||
|         $join->alias = $alias; | ||||
|          | ||||
|         return $this; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -181,9 +181,16 @@ class Repository | ||||
|         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; | ||||
|     } | ||||
| @ -455,7 +462,6 @@ class Repository | ||||
|         $searchRequest->count = $searchRequest->filter( clone $this ) | ||||
|             ->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND) | ||||
|             ->likes($searchRequest->likes(), Query\Where::CONDITION_OR) | ||||
|             ->orders($searchRequest->orders()) | ||||
|             ->groups($searchRequest->groups()) | ||||
|             ->count(); | ||||
|          | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user