This commit is contained in:
Dave Mc Nicoll 2023-04-13 15:39:21 -04:00
commit bd61522a07
13 changed files with 69 additions and 11 deletions

View File

@ -29,4 +29,5 @@ interface AdapterInterface {
public function queryBuilderClass() : string;
public function tableSyntax() : array;
public function whitelistAttributes(array &$parameters) : void;
public function generateAlterColumn(FieldDefinition $definition, array $field) : string|\Stringable;
}

View File

@ -100,4 +100,22 @@ trait DefaultAdapterTrait
{
$parameters = array_intersect_key($parameters, array_flip(static::ALLOWED_ATTRIBUTES));
}
public function generateAlterColumn(FieldDefinition $definition, array $field) : string|\Stringable
{
if ($field['previous']) {
$position = sprintf('AFTER %s', $adapter->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,
]);
}
}

View File

@ -203,4 +203,14 @@ class SQLite implements AdapterInterface {
$pdo->sqliteCreateFunction('month', fn($date) => ( new \DateTime($date) )->format('m'), 1);
$pdo->sqliteCreateFunction('year', fn($date) => ( new \DateTime($date) )->format('Y'), 1);
}
public function generateAlterColumn(FieldDefinition $definition, array $field) : string|\Stringable
{
return implode(" ", [
strtoupper($field['action']),
$this->escapeIdentifier($definition->getSqlName(), static::IDENTIFIER_FIELD),
$definition->getSqlType(),
$definition->getSqlParams(),
]);
}
}

View File

@ -2,6 +2,8 @@
namespace Ulmus\Attribute\Property\Field;
use Ulmus\Attribute\Attribute;
/**
* Since we need consistancy between the declaration of our ID and FK fields, it
* was decided to extend the PK class instead of Field for this case.
@ -20,5 +22,8 @@ class ForeignKey extends PrimaryKey {
public bool $nullable = false,
public mixed $default = null,
public bool $readonly = false,
) {}
public null|array|string|\Stringable $references = null,
) {
$this->references = Attribute::handleArrayField($this->references);
}
}

View File

@ -62,6 +62,13 @@ class EntityField implements WhereRawParameter
]);
}
public static function generateAlterColumn(AdapterInterface $adapter, array $field) : string
{
$definition = new FieldDefinition($adapter, $field['definition']);
return $adapter->generateAlterColumn($definition, $field);
}
public static function isObjectType($type) : bool
{
# @Should be fixed with isBuiltIn() instead, it won't be correct based only on name

View File

@ -56,7 +56,8 @@ abstract class Sql {
$this->identifier = $identifier;
}
public function __toString() {
public function __toString() : string
{
return $this->identifier;
}
};

View File

@ -3,8 +3,8 @@
namespace Ulmus\Entity\Sqlite;
use Ulmus\EntityCollection;
use Ulmus\{Attribute\Obj\Table};
use Ulmus\Query\{From, Select};
use Ulmus\{Attribute\Obj\Table, Repository};
use Ulmus\Attribute\Property\{Field, Filter, FilterJoin, Relation, Join, Virtual, Where};
#[Table(name: "sqlite_master")]
@ -27,6 +27,12 @@ class Schema
#[Field]
public ? string $sql;
#[Relation("oneToMany", key: "tableName", foreignKey: "tableName", entity: Column::class)]
##[Relation("oneToMany", key: "tableName", foreignKey: "tableName", entity: Column::class)]
#[Virtual(method: "filterColumns")]
public EntityCollection $columns;
public function filterColumns() : EntityCollection
{
return ( new Repository\SqliteRepository(Column::class) )->pragma('table_info', $this->tableName)->collectionFromQuery();
}
}

View File

@ -5,6 +5,7 @@ namespace Ulmus\Entity\Sqlite;
use Ulmus\ConnectionAdapter;
use Ulmus\Repository;
#[\Ulmus\Attribute\Obj\Table(name: "sqlite_master")]
class Table extends Schema
{
public static function repository(string $alias = Repository::DEFAULT_ALIAS, ConnectionAdapter $adapter = null): Repository

View File

@ -222,6 +222,11 @@ class EntityCollection extends \ArrayObject {
return $list;
}
public function sum($field) : float|int
{
return array_sum($this->column($field));
}
public function unique(\Stringable|callable|string $field, bool $strict = false) : self
{
$list = [];

View File

@ -35,8 +35,8 @@ class Alter extends Fragment {
public function renderFields() : string
{
return "(" . PHP_EOL . implode("," . PHP_EOL, array_map(function($field) {
return PHP_EOL . implode("," . PHP_EOL, array_map(function($field) {
return " " . EntityField::generateAlterColumn($this->adapter, $field);
}, $this->fieldList)) . PHP_EOL . ")";
}, $this->fieldList));
}
}

View File

@ -392,7 +392,7 @@ class QueryBuilder implements Query\QueryBuilderInterface
public function alter(Adapter\AdapterInterface $adapter, array $fieldlist, string $table, ? string $database = null, ? string $schema = null) : self
{
if ( null === $this->getFragment(Query\Create::class) ) {
if ( null === $this->getFragment(Query\Alter::class) ) {
if ( $schema ) {
$table = "$schema.$table";
}

View File

@ -301,6 +301,11 @@ class Repository
return $this->createSqlQuery()->runQuery();
}
public function alterTable(array $fields)
{
return $this->alterSqlQuery($fields)->runQuery();
}
public function listTables(? string $database = null)
{
return $this->showTablesSqlQuery($database)->runQuery();
@ -953,10 +958,9 @@ class Repository
public function alterSqlQuery(array $fields) : self
{
if ( null === $this->queryBuilder->getFragment(Query\Alter::class) ) {
$this->queryBuilder->create($this->adapter->adapter(), $this->escapeFieldList($this->entityResolver->fieldList(EntityResolver::KEY_ENTITY_NAME, true)), $this->escapeTable($this->entityResolver->tableName()), $this->entityResolver->schemaName());
$this->queryBuilder->alter($this->adapter->adapter(), $fields, $this->escapeTable($this->entityResolver->tableName()), $this->entityResolver->schemaName());
}
return $this;
}

View File

@ -6,7 +6,7 @@ use Ulmus\{ConnectionAdapter, QueryBuilder, Repository, Query, Ulmus, Entity};
class SqliteRepository extends Repository {
public function pragma(/*object|Stringable*/ $pragma, $argument = null, bool $callable = false) : self
public function pragma(\Stringable|string $pragma, $argument = null, bool $callable = false) : self
{
$this->queryBuilder->pragma($pragma, $argument, $callable);