- Some overdue modification made to allow more flexibility

This commit is contained in:
Dave M. 2023-10-27 17:53:55 +00:00
parent cc741566fb
commit 1927b43999
14 changed files with 88 additions and 51 deletions

View File

@ -15,20 +15,7 @@ interface AdapterInterface {
public function connect() : object /* | PdoObject|mixed */; public function connect() : object /* | PdoObject|mixed */;
public function buildDataSourceName() : string; public function buildDataSourceName() : string;
public function setup(array $configuration) : void; public function setup(array $configuration) : void;
public function escapeIdentifier(string $segment, int $type) : string;
public function defaultEngine() : ? string;
public function writableValue(/* mixed */ $value); /*: mixed*/ public function writableValue(/* mixed */ $value); /*: mixed*/
/* public function databaseName() : string;
public function mapFieldType(FieldDefinition $field) : string;
public function schemaTable(string $databaseName, string $tableName) /*: object|EntityCollection
*/
public function repositoryClass() : string; public function repositoryClass() : string;
public function queryBuilderClass() : string; public function queryBuilderClass() : string;
public function tableSyntax() : array;
public function whitelistAttributes(array &$parameters) : void;
public function generateAlterColumn(FieldDefinition $definition, array $field) : string|\Stringable;
public function splitAlterQuery() : bool;
} }

View File

