- Still working on Update and Insert statements
This commit is contained in:
parent
828daffec8
commit
3dc82b1f0d
|
@ -9,6 +9,7 @@ class Id extends \Ulmus\Annotation\Property\Field {
|
|||
$this->nullable = false;
|
||||
$this->attributes['unsigned'] = true;
|
||||
$this->attributes['primary_key'] = true;
|
||||
$this->attributes['auto_increment'] = true;
|
||||
|
||||
parent::__construct('int');
|
||||
}
|
||||
|
|
|
@ -2,56 +2,57 @@
|
|||
|
||||
namespace Ulmus\Common;
|
||||
|
||||
use PDO, PDOStatement;
|
||||
use PDO,
|
||||
PDOStatement;
|
||||
|
||||
class PdoObject extends PDO {
|
||||
|
||||
public function select(string $sql, array $parameters = []) : PDOStatement
|
||||
{
|
||||
# var_dump($sql, $parameters);
|
||||
# die();
|
||||
public function select(string $sql, array $parameters = []): PDOStatement {
|
||||
try {
|
||||
if ( false !== ( $statement = $this->prepare($sql) ) ) {
|
||||
if (false !== ( $statement = $this->prepare($sql) )) {
|
||||
$statement = $this->execute($statement, $parameters, false);
|
||||
$statement->setFetchMode(\PDO::FETCH_ASSOC);
|
||||
|
||||
|
||||
return $statement;
|
||||
}
|
||||
} catch (\PDOException $e) { throw $e; }
|
||||
} catch (\PDOException $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function runQuery(string $sql, array $parameters = []) : PDOStatement
|
||||
{
|
||||
public function runQuery(string $sql, array $parameters = []): PDOStatement {
|
||||
try {
|
||||
if ( false !== ( $statement = $this->prepare($sql) ) ) {
|
||||
if (false !== ( $statement = $this->prepare($sql) )) {
|
||||
return $this->execute($statement, $parameters, true);
|
||||
}
|
||||
} catch (\PDOException $e) { throw $e; }
|
||||
} catch (\PDOException $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function execute(PDOStatement $statement, array $parameters = [], bool $commit = true) : ? PDOStatement
|
||||
{
|
||||
try {
|
||||
if (! $this->inTransaction() ) {
|
||||
$this->beginTransaction();
|
||||
}
|
||||
|
||||
if ( empty($parameters) ? $statement->execute() : $statement->execute($parameters) ) {
|
||||
if ( $commit ) {
|
||||
$this->commit();
|
||||
|
||||
public function execute(PDOStatement $statement, array $parameters = [], bool $commit = true): ?PDOStatement {
|
||||
try {
|
||||
if (!$this->inTransaction()) {
|
||||
$this->beginTransaction();
|
||||
}
|
||||
|
||||
if (empty($parameters) ? $statement->execute() : $statement->execute($parameters)) {
|
||||
$statement->lastInsertId = $this->lastInsertId();
|
||||
|
||||
if ($commit) {
|
||||
$this->commit();
|
||||
}
|
||||
|
||||
return $statement;
|
||||
}
|
||||
else {
|
||||
throw new PDOException('Could not begin transaction or given statement is invalid.');
|
||||
}
|
||||
} catch (\PDOException $e) {
|
||||
$this->rollback();
|
||||
throw $e;
|
||||
}
|
||||
return $statement;
|
||||
} else {
|
||||
throw new PDOException('Could not begin transaction or given statement is invalid.');
|
||||
}
|
||||
} catch (\PDOException $e) {
|
||||
$this->rollback();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -121,11 +121,21 @@ trait EntityTrait {
|
|||
|
||||
public function entityGetDataset() : array
|
||||
{
|
||||
$fields = array_keys($this->resolveEntity()->fieldList());
|
||||
$dataset = [];
|
||||
$entityResolver = $this->resolveEntity();
|
||||
|
||||
foreach($entityResolver->fieldList() as $key => $field) {
|
||||
$annotation = $entityResolver->searchFieldAnnotation($key, new Field() );
|
||||
|
||||
return array_combine($fields, array_map(function(string $key) {
|
||||
return $this->$key;
|
||||
}, $fields));
|
||||
if ( isset($this->$key) ) {
|
||||
$dataset[ $annotation->name ?? $key ] = $this->$key;
|
||||
}
|
||||
elseif ( $field['nullable'] ) {
|
||||
$dataset[ $annotation->name ?? $key ] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $dataset;
|
||||
}
|
||||
|
||||
public function toArray() : array
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Ulmus\Exception;
|
||||
|
||||
class EntityRequiredField extends \RuntimeException {}
|
|
@ -31,6 +31,6 @@ class Insert extends Fragment {
|
|||
|
||||
protected function renderTable() : string
|
||||
{
|
||||
return $this->table . ( $this->alias ? " {$this->alias}" : "" );
|
||||
return $this->table;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Ulmus\Query;
|
||||
|
||||
use Ulmus\QueryBuilder;
|
||||
|
||||
class Set extends Fragment {
|
||||
|
||||
public int $order = 0;
|
||||
|
||||
public array $dataset;
|
||||
|
||||
public QueryBuilder $queryBuilder;
|
||||
|
||||
public function __construct(QueryBuilder $queryBuilder)
|
||||
{
|
||||
$this->queryBuilder = $queryBuilder;
|
||||
}
|
||||
|
||||
public function set(array $dataset) : self
|
||||
{
|
||||
$this->dataset = $dataset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() : string
|
||||
{
|
||||
return $this->renderSegments([
|
||||
'SET', $this->renderParameterPlaceholders(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function renderParameterPlaceholders() : string
|
||||
{
|
||||
$keys = [];
|
||||
|
||||
foreach($this->dataset as $key =>$value) {
|
||||
$this->queryBuilder->addParameter($value, ":v_$key");
|
||||
$keys[] = "$key=:v_$key";
|
||||
}
|
||||
|
||||
return implode(",", $keys);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Ulmus\Query;
|
||||
|
||||
class Update extends Fragment {
|
||||
|
||||
public int $order = -100;
|
||||
|
||||
public bool $quick = false;
|
||||
|
||||
public bool $ignore = false;
|
||||
|
||||
public array $fieldlist = [];
|
||||
|
||||
public string $priority;
|
||||
|
||||
public string $table;
|
||||
|
||||
public ? string $alias = null;
|
||||
|
||||
public function render() : string
|
||||
{
|
||||
return $this->renderSegments([
|
||||
'UPDATE',
|
||||
( $this->priority ?? false ),
|
||||
( $this->ignore ? 'IGNORE' : false ),
|
||||
$this->table,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function renderTable() : string
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
}
|
|
@ -2,10 +2,14 @@
|
|||
|
||||
namespace Ulmus\Query;
|
||||
|
||||
use Ulmus\QueryBuilder;
|
||||
|
||||
class Values extends Fragment {
|
||||
|
||||
public int $order = 0;
|
||||
|
||||
public ? int $fieldCount = null;
|
||||
|
||||
public array $rows;
|
||||
|
||||
public QueryBuilder $queryBuilder;
|
||||
|
@ -17,36 +21,38 @@ class Values extends Fragment {
|
|||
|
||||
public function add(array $row) : self
|
||||
{
|
||||
$this->rows[] = $row;
|
||||
if ($this->fieldCount === null) {
|
||||
$this->fieldCount = count($row);
|
||||
}
|
||||
|
||||
$this->rows[] = array_values($row);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() : string
|
||||
{
|
||||
$this->queryBuilder->addParameter($this->flattenRowsArray());
|
||||
$this->queryBuilder->addValues($this->flattenRowsArray());
|
||||
|
||||
return $this->renderSegments([
|
||||
'VALUES', '(' . $this->renderParameterPlaceholders() . ')',
|
||||
'VALUES', $this->renderParameterPlaceholders(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function renderParameterPlaceholders() : string
|
||||
{
|
||||
$return = [];
|
||||
$count = null;
|
||||
|
||||
foreach($this->rows as $row) {
|
||||
if ($count === null) {
|
||||
$count = count($row);
|
||||
if ($this->fieldCount === null) {
|
||||
}
|
||||
else {
|
||||
if (count($row) !== $count) {
|
||||
if (count($row) !== $this->fieldCount) {
|
||||
throw new \Exception("Insert statement must contains the same number of values for each rows.");
|
||||
}
|
||||
}
|
||||
|
||||
$return[] = implode(',', array_fill(0, $this->parameterCount, '?'));
|
||||
$return[] = implode(',', array_fill(0, $this->fieldCount, '?'));
|
||||
}
|
||||
|
||||
return "(" . implode('),(', $return) . ")";
|
||||
|
@ -54,6 +60,6 @@ class Values extends Fragment {
|
|||
|
||||
public function flattenRowsArray() : array
|
||||
{
|
||||
return iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($this->rows)));
|
||||
return \iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator($this->rows)));
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@ class QueryBuilder
|
|||
$insert = new Query\Insert();
|
||||
$this->push($insert);
|
||||
|
||||
$insert->fieldist = $fieldlist;
|
||||
$insert->fieldlist = $fieldlist;
|
||||
$insert->alias = $alias;
|
||||
$insert->table = $table;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ class QueryBuilder
|
|||
{
|
||||
|
||||
if ( false === ( $values = $this->has(Query\Values::class) ) ) {
|
||||
$values = new Query\Values();
|
||||
$values = new Query\Values($this);
|
||||
$this->push($values);
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,40 @@ class QueryBuilder
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function update(string $table, ? string $alias = null, ? string $database = null, ? string $schema = null) : self
|
||||
{
|
||||
if ( ! $this->has(Query\Update::class) ) {
|
||||
if ( $database ) {
|
||||
$table = "\"$database\".$table";
|
||||
}
|
||||
|
||||
if ( $schema ) {
|
||||
$table = "\"$schema\".$table";
|
||||
}
|
||||
|
||||
$update = new Query\Update();
|
||||
$this->push($update);
|
||||
|
||||
$update->alias = $alias;
|
||||
$update->table = $table;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function set(array $dataset) : self
|
||||
{
|
||||
|
||||
if ( false === ( $values = $this->has(Query\Set::class) ) ) {
|
||||
$set = new Query\Set($this);
|
||||
$this->push($set);
|
||||
}
|
||||
|
||||
$set->set($dataset);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function delete() : self
|
||||
{
|
||||
if ( ! $this->has(Query\Delete::class) ) {
|
||||
|
@ -180,12 +214,14 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
$orderBy->add($field, $direction);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function push(Query\Fragment $queryFragment) : self
|
||||
{
|
||||
$this->queryStack[] = $queryFragment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -226,10 +262,12 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
$this->parameters[$key] = $value;
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
public function addValues(array $values) {
|
||||
public function addValues(array $values) : void
|
||||
{
|
||||
$this->values = $values;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,19 +68,35 @@ class Repository
|
|||
}
|
||||
|
||||
public function deleteFromPk($value, $primaryKey = "id")
|
||||
{
|
||||
{
|
||||
return $this->where($primaryKey, $value)->deleteOne();
|
||||
}
|
||||
|
||||
public function save(object $entity) : bool
|
||||
{
|
||||
{
|
||||
$dataset = $entity->toArray();
|
||||
|
||||
$primaryKeyDefinition = Ulmus::resolveEntity($this->entityClass)->getPrimaryKeyField();
|
||||
|
||||
if ( ! $entity->isLoaded() ) {
|
||||
$save = $this->insertSqlQuery($dataset)->runQuery();
|
||||
$statement = $this->insertSqlQuery($dataset)->runQuery();
|
||||
|
||||
if ( ( 0 !== $statement->lastInsertId ) &&
|
||||
( null !== $primaryKeyDefinition )) {
|
||||
$pkField = key($primaryKeyDefinition);
|
||||
$entity->$pkField = $statement->lastInsertId;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$save = $this->updateSqlQuery($dataset)->runQuery();
|
||||
if ($primaryKeyDefinition === null) {
|
||||
throw new \Exception(sprintf("No primary key found for entity %s", $this->entityClass));
|
||||
}
|
||||
|
||||
$pkField = key($primaryKeyDefinition);
|
||||
$pkFieldName = $primaryKeyDefinition[$pkField]->name ?? $pkField;
|
||||
$this->where($pkFieldName, $dataset[$pkFieldName]);
|
||||
|
||||
# DATASET MUST BE DIFF OF MODIF ONLY !
|
||||
$update = $this->updateSqlQuery($dataset)->runQuery();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -119,6 +135,20 @@ class Repository
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function update(array $fieldlist, string $table, string $alias, ? string $schema) : self
|
||||
{
|
||||
$this->queryBuilder->update($table, $alias, $schema);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function set(array $dataset) : self
|
||||
{
|
||||
$this->queryBuilder->set($dataset);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function delete() : self
|
||||
{
|
||||
$this->queryBuilder->delete($this->alias);
|
||||
|
@ -176,7 +206,7 @@ class Repository
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function notWhere(array $condition) : self
|
||||
public function notWhere($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : self
|
||||
{
|
||||
$this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_AND, true);
|
||||
|
||||
|
@ -269,18 +299,21 @@ class Repository
|
|||
public function orderBy(string $field, ? string $direction = null) : self
|
||||
{
|
||||
$this->queryBuilder->orderBy($field, $direction);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function limit(int $value) : self
|
||||
{
|
||||
$this->queryBuilder->limit($value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function offset(int $value) : self
|
||||
{
|
||||
$this->queryBuilder->offset($value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -314,7 +347,7 @@ class Repository
|
|||
return $entityCollection;
|
||||
}
|
||||
|
||||
public function runQuery()
|
||||
public function runQuery() : \PDOStatement
|
||||
{
|
||||
return Ulmus::runQuery($this->queryBuilder);
|
||||
}
|
||||
|
@ -322,10 +355,10 @@ class Repository
|
|||
protected function insertSqlQuery(array $dataset) : self
|
||||
{
|
||||
if ( ! $this->queryBuilder->has(Query\Insert::class) ) {
|
||||
$this->insert(array_keys($dataset));
|
||||
$this->insert(array_keys($dataset), $this->entityResolver->tableName(), $this->alias, $this->entityResolver->schemaName());
|
||||
}
|
||||
|
||||
$this->values(count($dataset));
|
||||
$this->values($dataset);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -333,8 +366,10 @@ class Repository
|
|||
protected function updateSqlQuery(array $dataset) : self
|
||||
{
|
||||
if ( ! $this->queryBuilder->has(Query\Update::class) ) {
|
||||
# $this->insert();
|
||||
$this->update($dataset, $this->entityResolver->tableName(), $this->alias, $this->entityResolver->schemaName());
|
||||
}
|
||||
|
||||
$this->set($dataset);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
|
@ -32,9 +32,14 @@ abstract class Ulmus
|
|||
];
|
||||
}
|
||||
|
||||
public static function pdo(?ConnectionAdapter $adapter = null) : Common\PdoObject
|
||||
{
|
||||
return ( $adapter ?: static::$defaultAdapter )->pdo;
|
||||
}
|
||||
|
||||
public static function runQuery(QueryBuilder $queryBuilder, ?ConnectionAdapter $adapter = null)
|
||||
{
|
||||
return ( $adapter ?: static::$defaultAdapter )->pdo->runQuery($queryBuilder->render(), $queryBuilder->parameters ?? []);
|
||||
return static::pdo($adapter)->runQuery($queryBuilder->render(), array_merge($queryBuilder->values ?? [], $queryBuilder->parameters ?? []));
|
||||
}
|
||||
|
||||
public static function resolveEntity(string $entityClass) : Common\EntityResolver
|
||||
|
|
Loading…
Reference in New Issue