Compare commits
No commits in common. "8fff21ecb033bd4ba7177abbf5edd60d860c5043" and "761e0401b060e87c126a4fdd780a9afbb7dbff31" have entirely different histories.
8fff21ecb0
...
761e0401b0
src
Adapter
DefaultAdapterTrait.phpMsSQL.phpMsSQLFieldMapper.phpMySQL.phpMySQLFieldMapper.phpSQLite.phpSqlAdapterTrait.phpSqlFieldMapper.php
Attribute
Common
Entity
Migration
Query
Repository.phpRepository
@ -4,7 +4,7 @@ namespace Ulmus\Adapter;
|
|||||||
|
|
||||||
use Ulmus\{ConnectionAdapter, Entity\InformationSchema\Table, Migration\FieldDefinition, Repository, QueryBuilder\Sql\MysqlQueryBuilder, Entity};
|
use Ulmus\{ConnectionAdapter, Entity\InformationSchema\Table, Migration\FieldDefinition, Repository, QueryBuilder\Sql\MysqlQueryBuilder, Entity};
|
||||||
|
|
||||||
UNUSED? trait DefaultAdapterTrait
|
trait DefaultAdapterTrait
|
||||||
{
|
{
|
||||||
public function repositoryClass() : string
|
public function repositoryClass() : string
|
||||||
{
|
{
|
||||||
|
@ -9,14 +9,10 @@ use Ulmus\Exception\AdapterConfigurationException;
|
|||||||
use Ulmus\Ulmus;
|
use Ulmus\Ulmus;
|
||||||
|
|
||||||
use Ulmus\Migration\FieldDefinition;
|
use Ulmus\Migration\FieldDefinition;
|
||||||
use Ulmus\{Entity\InformationSchema\Table,
|
use Ulmus\{Entity\InformationSchema\Table, Migration\MigrateInterface, Repository, QueryBuilder};
|
||||||
Migration\MigrateInterface,
|
|
||||||
Migration\SqlMigrationTrait,
|
|
||||||
Repository,
|
|
||||||
QueryBuilder};
|
|
||||||
|
|
||||||
class MsSQL implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
class MsSQL implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
||||||
use SqlAdapterTrait, SqlMigrationTrait;
|
use SqlAdapterTrait;
|
||||||
|
|
||||||
const ALLOWED_ATTRIBUTES = [
|
const ALLOWED_ATTRIBUTES = [
|
||||||
'default', 'primary_key', 'auto_increment',
|
'default', 'primary_key', 'auto_increment',
|
||||||
@ -210,13 +206,6 @@ class MsSQL implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function mapFieldType(FieldDefinition $field, bool $typeOnly = false) : string
|
|
||||||
{
|
|
||||||
$mapper = new MsSQLFieldMapper($field);
|
|
||||||
|
|
||||||
return $typeOnly ? $mapper->type : $mapper->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function escapeIdentifier(string $segment, int $type) : string
|
public static function escapeIdentifier(string $segment, int $type) : string
|
||||||
{
|
{
|
||||||
switch($type) {
|
switch($type) {
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Adapter;
|
|
||||||
|
|
||||||
use Ulmus\Migration\FieldDefinition;
|
|
||||||
|
|
||||||
class MsSQLFieldMapper extends SqlFieldMapper
|
|
||||||
{
|
|
||||||
public function map() : void
|
|
||||||
{
|
|
||||||
parent::map();
|
|
||||||
|
|
||||||
if (in_array($this->type, [ 'CHAR', 'VARCHAR', 'TEXT', ])) {
|
|
||||||
$this->type = "N" . $this->type;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @TODO !
|
|
||||||
public function postProcess() : void
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
in_array($this->type, [ 'BLOB', 'TINYBLOB', 'MEDIUMBLOB', 'LONGBLOB', 'JSON', 'TEXT', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT', 'GEOMETRY' ]) &&
|
|
||||||
! is_object($this->field->default ?? false) # Could be a functional default, which would now be valid
|
|
||||||
) {
|
|
||||||
unset($this->field->default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
* */
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ use Ulmus\ConnectionAdapter;
|
|||||||
use Ulmus\Entity\Mysql\Table;
|
use Ulmus\Entity\Mysql\Table;
|
||||||
use Ulmus\Migration\FieldDefinition;
|
use Ulmus\Migration\FieldDefinition;
|
||||||
use Ulmus\Migration\MigrateInterface;
|
use Ulmus\Migration\MigrateInterface;
|
||||||
use Ulmus\Migration\SqlMigrationTrait;
|
|
||||||
use Ulmus\QueryBuilder\Sql;
|
use Ulmus\QueryBuilder\Sql;
|
||||||
use Ulmus\Common\PdoObject;
|
use Ulmus\Common\PdoObject;
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ use Ulmus\Exception\AdapterConfigurationException;
|
|||||||
use Ulmus\Repository;
|
use Ulmus\Repository;
|
||||||
|
|
||||||
class MySQL implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
class MySQL implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
||||||
use SqlAdapterTrait, SqlMigrationTrait;
|
use SqlAdapterTrait;
|
||||||
|
|
||||||
const ALLOWED_ATTRIBUTES = [
|
const ALLOWED_ATTRIBUTES = [
|
||||||
'default', 'primary_key', 'auto_increment', 'update',
|
'default', 'primary_key', 'auto_increment', 'update',
|
||||||
|
@ -6,6 +6,10 @@ use Ulmus\Migration\FieldDefinition;
|
|||||||
|
|
||||||
class MySQLFieldMapper extends SqlFieldMapper
|
class MySQLFieldMapper extends SqlFieldMapper
|
||||||
{
|
{
|
||||||
|
public readonly string $type;
|
||||||
|
|
||||||
|
public readonly string $length;
|
||||||
|
|
||||||
public function map() : void
|
public function map() : void
|
||||||
{
|
{
|
||||||
$type = $this->field->type;
|
$type = $this->field->type;
|
||||||
|
@ -7,10 +7,10 @@ use Ulmus\Common\PdoObject;
|
|||||||
use Ulmus\ConnectionAdapter;
|
use Ulmus\ConnectionAdapter;
|
||||||
use Ulmus\Entity;
|
use Ulmus\Entity;
|
||||||
use Ulmus\Migration\FieldDefinition;
|
use Ulmus\Migration\FieldDefinition;
|
||||||
use Ulmus\{Migration\MigrateInterface, Migration\SqlMigrationTrait, Repository, QueryBuilder};
|
use Ulmus\{Migration\MigrateInterface, Repository, QueryBuilder};
|
||||||
|
|
||||||
class SQLite implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
class SQLite implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
||||||
use SqlAdapterTrait, SqlMigrationTrait;
|
use SqlAdapterTrait;
|
||||||
|
|
||||||
const ALLOWED_ATTRIBUTES = [
|
const ALLOWED_ATTRIBUTES = [
|
||||||
'default', 'primary_key', 'auto_increment', 'collate nocase', 'collate binary', 'collate rtrim',
|
'default', 'primary_key', 'auto_increment', 'collate nocase', 'collate binary', 'collate rtrim',
|
||||||
|
@ -36,11 +36,44 @@ trait SqlAdapterTrait
|
|||||||
return $this->database;
|
return $this->database;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function schemaTable(ConnectionAdapter $adapter, $databaseName, string $tableName) : null|object
|
||||||
|
{
|
||||||
|
return Table::repository(Repository::DEFAULT_ALIAS, $adapter)
|
||||||
|
->select(\Ulmus\Common\Sql::raw('this.*'))
|
||||||
|
->where($this->escapeIdentifier('table_schema', AdapterInterface::IDENTIFIER_FIELD), $databaseName)
|
||||||
|
->loadOneFromField($this->escapeIdentifier('table_name', AdapterInterface::IDENTIFIER_FIELD), $tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mapFieldType(FieldDefinition $field, bool $typeOnly = false) : string
|
||||||
|
{
|
||||||
|
$mapper = new SqlFieldMapper($field);
|
||||||
|
|
||||||
|
return $typeOnly ? $mapper->type : $mapper->render();
|
||||||
|
}
|
||||||
|
|
||||||
public function whitelistAttributes(array &$parameters) : void
|
public function whitelistAttributes(array &$parameters) : void
|
||||||
{
|
{
|
||||||
$parameters = array_intersect_key($parameters, array_flip(static::ALLOWED_ATTRIBUTES));
|
$parameters = array_intersect_key($parameters, array_flip(static::ALLOWED_ATTRIBUTES));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function generateAlterColumn(FieldDefinition $definition, array $field) : string|\Stringable
|
||||||
|
{
|
||||||
|
if (! empty($field['previous']) ) {
|
||||||
|
$position = sprintf('AFTER %s', $this->escapeIdentifier($field['previous']->field, AdapterInterface::IDENTIFIER_FIELD));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$position = "FIRST";
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(" ", [
|
||||||
|
strtoupper($field['action']),
|
||||||
|
$this->escapeIdentifier($definition->getSqlName(), AdapterInterface::IDENTIFIER_FIELD),
|
||||||
|
$definition->getSqlType(),
|
||||||
|
$definition->getSqlParams(),
|
||||||
|
$position,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function writableValue(mixed $value) : mixed
|
public function writableValue(mixed $value) : mixed
|
||||||
{
|
{
|
||||||
switch (true) {
|
switch (true) {
|
||||||
@ -59,4 +92,9 @@ trait SqlAdapterTrait
|
|||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function splitAlterQuery() : bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,9 @@ use Ulmus\Entity;
|
|||||||
|
|
||||||
class SqlFieldMapper
|
class SqlFieldMapper
|
||||||
{
|
{
|
||||||
public string $type;
|
public readonly string $type;
|
||||||
|
|
||||||
public string $length;
|
public readonly string $length;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public FieldDefinition $field,
|
public FieldDefinition $field,
|
||||||
|
@ -10,12 +10,6 @@ class Attribute
|
|||||||
public static function handleArrayField(null|\Stringable|string|array $field, null|string|bool $alias = Repository::DEFAULT_ALIAS, string $separator = ', ') : mixed
|
public static function handleArrayField(null|\Stringable|string|array $field, null|string|bool $alias = Repository::DEFAULT_ALIAS, string $separator = ', ') : mixed
|
||||||
{
|
{
|
||||||
if ( is_array($field) ) {
|
if ( is_array($field) ) {
|
||||||
if (count($field) < 2) {
|
|
||||||
throw new \RuntimeException(
|
|
||||||
sprintf("Array field must be formed of at least two things, a class name, and a property. (received %s)", json_encode($field))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$class = array_shift($field);
|
$class = array_shift($field);
|
||||||
$field[1] ??= $alias;
|
$field[1] ??= $alias;
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ class Virtual extends Field implements ResettablePropertyInterface {
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
public null|string|array $method = null,
|
public null|string|array $method = null,
|
||||||
public ? \Closure $closure = null,
|
public ? \Closure $closure = null,
|
||||||
public null|string $name = null,
|
|
||||||
) {
|
) {
|
||||||
$this->method ??= [ static::class, 'noop' ];
|
$this->method ??= [ static::class, 'noop' ];
|
||||||
}
|
}
|
||||||
|
@ -115,11 +115,6 @@ class EntityResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPropertyEntityType(string $name) : false|string
|
|
||||||
{
|
|
||||||
return $this->reflectedClass->getProperties(true)[$name]->getTypes()[0]->type ?? false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function searchFieldAnnotation(string $field, array|object|string $annotationType, bool $caseSensitive = true) : ? object
|
public function searchFieldAnnotation(string $field, array|object|string $annotationType, bool $caseSensitive = true) : ? object
|
||||||
{
|
{
|
||||||
return $this->searchFieldAnnotationList($field, $annotationType, $caseSensitive)[0] ?? null;
|
return $this->searchFieldAnnotationList($field, $annotationType, $caseSensitive)[0] ?? null;
|
||||||
|
@ -56,10 +56,7 @@ class DatasetHandler
|
|||||||
}
|
}
|
||||||
elseif ( $field->expectType('array') ) {
|
elseif ( $field->expectType('array') ) {
|
||||||
if ( is_string($value)) {
|
if ( is_string($value)) {
|
||||||
if (empty($value)) {
|
if (substr($value, 0, 1) === "a") {
|
||||||
yield $field->name => [];
|
|
||||||
}
|
|
||||||
elseif (substr($value, 0, 1) === "a") {
|
|
||||||
|
|
||||||
yield $field->name => unserialize($value);
|
yield $field->name => unserialize($value);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@ class Column
|
|||||||
{
|
{
|
||||||
use \Ulmus\EntityTrait;
|
use \Ulmus\EntityTrait;
|
||||||
|
|
||||||
|
#[Field\Id]
|
||||||
|
public ? id $srs_id;
|
||||||
|
|
||||||
#[Field(name: "TABLE_CATALOG", length: 512)]
|
#[Field(name: "TABLE_CATALOG", length: 512)]
|
||||||
public string $tableCatalog;
|
public string $tableCatalog;
|
||||||
|
|
||||||
@ -61,10 +64,24 @@ class Column
|
|||||||
# #[Field(name: "COLLATION_TYPE", type: "longtext")]
|
# #[Field(name: "COLLATION_TYPE", type: "longtext")]
|
||||||
# public string $type;
|
# public string $type;
|
||||||
|
|
||||||
|
#[Field(name: "COLUMN_KEY", length: 3)]
|
||||||
|
public string $key;
|
||||||
|
|
||||||
|
#[Field(name: "EXTRA", length: 30)]
|
||||||
|
public string $extra;
|
||||||
|
|
||||||
|
#[Field(name: "PRIVILEGES", length: 80)]
|
||||||
|
public string $privileges;
|
||||||
|
|
||||||
|
#[Field(name: "COLUMN_COMMENT", length: 1024)]
|
||||||
|
public string $comment;
|
||||||
|
|
||||||
# #[Field(name: "IS_GENERATED", length: 6)]
|
# #[Field(name: "IS_GENERATED", length: 6)]
|
||||||
# public string $generated;
|
# public string $generated;
|
||||||
|
|
||||||
|
#[Field(name: "GENERATION_EXPRESSION", type: "longtext")]
|
||||||
|
public ? string $generationExpression;
|
||||||
|
|
||||||
public function matchFieldDefinition(ReflectedProperty $definition) : bool
|
public function matchFieldDefinition(ReflectedProperty $definition) : bool
|
||||||
{
|
{
|
||||||
$nullable = $this->nullable === 'YES';
|
$nullable = $this->nullable === 'YES';
|
||||||
|
@ -2,28 +2,8 @@
|
|||||||
|
|
||||||
namespace Ulmus\Entity\Mysql;
|
namespace Ulmus\Entity\Mysql;
|
||||||
|
|
||||||
use Ulmus\Attribute\Property\Field;
|
|
||||||
|
|
||||||
class Column extends \Ulmus\Entity\InformationSchema\Column
|
class Column extends \Ulmus\Entity\InformationSchema\Column
|
||||||
{
|
{
|
||||||
#[Field\Id]
|
|
||||||
public ? id $srs_id;
|
|
||||||
|
|
||||||
#[Field(name: "COLUMN_KEY", length: 3)]
|
|
||||||
public string $key;
|
|
||||||
|
|
||||||
#[Field(name: "EXTRA", length: 30)]
|
|
||||||
public string $extra;
|
|
||||||
|
|
||||||
#[Field(name: "PRIVILEGES", length: 80)]
|
|
||||||
public string $privileges;
|
|
||||||
|
|
||||||
#[Field(name: "COLUMN_COMMENT", length: 1024)]
|
|
||||||
public string $comment;
|
|
||||||
|
|
||||||
#[Field(name: "GENERATION_EXPRESSION", type: "longtext")]
|
|
||||||
public ? string $generationExpression;
|
|
||||||
|
|
||||||
# TODO ! Handle FUNCTIONAL default value
|
# TODO ! Handle FUNCTIONAL default value
|
||||||
protected function canHaveDefaultValue(): bool
|
protected function canHaveDefaultValue(): bool
|
||||||
{
|
{
|
||||||
@ -32,5 +12,4 @@ class Column extends \Ulmus\Entity\InformationSchema\Column
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,57 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Migration;
|
|
||||||
|
|
||||||
use Ulmus\Adapter\AdapterInterface;
|
|
||||||
use Ulmus\Adapter\SqlFieldMapper;
|
|
||||||
use Ulmus\ConnectionAdapter;
|
|
||||||
use Ulmus\Entity\Mysql\Table;
|
|
||||||
use Ulmus\Repository;
|
|
||||||
|
|
||||||
trait SqlMigrationTrait
|
|
||||||
{
|
|
||||||
protected array $QUERY_REPLACE = [
|
|
||||||
'change' => "alter",
|
|
||||||
];
|
|
||||||
|
|
||||||
public function schemaTable(ConnectionAdapter $adapter, $databaseName, string $tableName) : null|object
|
|
||||||
{
|
|
||||||
return \Ulmus\Entity\InformationSchema\Table::repository(Repository::DEFAULT_ALIAS, $adapter)
|
|
||||||
->select(\Ulmus\Common\Sql::raw('this.*'))
|
|
||||||
->where($this->escapeIdentifier('table_schema', AdapterInterface::IDENTIFIER_FIELD), $databaseName)
|
|
||||||
->or($this->escapeIdentifier('table_catalog', AdapterInterface::IDENTIFIER_FIELD), $databaseName)
|
|
||||||
->loadOneFromField($this->escapeIdentifier('table_name', AdapterInterface::IDENTIFIER_FIELD), $tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function mapFieldType(FieldDefinition $field, bool $typeOnly = false) : string
|
|
||||||
{
|
|
||||||
$mapper = new SqlFieldMapper($field);
|
|
||||||
|
|
||||||
return $typeOnly ? $mapper->type : $mapper->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function generateAlterColumn(FieldDefinition $definition, array $field) : string|\Stringable
|
|
||||||
{
|
|
||||||
if ($field['action'] === 'add') {
|
|
||||||
if (! empty($field['previous'])) {
|
|
||||||
$position = sprintf('AFTER %s', $this->escapeIdentifier($field['previous']->field, AdapterInterface::IDENTIFIER_FIELD));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$position = "FIRST";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return implode(" ", array_filter([
|
|
||||||
strtoupper($field['action']),
|
|
||||||
$this->escapeIdentifier($definition->getSqlName(), AdapterInterface::IDENTIFIER_FIELD),
|
|
||||||
$definition->getSqlType(),
|
|
||||||
$definition->getSqlParams(),
|
|
||||||
$position ?? null,
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function splitAlterQuery() : bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,8 +12,6 @@ class Select extends Fragment {
|
|||||||
|
|
||||||
public bool $union = false;
|
public bool $union = false;
|
||||||
|
|
||||||
public bool $isInternalSelect = false;
|
|
||||||
|
|
||||||
public ? int $top = null;
|
public ? int $top = null;
|
||||||
|
|
||||||
protected array $fields = [];
|
protected array $fields = [];
|
||||||
|
@ -416,8 +416,7 @@ class Repository implements RepositoryInterface
|
|||||||
|
|
||||||
public function withJoin(string|array $fields, array $options = []) : self
|
public function withJoin(string|array $fields, array $options = []) : self
|
||||||
{
|
{
|
||||||
$selectObj = $this->queryBuilder->getFragment(Query\Select::class);
|
$canSelect = null === $this->queryBuilder->getFragment(Query\Select::class);
|
||||||
$canSelect = empty($selectObj) || $selectObj->isInternalSelect === true;
|
|
||||||
|
|
||||||
if ( $canSelect ) {
|
if ( $canSelect ) {
|
||||||
$select = $this->entityResolver->fieldList(EntityResolver::KEY_COLUMN_NAME, true);
|
$select = $this->entityResolver->fieldList(EntityResolver::KEY_COLUMN_NAME, true);
|
||||||
@ -425,13 +424,18 @@ class Repository implements RepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
# @TODO Apply FILTER annotation to this too !
|
# @TODO Apply FILTER annotation to this too !
|
||||||
foreach(array_filter((array) $fields, fn($e) => ! isset($this->joined[$e])) as $item) {
|
foreach(array_filter((array) $fields) as $item) {
|
||||||
|
if ( isset($this->joined[$item]) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
$this->joined[$item] = true;
|
$this->joined[$item] = true;
|
||||||
|
}
|
||||||
|
|
||||||
$attribute = $this->entityResolver->searchFieldAnnotation($item, [ Join::class ]) ?:
|
$attribute = $this->entityResolver->searchFieldAnnotation($item, [ Join::class ]) ?:
|
||||||
$this->entityResolver->searchFieldAnnotation($item, [ Relation::class ]);
|
$this->entityResolver->searchFieldAnnotation($item, [ Relation::class ]);
|
||||||
|
|
||||||
$isRelation = $attribute instanceof Relation;
|
$isRelation = ( $attribute instanceof Relation ) || ($attribute instanceof Relation);
|
||||||
|
|
||||||
if ($isRelation && ( $attribute->isManyToMany() )) {
|
if ($isRelation && ( $attribute->isManyToMany() )) {
|
||||||
throw new \Exception("Many-to-many relation can not be preloaded within joins.");
|
throw new \Exception("Many-to-many relation can not be preloaded within joins.");
|
||||||
@ -440,7 +444,7 @@ class Repository implements RepositoryInterface
|
|||||||
if ( $attribute ) {
|
if ( $attribute ) {
|
||||||
$alias = $attribute->alias ?? $item;
|
$alias = $attribute->alias ?? $item;
|
||||||
|
|
||||||
$entity = $attribute->entity ?? $this->entityResolver->getPropertyEntityType($item);
|
$entity = $attribute->entity ?? $this->entityResolver->reflectedClass->getProperties(true)[$item]->getTypes()[0]->type;
|
||||||
|
|
||||||
foreach($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) {
|
foreach($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) {
|
||||||
if ( null === $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Relation\Ignore::class ]) ) {
|
if ( null === $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Relation\Ignore::class ]) ) {
|
||||||
@ -481,9 +485,9 @@ class Repository implements RepositoryInterface
|
|||||||
|
|
||||||
$key = is_string($attribute->key) ? $this->entityClass::field($attribute->key) : $attribute->key;
|
$key = is_string($attribute->key) ? $this->entityClass::field($attribute->key) : $attribute->key;
|
||||||
|
|
||||||
$foreignKey = $this->evalClosure($attribute->foreignKey, $entity, $alias);
|
$foreignKey = is_string($attribute->foreignKey) ? $entity::field($attribute->foreignKey, $alias) : $attribute->foreignKey;
|
||||||
|
|
||||||
$this->join($isRelation ? "LEFT" : $attribute->type, $entity::resolveEntity()->tableName(), $key, $foreignKey, $alias, function($join) use ($item, $entity, $alias, $options) {
|
$this->join("LEFT", $entity::resolveEntity()->tableName(), $key, $foreignKey, $alias, function($join) use ($item, $entity, $alias, $options) {
|
||||||
if ( ! in_array(WithOptionEnum::SkipJoinWhere, $options)) {
|
if ( ! in_array(WithOptionEnum::SkipJoinWhere, $options)) {
|
||||||
foreach($this->entityResolver->searchFieldAnnotationList($item, [ Where::class ]) as $condition) {
|
foreach($this->entityResolver->searchFieldAnnotationList($item, [ Where::class ]) as $condition) {
|
||||||
if ( ! is_object($condition->field) ) {
|
if ( ! is_object($condition->field) ) {
|
||||||
@ -514,12 +518,6 @@ class Repository implements RepositoryInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($canSelect) {
|
|
||||||
if ( $selectObj ??= $this->queryBuilder->getFragment(Query\Select::class) ) {
|
|
||||||
$selectObj->isInternalSelect = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,7 +549,7 @@ class Repository implements RepositoryInterface
|
|||||||
->selectJsonEntity($relationRelation->entity, $alias)->open();
|
->selectJsonEntity($relationRelation->entity, $alias)->open();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$entity = $relation->entity ?? $this->entityResolver->getPropertyEntityType($name);
|
$entity = $relation->entity ?? $this->entityResolver->properties[$item]['type'];
|
||||||
$repository = $entity::repository()->selectJsonEntity($entity, $alias)->open();
|
$repository = $entity::repository()->selectJsonEntity($entity, $alias)->open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,7 +590,7 @@ class Repository implements RepositoryInterface
|
|||||||
$order = $this->entityResolver->searchFieldAnnotationList($name, [ OrderBy::class ]);
|
$order = $this->entityResolver->searchFieldAnnotationList($name, [ OrderBy::class ]);
|
||||||
$where = $this->entityResolver->searchFieldAnnotationList($name, [ Where::class ]);
|
$where = $this->entityResolver->searchFieldAnnotationList($name, [ Where::class ]);
|
||||||
|
|
||||||
$baseEntity = $relation->entity ?? $relation->bridge ?? $this->entityResolver->getPropertyEntityType($name);
|
$baseEntity = $relation->entity ?? $relation->bridge ?? $this->entityResolver->properties[$name]['type'];
|
||||||
$baseEntityResolver = $baseEntity::resolveEntity();
|
$baseEntityResolver = $baseEntity::resolveEntity();
|
||||||
|
|
||||||
$property = ($baseEntityResolver->field($relation->foreignKey, 01, false) ?: $baseEntityResolver->field($relation->foreignKey, 02))['name'];
|
$property = ($baseEntityResolver->field($relation->foreignKey, 01, false) ?: $baseEntityResolver->field($relation->foreignKey, 02))['name'];
|
||||||
@ -646,22 +644,6 @@ class Repository implements RepositoryInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
## AWAITING THE Closures in constant expression from PHP 8.5 !
|
|
||||||
protected function evalClosure(string $content, string $entityClass, mixed $alias = self::DEFAULT_ALIAS) : mixed
|
|
||||||
{
|
|
||||||
if (is_string($content)) {
|
|
||||||
if ( str_starts_with($content, 'fn(') ) {
|
|
||||||
$closure = eval("return $content;");
|
|
||||||
|
|
||||||
return $closure($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $entityClass::field($content, $alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest, bool $count = true) : self
|
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest, bool $count = true) : self
|
||||||
{
|
{
|
||||||
if ($count) {
|
if ($count) {
|
||||||
@ -766,15 +748,7 @@ class Repository implements RepositoryInterface
|
|||||||
|
|
||||||
public function instanciateEntity(? string $entityClass = null) : object
|
public function instanciateEntity(? string $entityClass = null) : object
|
||||||
{
|
{
|
||||||
$entityClass ??= $this->entityClass;
|
$entity = ( new \ReflectionClass($entityClass ?? $this->entityClass) )->newInstanceWithoutConstructor();
|
||||||
|
|
||||||
try {
|
|
||||||
$entity = new $entityClass();
|
|
||||||
}
|
|
||||||
catch (\Throwable $ex) {
|
|
||||||
$entity = ( new \ReflectionClass($entityClass) )->newInstanceWithoutConstructor();
|
|
||||||
}
|
|
||||||
|
|
||||||
$entity->initializeEntity();
|
$entity->initializeEntity();
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
namespace Ulmus\Repository;
|
namespace Ulmus\Repository;
|
||||||
|
|
||||||
use Ulmus\{
|
use Ulmus\{
|
||||||
Ulmus, Query, Common\EntityResolver, Repository, Event, Common\Sql
|
Ulmus, Query, Common\EntityResolver, Repository, Event,
|
||||||
};
|
};
|
||||||
|
|
||||||
use Ulmus\Attribute\Property\{
|
use Ulmus\Attribute\Property\{
|
||||||
@ -57,7 +57,7 @@ class RelationBuilder
|
|||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( $relation = $this->resolver->searchFieldAnnotation($name, [ Relation::class, Join::class ] ) ) {
|
if ( $relation = $this->resolver->searchFieldAnnotation($name, [ Relation::class ] ) ) {
|
||||||
return $this->instanciateEmptyObject($name, $relation);
|
return $this->instanciateEmptyObject($name, $relation);
|
||||||
}
|
}
|
||||||
elseif ($virtual = $this->resolveVirtual($name)) {
|
elseif ($virtual = $this->resolveVirtual($name)) {
|
||||||
@ -276,17 +276,12 @@ class RelationBuilder
|
|||||||
if ( $relation->generateKey ) {
|
if ( $relation->generateKey ) {
|
||||||
$value = call_user_func_array($relation->generateKey, [ $this->entity ]);
|
$value = call_user_func_array($relation->generateKey, [ $this->entity ]);
|
||||||
}
|
}
|
||||||
elseif (isset($this->entity->$field)) {
|
else {
|
||||||
$value = $this->entity->$field;
|
$value = $this->entity->$field;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($value)) {
|
|
||||||
$this->repository->where( is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey), $value );
|
$this->repository->where( is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey), $value );
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$this->repository->where(Sql::raw('TRUE'), Sql::raw('FALSE'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->applyFilter($this->repository, $name);
|
return $this->applyFilter($this->repository, $name);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user