- Still working on Update and Insert statements

This commit is contained in:
Dave M. 2020-02-05 23:41:57 -05:00
parent 828daffec8
commit 3dc82b1f0d
11 changed files with 243 additions and 62 deletions

View File

@ -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');
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -0,0 +1,5 @@
<?php
namespace Ulmus\Exception;
class EntityRequiredField extends \RuntimeException {}

View File

@ -31,6 +31,6 @@ class Insert extends Fragment {
protected function renderTable() : string
{
return $this->table . ( $this->alias ? " {$this->alias}" : "" );
return $this->table;
}
}

45
src/Query/Set.php Normal file
View File

@ -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);
}
}

35
src/Query/Update.php Normal file
View File

@ -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;
}
}

View File

@ -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)));
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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