- Some bugfixes were made, added a new diff before saving results. Also, a new method was added for insert, update and delete respectively for other drivers to override as needed
This commit is contained in:
parent
58afe841e7
commit
dc5e088551
|
@ -15,7 +15,9 @@ class Field implements \Ulmus\Annotation\Annotation {
|
|||
public array $attributes = [];
|
||||
|
||||
public bool $nullable;
|
||||
|
||||
|
||||
public bool $readonly = false;
|
||||
|
||||
public function __construct(? string $type = null, ? int $length = null)
|
||||
{
|
||||
if ( $type !== null ) {
|
||||
|
|
|
@ -125,18 +125,20 @@ class EntityResolver {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function searchFieldAnnotation(string $field, Annotation $annotationType) : ? Annotation
|
||||
public function searchFieldAnnotation(string $field, Annotation $annotationType, bool $caseSensitive = true) : ? Annotation
|
||||
{
|
||||
$found = $this->searchFieldAnnotationList($field, $annotationType);
|
||||
$found = $this->searchFieldAnnotationList($field, $annotationType, $caseSensitive);
|
||||
return $found ? $found[0] : null;
|
||||
}
|
||||
|
||||
public function searchFieldAnnotationList(string $field, Annotation $annotationType) : array
|
||||
public function searchFieldAnnotationList(string $field, Annotation $annotationType, bool $caseSensitive = true) : array
|
||||
{
|
||||
$list = [];
|
||||
|
||||
if ( null !== ( $this->properties[$field] ?? null ) ) {
|
||||
foreach($this->properties[$field]['tags'] ?? [] as $tag) {
|
||||
|
||||
$search = $caseSensitive ? $this->properties : array_change_key_case($this->properties, \CASE_LOWER);
|
||||
|
||||
if ( null !== ( $search[$field] ?? null ) ) {
|
||||
foreach($search[$field]['tags'] ?? [] as $tag) {
|
||||
if ( $tag['object'] instanceof $annotationType ) {
|
||||
$list[] = $tag['object'];
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class PdoObject extends PDO {
|
|||
public function runQuery(string $sql, array $parameters = []): ? PDOStatement
|
||||
{
|
||||
static::$dump && call_user_func_array(static::$dump, [ $sql, $parameters ]);
|
||||
|
||||
# \debogueur([ $sql, $parameters ]);
|
||||
try {
|
||||
if (false !== ( $statement = $this->prepare($sql) )) {
|
||||
return $this->execute($statement, $parameters, true);
|
||||
|
@ -42,6 +42,21 @@ class PdoObject extends PDO {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function runInsertQuery(array $filter, array $dataset)
|
||||
{
|
||||
return $this->runQuery($filter, $dataset);
|
||||
}
|
||||
|
||||
public function runUpdateQuery(array $filter, array $dataset)
|
||||
{
|
||||
return $this->runQuery($filter, $dataset);
|
||||
}
|
||||
|
||||
public function runDeleteQuery(string $sql, array $parameters = []): ? PDOStatement
|
||||
{
|
||||
return $this->runQuery($sql, $parameters);
|
||||
}
|
||||
|
||||
public function execute(PDOStatement $statement, array $parameters = [], bool $commit = true): ? PDOStatement
|
||||
{
|
||||
try {
|
||||
|
|
|
@ -62,19 +62,19 @@ trait EntityTrait {
|
|||
/**
|
||||
* @Ignore
|
||||
*/
|
||||
public function entityFillFromDataset(iterable $dataset) : self
|
||||
public function entityFillFromDataset(iterable $dataset, bool $overwriteDataset = false) : self
|
||||
{
|
||||
$loaded = $this->isLoaded();
|
||||
|
||||
|
||||
$entityResolver = $this->resolveEntity();
|
||||
|
||||
|
||||
foreach($dataset as $key => $value) {
|
||||
$field = $entityResolver->field(strtolower($key), EntityResolver::KEY_COLUMN_NAME, false) ?? null;
|
||||
|
||||
|
||||
if ( $field === null ) {
|
||||
$field = $entityResolver->field(strtolower($key), EntityResolver::KEY_LC_ENTITY_NAME, false);
|
||||
}
|
||||
|
||||
|
||||
if ( $field === null ) {
|
||||
if ($this->entityStrictFieldsDeclaration ) {
|
||||
throw new \Exception("Field `$key` can not be found within your entity ".static::class);
|
||||
|
@ -98,9 +98,9 @@ trait EntityTrait {
|
|||
|
||||
if ( $field['type'] === 'string' ) {
|
||||
$annotation = $entityResolver->searchFieldAnnotation($field['name'], new Field() );
|
||||
|
||||
|
||||
if ( $annotation->length ?? null ) {
|
||||
$value = substr($value, 0, $annotation->length);
|
||||
$value = mb_substr($value, 0, $annotation->length);
|
||||
}
|
||||
}
|
||||
elseif ( $field['type'] === 'bool' ) {
|
||||
|
@ -112,17 +112,20 @@ trait EntityTrait {
|
|||
elseif ( ! $field['builtin'] ) {
|
||||
$this->{$field['name']} = Ulmus::instanciateObject($field['type'], [ $value ]);
|
||||
}
|
||||
|
||||
|
||||
# Keeping original data to diff on UPDATE query
|
||||
if ( ! $loaded || $isLoadedDataset ) {
|
||||
if ( ! $loaded ) {
|
||||
#if ( $field !== null ) {
|
||||
# $annotation = $entityResolver->searchFieldAnnotation($field['name'], new Field() );
|
||||
# $this->entityLoadedDataset[$annotation ? $annotation->name : $field['name']] = $dataset; # <--------- THIS TO FIX !!!!!!
|
||||
#}
|
||||
$this->entityLoadedDataset = array_change_key_case($dataset, \CASE_LOWER);
|
||||
}
|
||||
elseif ($overwriteDataset) {
|
||||
$this->entityLoadedDataset = array_change_key_case($dataset, \CASE_LOWER) + $this->entityLoadedDataset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,11 @@ class Repository
|
|||
return $this->collectionFromQuery();
|
||||
}
|
||||
|
||||
public function loadAllFromField($field, $value) : EntityCollection
|
||||
{
|
||||
return $this->loadFromField($field, $value);
|
||||
}
|
||||
|
||||
public function loadFromField($field, $value) : EntityCollection
|
||||
{
|
||||
return $this->where($field, $value)->collectionFromQuery();
|
||||
|
@ -81,12 +86,12 @@ class Repository
|
|||
|
||||
public function deleteOne()
|
||||
{
|
||||
return $this->limit(1)->deleteSqlQuery()->runQuery();
|
||||
return $this->limit(1)->deleteSqlQuery()->runDeleteQuery();
|
||||
}
|
||||
|
||||
public function deleteAll()
|
||||
{
|
||||
return $this->deleteSqlQuery()->runQuery();
|
||||
return $this->deleteSqlQuery()->runDeleteQuery();
|
||||
}
|
||||
|
||||
public function deleteFromPk($value) : bool
|
||||
|
@ -140,7 +145,7 @@ class Repository
|
|||
$primaryKeyDefinition = Ulmus::resolveEntity($this->entityClass)->getPrimaryKeyField();
|
||||
|
||||
if ( ! $entity->isLoaded() ) {
|
||||
$statement = $this->insertSqlQuery($fieldsAndValue ?? $dataset, $replace)->runQuery();
|
||||
$statement = $this->insertSqlQuery($fieldsAndValue ?? $dataset, $replace)->runInsertQuery();
|
||||
|
||||
if ( ( 0 !== $statement->lastInsertId ) &&
|
||||
( null !== $primaryKeyDefinition )) {
|
||||
|
@ -156,16 +161,16 @@ class Repository
|
|||
throw new \Exception(sprintf("No primary key found for entity %s", $this->entityClass));
|
||||
}
|
||||
|
||||
$diff = $fieldsAndValue ?? $this->generateDatasetDiff($entity);
|
||||
$diff = $fieldsAndValue ?? $this->generateWritableDataset($entity);
|
||||
|
||||
if ( [] !== $diff ) {
|
||||
$pkField = key($primaryKeyDefinition);
|
||||
$pkFieldName = $primaryKeyDefinition[$pkField]->name ?? $pkField;
|
||||
$this->where($pkFieldName, $dataset[$pkFieldName]);
|
||||
|
||||
$update = $this->updateSqlQuery($diff)->runQuery();
|
||||
$update = $this->updateSqlQuery($diff)->runUpdateQuery();
|
||||
|
||||
$entity->entityFillFromDataset($dataset);
|
||||
$entity->entityFillFromDataset($dataset, true);
|
||||
|
||||
return $update ? (bool) $update->rowCount() : false;
|
||||
}
|
||||
|
@ -220,6 +225,22 @@ class Repository
|
|||
return array_diff_assoc($oldValues ? $dataset : $array , $oldValues ? $array : $dataset );
|
||||
}
|
||||
|
||||
|
||||
public function generateWritableDataset(object $entity, bool $oldValues = false) : array
|
||||
{
|
||||
$intersect = [];
|
||||
|
||||
$dataset = $this->generateDatasetDiff($entity, $oldValues);
|
||||
|
||||
foreach($dataset as $field => $value) {
|
||||
if ( false === ( $this->entityResolver->searchFieldAnnotation($field, new Field, false)->readonly ?? false ) ) {
|
||||
$intersect[$field] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return array_intersect_key($dataset, $intersect);
|
||||
}
|
||||
|
||||
public function yield() : \Generator
|
||||
{
|
||||
$class = $this->entityClass;
|
||||
|
@ -482,7 +503,7 @@ class Repository
|
|||
}
|
||||
|
||||
foreach($this->entityResolver->searchFieldAnnotationList($item, new Filter() ) as $filter) {
|
||||
call_user_func_array([ $this->entityClass, $filter->method ], [ $this, $item ]);
|
||||
call_user_func_array([ $this->entityClass, $filter->method ], [ $this, $item, true ]);
|
||||
}
|
||||
|
||||
$this->close();
|
||||
|
@ -508,7 +529,7 @@ class Repository
|
|||
}
|
||||
|
||||
foreach($this->entityResolver->searchFieldAnnotationList($item, new FilterJoin() ) as $filter) {
|
||||
call_user_func_array([ $this->entityClass, $filter->method ], [ $join, $item ]);
|
||||
call_user_func_array([ $this->entityClass, $filter->method ], [ $join, $item, true ]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -617,6 +638,27 @@ class Repository
|
|||
return Ulmus::runQuery($this->queryBuilder, $this->adapter);
|
||||
}
|
||||
|
||||
public function runInsertQuery() /* : mixed */
|
||||
{
|
||||
$this->finalizeQuery();
|
||||
|
||||
return Ulmus::runInsertQuery($this->queryBuilder, $this->adapter);
|
||||
}
|
||||
|
||||
public function runUpdateQuery() /* : mixed */
|
||||
{
|
||||
$this->finalizeQuery();
|
||||
|
||||
return Ulmus::runUpdateQuery($this->queryBuilder, $this->adapter);
|
||||
}
|
||||
|
||||
public function runDeleteQuery() /* : mixed */
|
||||
{
|
||||
$this->finalizeQuery();
|
||||
|
||||
return Ulmus::runDeleteQuery($this->queryBuilder, $this->adapter);
|
||||
}
|
||||
|
||||
public function resetQuery() : self
|
||||
{
|
||||
$this->queryBuilder->reset();
|
||||
|
|
|
@ -106,7 +106,7 @@ class RelationBuilder
|
|||
protected function applyFilter(Repository $repository, string $name) : Repository
|
||||
{
|
||||
foreach($this->filters ?? [] as $filter) {
|
||||
$repository = call_user_func_array([ $this->entity, $filter->method ], [ $repository, $name ]);
|
||||
$repository = call_user_func_array([ $this->entity, $filter->method ], [ $repository, $name, false ]);
|
||||
}
|
||||
|
||||
return $repository;
|
||||
|
@ -156,7 +156,7 @@ class RelationBuilder
|
|||
}
|
||||
|
||||
foreach($data ?: $this->entity->entityLoadedDataset as $key => $value) {
|
||||
if ( $key === sprintf(static::SUBQUERY_FIELD_SUFFIX, $name) ) {
|
||||
if ( $key === sprintf(static::SUBQUERY_FIELD_SUFFIX, strtolower($name)) ) {
|
||||
if ($value) {
|
||||
if ( null === ( $dataset = \json_decode($value, true) ) ) {
|
||||
throw new \Exception(sprintf("JSON error '%s' from '%s'", \json_last_error_msg(), $value));
|
||||
|
@ -168,7 +168,7 @@ class RelationBuilder
|
|||
return $entity::entityCollection();
|
||||
}
|
||||
}
|
||||
elseif ( substr($key, 0, $len ) === sprintf(static::JOIN_FIELD_SEPARATOR, $name) ) {
|
||||
elseif ( substr($key, 0, $len ) === sprintf(static::JOIN_FIELD_SEPARATOR, strtolower($name)) ) {
|
||||
$vars[substr($key, $len)] = $value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,24 @@ abstract class Ulmus
|
|||
return $return;
|
||||
}
|
||||
|
||||
public static function runInsertQuery(Query\QueryBuilderInterface $queryBuilder, ? ConnectionAdapter $adapter = null)
|
||||
{
|
||||
return static::runQuery($queryBuilder, $adapter);
|
||||
}
|
||||
|
||||
public static function runUpdateQuery(Query\QueryBuilderInterface $queryBuilder, ? ConnectionAdapter $adapter = null)
|
||||
{
|
||||
return static::runQuery($queryBuilder, $adapter);
|
||||
}
|
||||
|
||||
public static function runDeleteQuery(Query\QueryBuilderInterface $queryBuilder, ? ConnectionAdapter $adapter = null)
|
||||
{
|
||||
$return = static::connector($adapter)->runDeleteQuery($queryBuilder->render(), array_merge($queryBuilder->values ?? [], $queryBuilder->parameters ?? []));
|
||||
$queryBuilder->reset();
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function resolveEntity(string $entityClass) : Common\EntityResolver
|
||||
{
|
||||
return static::$resolved[$entityClass] ?? static::$resolved[$entityClass] = new Common\EntityResolver($entityClass);
|
||||
|
|
Loading…
Reference in New Issue