@ -9,10 +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, Repository, QueryBuilder}; use Ulmus\{Entity\InformationSchema\Table, Migration\MigrateInterface, Repository, QueryBuilder};
class MsSQL implements AdapterInterface { class MsSQL implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
use DefaultAdapterTrait; use SqlAdapterTrait;
const ALLOWED_ATTRIBUTES = [ const ALLOWED_ATTRIBUTES = [
'default', 'primary_key', 'auto_increment', 'default', 'primary_key', 'auto_increment',

View File

@ -3,6 +3,7 @@
namespace Ulmus\Adapter; namespace Ulmus\Adapter;
use Ulmus\Entity\InformationSchema\Table; use Ulmus\Entity\InformationSchema\Table;
use Ulmus\Migration\MigrateInterface;
use Ulmus\QueryBuilder; use Ulmus\QueryBuilder;
use Ulmus\Repository; use Ulmus\Repository;
use Ulmus\Common\PdoObject; use Ulmus\Common\PdoObject;
@ -11,8 +12,8 @@ use Ulmus\Exception\AdapterConfigurationException;
use Ulmus\Ulmus; use Ulmus\Ulmus;
use Ulmus\Migration\FieldDefinition; use Ulmus\Migration\FieldDefinition;
class MySQL implements AdapterInterface { class MySQL implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
use DefaultAdapterTrait; use SqlAdapterTrait;
const ALLOWED_ATTRIBUTES = [ const ALLOWED_ATTRIBUTES = [
'default', 'primary_key', 'auto_increment', 'update', 'default', 'primary_key', 'auto_increment', 'update',
@ -21,13 +22,13 @@ class MySQL implements AdapterInterface {
const DSN_PREFIX = "mysql"; const DSN_PREFIX = "mysql";
public string $hostname; public string $hostname;
public string $database; public string $database;
public string $username; protected string $username;
public string $password; protected string $password;
public string $charset = "utf8mb4"; public string $charset = "utf8mb4";
public ? string $socket; public ? string $socket;

View File

@ -8,10 +8,11 @@ use Ulmus\ConnectionAdapter;
use Ulmus\Entity\Sqlite\Table; use Ulmus\Entity\Sqlite\Table;
use Ulmus\Exception\AdapterConfigurationException; use Ulmus\Exception\AdapterConfigurationException;
use Ulmus\Migration\FieldDefinition; use Ulmus\Migration\FieldDefinition;
use Ulmus\{Repository, QueryBuilder, Ulmus}; use Ulmus\{Migration\MigrateInterface, Repository, QueryBuilder, Ulmus};
class SQLite implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
use SqlAdapterTrait;
class SQLite implements AdapterInterface {
use DefaultAdapterTrait;
const ALLOWED_ATTRIBUTES = [ const ALLOWED_ATTRIBUTES = [
'default', 'primary_key', 'auto_increment' 'default', 'primary_key', 'auto_increment'
]; ];

View File

@ -0,0 +1,9 @@
<?php
namespace Ulmus\Adapter;
interface SqlAdapterInterface
{
public function escapeIdentifier(string $segment, int $type) : string;
public function defaultEngine() : ? string;
}

View File

@ -2,14 +2,15 @@
namespace Ulmus\Adapter; namespace Ulmus\Adapter;
use Ulmus\{ConnectionAdapter, use Ulmus\{Common\Sql,
ConnectionAdapter,
Entity\InformationSchema\Table, Entity\InformationSchema\Table,
Migration\FieldDefinition, Migration\FieldDefinition,
Repository, Repository,
QueryBuilder, QueryBuilder,
Ulmus}; Ulmus};
trait DefaultAdapterTrait trait SqlAdapterTrait
{ {
public function repositoryClass() : string public function repositoryClass() : string
{ {
@ -133,7 +134,7 @@ trait DefaultAdapterTrait
case is_object($value): case is_object($value):
return Ulmus::convertObject($value); return Ulmus::convertObject($value);
case is_array($value): case is_array($value):
return json_encode($value); return json_encode($value);
case is_bool($value): case is_bool($value):

View File

@ -0,0 +1,8 @@
<?php
namespace Ulmus\Attribute\Obj;
interface AdapterAttributeInterface
{
public function adapter() : false|string;
}

View File

@ -3,7 +3,7 @@
namespace Ulmus\Attribute\Obj; namespace Ulmus\Attribute\Obj;
#[\Attribute(\Attribute::TARGET_CLASS)] #[\Attribute(\Attribute::TARGET_CLASS)]
class Table { class Table implements AdapterAttributeInterface {
public function __construct( public function __construct(
public ? string $name = null, public ? string $name = null,
public ? string $database = null, public ? string $database = null,
@ -11,4 +11,9 @@ class Table {
public ? string $adapter = null, public ? string $adapter = null,
public ? string $engine = null, public ? string $engine = null,
) {} ) {}
public function adapter() : false|string
{
return $this->adapter ?: false;
}
} }

View File

@ -61,16 +61,7 @@ class EntityResolver {
public function searchField($name) : null|array public function searchField($name) : null|array
{ {
try{ return $this->field($name, self::KEY_ENTITY_NAME, false) ?: $this->field($name, self::KEY_COLUMN_NAME, false);
return $this->field($name, self::KEY_ENTITY_NAME, false) ?: $this->field($name, self::KEY_COLUMN_NAME, false);
}
catch(\Throwable $e) {
if ( $throwException) {
throw new \InvalidArgumentException("Can't find entity field's column named `$name` from entity {$this->entityClass}");
}
}
return null;
} }
public function fieldList($fieldKey = self::KEY_ENTITY_NAME, bool $skipVirtual = false) : array public function fieldList($fieldKey = self::KEY_ENTITY_NAME, bool $skipVirtual = false) : array
@ -173,7 +164,7 @@ class EntityResolver {
return $table->name ?? ""; return $table->name ?? "";
} }
public function tableAnnotation($required = false) : Table|Attribute\Obj\Table public function tableAnnotation($required = false) : null|Table|Attribute\Obj\Table
{ {
if ( null === $table = $this->getTableAttribute() ) { if ( null === $table = $this->getTableAttribute() ) {
if ($required) { if ($required) {
@ -191,10 +182,10 @@ class EntityResolver {
public function sqlAdapter() : \Ulmus\ConnectionAdapter public function sqlAdapter() : \Ulmus\ConnectionAdapter
{ {
if ( null !== $table = $this->getTableAttribute() ) { if ( $adapterObj = $this->getAdapterInterfaceAttribute()) {
if ( $table->adapter ?? null ) { if ( false !== $adapterName = $adapterObj->adapter() ) {
if ( null === ( $adapter = \Ulmus\Ulmus::$registeredAdapters[$table->adapter] ?? null ) ) { if ( null === ( $adapter = \Ulmus\Ulmus::$registeredAdapters[$adapterName] ?? null ) ) {
throw new \Exception("Requested database adapter `{$table->adapter}` is not registered."); throw new \Exception("Requested database adapter `$adapterName` is not registered.");
} }
else { else {
return $adapter; return $adapter;
@ -250,6 +241,11 @@ class EntityResolver {
return null; return null;
} }
protected function getAdapterInterfaceAttribute() : null|object
{
return $this->getAttributeImplementing(Attribute\Obj\AdapterAttributeInterface::class);
}
protected function getTableAttribute() protected function getTableAttribute()
{ {
return $this->getAnnotationFromClassname(Attribute\Obj\Table::class, false) ?: $this->getAnnotationFromClassname( Table::class, false ); return $this->getAnnotationFromClassname(Attribute\Obj\Table::class, false) ?: $this->getAnnotationFromClassname( Table::class, false );
@ -294,6 +290,17 @@ class EntityResolver {
return null; return null;
} }
public function getAttributeImplementing(string $interface) : ? object
{
foreach (array_reverse($this->class['tags']) as $item) {
if ($item['object'] instanceof $interface) {
return $item['object'];
}
}
return null;
}
public function instanciateAnnotationObject(array|\ReflectionAttribute $tagDefinition) : object public function instanciateAnnotationObject(array|\ReflectionAttribute $tagDefinition) : object
{ {
if ($tagDefinition instanceof \ReflectionAttribute) { if ($tagDefinition instanceof \ReflectionAttribute) {

View File

@ -53,7 +53,7 @@ class ConnectionAdapter
public function connect() : self public function connect() : self
{ {
$this->pdo = $this->adapter->connect(); $this->pdo = $this->adapter->connect();
return $this; return $this;
} }

View File

@ -27,7 +27,7 @@ trait EntityTrait {
public array $entityLoadedDataset = []; public array $entityLoadedDataset = [];
#[Ignore] #[Ignore]
public function __construct() { public function __construct(array $dataset = null) {
$this->resetVirtualProperties(); $this->resetVirtualProperties();
} }

View File

@ -0,0 +1,15 @@
<?php
namespace Ulmus\Migration;
interface MigrateInterface
{
public function tableSyntax() : array;
public function whitelistAttributes(array &$parameters) : void;
public function generateAlterColumn(FieldDefinition $definition, array $field) : string|\Stringable;
public function splitAlterQuery() : bool;
/* public function databaseName() : string;
public function mapFieldType(FieldDefinition $field) : string;
public function schemaTable(string $databaseName, string $tableName) /*: object|EntityCollection */
}

View File

@ -65,7 +65,7 @@ class Repository
return $primaryKey ? $this->loadOneFromField($primaryKey, $value) : $this->wherePrimaryKey($value)->loadOne(); return $primaryKey ? $this->loadOneFromField($primaryKey, $value) : $this->wherePrimaryKey($value)->loadOne();
} }
public function loadAll() : EntityCollection public function loadAll () : EntityCollection
{ {
return $this->selectSqlQuery()->collectionFromQuery(); return $this->selectSqlQuery()->collectionFromQuery();
} }
@ -590,7 +590,7 @@ class Repository
$pkField = key($primaryKeyField); $pkField = key($primaryKeyField);
return $this->where($primaryKeyField[$pkField]->name ?? $pkField, $value); return $this->where($this->entityClass::field($primaryKeyField[$pkField]->name ?? $pkField), $value);
} }
public function withJoin(string|array $fields, array $options = []) : self public function withJoin(string|array $fields, array $options = []) : self

View File

@ -187,7 +187,7 @@ class RelationBuilder
return $relation->bridgeField ?? false ? $relation->bridge::entityCollection() : $relationRelation->entity::entityCollection(); return $relation->bridgeField ?? false ? $relation->bridge::entityCollection() : $relationRelation->entity::entityCollection();
} }
return new $class(); throw new \InvalidArgumentException("Unknown or no relation was provided as relation type.");
} }
protected function fetchFromDataset($name, ? array $data = null) : object|bool protected function fetchFromDataset($name, ? array $data = null) : object|bool
@ -227,6 +227,9 @@ class RelationBuilder
elseif ( substr($key, 0, $len ) === sprintf(static::JOIN_FIELD_SEPARATOR, strtolower($name)) ) { elseif ( substr($key, 0, $len ) === sprintf(static::JOIN_FIELD_SEPARATOR, strtolower($name)) ) {
$vars[substr($key, $len)] = $value; $vars[substr($key, $len)] = $value;
} }
else {
# load here for API objects !
}
} }
if ($vars) { if ($vars) {