Compare commits
	
		
			4 Commits
		
	
	
		
			26febb631d
			...
			197eee90f7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 197eee90f7 | |||
| 0a7ff4fd21 | |||
| 00e20a7692 | |||
| d600908f47 | 
							
								
								
									
										95
									
								
								docs/00-intro.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								docs/00-intro.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,95 @@
 | 
			
		||||
# Ulmus
 | 
			
		||||
 | 
			
		||||
Welcome to the official Ulmus documentation.
 | 
			
		||||
 | 
			
		||||
## Quick start
 | 
			
		||||
 | 
			
		||||
Creating a simple user entity:
 | 
			
		||||
 | 
			
		||||
*/app/entity/user.php*
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace MyApp\Entity;
 | 
			
		||||
 | 
			
		||||
use Ulmus\Entity\Field\Datetime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Table('name' => "user")
 | 
			
		||||
 */
 | 
			
		||||
class User
 | 
			
		||||
{
 | 
			
		||||
    use \Ulmus\EntityTrait;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
    * @Id
 | 
			
		||||
    */
 | 
			
		||||
    public int $id;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
    * @Field 
 | 
			
		||||
    */
 | 
			
		||||
    public string $fullname;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
    * @Field 
 | 
			
		||||
    */
 | 
			
		||||
    public ? string $email;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
    * @Field('name' => 'is_admin')
 | 
			
		||||
    */
 | 
			
		||||
    public bool $isAdmin = false;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
    * @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
									
								
								docs/01-load.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/01-load.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/01-save.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/01-save.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/10-join.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/10-join.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/10-relation.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/10-relation.md
									
									
									
									
									
										Normal file
									
								
							@ -19,7 +19,8 @@ interface AdapterInterface {
 | 
			
		||||
    public function defaultEngine() : ? string;
 | 
			
		||||
 | 
			
		||||
    public function writableValue(/* mixed */ $value); /*: mixed*/
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    /*   public function databaseName() : string;
 | 
			
		||||
    public function mapFieldType(FieldDefinition $field) : string;
 | 
			
		||||
    public function schemaTable(string $databaseName, string $tableName) /*: object|EntityCollection
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
namespace Ulmus\Adapter;
 | 
			
		||||
 | 
			
		||||
use Ulmus\{Entity\InformationSchema\Table, Migration\FieldDefinition, Repository, QueryBuilder};
 | 
			
		||||
use Ulmus\{ConnectionAdapter, Entity\InformationSchema\Table, Migration\FieldDefinition, Repository, QueryBuilder};
 | 
			
		||||
 | 
			
		||||
trait DefaultAdapterTrait
 | 
			
		||||
{
 | 
			
		||||
@ -30,9 +30,9 @@ trait DefaultAdapterTrait
 | 
			
		||||
        return $this->database;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function schemaTable(string $databaseName, string $tableName) /* : ? object */
 | 
			
		||||
    public function schemaTable(ConnectionAdapter $parent, $databaseName, string $tableName) /* : ? object */
 | 
			
		||||
    {
 | 
			
		||||
        return Table::repository()->where(Table::field('schema'), $databaseName)->loadOneFromField(Table::field('name'), $tableName);
 | 
			
		||||
        return Table::repository(Repository::DEFAULT_ALIAS, $parent)->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
 | 
			
		||||
 | 
			
		||||
@ -83,6 +83,9 @@ class MsSQL implements AdapterInterface {
 | 
			
		||||
        catch(PDOException $ex){
 | 
			
		||||
            throw $ex;
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            $this->password = str_repeat('*', random_int(8,16));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $pdo;
 | 
			
		||||
    }
 | 
			
		||||
@ -212,9 +215,12 @@ class MsSQL implements AdapterInterface {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function writableValue(/* mixed */ $value) /*: mixed*/
 | 
			
		||||
    public function writableValue(mixed $value) /*: mixed*/
 | 
			
		||||
    {
 | 
			
		||||
        switch (true) {
 | 
			
		||||
            case $value instanceof \UnitEnum:
 | 
			
		||||
                return Ulmus::convertEnum($value);
 | 
			
		||||
 | 
			
		||||
            case is_object($value):
 | 
			
		||||
                return Ulmus::convertObject($value);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -77,7 +77,7 @@ class MySQL implements AdapterInterface {
 | 
			
		||||
            throw $ex;
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            $this->password = str_repeat('*', strlen($this->password));
 | 
			
		||||
            $this->password = str_repeat('*', random_int(8,16));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $pdo;
 | 
			
		||||
@ -148,9 +148,12 @@ class MySQL implements AdapterInterface {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function writableValue(/* mixed */ $value) /*: mixed*/
 | 
			
		||||
    public function writableValue(mixed  $value) : mixed
 | 
			
		||||
    {
 | 
			
		||||
        switch (true) {
 | 
			
		||||
            case $value instanceof \UnitEnum:
 | 
			
		||||
                return Ulmus::convertEnum($value);
 | 
			
		||||
 | 
			
		||||
            case is_object($value):
 | 
			
		||||
                return Ulmus::convertObject($value);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -87,7 +87,7 @@ class SQLite implements AdapterInterface {
 | 
			
		||||
        return substr($base, 0, strrpos($base, '.') ?: strlen($base));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function schemaTable(string $databaseName, string $tableName) /* : ? object */
 | 
			
		||||
    public function schemaTable(string $databaseName, string $tableName) : null|object
 | 
			
		||||
    {
 | 
			
		||||
        return Table::repository()->loadOneFromField(Table::field('tableName'), $tableName);
 | 
			
		||||
    }
 | 
			
		||||
@ -131,9 +131,12 @@ class SQLite implements AdapterInterface {
 | 
			
		||||
        return $typeOnly ? $type : $type . ( $length ? "($length" . ( isset($precision) ? ",$precision" : "" ) . ")" : "" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function writableValue(/* mixed */ $value) /*: mixed*/
 | 
			
		||||
    public function writableValue(mixed  $value) /*: mixed*/
 | 
			
		||||
    {
 | 
			
		||||
        switch (true) {
 | 
			
		||||
            case $value instanceof \UnitEnum:
 | 
			
		||||
                return Ulmus::convertEnum($value);
 | 
			
		||||
 | 
			
		||||
            case is_object($value):
 | 
			
		||||
                return Ulmus::convertObject($value);
 | 
			
		||||
 | 
			
		||||
@ -168,6 +171,8 @@ class SQLite implements AdapterInterface {
 | 
			
		||||
 | 
			
		||||
    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('left', fn($string, $length) => substr($string, 0, $length), 2);
 | 
			
		||||
@ -189,4 +194,4 @@ class SQLite implements AdapterInterface {
 | 
			
		||||
            return (int) in_array($string, explode(',', $string_list));
 | 
			
		||||
        }, 2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -38,7 +38,7 @@ class ConnectionAdapter
 | 
			
		||||
        
 | 
			
		||||
        $this->adapter->setup($connection);
 | 
			
		||||
 | 
			
		||||
        unset($this->configuration['connections'][$this->name]);
 | 
			
		||||
        unset($this->configuration['connections']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getConfiguration() : array
 | 
			
		||||
@ -71,7 +71,7 @@ class ConnectionAdapter
 | 
			
		||||
    {
 | 
			
		||||
        return $this->pdo();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Instanciate an adapter which interact with the data source
 | 
			
		||||
     * @param  string $name An Ulmus adapter or full class name implementing AdapterInterface
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,16 @@ class ObjectInstanciator {
 | 
			
		||||
        
 | 
			
		||||
        return (string) $obj;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    public function enum(\UnitEnum $obj)
 | 
			
		||||
    {
 | 
			
		||||
        if (! $obj instanceof \BackedEnum) {
 | 
			
		||||
            throw new \Ulmus\Exception\BackedEnumRequired("Unable to extract a UnitEnum value from this variable. You must define your enum as a BackedEnum instead of an UnitEnum.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $obj->value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function registerObject(string $type, Callable $callback) : void
 | 
			
		||||
    {
 | 
			
		||||
        $this->objectCallbackDefinition[$type] = $callback;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										48
									
								
								src/Entity/Sqlite/Column.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/Entity/Sqlite/Column.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Ulmus\Entity\Sqlite;
 | 
			
		||||
 | 
			
		||||
use Ulmus\EntityCollection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Table
 | 
			
		||||
 */
 | 
			
		||||
class Column
 | 
			
		||||
{
 | 
			
		||||
    use \Ulmus\EntityTrait;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Id
 | 
			
		||||
     */
 | 
			
		||||
    public int $cid;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Field
 | 
			
		||||
     */
 | 
			
		||||
    public string $type;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Field
 | 
			
		||||
     */
 | 
			
		||||
    public string $name;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Virtual
 | 
			
		||||
     */
 | 
			
		||||
    public string $tableName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Field('name' => "notnull")
 | 
			
		||||
     */
 | 
			
		||||
    public bool $notNull;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Field('name' => 'dflt_value')
 | 
			
		||||
     */
 | 
			
		||||
    public ? string $defaultValue;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Field('name' => "pk")
 | 
			
		||||
     */
 | 
			
		||||
    public bool $primaryKey;
 | 
			
		||||
}
 | 
			
		||||
@ -2,13 +2,14 @@
 | 
			
		||||
 | 
			
		||||
namespace Ulmus\Entity\Sqlite;
 | 
			
		||||
 | 
			
		||||
use Ulmus\ConnectionAdapter;
 | 
			
		||||
use Ulmus\Repository;
 | 
			
		||||
 | 
			
		||||
class Table extends Schema
 | 
			
		||||
{
 | 
			
		||||
    public static function repository(string $alias = Repository::DEFAULT_ALIAS): Repository
 | 
			
		||||
    public static function repository(string $alias = Repository::DEFAULT_ALIAS, ConnectionAdapter $adapter = null): Repository
 | 
			
		||||
    {
 | 
			
		||||
        return new class(static::class, $alias) extends Repository\SqliteRepository
 | 
			
		||||
        return new class(static::class, $alias, $adapter) extends Repository\SqliteRepository
 | 
			
		||||
        {
 | 
			
		||||
            public function finalizeQuery(): void
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
@ -78,11 +78,19 @@ trait EntityTrait {
 | 
			
		||||
 | 
			
		||||
                $this->{$field['name']} = $value;
 | 
			
		||||
            }
 | 
			
		||||
            elseif ( $value instanceof \UnitEnum ) {
 | 
			
		||||
                $this->{$field['name']} = $value;
 | 
			
		||||
            }
 | 
			
		||||
            elseif (enum_exists($field['type'])) {
 | 
			
		||||
                $this->{$field['name']} = $field['type']::from($value);
 | 
			
		||||
            }
 | 
			
		||||
            elseif ( ! $field['builtin'] ) {
 | 
			
		||||
                try {
 | 
			
		||||
                    $this->{$field['name']} = Ulmus::instanciateObject($field['type'], [ $value ]);
 | 
			
		||||
                }
 | 
			
		||||
                catch(\Error $e) {
 | 
			
		||||
                    $f = $field['type'];
 | 
			
		||||
                    dump($f, $f::from($value));
 | 
			
		||||
                    throw new \Error(sprintf("%s for class '%s' on field '%s'", $e->getMessage(), get_class($this), $field['name']));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@ -99,7 +107,7 @@ trait EntityTrait {
 | 
			
		||||
                $this->entityLoadedDataset = array_change_key_case($dataset, \CASE_LOWER) + $this->entityLoadedDataset;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -285,9 +293,9 @@ trait EntityTrait {
 | 
			
		||||
    /**
 | 
			
		||||
     * @Ignore
 | 
			
		||||
     */
 | 
			
		||||
    public static function repository(string $alias = Repository::DEFAULT_ALIAS) : Repository
 | 
			
		||||
    public static function repository(string $alias = Repository::DEFAULT_ALIAS, ConnectionAdapter $adapter = null) : Repository
 | 
			
		||||
    {
 | 
			
		||||
        return Ulmus::repository(static::class, $alias);
 | 
			
		||||
        return Ulmus::repository(static::class, $alias, $adapter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -301,7 +309,6 @@ trait EntityTrait {
 | 
			
		||||
        return $collection;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @Ignore
 | 
			
		||||
     */
 | 
			
		||||
@ -315,6 +322,7 @@ trait EntityTrait {
 | 
			
		||||
     */
 | 
			
		||||
    public static function field($name, ? string $alias = Repository::DEFAULT_ALIAS) : EntityField
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        return new EntityField(static::class, $name, $alias ? Ulmus::repository(static::class)->adapter->adapter()->escapeIdentifier($alias, Adapter\AdapterInterface::IDENTIFIER_FIELD) : Repository::DEFAULT_ALIAS, Ulmus::resolveEntity(static::class));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								src/Exception/BackedEnumRequired.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/Exception/BackedEnumRequired.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Ulmus\Exception;
 | 
			
		||||
 | 
			
		||||
class BackedEnumRequired extends \RuntimeException {}
 | 
			
		||||
							
								
								
									
										45
									
								
								src/Query/Show.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/Query/Show.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Ulmus\Query;
 | 
			
		||||
 | 
			
		||||
class Show extends Fragment {
 | 
			
		||||
 | 
			
		||||
    public int $order = -100;
 | 
			
		||||
 | 
			
		||||
    const SQL_TOKEN = "SHOW";
 | 
			
		||||
 | 
			
		||||
    const SQL_TOKEN_FROM = "FROM";
 | 
			
		||||
 | 
			
		||||
    const SQL_SHOW_DATABASES = "DATABASES";
 | 
			
		||||
 | 
			
		||||
    const SQL_SHOW_TABLES = "TABLES";
 | 
			
		||||
 | 
			
		||||
    public string $show;
 | 
			
		||||
 | 
			
		||||
    public string $from;
 | 
			
		||||
 | 
			
		||||
    public string $in;
 | 
			
		||||
 | 
			
		||||
    public function set(string $show, ? string $from = null, ? string $in = null) : self
 | 
			
		||||
    {
 | 
			
		||||
        $this->show = $show;
 | 
			
		||||
 | 
			
		||||
        if ( $from !== null ) {
 | 
			
		||||
            $this->from = $from;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ( $in !== null ) {
 | 
			
		||||
            $this->in = $in;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function render() : string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->renderSegments([
 | 
			
		||||
            static::SQL_TOKEN, $this->show,
 | 
			
		||||
        ] + ( ! empty($this->from) ? [ static::SQL_TOKEN_FROM, $this->from ] : [] ) + ( ! empty($this->in) ? [ static::SQL_TOKEN_IN, $this->in ] : [] ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -314,6 +314,39 @@ class QueryBuilder implements Query\QueryBuilderInterface
 | 
			
		||||
        return $join;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showDatabases() : self
 | 
			
		||||
    {
 | 
			
		||||
        $show = new Query\Show();
 | 
			
		||||
 | 
			
		||||
        $this->push($show);
 | 
			
		||||
 | 
			
		||||
        $show->set(Query\Show::SQL_SHOW_DATABASES);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showTables(? string $database = null) : self
 | 
			
		||||
    {
 | 
			
		||||
        $show = new Query\Show();
 | 
			
		||||
 | 
			
		||||
        $this->push($show);
 | 
			
		||||
 | 
			
		||||
        $show->set(Query\Show::SQL_SHOW_TABLES, $database);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showColumns(string $table) : self
 | 
			
		||||
    {
 | 
			
		||||
        $show = new Query\Show();
 | 
			
		||||
 | 
			
		||||
        $this->push($show);
 | 
			
		||||
 | 
			
		||||
        $show->set(Query\Show::SQL_SHOW_COLUMNS, $table);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function truncate(string $table, ? string $alias = null, ? string $database = null, ? string $schema = null) : self
 | 
			
		||||
    {
 | 
			
		||||
        if ( $schema ) {
 | 
			
		||||
 | 
			
		||||
@ -21,4 +21,22 @@ class SqliteQueryBuilder extends QueryBuilder implements Query\QueryBuilderInter
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function showColumns(string $table) : self
 | 
			
		||||
    {
 | 
			
		||||
        $this->pragma('table_info', $table, true);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showTables(? string $database = null) : self
 | 
			
		||||
    {
 | 
			
		||||
        $show = new Query\Show();
 | 
			
		||||
 | 
			
		||||
        $this->push($show);
 | 
			
		||||
 | 
			
		||||
        $show->set(Query\Show::SQL_SHOW_TABLES, $database);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@ class Repository
 | 
			
		||||
 | 
			
		||||
    public function loadOne() : ? object
 | 
			
		||||
    {
 | 
			
		||||
        return $this->limit(1)->collectionFromQuery()[0] ?? null;
 | 
			
		||||
        return $this->limit(1)->selectSqlQuery()->collectionFromQuery()[0] ?? null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function loadOneFromField($field, $value) : ? object
 | 
			
		||||
@ -53,7 +53,7 @@ class Repository
 | 
			
		||||
 | 
			
		||||
    public function loadAll() : EntityCollection
 | 
			
		||||
    {
 | 
			
		||||
        return $this->collectionFromQuery();
 | 
			
		||||
        return $this->selectSqlQuery()->collectionFromQuery();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function loadAllFromField($field, $value, $operator= Query\Where::OPERATOR_EQUAL) : EntityCollection
 | 
			
		||||
@ -63,7 +63,7 @@ class Repository
 | 
			
		||||
 | 
			
		||||
    public function loadFromField($field, $value, $operator= Query\Where::OPERATOR_EQUAL) : EntityCollection
 | 
			
		||||
    {
 | 
			
		||||
        return $this->where($field, $value, $operator)->collectionFromQuery();
 | 
			
		||||
        return $this->selectSqlQuery()->where($field, $value, $operator)->collectionFromQuery();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function count() : int
 | 
			
		||||
@ -278,7 +278,7 @@ class Repository
 | 
			
		||||
 | 
			
		||||
        $this->finalizeQuery();
 | 
			
		||||
 | 
			
		||||
        $result = Ulmus::runSelectQuery($this->queryBuilder, $this->adapter);
 | 
			
		||||
        # ??? $result = Ulmus::runSelectQuery($this->queryBuilder, $this->adapter);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
@ -288,12 +288,26 @@ class Repository
 | 
			
		||||
        return $this->createSqlQuery()->runQuery();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function listTables(? string $database = null)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->showTablesSqlQuery($database)->runQuery();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function listColumns(? string $table = null)
 | 
			
		||||
    {
 | 
			
		||||
        $table ??= $this->entityResolver->tableName();
 | 
			
		||||
 | 
			
		||||
        $this->showColumnsSqlQuery($table);
 | 
			
		||||
 | 
			
		||||
        return $this->collectionFromQuery(Entity\InformationSchema\Column::class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function generateDatasetDiff(object $entity, bool $oldValues = false) : array
 | 
			
		||||
    {
 | 
			
		||||
        $array = array_change_key_case($entity->toArray());
 | 
			
		||||
 | 
			
		||||
        $dataset = array_change_key_case($entity->entityGetDataset(false, true));
 | 
			
		||||
 | 
			
		||||
# dump($array, $dataset);
 | 
			
		||||
        return array_udiff_assoc($oldValues ? $dataset : $array , $oldValues ? $array : $dataset, function($e1, $e2) {
 | 
			
		||||
            if ( is_array($e1) ) {
 | 
			
		||||
                if (is_array($e2)) {
 | 
			
		||||
@ -584,7 +598,9 @@ class Repository
 | 
			
		||||
                    if ( null === $entity::resolveEntity()->searchFieldAnnotation($field['name'], new RelationIgnore) ) {
 | 
			
		||||
                        $escAlias = $this->escapeIdentifier($alias);
 | 
			
		||||
 | 
			
		||||
                        $this->select("$escAlias.$key as $alias\${$field['name']}");
 | 
			
		||||
                        $name = $entity::resolveEntity()->searchFieldAnnotation($field['name'], new Field())->name ?? $field['name'];
 | 
			
		||||
 | 
			
		||||
                        $this->select("$escAlias.$key as $alias\${$name}");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -785,14 +801,12 @@ class Repository
 | 
			
		||||
 | 
			
		||||
    public function collectionFromQuery(? string $entityClass = null) : EntityCollection
 | 
			
		||||
    {
 | 
			
		||||
        $class = $entityClass ?: $this->entityClass;
 | 
			
		||||
        $class = $entityClass ?? $this->entityClass;
 | 
			
		||||
 | 
			
		||||
        $entityCollection = $this->instanciateEntityCollection();
 | 
			
		||||
 | 
			
		||||
        $this->selectSqlQuery();
 | 
			
		||||
        $entityCollection = $class::entityCollection();
 | 
			
		||||
 | 
			
		||||
        $this->finalizeQuery();
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        foreach(Ulmus::iterateQueryBuilder($this->queryBuilder, $this->adapter) as $entityData) {
 | 
			
		||||
            $entityCollection->append( ( new $class() )->resetVirtualProperties()->entityFillFromDataset($entityData) );
 | 
			
		||||
        }
 | 
			
		||||
@ -916,6 +930,33 @@ class Repository
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showDatabasesSqlQuery() : self
 | 
			
		||||
    {
 | 
			
		||||
        if ( null === $this->queryBuilder->getFragment(Query\Show::class) ) {
 | 
			
		||||
            $this->queryBuilder->showDatabases();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showTablesSqlQuery() : self
 | 
			
		||||
    {
 | 
			
		||||
        if ( null === $this->queryBuilder->getFragment(Query\Show::class) ) {
 | 
			
		||||
            $this->queryBuilder->showTables();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showColumnsSqlQuery(string $table) : self
 | 
			
		||||
    {
 | 
			
		||||
        if ( null === $this->queryBuilder->getFragment(Query\Show::class) ) {
 | 
			
		||||
            $this->queryBuilder->showColumns($table);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function fromRow($row) : self
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
namespace Ulmus\Repository;
 | 
			
		||||
 | 
			
		||||
use Ulmus\{ConnectionAdapter, QueryBuilder, Repository, Query, Ulmus};
 | 
			
		||||
use Ulmus\{ConnectionAdapter, QueryBuilder, Repository, Query, Ulmus, Entity};
 | 
			
		||||
 | 
			
		||||
class SqliteRepository extends Repository {
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,15 @@ class SqliteRepository extends Repository {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function listColumns(? string $table = null)
 | 
			
		||||
    {
 | 
			
		||||
        $table ??= $this->entityResolver->tableName();
 | 
			
		||||
        $this->showColumnsSqlQuery($table);
 | 
			
		||||
 | 
			
		||||
        return $this->collectionFromQuery(Entity\Sqlite\Column::class)->iterate(fn($e) => $e->tableName = $table);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected function serverRequestCountRepository() : Repository
 | 
			
		||||
    {
 | 
			
		||||
        return new static($this->entityClass, $this->alias, $this->adapter);
 | 
			
		||||
 | 
			
		||||
@ -107,11 +107,12 @@ abstract class Ulmus
 | 
			
		||||
        return static::$resolved[$entityClass] ?? static::$resolved[$entityClass] = new Common\EntityResolver($entityClass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function repository(string $entityClass, ...$arguments) : Repository
 | 
			
		||||
    public static function repository(string $entityClass, string $alias = Repository::DEFAULT_ALIAS, ConnectionAdapter $adapter = null) : Repository
 | 
			
		||||
    {
 | 
			
		||||
        $cls = $entityClass::resolveEntity()->sqlAdapter()->adapter()->repositoryClass();
 | 
			
		||||
        $adapter ??= $entityClass::resolveEntity()->sqlAdapter();
 | 
			
		||||
        $cls = $adapter->adapter()->repositoryClass();
 | 
			
		||||
 | 
			
		||||
        return new $cls($entityClass, ...$arguments);
 | 
			
		||||
        return new $cls($entityClass, $alias, $adapter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function queryBuilder($entityClass, ...$arguments) : Query\QueryBuilderInterface
 | 
			
		||||
@ -130,12 +131,17 @@ abstract class Ulmus
 | 
			
		||||
    {
 | 
			
		||||
        return ( static::$objectInstanciator ?? static::$objectInstanciator = new Entity\ObjectInstanciator() )->convert($obj);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    public static function convertEnum(\UnitEnum $enum)
 | 
			
		||||
    {
 | 
			
		||||
        return ( static::$objectInstanciator ?? static::$objectInstanciator = new Entity\ObjectInstanciator() )->enum($enum);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function encodeArray(array $array)
 | 
			
		||||
    {
 | 
			
		||||
        return json_encode($array);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    public static function registerAdapter(ConnectionAdapter $adapter, bool $default = false) : void
 | 
			
		||||
    {
 | 
			
		||||
        if ($default) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user