Compare commits
141
Commits
c14644cdda
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fd6889c6f | ||
|
|
bd0d928f35 | ||
|
|
5a5d326d70 | ||
|
|
b5e96eb7e0 | ||
|
|
7c589ab7b4 | ||
|
|
589524ca3a | ||
|
|
1fac12c928 | ||
|
|
9eed2fe1a8 | ||
|
|
b601939459 | ||
|
|
e3314f40ac | ||
|
|
4ad44f73d7 | ||
|
|
68a6636c06 | ||
|
|
70c6cde603 | ||
|
|
079a3fd110 | ||
|
|
ec4d02b9d9 | ||
|
|
35ceb97241 | ||
|
|
83f673b37f | ||
|
|
411992c7a8 | ||
|
|
5f4f23a8e4 | ||
|
|
2fda7e82d7 | ||
|
|
573d4cc06b | ||
|
|
18313fd7f5 | ||
|
|
9503b24467 | ||
|
|
3c2ae86653 | ||
|
|
9977a25cf5 | ||
|
|
3ba8a2a5d0 | ||
|
|
4106c8db91 | ||
|
|
d5cca085bc | ||
|
|
c56b584140 | ||
|
|
8b1c11676d | ||
|
|
aa07c728fe | ||
|
|
d4181065cf | ||
|
|
62998faf40 | ||
|
|
feee26cd26 | ||
|
|
e37944c63a | ||
|
|
1d38ae8245 | ||
|
|
0c8591f238 | ||
|
|
bbfd7c02b4 | ||
|
|
bd9078230d | ||
|
|
f3be11a590 | ||
|
|
2de3139c80 | ||
|
|
e37eeb85f1 | ||
|
|
7de0ecb028 | ||
|
|
75231f32b3 | ||
|
|
1dd9da6eb6 | ||
|
|
b38b81d03c | ||
|
|
950df5eb99 | ||
|
|
9fdebf454d | ||
|
|
4571517dc8 | ||
|
|
15be1597b8 | ||
|
|
fa4e686f35 | ||
|
|
d9fa51fa18 | ||
|
|
d4d68a029d | ||
|
|
ea667db552 | ||
|
|
afe5144dc7 | ||
|
|
62792e8325 | ||
|
|
3a80fee9c3 | ||
|
|
7f8780d328 | ||
|
|
9a9f473f3f | ||
|
|
fab70aec6a | ||
|
|
c1755d250b | ||
|
|
acab934f6f | ||
|
|
2e377374d4 | ||
|
|
c2cccc0222 | ||
|
|
ab582c9318 | ||
|
|
a4b81f1932 | ||
|
|
ab1d7e4f5b | ||
|
|
bfc1e1cf93 | ||
|
|
531908b04c | ||
|
|
07ae8faaac | ||
|
|
756474d460 | ||
|
|
d297fd9e86 | ||
|
|
fed7d2e302 | ||
|
|
3736fbe0f6 | ||
|
|
667c1fe9ab | ||
|
|
d2bd6c2f58 | ||
|
|
953fc35680 | ||
|
|
6c6733b503 | ||
|
|
e641bc321d | ||
|
|
da5d203768 | ||
|
|
f77c93ad20 | ||
|
|
c9d9281c63 | ||
|
|
8e0dce3e71 | ||
|
|
1927b43999 | ||
|
|
cc741566fb | ||
|
|
8489cb4841 | ||
|
|
9ebf7b05d7 | ||
|
|
338b599d39 | ||
|
|
d01624b8aa | ||
|
|
01ab6e82d4 | ||
|
|
a4743b471c | ||
|
|
bd61522a07 | ||
|
|
f3712c9cc7 | ||
|
|
cfaebbecc4 | ||
|
|
eb6434bb72 | ||
|
|
2ad52aba85 | ||
|
|
3c5aa51850 | ||
|
|
9514a46ae7 | ||
|
|
cee978ecfd | ||
|
|
43880eb428 | ||
|
|
58bdce0ea8 | ||
|
|
fa8adcace1 | ||
|
|
36cddf8f78 | ||
|
|
c6bfaa05f2 | ||
|
|
c9c6a11ebd | ||
|
|
d4a9fc8463 | ||
|
|
94edb09352 | ||
|
|
dcccce7893 | ||
|
|
31f031715d | ||
|
|
26ffecbb6e | ||
|
|
88e9f048db | ||
|
|
70021d829d | ||
|
|
e6d0279c1a | ||
|
|
5295a335b3 | ||
|
|
43a913a602 | ||
|
|
197eee90f7 | ||
|
|
0a7ff4fd21 | ||
|
|
00e20a7692 | ||
|
|
d600908f47 | ||
|
|
26febb631d | ||
|
|
5ef20533b2 | ||
|
|
b6752f4364 | ||
|
|
497fe5547b | ||
|
|
902167c2ed | ||
|
|
b20e537038 | ||
|
|
0e8443b1c1 | ||
|
|
dfb84c104d | ||
|
|
e97df353ae | ||
|
|
00ebf3381f | ||
|
|
430cd03bc4 | ||
|
|
8507283d27 | ||
|
|
fc9b536eee | ||
|
|
c3c320112b | ||
|
|
e1990e7cc0 | ||
|
|
84682d1c8e | ||
|
|
52f240ef15 | ||
|
|
724ab250ab | ||
|
|
e14a3670fc | ||
|
|
486077b2d4 | ||
|
|
325704260b | ||
|
|
16d76470da |
No files matched your search
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Dave Mc Nicoll",
|
"name": "Dave Mc Nicoll",
|
||||||
"email": "mcndave@gmail.com"
|
"email": "info@mcnd.ca"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
# Ulmus
|
||||||
|
|
||||||
|
Welcome to the official Ulmus documentation.
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
Creating a simple user exemple entity:
|
||||||
|
|
||||||
|
*/app/entity/user.php*
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MyApp\Entity;
|
||||||
|
|
||||||
|
use Ulmus\Entity\Field\Datetime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Table('name' => "user")
|
||||||
|
*/
|
||||||
|
class User
|
||||||
|
{
|
||||||
|
use \Ulmus\EntityTrait;
|
||||||
|
|
||||||
|
#[Field\Id]
|
||||||
|
public int $id;
|
||||||
|
|
||||||
|
#[Field]
|
||||||
|
public string $fullname;
|
||||||
|
|
||||||
|
#[Field]
|
||||||
|
public ? string $email;
|
||||||
|
|
||||||
|
#[Field]
|
||||||
|
public bool $isAdmin = false;
|
||||||
|
|
||||||
|
#[Field\Datetime]
|
||||||
|
public Datetime $birthday;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Loading a user using a Primary Key
|
||||||
|
|
||||||
|
With this entity, we could quickly load a user using the `@Id` field using:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$user = Entity\User::repository()->loadFromPk((int) $_GET['id']);
|
||||||
|
```
|
||||||
|
|
||||||
|
Or we could also, load another single entity using a specific field:
|
||||||
|
|
||||||
|
```php
|
||||||
|
# fetch a single user
|
||||||
|
$user = Entity\User::repository()->loadOneFromField((string) $_POST['email'], 'email');
|
||||||
|
|
||||||
|
# Fetch every admins
|
||||||
|
$admin_list = Entity\User::repository()->loadFromField(true, 'isAdmin');
|
||||||
|
```
|
||||||
|
|
||||||
|
Using the same entity class, we could create a new user and save it using:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$user = new Entity\User();
|
||||||
|
$user->fullname = "Johnny Does";
|
||||||
|
$user->birthday = "1980-01-15";
|
||||||
|
|
||||||
|
if ( Entity\User::repository()->save($user) ) {
|
||||||
|
echo "User created successfully !";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo "User could not be saved :\";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Which would result in the following query (from MySQL adapter) being generated and executed :
|
||||||
|
|
||||||
|
```SQL
|
||||||
|
INSERT INTO `user` VALUES fullname = :fullname, birthday = :birthday;
|
||||||
|
```
|
||||||
|
|
||||||
|
Binded using:
|
||||||
|
|
||||||
|
```PHP
|
||||||
|
'fullname' => "Johnny Does",
|
||||||
|
'birthday' => "1980-01-15",
|
||||||
|
```
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Search Request
|
||||||
|
|
||||||
|
Ulmus comes with a simple search request processor which allows both flexibility and simplicity.
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
Creating a simple user exemple entity:
|
||||||
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -15,12 +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 writableValue(/* mixed */ $value); /*: mixed*/
|
||||||
public function defaultEngine() : ? string;
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Ulmus\Adapter;
|
namespace Ulmus\Adapter;
|
||||||
|
|
||||||
use Ulmus\{Entity\InformationSchema\Table, Migration\FieldDefinition, Repository, QueryBuilder};
|
use Ulmus\{ConnectionAdapter, Entity\InformationSchema\Table, Migration\FieldDefinition, Repository, QueryBuilder\Sql\MysqlQueryBuilder, Entity};
|
||||||
|
|
||||||
trait DefaultAdapterTrait
|
trait DefaultAdapterTrait
|
||||||
{
|
{
|
||||||
@@ -13,7 +13,7 @@ trait DefaultAdapterTrait
|
|||||||
|
|
||||||
public function queryBuilderClass() : string
|
public function queryBuilderClass() : string
|
||||||
{
|
{
|
||||||
return QueryBuilder::class;
|
return MysqlQueryBuilder::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tableSyntax() : array
|
public function tableSyntax() : array
|
||||||
@@ -30,9 +30,12 @@ trait DefaultAdapterTrait
|
|||||||
return $this->database;
|
return $this->database;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function schemaTable(string $databaseName, string $tableName) /* : ? object */
|
public function schemaTable(ConnectionAdapter $adapter, $databaseName, string $tableName) : null|object
|
||||||
{
|
{
|
||||||
return Table::repository()->where(Table::field('schema'), $databaseName)->loadOneFromField(Table::field('name'), $tableName);
|
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
|
public function mapFieldType(FieldDefinition $field, bool $typeOnly = false) : string
|
||||||
@@ -90,6 +93,29 @@ trait DefaultAdapterTrait
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $typeOnly ? $type : $type . ( $length ? "($length" . ( $precision ? ",$precision" : "" ) . ")" : "" );
|
return $typeOnly ? $type : $type . ( isset($length) ? "($length" . ( ! empty($precision) ? ",$precision" : "" ) . ")" : "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function whitelistAttributes(array &$parameters) : void
|
||||||
|
{
|
||||||
|
$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', $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,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+33
-7
@@ -5,11 +5,18 @@ namespace Ulmus\Adapter;
|
|||||||
use Ulmus\Common\PdoObject;
|
use Ulmus\Common\PdoObject;
|
||||||
|
|
||||||
use Ulmus\Exception\AdapterConfigurationException;
|
use Ulmus\Exception\AdapterConfigurationException;
|
||||||
use Ulmus\Migration\FieldDefinition;
|
|
||||||
use Ulmus\{Entity\InformationSchema\Table, Repository, QueryBuilder};
|
|
||||||
|
|
||||||
class MsSQL implements AdapterInterface {
|
use Ulmus\Ulmus;
|
||||||
use DefaultAdapterTrait;
|
|
||||||
|
use Ulmus\Migration\FieldDefinition;
|
||||||
|
use Ulmus\{Entity\InformationSchema\Table, Migration\MigrateInterface, Repository, QueryBuilder};
|
||||||
|
|
||||||
|
class MsSQL implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
||||||
|
use SqlAdapterTrait;
|
||||||
|
|
||||||
|
const ALLOWED_ATTRIBUTES = [
|
||||||
|
'default', 'primary_key', 'auto_increment',
|
||||||
|
];
|
||||||
|
|
||||||
const DSN_PREFIX = "sqlsrv";
|
const DSN_PREFIX = "sqlsrv";
|
||||||
|
|
||||||
@@ -44,7 +51,9 @@ class MsSQL implements AdapterInterface {
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
?string $server = null,
|
?string $server = null,
|
||||||
?string $database = null,
|
?string $database = null,
|
||||||
|
#[\SensitiveParameter]
|
||||||
?string $username = null,
|
?string $username = null,
|
||||||
|
#[\SensitiveParameter]
|
||||||
?string $password = null,
|
?string $password = null,
|
||||||
?int $port = null
|
?int $port = null
|
||||||
) {
|
) {
|
||||||
@@ -77,9 +86,12 @@ class MsSQL implements AdapterInterface {
|
|||||||
$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
|
$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
|
||||||
$pdo->setAttribute(\PDO::SQLSRV_ATTR_ENCODING, \PDO::SQLSRV_ENCODING_UTF8);
|
$pdo->setAttribute(\PDO::SQLSRV_ATTR_ENCODING, \PDO::SQLSRV_ENCODING_UTF8);
|
||||||
}
|
}
|
||||||
catch(PDOException $ex){
|
catch(\PDOException $ex){
|
||||||
throw $ex;
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
$this->password = str_repeat('*', random_int(8,16));
|
||||||
|
}
|
||||||
|
|
||||||
return $pdo;
|
return $pdo;
|
||||||
}
|
}
|
||||||
@@ -97,6 +109,9 @@ class MsSQL implements AdapterInterface {
|
|||||||
if ( $this->encrypt ?? false ) {
|
if ( $this->encrypt ?? false ) {
|
||||||
$parts[] = "Encrypt=1";
|
$parts[] = "Encrypt=1";
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$parts[] = "Encrypt=0";
|
||||||
|
}
|
||||||
|
|
||||||
if ( $this->failoverPartner ?? false ) {
|
if ( $this->failoverPartner ?? false ) {
|
||||||
$parts[] = "Failover_Partner={$this->failoverPartner}";
|
$parts[] = "Failover_Partner={$this->failoverPartner}";
|
||||||
@@ -127,7 +142,7 @@ class MsSQL implements AdapterInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->trustServerCertificate ?? false ) {
|
if ( $this->trustServerCertificate ?? false ) {
|
||||||
$parts[] = "TrustServerCertificate=1";
|
$parts[] = "TrustServerCertificate=yes";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->WSID ?? false ) {
|
if ( $this->WSID ?? false ) {
|
||||||
@@ -191,9 +206,10 @@ class MsSQL implements AdapterInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function escapeIdentifier(string $segment, int $type) : string
|
public static function escapeIdentifier(string $segment, int $type) : string
|
||||||
{
|
{
|
||||||
switch($type) {
|
switch($type) {
|
||||||
|
default:
|
||||||
case static::IDENTIFIER_SCHEMA:
|
case static::IDENTIFIER_SCHEMA:
|
||||||
case static::IDENTIFIER_DATABASE:
|
case static::IDENTIFIER_DATABASE:
|
||||||
case static::IDENTIFIER_TABLE:
|
case static::IDENTIFIER_TABLE:
|
||||||
@@ -209,4 +225,14 @@ class MsSQL implements AdapterInterface {
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function repositoryClass() : string
|
||||||
|
{
|
||||||
|
return Repository\MssqlRepository::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function queryBuilderClass() : string
|
||||||
|
{
|
||||||
|
return QueryBuilder\Sql\MssqlQueryBuilder::class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+40
-11
@@ -2,16 +2,22 @@
|
|||||||
|
|
||||||
namespace Ulmus\Adapter;
|
namespace Ulmus\Adapter;
|
||||||
|
|
||||||
use Ulmus\Entity\InformationSchema\Table;
|
use Ulmus\ConnectionAdapter;
|
||||||
use Ulmus\QueryBuilder;
|
use Ulmus\Entity\Mysql\Table;
|
||||||
use Ulmus\Repository;
|
use Ulmus\Migration\FieldDefinition;
|
||||||
|
use Ulmus\Migration\MigrateInterface;
|
||||||
|
use Ulmus\QueryBuilder\Sql;
|
||||||
use Ulmus\Common\PdoObject;
|
use Ulmus\Common\PdoObject;
|
||||||
|
|
||||||
use Ulmus\Exception\AdapterConfigurationException;
|
use Ulmus\Exception\AdapterConfigurationException;
|
||||||
use Ulmus\Migration\FieldDefinition;
|
use Ulmus\Repository;
|
||||||
|
|
||||||
class MySQL implements AdapterInterface {
|
class MySQL implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
||||||
use DefaultAdapterTrait;
|
use SqlAdapterTrait;
|
||||||
|
|
||||||
|
const ALLOWED_ATTRIBUTES = [
|
||||||
|
'default', 'primary_key', 'auto_increment', 'update',
|
||||||
|
];
|
||||||
|
|
||||||
const DSN_PREFIX = "mysql";
|
const DSN_PREFIX = "mysql";
|
||||||
|
|
||||||
@@ -19,9 +25,9 @@ class MySQL implements AdapterInterface {
|
|||||||
|
|
||||||
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";
|
||||||
|
|
||||||
@@ -32,7 +38,9 @@ class MySQL implements AdapterInterface {
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
?string $hostname = null,
|
?string $hostname = null,
|
||||||
?string $database = null,
|
?string $database = null,
|
||||||
|
#[\SensitiveParameter]
|
||||||
?string $username = null,
|
?string $username = null,
|
||||||
|
#[\SensitiveParameter]
|
||||||
?string $password = null,
|
?string $password = null,
|
||||||
?int $port = null,
|
?int $port = null,
|
||||||
?string $charset = null
|
?string $charset = null
|
||||||
@@ -72,11 +80,11 @@ class MySQL implements AdapterInterface {
|
|||||||
$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
|
$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
|
||||||
$pdo->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
$pdo->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
||||||
}
|
}
|
||||||
catch(PDOException $ex){
|
catch(\PDOException $ex){
|
||||||
throw $ex;
|
throw $ex;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
$this->password = str_repeat('*', strlen($this->password));
|
$this->password = str_repeat('*', random_int(8,16));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $pdo;
|
return $pdo;
|
||||||
@@ -134,9 +142,17 @@ class MySQL implements AdapterInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function escapeIdentifier(string $segment, int $type) : string
|
public function mapFieldType(FieldDefinition $field, bool $typeOnly = false) : string
|
||||||
|
{
|
||||||
|
$mapper = new MySQLFieldMapper($field);
|
||||||
|
|
||||||
|
return $typeOnly ? $mapper->type : $mapper->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function escapeIdentifier(string $segment, int $type) : string
|
||||||
{
|
{
|
||||||
switch($type) {
|
switch($type) {
|
||||||
|
default:
|
||||||
case static::IDENTIFIER_DATABASE:
|
case static::IDENTIFIER_DATABASE:
|
||||||
case static::IDENTIFIER_TABLE:
|
case static::IDENTIFIER_TABLE:
|
||||||
case static::IDENTIFIER_FIELD:
|
case static::IDENTIFIER_FIELD:
|
||||||
@@ -151,4 +167,17 @@ class MySQL implements AdapterInterface {
|
|||||||
{
|
{
|
||||||
return "InnoDB";
|
return "InnoDB";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function queryBuilderClass() : string
|
||||||
|
{
|
||||||
|
return Sql\MysqlQueryBuilder::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Adapter;
|
||||||
|
|
||||||
|
use Ulmus\Migration\FieldDefinition;
|
||||||
|
|
||||||
|
class MySQLFieldMapper extends SqlFieldMapper
|
||||||
|
{
|
||||||
|
public readonly string $type;
|
||||||
|
|
||||||
|
public readonly string $length;
|
||||||
|
|
||||||
|
public function map() : void
|
||||||
|
{
|
||||||
|
$type = $this->field->type;
|
||||||
|
$length = $this->field->length;
|
||||||
|
|
||||||
|
if ( enum_exists($type) ) {
|
||||||
|
# Haven't found a better way yet to check for BackendEnum without an instance of the object
|
||||||
|
if ( ! method_exists($type, 'tryFrom') ) {
|
||||||
|
throw new \Ulmus\Exception\BackedEnumRequired(sprintf("You must define your enum as a BackedEnum instead of an UnitEnum for field '%s'.", $this->field->getColumnName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->length = implode(',', array_map(fn($e) => MySQL::escapeIdentifier($e->value, MySQL::IDENTIFIER_VALUE) , $type::cases()));
|
||||||
|
$this->type = "ENUM";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parent::map();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+152
-29
@@ -2,44 +2,45 @@
|
|||||||
|
|
||||||
namespace Ulmus\Adapter;
|
namespace Ulmus\Adapter;
|
||||||
|
|
||||||
|
use Collator;
|
||||||
use Ulmus\Common\PdoObject;
|
use Ulmus\Common\PdoObject;
|
||||||
|
use Ulmus\ConnectionAdapter;
|
||||||
use Ulmus\Entity\Sqlite\Table;
|
use Ulmus\Entity;
|
||||||
use Ulmus\Exception\AdapterConfigurationException;
|
|
||||||
use Ulmus\Migration\FieldDefinition;
|
use Ulmus\Migration\FieldDefinition;
|
||||||
use Ulmus\{ Repository, QueryBuilder };
|
use Ulmus\{Migration\MigrateInterface, Repository, QueryBuilder};
|
||||||
|
|
||||||
class SQLite implements AdapterInterface {
|
class SQLite implements AdapterInterface, MigrateInterface, SqlAdapterInterface {
|
||||||
use DefaultAdapterTrait;
|
use SqlAdapterTrait;
|
||||||
|
|
||||||
|
const ALLOWED_ATTRIBUTES = [
|
||||||
|
'default', 'primary_key', 'auto_increment', 'collate nocase', 'collate binary', 'collate rtrim',
|
||||||
|
];
|
||||||
|
|
||||||
const DSN_PREFIX = "sqlite";
|
const DSN_PREFIX = "sqlite";
|
||||||
|
|
||||||
public string $path;
|
|
||||||
|
|
||||||
public array $pragma;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
? string $path = null,
|
public null|string $path = null,
|
||||||
? array $pragma = null
|
public null|array $pragmaBegin = null,
|
||||||
) {
|
public null|array $pragmaClose = null,
|
||||||
if ($path !== null) {
|
) { }
|
||||||
$this->path = $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($pragma !== null) {
|
|
||||||
$this->pragma = $pragma;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function connect() : PdoObject
|
public function connect() : PdoObject
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$pdo = new PdoObject($this->buildDataSourceName(), null, null);
|
$pdo = new PdoObject\SqlitePdoObject($this->buildDataSourceName(), null, null);
|
||||||
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||||
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
|
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
|
||||||
$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
|
$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
$pdo->onClose = function(PdoObject $obj) {
|
||||||
|
static::registerPragma($obj, $this->pragmaClose);
|
||||||
|
};
|
||||||
|
|
||||||
|
$this->exportFunctions($pdo);
|
||||||
|
$this->exportCollations($pdo);
|
||||||
|
$this->registerPragma($pdo, $this->pragmaBegin);
|
||||||
}
|
}
|
||||||
catch(PDOException $ex){
|
catch(\PDOException $ex){
|
||||||
throw $ex;
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,13 +57,15 @@ class SQLite implements AdapterInterface {
|
|||||||
public function setup(array $configuration) : void
|
public function setup(array $configuration) : void
|
||||||
{
|
{
|
||||||
$this->path = $configuration['path'] ?? "";
|
$this->path = $configuration['path'] ?? "";
|
||||||
$this->pragma = $configuration['pragma'] ?? [];
|
$this->pragmaBegin = array_filter($configuration['pragma_begin'] ?? []);
|
||||||
|
$this->pragmaClose = array_filter($configuration['pragma_close'] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
# https://sqlite.org/lang_keywords.html
|
# https://sqlite.org/lang_keywords.html
|
||||||
public function escapeIdentifier(string $segment, int $type) : string
|
public static function escapeIdentifier(string $segment, int $type) : string
|
||||||
{
|
{
|
||||||
switch($type) {
|
switch($type) {
|
||||||
|
default:
|
||||||
case static::IDENTIFIER_DATABASE:
|
case static::IDENTIFIER_DATABASE:
|
||||||
case static::IDENTIFIER_TABLE:
|
case static::IDENTIFIER_TABLE:
|
||||||
case static::IDENTIFIER_FIELD:
|
case static::IDENTIFIER_FIELD:
|
||||||
@@ -85,15 +88,16 @@ class SQLite implements AdapterInterface {
|
|||||||
return substr($base, 0, strrpos($base, '.') ?: strlen($base));
|
return substr($base, 0, strrpos($base, '.') ?: strlen($base));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function schemaTable(string $databaseName, string $tableName) /* : ? object */
|
public function schemaTable(ConnectionAdapter $adapter, string $databaseName, string $tableName) : null|object
|
||||||
{
|
{
|
||||||
return Table::repository()->loadOneFromField(Table::field('tableName'), $tableName);
|
return Entity\Sqlite\Table::repository(Repository::DEFAULT_ALIAS, $adapter)
|
||||||
|
->select(\Ulmus\Common\Sql::raw('this.*'))
|
||||||
|
->loadOneFromField(Entity\Sqlite\Table::field('tableName'), $tableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function mapFieldType(FieldDefinition $field, bool $typeOnly = false) : string
|
public function mapFieldType(FieldDefinition $field, bool $typeOnly = false) : string
|
||||||
{
|
{
|
||||||
$type = $field->type;
|
$type = $field->type;
|
||||||
|
|
||||||
$length = $field->length;
|
$length = $field->length;
|
||||||
|
|
||||||
if ( is_a($type, Entity\Field\Date::class, true) || is_a($type, Entity\Field\Time::class, true) || is_a($type, \DateTime::class, true) ) {
|
if ( is_a($type, Entity\Field\Date::class, true) || is_a($type, Entity\Field\Time::class, true) || is_a($type, \DateTime::class, true) ) {
|
||||||
@@ -111,6 +115,10 @@ class SQLite implements AdapterInterface {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "array":
|
case "array":
|
||||||
|
$type = "JSON";
|
||||||
|
$length = null;
|
||||||
|
break;
|
||||||
|
|
||||||
case "string":
|
case "string":
|
||||||
$type = "TEXT";
|
$type = "TEXT";
|
||||||
$length = null;
|
$length = null;
|
||||||
@@ -126,7 +134,11 @@ class SQLite implements AdapterInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $typeOnly ? $type : $type . ( $length ? "($length" . ( $precision ? ",$precision" : "" ) . ")" : "" );
|
if (in_array($type, [ 'JSON', 'TEXT', 'BLOB', 'GEOMETRY' ])) {
|
||||||
|
unset($field->default);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $typeOnly ? $type : $type . ( $length ? "($length" . ")" : "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tableSyntax() : array
|
public function tableSyntax() : array
|
||||||
@@ -137,4 +149,115 @@ class SQLite implements AdapterInterface {
|
|||||||
'unsigned' => "",
|
'unsigned' => "",
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function repositoryClass() : string
|
||||||
|
{
|
||||||
|
return Repository\SqliteRepository::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function queryBuilderClass() : string
|
||||||
|
{
|
||||||
|
return QueryBuilder\Sql\SqliteQueryBuilder::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exportFunctions(PdoObject $pdo) : void
|
||||||
|
{
|
||||||
|
$pdo->sqliteCreateFunction('if', fn($comparison, $yes, $no) => $comparison ? $yes : $no, 3);
|
||||||
|
$pdo->sqliteCreateFunction('length', fn($string) => strlen($string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('lcase', fn($string) => strtolower($string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('ucase', fn($string) => strtoupper($string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('md5', fn($string) => md5($string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('sha1', fn($string) => sha1($string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('sha256', fn($string) => hash('sha256', $string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('sha512', fn($string) => hash('sha512', $string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('whirlpool', fn($string) => hash('whirlpool', $string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('murmur3a', fn($string) => hash('murmur3a', $string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('murmur3c', fn($string) => hash('murmur3c', $string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('murmur3f', fn($string) => hash('murmur3f', $string), 1);
|
||||||
|
$pdo->sqliteCreateFunction('left', fn($string, $length) => substr($string, 0, $length), 2);
|
||||||
|
$pdo->sqliteCreateFunction('right', fn($string, $length) => substr($string, -$length), 2);
|
||||||
|
$pdo->sqliteCreateFunction('strcmp', fn($s1, $s2) => strcmp($s1, $s2), 2);
|
||||||
|
$pdo->sqliteCreateFunction('lpad', fn($string, $length, $pad) => str_pad($string, $length, $pad, STR_PAD_LEFT), 3);
|
||||||
|
$pdo->sqliteCreateFunction('rpad', fn($string, $length, $pad) => str_pad($string, $length, $pad, STR_PAD_RIGHT), 3);
|
||||||
|
$pdo->sqliteCreateFunction('concat', fn(...$args) => implode('', $args), -1);
|
||||||
|
$pdo->sqliteCreateFunction('concat_ws', fn($separator, ...$args) => implode($separator, $args), -1);
|
||||||
|
$pdo->sqliteCreateFunction('find_in_set', function($string, $string_list) {
|
||||||
|
if ( $string === null || $string_list === null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($string_list === "") {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) in_array($string, explode(',', $string_list));
|
||||||
|
}, 2);
|
||||||
|
$pdo->sqliteCreateFunction('day', fn($date) => ( new \DateTime($date) )->format('j'), 1);
|
||||||
|
$pdo->sqliteCreateFunction('month', fn($date) => ( new \DateTime($date) )->format('n'), 1);
|
||||||
|
$pdo->sqliteCreateFunction('year', fn($date) => ( new \DateTime($date) )->format('Y'), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function exportCollations(PdoObject $pdo) : void
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( class_exists('Locale') ) {
|
||||||
|
# @TODO debug this, case-sensitivity not working properly !!
|
||||||
|
$collator = new Collator(\Locale::getDefault());
|
||||||
|
$collator->setStrength(Collator::TERTIARY);
|
||||||
|
$collator->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON);
|
||||||
|
|
||||||
|
$pdo->sqliteCreateCollation('locale_cmp', fn($e1, $e2) => $collator->compare($e1, $e2));
|
||||||
|
$pdo->sqliteCreateCollation('locale_cmp_desc', fn($e1, $e2) => $collator->compare($e2, $e1));
|
||||||
|
|
||||||
|
$collatorCi = new Collator(\Locale::getDefault());
|
||||||
|
$collatorCi->setStrength(Collator::SECONDARY);
|
||||||
|
$collatorCi->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON);
|
||||||
|
|
||||||
|
$pdo->sqliteCreateCollation('locale_cmp_ci', fn($e1, $e2) => $collatorCi->compare($e1, $e2));
|
||||||
|
$pdo->sqliteCreateCollation('locale_cmp_ci_desc', fn($e1, $e2) => $collatorCi->compare($e2, $e1));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$comp = fn(string $e1, string $e2) => \iconv('UTF-8', 'ASCII//TRANSLIT', $e1) <=> \iconv('UTF-8', 'ASCII//TRANSLIT', $e2);
|
||||||
|
$pdo->sqliteCreateCollation('locale_cmp', fn($e1, $e2) => $comp);
|
||||||
|
$pdo->sqliteCreateCollation('locale_cmp_desc', fn($e2, $e1) => $comp);
|
||||||
|
|
||||||
|
$compCi = fn(string $e1, string $e2) => strtoupper(\iconv('UTF-8', 'ASCII//TRANSLIT', $e1)) <=> strtoupper(\iconv('UTF-8', 'ASCII//TRANSLIT', $e2));
|
||||||
|
$pdo->sqliteCreateCollation('locale_cmp_ci', fn($e1, $e2) => $compCi);
|
||||||
|
$pdo->sqliteCreateCollation('locale_cmp_ci_desc', fn($e2, $e1) => $compCi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function registerPragma(PdoObject $pdo, array $pragmaList) : void
|
||||||
|
{
|
||||||
|
$builder = new QueryBuilder\Sql\SqliteQueryBuilder();
|
||||||
|
|
||||||
|
foreach($pragmaList as $pragma) {
|
||||||
|
list($key, $value) = explode('=', $pragma) + [ null, null ];
|
||||||
|
|
||||||
|
$sql = $builder->pragma($key, $value)->render();
|
||||||
|
$query = $pdo->query($sql);
|
||||||
|
|
||||||
|
if ( ! $query->execute() ) {
|
||||||
|
throw new \InvalidArgumentException(sprintf("Pragma query could not be executed : %s", $sql));
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function splitAlterQuery() : bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Adapter;
|
||||||
|
|
||||||
|
interface SqlAdapterInterface
|
||||||
|
{
|
||||||
|
public static function escapeIdentifier(string $segment, int $type) : string;
|
||||||
|
public function defaultEngine() : ? string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Adapter;
|
||||||
|
|
||||||
|
use Ulmus\{Common\Sql,
|
||||||
|
ConnectionAdapter,
|
||||||
|
Entity\InformationSchema\Table,
|
||||||
|
Migration\FieldDefinition,
|
||||||
|
Repository,
|
||||||
|
QueryBuilder\SqlQueryBuilder,
|
||||||
|
Ulmus};
|
||||||
|
|
||||||
|
trait SqlAdapterTrait
|
||||||
|
{
|
||||||
|
public function repositoryClass() : string
|
||||||
|
{
|
||||||
|
return Repository::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function queryBuilderClass() : string
|
||||||
|
{
|
||||||
|
return SqlQueryBuilder::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tableSyntax() : array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'ai' => "AUTO_INCREMENT",
|
||||||
|
'pk' => "PRIMARY KEY",
|
||||||
|
'unsigned' => "UNSIGNED",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function databaseName() : string
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
$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
|
||||||
|
{
|
||||||
|
switch (true) {
|
||||||
|
case $value instanceof \UnitEnum:
|
||||||
|
return Ulmus::convertEnum($value);
|
||||||
|
|
||||||
|
case is_object($value):
|
||||||
|
return Ulmus::convertObject($value);
|
||||||
|
|
||||||
|
case is_array($value):
|
||||||
|
return json_encode($value);
|
||||||
|
|
||||||
|
case is_bool($value):
|
||||||
|
return (int) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function splitAlterQuery() : bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Adapter;
|
||||||
|
|
||||||
|
use Ulmus\Migration\FieldDefinition;
|
||||||
|
use Ulmus\Entity;
|
||||||
|
|
||||||
|
class SqlFieldMapper
|
||||||
|
{
|
||||||
|
public readonly string $type;
|
||||||
|
|
||||||
|
public readonly string $length;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
public FieldDefinition $field,
|
||||||
|
) {
|
||||||
|
$this->map();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function map() : void
|
||||||
|
{
|
||||||
|
$type = $this->field->type;
|
||||||
|
$length = $this->field->length;
|
||||||
|
|
||||||
|
if ( is_a($type, Entity\Field\Date::class, true) ) {
|
||||||
|
$type = "DATE";
|
||||||
|
}
|
||||||
|
elseif ( is_a($type, Entity\Field\Time::class, true) ) {
|
||||||
|
$type = "TIME";
|
||||||
|
}
|
||||||
|
elseif ( is_a($type, \DateTime::class, true) ) {
|
||||||
|
$type = "DATETIME";
|
||||||
|
}
|
||||||
|
elseif ( enum_exists($type) ) {
|
||||||
|
# Haven't found a better way yet to check for BackendEnum without an instance of the object
|
||||||
|
if ( ! method_exists($type, 'tryFrom') ) {
|
||||||
|
throw new \Ulmus\Exception\BackedEnumRequired(sprintf("You must define your enum as a BackedEnum instead of an UnitEnum for field '%s'.", $this->field->getColumnName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = "string";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($type) {
|
||||||
|
case "bool":
|
||||||
|
$this->type = "TINYINT";
|
||||||
|
$this->length = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "array":
|
||||||
|
$this->type = "JSON";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "string":
|
||||||
|
if ($length && $length <= 255) {
|
||||||
|
$this->type = "VARCHAR";
|
||||||
|
$this->length = $length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elseif (! $length || ( $length <= 65535 ) ) {
|
||||||
|
$this->type = "TEXT";
|
||||||
|
}
|
||||||
|
elseif ( $length <= 16777215 ) {
|
||||||
|
$this->type = "MEDIUMTEXT";
|
||||||
|
}
|
||||||
|
elseif ($length <= 4294967295) {
|
||||||
|
$this->type = "LONGTEXT";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new \Exception("A column with a length bigger than 4GB cannot be created.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Length is unnecessary on TEXT fields
|
||||||
|
unset($length);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "float":
|
||||||
|
$this->type = "DOUBLE";
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ($length) {
|
||||||
|
$this->length = $length;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->type ??= strtoupper($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->postProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render() : string
|
||||||
|
{
|
||||||
|
return $this->type . ( isset($this->length) ? "($this->length)" : "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postProcess() : void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation;
|
|
||||||
|
|
||||||
interface Annotation {}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation;
|
|
||||||
|
|
||||||
use Reflector, ReflectionClass, ReflectionProperty, ReflectionMethod;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class exists while waiting for the official RFC [ https://wiki.php.net/rfc/annotations_v2 ]
|
|
||||||
*/
|
|
||||||
class AnnotationReader
|
|
||||||
{
|
|
||||||
const PHP_TYPES = [ "string", "int", "float", "object", "double", "closure", ];
|
|
||||||
|
|
||||||
public string $class;
|
|
||||||
|
|
||||||
public function __construct($class) {
|
|
||||||
$this->class = $class;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromClass($class) : self
|
|
||||||
{
|
|
||||||
return new static($class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProperty(ReflectionProperty $property)
|
|
||||||
{
|
|
||||||
return $this->parseDocComment($property);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getClass(ReflectionClass $class)
|
|
||||||
{
|
|
||||||
return $this->parseDocComment($class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMethod(ReflectionMethod $method)
|
|
||||||
{
|
|
||||||
return $this->parseDocComment($method);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function parseDocComment(Reflector $reflect)
|
|
||||||
{
|
|
||||||
$namespace = $this->getObjectNamespace($reflect);
|
|
||||||
$tags = [];
|
|
||||||
|
|
||||||
foreach(preg_split("/\r\n|\n|\r/", $reflect->getDocComment()) as $line) {
|
|
||||||
$line = ltrim($line, "* \t\/");
|
|
||||||
$line = rtrim($line, "\t ");
|
|
||||||
|
|
||||||
if ( substr($line, 0, 1) === '@' ) {
|
|
||||||
$line = ltrim($line, '@');
|
|
||||||
|
|
||||||
$open = strpos($line, "(");
|
|
||||||
$close = strrpos($line, ")");
|
|
||||||
|
|
||||||
if ( ! in_array(false, [ $open, $close ], true) && ( ++$open !== $close ) ) {
|
|
||||||
$arguments = substr($line, $open, $close - $open);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$tags[] = [
|
|
||||||
'tag' => substr($line, 0, $open - 1),
|
|
||||||
'arguments' => eval("namespace $namespace; return [ $arguments ];" ),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
catch(\Throwable $error) {
|
|
||||||
throw new \InvalidArgumentException("An error occured while parsing annotation from '" . $this->getObjectName($reflect) . "' : @$line -- " . $error->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$tags[] = [
|
|
||||||
'tag' => $line,
|
|
||||||
'arguments' => [],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getObjectName(Reflector $reflect) : string
|
|
||||||
{
|
|
||||||
switch(true) {
|
|
||||||
case $reflect instanceof ReflectionMethod :
|
|
||||||
case $reflect instanceof ReflectionProperty :
|
|
||||||
return $reflect->class . "::" . $reflect->name;
|
|
||||||
|
|
||||||
case $reflect instanceof ReflectionClass :
|
|
||||||
return $reflect->name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getObjectNamespace(Reflector $reflect) : string
|
|
||||||
{
|
|
||||||
switch(true) {
|
|
||||||
case $reflect instanceof ReflectionMethod :
|
|
||||||
case $reflect instanceof ReflectionProperty :
|
|
||||||
return $reflect->getDeclaringClass()->getNamespaceName();
|
|
||||||
|
|
||||||
case $reflect instanceof ReflectionClass :
|
|
||||||
return $reflect->getNamespaceName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Classes;
|
|
||||||
|
|
||||||
class Collation implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Classes;
|
|
||||||
|
|
||||||
class Method implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Classes;
|
|
||||||
|
|
||||||
class Table implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
public string $name;
|
|
||||||
|
|
||||||
public string $database;
|
|
||||||
|
|
||||||
public string $schema;
|
|
||||||
|
|
||||||
public string $adapter;
|
|
||||||
|
|
||||||
public string $engine;
|
|
||||||
|
|
||||||
public function __construct($name = null, $engine = null)
|
|
||||||
{
|
|
||||||
if ( $name !== null ) {
|
|
||||||
$this->name = $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $engine !== null ) {
|
|
||||||
$this->engine = $engine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class Field implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
public string $type;
|
|
||||||
|
|
||||||
public string $name;
|
|
||||||
|
|
||||||
public int $length;
|
|
||||||
|
|
||||||
public int $precision;
|
|
||||||
|
|
||||||
public array $attributes = [];
|
|
||||||
|
|
||||||
public bool $nullable;
|
|
||||||
|
|
||||||
public bool $readonly = false;
|
|
||||||
|
|
||||||
public function __construct(? string $type = null, ? int $length = null)
|
|
||||||
{
|
|
||||||
if ( $type !== null ) {
|
|
||||||
$this->type = $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $length !== null ) {
|
|
||||||
$this->length = $length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Bigint extends \Ulmus\Annotation\Property\Field
|
|
||||||
{
|
|
||||||
public function __construct(? string $type = "bigint", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Blob extends \Ulmus\Annotation\Property\Field
|
|
||||||
{
|
|
||||||
public function __construct(? string $type = "blob", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class CreatedAt extends \Ulmus\Annotation\Property\Field {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->nullable = false;
|
|
||||||
$this->type = "timestamp";
|
|
||||||
$this->attributes['default'] = "CURRENT_TIMESTAMP";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Date extends \Ulmus\Annotation\Property\Field {
|
|
||||||
|
|
||||||
public function __construct(? string $type = "date", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Datetime extends \Ulmus\Annotation\Property\Field {
|
|
||||||
|
|
||||||
public function __construct(? string $type = "datetime", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Since we need consistancy between the declaration of our ID and FK fields, it
|
|
||||||
* was decided to extend the Id class instead of Field for this case.
|
|
||||||
*/
|
|
||||||
class ForeignKey extends Id {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
unset($this->nullable);
|
|
||||||
$this->attributes['primary_key'] = false;
|
|
||||||
$this->attributes['auto_increment'] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Id extends \Ulmus\Annotation\Property\Field {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->nullable = false;
|
|
||||||
$this->attributes['unsigned'] = true;
|
|
||||||
$this->attributes['primary_key'] = true;
|
|
||||||
$this->attributes['auto_increment'] = true;
|
|
||||||
|
|
||||||
parent::__construct('bigint');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Longblob extends \Ulmus\Annotation\Property\Field
|
|
||||||
{
|
|
||||||
public function __construct(? string $type = "longblob", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Longtext extends \Ulmus\Annotation\Property\Field
|
|
||||||
{
|
|
||||||
public function __construct(? string $type = "longtext", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Mediumblob extends \Ulmus\Annotation\Property\Field
|
|
||||||
{
|
|
||||||
public function __construct(? string $type = "mediumblob", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Mediumtext extends \Ulmus\Annotation\Property\Field
|
|
||||||
{
|
|
||||||
public function __construct(? string $type = "mediumtext", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Text extends \Ulmus\Annotation\Property\Field
|
|
||||||
{
|
|
||||||
public function __construct(? string $type = "text", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Time extends \Ulmus\Annotation\Property\Field {
|
|
||||||
|
|
||||||
public function __construct(? string $type = "time", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Blob extends \Ulmus\Annotation\Property\Field
|
|
||||||
{
|
|
||||||
public function __construct(? string $type = "tinyblob", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class Tinyint extends \Ulmus\Annotation\Property\Field
|
|
||||||
{
|
|
||||||
public function __construct(? string $type = "tinyint", ? int $length = null)
|
|
||||||
{
|
|
||||||
parent::__construct($type, $length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Field;
|
|
||||||
|
|
||||||
class UpdatedAt extends \Ulmus\Annotation\Property\Field {
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->nullable = true;
|
|
||||||
$this->type = "timestamp";
|
|
||||||
$this->attributes['update'] = "CURRENT_TIMESTAMP";
|
|
||||||
$this->attributes['default'] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class Filter implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
public string $method;
|
|
||||||
|
|
||||||
public function __construct(string $method = null)
|
|
||||||
{
|
|
||||||
if ( $method !== null ) {
|
|
||||||
$this->method = $method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class FilterJoin implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
public string $method;
|
|
||||||
|
|
||||||
public function __construct(string $method = null)
|
|
||||||
{
|
|
||||||
if ( $method !== null ) {
|
|
||||||
$this->method = $method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class Having extends Where {}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class Join implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
public string $type;
|
|
||||||
|
|
||||||
public /*string|Stringable*/ $key;
|
|
||||||
|
|
||||||
public /*string|Stringable*/ $foreignKey;
|
|
||||||
|
|
||||||
public string $entity;
|
|
||||||
|
|
||||||
public string $alias;
|
|
||||||
|
|
||||||
public function __construct(? string $type = null, /*? string|Stringable*/ $key = null, /*? string|Stringable*/ $foreignKey = null)
|
|
||||||
{
|
|
||||||
if ($type !== null) {
|
|
||||||
$this->type = $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($key !== null) {
|
|
||||||
$this->key = $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($foreignKey !== null) {
|
|
||||||
$this->foreignKey = $foreignKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class On extends Where {}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
use Ulmus\Query;
|
|
||||||
|
|
||||||
class OrWhere extends Where {
|
|
||||||
|
|
||||||
public function __construct(/* ? Stringable */ $field = null, $value = null, ? string $operator = null, ? string $condition = null)
|
|
||||||
{
|
|
||||||
parent::__construct($field, $value, $operator, Query\Where::CONDITION_OR);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class OrderBy implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
public string $field;
|
|
||||||
|
|
||||||
public string $order = "ASC";
|
|
||||||
|
|
||||||
public function __construct(string $field = null, string $order = null)
|
|
||||||
{
|
|
||||||
if ( $field !== null ) {
|
|
||||||
$this->field = $field;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $order !== null ) {
|
|
||||||
$this->order = $order;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class Relation implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
public string $type;
|
|
||||||
|
|
||||||
public /*stringable*/ $key;
|
|
||||||
|
|
||||||
public /* callable */ $generateKey;
|
|
||||||
|
|
||||||
public /*stringable*/ $foreignKey;
|
|
||||||
|
|
||||||
public array $foreignKeys;
|
|
||||||
|
|
||||||
public string $bridge;
|
|
||||||
|
|
||||||
public /*stringable*/ $bridgeKey;
|
|
||||||
|
|
||||||
public /*stringable*/ $bridgeForeignKey;
|
|
||||||
|
|
||||||
public string $entity;
|
|
||||||
|
|
||||||
public string $join;
|
|
||||||
|
|
||||||
public string $function = "loadAll";
|
|
||||||
|
|
||||||
public function __construct(string $type = null)
|
|
||||||
{
|
|
||||||
if ( $type !== null ) {
|
|
||||||
$this->type = $type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function entity() {
|
|
||||||
try {
|
|
||||||
$e = $this->entity;
|
|
||||||
} catch (\Throwable $ex) {
|
|
||||||
throw new \Exception("Your @Relation annotation seems to be missing an `entity` entry.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new $e();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function bridge() {
|
|
||||||
$e = $this->bridge;
|
|
||||||
|
|
||||||
return new $e();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function normalizeType() : string
|
|
||||||
{
|
|
||||||
return strtolower(str_replace(['-', '_', ' '], '', $this->type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isOneToOne() : bool
|
|
||||||
{
|
|
||||||
return $this->normalizeType() === 'onetoone';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isOneToMany() : bool
|
|
||||||
{
|
|
||||||
return $this->normalizeType() === 'onetomany';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isManyToMany() : bool
|
|
||||||
{
|
|
||||||
return $this->normalizeType() === 'manytomany';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasBridge() : bool
|
|
||||||
{
|
|
||||||
return isset($this->bridge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property\Relation;
|
|
||||||
|
|
||||||
class Ignore implements \Ulmus\Annotation\Annotation {}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class Virtual extends Field {
|
|
||||||
public Closure $closure;
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
use Ulmus\Query;
|
|
||||||
|
|
||||||
class Where implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
public /* stringable */ $field;
|
|
||||||
|
|
||||||
public $value;
|
|
||||||
|
|
||||||
public string $operator;
|
|
||||||
|
|
||||||
public string $condition;
|
|
||||||
|
|
||||||
public function __construct(/* ? Stringable */ $field = null, $value = null, ? string $operator = null, ? string $condition = null)
|
|
||||||
{
|
|
||||||
if ( $field !== null ) {
|
|
||||||
$this->field = $field;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $value !== null ) {
|
|
||||||
$this->value = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->operator = $operator !== null ? $operator : Query\Where::OPERATOR_EQUAL;
|
|
||||||
$this->condition = $condition !== null ? $condition : Query\Where::CONDITION_AND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
|
||||||
|
|
||||||
class WithJoin implements \Ulmus\Annotation\Annotation {
|
|
||||||
|
|
||||||
protected array $joins;
|
|
||||||
|
|
||||||
public function __construct(/*Stringable|array|null*/ $joins = null)
|
|
||||||
{
|
|
||||||
if ( $joins ) {
|
|
||||||
$this->joins = (array)$joins;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute;
|
||||||
|
|
||||||
|
use Ulmus\Common\EntityField;
|
||||||
|
use Ulmus\Repository;
|
||||||
|
|
||||||
|
class Attribute
|
||||||
|
{
|
||||||
|
public static function handleArrayField(null|\Stringable|string|array $field, null|string|bool $alias = Repository::DEFAULT_ALIAS, string $separator = ', ') : mixed
|
||||||
|
{
|
||||||
|
if ( is_array($field) ) {
|
||||||
|
$class = array_shift($field);
|
||||||
|
$field[1] ??= $alias;
|
||||||
|
|
||||||
|
if (is_array($field[0])) {
|
||||||
|
$field[] = $separator;
|
||||||
|
return $class::fields(...$field);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $class::field(...$field);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $field;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute;
|
||||||
|
|
||||||
|
enum ConstrainActionEnum : string
|
||||||
|
{
|
||||||
|
case Cascade = 'cascade';
|
||||||
|
|
||||||
|
case NoAction = 'noaction';
|
||||||
|
|
||||||
|
case Restrict = 'restrict';
|
||||||
|
|
||||||
|
case SetNull = 'setnull';
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute;
|
||||||
|
|
||||||
|
enum IndexTypeEnum : string
|
||||||
|
{
|
||||||
|
case Primary = 'primary';
|
||||||
|
|
||||||
|
case Index = 'index';
|
||||||
|
|
||||||
|
case Unique = 'unique';
|
||||||
|
|
||||||
|
case Spatial = 'spatial';
|
||||||
|
|
||||||
|
case Fulltext = 'fulltext';
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Obj;
|
||||||
|
|
||||||
|
interface AdapterAttributeInterface
|
||||||
|
{
|
||||||
|
public function adapter() : false|string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Obj;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_CLASS)]
|
||||||
|
class Collation {
|
||||||
|
public function __construct(
|
||||||
|
public string $name = ""
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Obj;
|
||||||
|
|
||||||
|
use Ulmus\Attribute\Attribute;
|
||||||
|
use Ulmus\Attribute\ConstrainActionEnum;
|
||||||
|
use Ulmus\Attribute\IndexTypeEnum;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
|
||||||
|
class Constrain {
|
||||||
|
public function __construct(
|
||||||
|
public array $columns,
|
||||||
|
public null|IndexTypeEnum $type = null,
|
||||||
|
public null|string $name = null,
|
||||||
|
public null|array|string|\Stringable $foreignKey = null,
|
||||||
|
public null|array|string|\Stringable $references = null,
|
||||||
|
public ConstrainActionEnum $onDelete = ConstrainActionEnum::NoAction,
|
||||||
|
public ConstrainActionEnum $onUpdate = ConstrainActionEnum::NoAction,
|
||||||
|
) {
|
||||||
|
$this->foreignKey = Attribute::handleArrayField($this->foreignKey, false);
|
||||||
|
$this->references = Attribute::handleArrayField($this->references, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Obj;
|
||||||
|
|
||||||
|
use Ulmus\Attribute\IndexTypeEnum;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
|
||||||
|
class Index {
|
||||||
|
public function __construct(
|
||||||
|
public string|array $column,
|
||||||
|
public IndexTypeEnum $type = IndexTypeEnum::Unique,
|
||||||
|
public null|string $name = null,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Obj;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_CLASS)]
|
||||||
|
class Method {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Obj;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_CLASS)]
|
||||||
|
class Table implements AdapterAttributeInterface {
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $database = null,
|
||||||
|
public ? string $schema = null,
|
||||||
|
public ? string $adapter = null,
|
||||||
|
public ? string $engine = null,
|
||||||
|
public string $description = "",
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function adapter() : false|string
|
||||||
|
{
|
||||||
|
return $this->adapter ?: false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Collation {
|
||||||
|
public function __construct(
|
||||||
|
public string $name = ""
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Field {
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = null,
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
public null|int $decimal = null,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Bigint extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "bigint",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Binary extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "binary",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
public string $description = "",
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Bit extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "bit",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Blob extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "blob",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Char extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "char",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
public string $description = "",
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class CreatedAt extends \Ulmus\Attribute\Property\Field {
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "timestamp",
|
||||||
|
public array $attributes = [
|
||||||
|
'default' => "CURRENT_TIMESTAMP",
|
||||||
|
],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Date extends \Ulmus\Attribute\Property\Field {
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "date",
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Datetime extends \Ulmus\Attribute\Property\Field {
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "datetime",
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Decimal extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "decimal",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Double extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "float",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
public string $description = "",
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Float extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "float",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
use Ulmus\Attribute\Attribute;
|
||||||
|
use Ulmus\Attribute\ConstrainActionEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class ForeignKey extends PrimaryKey {
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = null,
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [
|
||||||
|
'primary_key' => false,
|
||||||
|
'auto_increment' => false
|
||||||
|
],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
public null|string $relation = null,
|
||||||
|
public ConstrainActionEnum $onDelete = ConstrainActionEnum::NoAction,
|
||||||
|
public ConstrainActionEnum $onUpdate = ConstrainActionEnum::NoAction,
|
||||||
|
) {
|
||||||
|
#$this->references = Attribute::handleArrayField($this->references, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Id extends \Ulmus\Attribute\Property\Field {
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = 'bigint',
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [
|
||||||
|
'unsigned' => true,
|
||||||
|
'auto_increment' => true,
|
||||||
|
'primary_key' => true,
|
||||||
|
],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = true,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Json extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "json",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
public string $description = "",
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Longblob extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "longblob",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Longtext extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "longtext",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Mediumblob extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "mediumblob",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Mediumint extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "mediumint",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Mediumtext extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "mediumtext",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Numeric extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "numeric",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class PrimaryKey extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = 'bigint',
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [
|
||||||
|
'primary_key' => true,
|
||||||
|
],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Smallint extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "smallint",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Text extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "text",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Time extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "time",
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Timestamp extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "timestamp",
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Blob extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "tinyblob",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Tinyint extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "tinyint",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Tinytext extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "tinytext",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class UpdatedAt extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "timestamp",
|
||||||
|
public array $attributes = [
|
||||||
|
'update' => "CURRENT_TIMESTAMP",
|
||||||
|
'default' => null,
|
||||||
|
],
|
||||||
|
public bool $nullable = true,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Varbinary extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "varbinary",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
public string $description = "",
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Varchar extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "varchar",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
public string $description = "",
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Year extends \Ulmus\Attribute\Property\Field
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ? string $name = null,
|
||||||
|
public ? string $type = "year",
|
||||||
|
public null|int|string $length = null,
|
||||||
|
public ? int $precision = null,
|
||||||
|
public array $attributes = [],
|
||||||
|
public bool $nullable = false,
|
||||||
|
public mixed $default = null,
|
||||||
|
public bool $readonly = false,
|
||||||
|
public string $description = "",
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)]
|
||||||
|
class Filter {
|
||||||
|
public function __construct(
|
||||||
|
public string $method = ""
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)]
|
||||||
|
class FilterJoin {
|
||||||
|
public function __construct(
|
||||||
|
public string $method = ""
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Ulmus\Annotation\Property;
|
namespace Ulmus\Attribute\Property;
|
||||||
|
|
||||||
class GroupBy implements \Ulmus\Annotation\Annotation {
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)]
|
||||||
|
class GroupBy {
|
||||||
|
|
||||||
public array $fields = [];
|
public array $fields = [];
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)]
|
||||||
|
class Having extends Where {}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property;
|
||||||
|
|
||||||
|
use Ulmus\Attribute\IndexTypeEnum;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Index {
|
||||||
|
public function __construct(
|
||||||
|
public IndexTypeEnum $type = IndexTypeEnum::Index,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property;
|
||||||
|
|
||||||
|
use Ulmus\Attribute\Attribute;
|
||||||
|
|
||||||
|
#[\Attribute]
|
||||||
|
class Join implements ResettablePropertyInterface {
|
||||||
|
public function __construct(
|
||||||
|
public string $type,
|
||||||
|
public null|string|\Stringable|array $key = null,
|
||||||
|
public null|string|\Stringable|array $foreignKey = null,
|
||||||
|
public null|string $entity = null,
|
||||||
|
public null|string $alias = null,
|
||||||
|
) {
|
||||||
|
$this->key = Attribute::handleArrayField($this->key);
|
||||||
|
$this->foreignKey = Attribute::handleArrayField($this->foreignKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)]
|
||||||
|
class On extends Where {}
|
||||||
Loaded 100 of 200 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user