diff --git a/phpunit.xml b/phpunit.xml index 02aa395..3e376f0 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,11 +1,12 @@ - + ./tests - + + ./app ./src @@ -13,5 +14,5 @@ ./src/Collection.php - + diff --git a/phpunit.xml.bak b/phpunit.xml.bak index 6918612..3e376f0 100644 --- a/phpunit.xml.bak +++ b/phpunit.xml.bak @@ -1,21 +1,18 @@ - - - - ./tests - - - - - ./app - ./src - - - ./src/Collection.php - - + + + + ./tests + + + + + + ./app + ./src + + + ./src/Collection.php + + diff --git a/src/Database.php b/src/Database.php index 76d4c37..528d090 100644 --- a/src/Database.php +++ b/src/Database.php @@ -2,9 +2,6 @@ declare(strict_types=1); namespace Scrawler\Arca; -use Scrawler\Arca\Manager\TableManager; -use Scrawler\Arca\Manager\RecordManager; -use Scrawler\Arca\Manager\ModelManager; use \Doctrine\DBAL\Connection; /** @@ -28,21 +25,6 @@ class Database * @var \Doctrine\DBAL\Schema\AbstractSchemaManager */ public \Doctrine\DBAL\Schema\AbstractSchemaManager $manager; - /** - * Instance of table manager responsible for working with tables - * @var \Scrawler\Arca\Manager\TableManager - */ - private TableManager $tableManager; - /** - * Instance of record manager responsible for working with records - * @var \Scrawler\Arca\Manager\RecordManager - */ - private RecordManager $recordManager; - /** - * Model manager rsponisble for bootstrapping model instance - * @var \Scrawler\Arca\Manager\ModelManager - */ - private ModelManager $modelManager; /** * When $isFrozen is set to true tables are not updated/created * @var bool @@ -54,28 +36,28 @@ class Database */ private bool $useUUID = false; - public function __construct(Connection $connection) + public function __construct(Connection $connection , bool $useUUID = false) { $this->connection = $connection; $this->platform = $this->connection->getDatabasePlatform(); $this->manager = $this->connection->createSchemaManager(); - - } + $this->useUUID = $useUUID; + Managers::create($connection, $useUUID); + $this->registerEvents(); - /** - * Once you initialize database, use this to set all manager for database class to work correctly - * @param TableManager $tableManager - * @param RecordManager $recordManager - * @param ModelManager $modelManager - * @return void - */ - public function setManagers(TableManager $tableManager, RecordManager $recordManager, ModelManager $modelManager){ - $this->tableManager = $tableManager; - $this->recordManager = $recordManager; - $this->modelManager = $modelManager; + } + public function registerEvents() + { + Event::subscribeTo('model.save', function ($model) { + return $this->save($model); + }); + Event::subscribeTo('model.delete', function ($model) { + return $this->delete($model); + }); } + /** * Executes an SQL query and returns the number of row affected * @@ -108,7 +90,7 @@ public function getAll(string $sql, array $params=[]): array */ public function create(string $name) : Model { - return $this->modelManager->create($name); + return new Model($name); } /** @@ -148,18 +130,18 @@ public function save(\Scrawler\Arca\Model $model) : mixed private function createTables($model) { if (!$this->isFroozen) { - $table = $this->tableManager->createTable($model); - $this->tableManager->saveOrUpdateTable($model->getName(), $table); + $table = Managers::tableManager()->createTable($model); + Managers::tableManager()->saveOrUpdateTable($model->getName(), $table); } } private function createRecords($model) : mixed { if ($model->isLoaded()) { - return $this->recordManager->update($model); + return Managers::recordManager()->update($model); } - return $this->recordManager->insert($model); + return Managers::recordManager()->insert($model); } @@ -263,11 +245,6 @@ private function saveForeignMtm(\Scrawler\Arca\Model $model, mixed $id): void } } - public function getTableManager() - { - return $this->tableManager; - } - /** * Delete record from database * @@ -276,15 +253,11 @@ public function getTableManager() */ public function delete(\Scrawler\Arca\Model $model) : mixed { - return $this->recordManager->delete($model); + return Managers::recordManager()->delete($model); } /** * Get collection of all records from table - * - * @param String $table - * @param mixed|null $id - * @return mixed */ public function get(String $table,mixed $id = null) : Model|Collection { @@ -293,19 +266,16 @@ public function get(String $table,mixed $id = null) : Model|Collection return $this->getOne($table,$id); } - return $this->recordManager->getAll($table); + return Managers::recordManager()->getAll($table); } /** * Get single record * - * @param String $table - * @param mixed $id - * @return mixed */ public function getOne(String $table, mixed $id) : Model { - return $this->recordManager->getById($this->create($table), $id); + return Managers::recordManager()->getById($this->create($table), $id); } /** @@ -317,7 +287,7 @@ public function getOne(String $table, mixed $id) : Model */ public function find(string $name) : QueryBuilder { - return $this->recordManager->find($name); + return Managers::recordManager()->find($name); } /** @@ -329,24 +299,6 @@ public function freeze() : void $this->isFroozen = true; } - /** - * Call this to useUUID over normal id - * @return void - */ - public function useUUID() : void - { - $this->useUUID = true; - } - - /** - * Call this to use id (id is used by default) - * @return void - */ - public function useID() : void - { - $this->useUUID = false; - } - /** * Checks if database is currently using uuid rather than id * @return bool diff --git a/src/Event.php b/src/Event.php new file mode 100644 index 0000000..27ba246 --- /dev/null +++ b/src/Event.php @@ -0,0 +1,66 @@ + $weight) { + foreach ($weight as $callback) { + $data = call_user_func_array($callback, $params); + } + } + + return $data; + } + + /** + * Check that an event is valid before interacting with it. + * + */ + private static function isEvent($eventname) + { + if (!isset(self::$events[$eventname]) || !is_array(self::$events[$eventname])) { + return false; + } + return true; + } +} + diff --git a/src/Facade/Database.php b/src/Facade/Database.php index dfc53c2..6608c3d 100644 --- a/src/Facade/Database.php +++ b/src/Facade/Database.php @@ -3,22 +3,19 @@ namespace Scrawler\Arca\Facade; -use Scrawler\Arca\Manager\TableManager; -use Scrawler\Arca\Manager\RecordManager; -use Scrawler\Arca\Manager\ModelManager; + use Scrawler\Arca\Database as DB; class Database { private static $database; - public static function connect(array $connectionParams) + public static function connect(array $connectionParams,$isUsingUUID = false) { if (self::$database == null) { $connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); - self::$database = new DB($connection); - self::$database->setManagers(new TableManager(self::$database), new RecordManager(self::$database), new ModelManager(self::$database)); + self::$database = new DB($connection,$isUsingUUID); return self::$database; } diff --git a/src/Manager/ModelManager.php b/src/Manager/ModelManager.php index 39ccfea..a51e446 100644 --- a/src/Manager/ModelManager.php +++ b/src/Manager/ModelManager.php @@ -2,30 +2,19 @@ namespace Scrawler\Arca\Manager; -use \Scrawler\Arca\Database; use \Scrawler\Arca\Model; /** * Class for initializing and managing models */ class ModelManager { - private Database $db; - - /** - * Create ModelManager - * @param \Scrawler\Arca\Database $db - */ - public function __construct(Database $db){ - $this->db = $db; - } - /** * Creates and return models - * @param string $name - * @return Model + */ - public function create(string $name){ - return new Model($name,$this->db); + function create(string $name): Model + { + return new Model($name); } } \ No newline at end of file diff --git a/src/Manager/RecordManager.php b/src/Manager/RecordManager.php index d217e1d..1057238 100644 --- a/src/Manager/RecordManager.php +++ b/src/Manager/RecordManager.php @@ -5,7 +5,7 @@ use \Scrawler\Arca\Collection; use \Scrawler\Arca\QueryBuilder; use \Scrawler\Arca\Model; -use \Scrawler\Arca\Database; +use \Doctrine\DBAL\Connection; use Ramsey\Uuid\Uuid; /** @@ -13,46 +13,45 @@ */ class RecordManager { - private Database $db; + private Connection $connection; + + private bool $isUsingUUID; /** * Create RecordManager - * @param \Scrawler\Arca\Database $db */ - public function __construct(Database $db) + public function __construct(Connection $connection, bool $isUsingUUID = false) { - $this->db = $db; + $this->connection = $connection; + $this->isUsingUUID = $isUsingUUID; } + /** * Create a new record * - * @param \Scrawler\Arca\Model $model - * @return mixed $id int for id and string for uuid */ public function insert(Model $model) : mixed { - if ($this->db->isUsingUUID()) { + if ($this->isUsingUUID) { $model->id = UUID::uuid4()->toString(); } - $this->db->connection->insert($model->getName(), $model->getProperties()); - if ($this->db->isUsingUUID()) { + $this->connection->insert($model->getName(), $model->getProperties()); + if ($this->isUsingUUID) { return $model->id; } - return (int) $this->db->connection->lastInsertId(); + return (int) $this->connection->lastInsertId(); } /** * Update a record * - * @param \Scrawler\Arca\Model $model - * @return mixed $id */ public function update(Model $model) : mixed { - $this->db->connection->update($model->getName(), $model->getProperties(), ['id'=>$model->getId()]); + $this->connection->update($model->getName(), $model->getProperties(), ['id'=>$model->getId()]); return $model->getId(); } @@ -60,28 +59,24 @@ public function update(Model $model) : mixed /** * Delete a record * - * @param \Scrawler\Arca\Model $model - * @return mixed $id */ public function delete(Model $model) : mixed { - $this->db->connection->delete($model->getName(), ['id'=>$model->getId()]); + $this->connection->delete($model->getName(), ['id'=>$model->getId()]); return $model->getId(); } /** * Get single record by id * - * @param \Scrawler\Arca\Model $model - * @return \Scrawler\Arca\Model */ public function getById(Model $model, mixed $id): Model { - $query = (new QueryBuilder($this->db)) + $query = (new QueryBuilder($this->connection)) ->select('*') ->from($model->getName(), 't') ->where("t.id = '".$id."'"); - $result = $this->db->connection->executeQuery($query)->fetchAssociative(); + $result = $this->connection->executeQuery($query)->fetchAssociative(); $result = $result ? $result : []; return $model->setProperties($result)->setLoaded(); } @@ -90,12 +85,10 @@ public function getById(Model $model, mixed $id): Model /** * Get all records * - * @param string $tableName - * @return \Scrawler\Arca\Collection */ public function getAll(string $tableName): Collection { - return (new QueryBuilder($this->db)) + return (new QueryBuilder($this->connection)) ->select('*') ->from($tableName, 't') ->get(); @@ -104,12 +97,10 @@ public function getAll(string $tableName): Collection /** * get query builder from db * - * @param String $name - * @return \Scrawler\Arca\QueryBuilder */ public function find(String $name) : QueryBuilder { - return (new QueryBuilder($this->db)) + return (new QueryBuilder($this->connection)) ->select('*') ->from($name, 't'); } diff --git a/src/Manager/TableManager.php b/src/Manager/TableManager.php index 1c4e8ae..a11cf12 100644 --- a/src/Manager/TableManager.php +++ b/src/Manager/TableManager.php @@ -5,27 +5,40 @@ use \Doctrine\DBAL\Schema\Schema; use \Doctrine\DBAL\Schema\Table; use \Doctrine\DBAL\Schema\Comparator; -use \Scrawler\Arca\Database; +use \Doctrine\DBAL\Connection; +use \Doctrine\DBAL\Schema\AbstractSchemaManager; +use Scrawler\Arca\Model; /** * Class resposible for creating and modifing table */ class TableManager { - private Database $db; + private Connection $connection; + + private bool $isUsingUUID; + + private AbstractSchemaManager $manager; + + private \Doctrine\DBAL\Platforms\AbstractPlatform $platform; + + + /** * create TableManager */ - public function __construct($db) + public function __construct(Connection $connection, bool $isUsingUUID = false) { - $this->db = $db; + $this->connection = $connection; + $this->isUsingUUID = $isUsingUUID; + $this->manager = $this->connection->getSchemaManager(); + $this->platform = $this->connection->getDatabasePlatform(); } + /** * Creates a table schema from table instance - * @param \Scrawler\Arca\Model $model - * @return \Doctrine\DBAL\Schema\Schema */ public function createTableSchema(Table $table): Schema { @@ -34,33 +47,27 @@ public function createTableSchema(Table $table): Schema /** * Get Table schema from existing table - * @param String $table (name of table) - * @return \Doctrine\DBAL\Schema\Schema */ - public function getTableSchema(String $table): Schema + public function getTableSchema(string $table): Schema { - return new Schema([$this->db->manager->listTableDetails($table)]); + return new Schema([$this->manager->listTableDetails($table)]); } /** * Get Table detail from existing table - * @param String $table (name of table) - * @return \Doctrine\DBAL\Schema\Table */ - public function getTable(String $table) : Table + public function getTable(string $table) : Table { - return $this->db->manager->listTableDetails($table); + return $this->manager->listTableDetails($table); } /** * Create table from model - * @param \Scrawler\Arca\Model $model - * @return \Doctrine\DBAL\Schema\Table */ - public function createTable($model) : Table + public function createTable(Model $model) : Table { $table = new Table($model->getName()); - if ($this->db->isUsingUUID()) { + if ($this->isUsingUUID) { $table->addColumn('id', 'string', ['length' => 36, 'notnull' => true,]); } else { $table->addColumn("id", "integer", array("unsigned" => true, "autoincrement" => true)); @@ -77,25 +84,20 @@ public function createTable($model) : Table /** * Save table to database - * @param \Doctrine\DBAL\Schema\Table $table - * @return void */ public function saveTable(Table $table): void { $schema = $this->createTableSchema($table); - $queries = $schema->toSql($this->db->platform); + $queries = $schema->toSql($this->platform); foreach ($queries as $query) { - $this->db->connection->executeQuery($query); + $this->connection->executeQuery($query); } } /** * Add missing column to existing table from given table - * @param String $table_name (table name of existing table) - * @param \Doctrine\DBAL\Schema\Table $new_table (table schema of new table) - * @return void */ - public function updateTable(String $table_name, Table $new_table) : void + public function updateTable(string $table_name, Table $new_table) : void { $comparator = new Comparator(); $old_table = $this->getTable($table_name); @@ -110,28 +112,24 @@ public function updateTable(String $table_name, Table $new_table) : void $new_schema = $this->createTableSchema($mod_table); $schemaDiff = $comparator->compareSchemas($old_schema, $new_schema); - $queries = $schemaDiff->toSaveSql($this->db->platform); + $queries = $schemaDiff->toSaveSql($this->platform); foreach ($queries as $query) { - $this->db->connection->executeQuery($query); + $this->connection->executeQuery($query); } } } /** * Check if table exists - * @param String $table_name - * @return bool */ - public function tableExists(String $table_name): bool + public function tableExists(string $table_name): bool { return !empty($this->getTable($table_name)->getColumns()); } /** * If table exist update it else create it - * @param String $table_name (table name of existing table) - * @param \Doctrine\DBAL\Schema\Table $new_table (table schema of new table) */ public function saveOrUpdateTable(String $table_name, Table $new_table): void { diff --git a/src/Managers.php b/src/Managers.php new file mode 100644 index 0000000..33cd31e --- /dev/null +++ b/src/Managers.php @@ -0,0 +1,42 @@ +db = $db; + $this->table = $name; $this->__meta['has_foreign']['oto'] = false; $this->__meta['has_foreign']['otm'] = false; @@ -30,8 +30,6 @@ public function __construct(string $name, Database $db) /** * adds the key to properties * - * @param String $key - * @param Mixed $val */ public function __set(string $key, mixed $val): void { @@ -39,10 +37,8 @@ public function __set(string $key, mixed $val): void } /** - * adds the key to properties + * Adds the key to properties * - * @param String $key - * @param Mixed $val */ public function set(string $key, mixed $val): void { @@ -80,8 +76,6 @@ public function set(string $key, mixed $val): void /** * Get a key from properties, keys can be relational * like sharedList,ownList or foreign table - * @param string $key - * @return mixed */ public function __get(string $key): mixed { @@ -91,30 +85,28 @@ public function __get(string $key): mixed /** * Get a key from properties, keys can be relational * like sharedList,ownList or foreign table - * @param string $key - * @return mixed */ - public function get(string $key) + public function get(string $key) : mixed { if (preg_match('/[A-Z]/', $key)) { $parts = preg_split('/(?=[A-Z])/', $key, -1, PREG_SPLIT_NO_EMPTY); if (strtolower($parts[0]) == 'own') { if (strtolower($parts[2]) == 'list') { - return $this->db->find(strtolower($parts[1]))->where($this->getName() . '_id = "' . $this->_id . '"')->get(); + return Managers::recordManager()->find(strtolower($parts[1]))->where($this->getName() . '_id = "' . $this->_id . '"')->get(); } } if (strtolower($parts[0]) == 'shared') { if (strtolower($parts[2]) == 'list') { - $rel_table = $this->db->getTableManager()->tableExists($this->table . '_' . strtolower($parts[1])) ? $this->table . '_' . strtolower($parts[1]) : strtolower($parts[1]) . '_' . $this->table; - $relations = $this->db->find($rel_table)->where($this->getName() . '_id = "' . $this->_id . '"')->get(); + $rel_table = Managers::tableManager()->tableExists($this->table . '_' . strtolower($parts[1])) ? $this->table . '_' . strtolower($parts[1]) : strtolower($parts[1]) . '_' . $this->table; + $relations = Managers::recordManager()->find($rel_table)->where($this->getName() . '_id = "' . $this->_id . '"')->get(); $rel_ids = ''; foreach ($relations as $relation) { $key = strtolower($parts[1]) . '_id'; $rel_ids .= "'" . $relation->$key . "',"; } $rel_ids = substr($rel_ids, 0, -1); - return $this->db->find(strtolower($parts[1]))->where('id IN (' . $rel_ids . ')')->get(); + return Managers::recordManager()->find(strtolower($parts[1]))->where('id IN (' . $rel_ids . ')')->get(); } } } @@ -124,7 +116,7 @@ public function get(string $key) } if (array_key_exists($key . '_id', $this->properties)) { - return $this->db->get($key, $this->properties[$key . '_id']); + return Managers::recordManager()->getById(Managers::modelManager()->create($key), $this->properties[$key . '_id']); } throw new Exception\KeyNotFoundException(); @@ -142,7 +134,6 @@ public function with(array $relations) : Model /** * Unset a property from model * - * @param string $key */ public function __unset(string $key): void { @@ -152,7 +143,6 @@ public function __unset(string $key): void /** * Unset a property from model * - * @param string $key */ public function unset(string $key): void { @@ -162,8 +152,6 @@ public function unset(string $key): void /** * Check if property exists * - * @param string $key - * @return boolean */ public function __isset(string $key): bool { @@ -183,9 +171,6 @@ public function isset(string $key): bool /** * Set all properties of model via array - * - * @param array $properties - * @return Model */ public function setProperties(array $properties): Model { @@ -199,7 +184,6 @@ public function setProperties(array $properties): Model /** * Get all properties in array form * - * @return array */ public function getProperties(): array { @@ -209,7 +193,6 @@ public function getProperties(): array /** * Get all properties in array form * - * @return array */ public function toArray(): array { @@ -218,7 +201,6 @@ public function toArray(): array /** * check if model loaded from db - * @return array */ public function isLoaded(): bool { @@ -228,7 +210,6 @@ public function isLoaded(): bool /** * call when model is loaded from database * - * @return Model */ public function setLoaded(): Model { @@ -239,7 +220,6 @@ public function setLoaded(): Model /** * Get current table name of model * - * @return String */ public function getName(): string { @@ -249,7 +229,6 @@ public function getName(): string /** * Get current model Id or UUID * - * @return mixed */ public function getId(): mixed { @@ -260,11 +239,10 @@ public function getId(): mixed /** * Save model to database * - * @return mixed returns int when id is used else returns string for uuid */ public function save(): mixed { - $id = $this->db->save($this); + $id = Event::dispatch('model.save', [$this]); $this->id = $id; $this->_id = $id; return $id; @@ -275,12 +253,11 @@ public function save(): mixed */ public function delete(): void { - $this->db->delete($this); + Event::dispatch('model.delete', [$this]); } /** * Converts model into json object - * @return string */ public function toString(): string { @@ -289,7 +266,6 @@ public function toString(): string /** * Converts model into json object - * @return string */ public function __toString(): string { @@ -300,18 +276,14 @@ public function __toString(): string /** * Function used to compare to models * - * @param self $other - * @return boolean */ - public function equals(self$other): bool + public function equals(self $other): bool { return ($this->getId() === $other->getId() && $this->toString() === $other->toString()); } /** * Check if model has any relations - * - * @return boolean */ public function hasForeign($type): bool { @@ -320,8 +292,6 @@ public function hasForeign($type): bool /** * returns all relational models - * - * @return array */ public function getForeignModels($type): array { diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index bfa29b5..7f098fb 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -10,13 +10,9 @@ class QueryBuilder extends \Doctrine\DBAL\Query\QueryBuilder private string $table; private array $relations= []; - private Database $db; - - public function __construct(Database $db) + public function __construct(\Doctrine\DBAL\Connection $connection) { - $this->db = $db; - parent::__construct($this->db->connection); - + parent::__construct($connection); } public function with(string $relation): QueryBuilder @@ -36,7 +32,7 @@ public function from($from, $alias = null): QueryBuilder public function get(): Collection { - $model = $this->db->create($this->table); + $model = Managers::modelManager()->create($this->table); $relations = $this->relations; $this->relations = []; return Collection::fromIterable($this->fetchAllAssociative()) @@ -48,6 +44,6 @@ public function first(): Model $relations = $this->relations; $this->relations = []; $result = $this->fetchAssociative() ? $this->fetchAssociative() : []; - return ($this->db->create($this->table))->setProperties($result)->with($relations)->setLoaded(); + return (Managers::modelManager()->create($this->table))->setProperties($result)->with($relations)->setLoaded(); } } \ No newline at end of file diff --git a/tests/Pest.php b/tests/Pest.php index dfaa7b8..b50955d 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -15,10 +15,9 @@ function db($uuid = "ID") $db = Scrawler\Arca\Facade\Database::connect($connectionParams); if ($uuid == 'UUID') { - $db->useUUID(); - return $db; + $db = Scrawler\Arca\Facade\Database::connect($connectionParams, true); } - $db->useID(); + return $db; }