Releases: iloElias/maestro
Releases · iloElias/maestro
1.2.0 Table creation update
New Features in the Upcoming Update
Primary Key Selection
In the new update, the primary key will be automatically chosen if there are two or more identifiers in the [Table
]
Usage of @comment
There is a new way to use @comment
in the class properties to add comments directly in the code. This can be useful for documentation and code readability.
Example: User Class
<?php
namespace Maestro\Example;
use Ilias\Maestro\Abstract\Table;
use Ilias\Maestro\Database\Expression;
use Ilias\Maestro\Types\Serial;
use Ilias\Maestro\Types\Timestamp;
use Ilias\Maestro\Types\Unique;
final class User extends Table
{
public Hr $schema;
/** @primary */
public Serial $id;
/** @primary
* @not_nuable */
public Unique | Expression | string $uuid = Expression::RANDOM_UUID;
/** @not_nuable */
public string $firstName;
/** @not_nuable */
public string $lastName;
/** @unique */
public string $nickname;
/** @unique */
public string $email;
public string $password;
public bool $active = true;
public Timestamp | Expression | string $createdIn = Expression::CURRENT_TIMESTAMP;
public Timestamp $updatedIn;
public Timestamp $inactivatedIn;
public function __construct(
string $nickname,
string $email,
string $password,
bool $active,
Timestamp $createdIn
) {
$this->nickname = $nickname;
$this->email = $email;
$this->password = $password;
$this->active = $active;
$this->createdIn = $createdIn;
}
}
Example: Manager Class
<?php
namespace Ilias\Maestro\Core;
use PDO;
use InvalidArgumentException;
use Throwable;
use Ilias\Maestro\Abstract\Database;
use Ilias\Maestro\Abstract\Identifier;
use Ilias\Maestro\Abstract\Query;
use Ilias\Maestro\Abstract\Schema;
use Ilias\Maestro\Abstract\Table;
use Ilias\Maestro\Database\PDOConnection;
use Ilias\Maestro\Exceptions\NotFinalExceptions;
use Ilias\Maestro\Database\Expression;
use Ilias\Maestro\Utils\Utils;
/**
* Class Manager
*
* This class provides methods to create and manage a PostgreSQL database schema,
* including creating schemas, tables, and foreign key constraints. It also provides
* methods to insert, update, and select data from tables.
*
* @package Ilias\Maestro\Core
*/
class Manager
{
public static array $idCreationPattern = [
'PRIMARY KEY',
];
public PDO $pdo;
public function __construct(
private string $strictType = Maestro::SQL_STRICT
) {
$this->pdo = PDOConnection::getInstance();
}
// Other methods...
/**
* Create a table.
*
* @param string $table
* @return string
* @throws NotFinalExceptions
*/
public function createTable(string $table): string
{
if (!Utils::isFinalClass($table)) {
throw new NotFinalExceptions("The " . $table::getSanitizedName() . " class was not identified as \"final\"");
}
$reflectionClass = new \ReflectionClass($table);
$tableName = $table::getSanitizedName();
$columns = $table::tableColumns();
$primaryColumn = $table::tableIdentifier();
$uniqueColumns = $table::getUniqueColumns();
$notNullColumns = $this->getNotNullProperties($reflectionClass);
$schemaName = $this->schemaNameFromTable($table);
$columnDefs = [];
foreach ($columns as $name => $type) {
$sanitizedColumnName = Utils::sanitizeForPostgres($name);
$isIdentifier = Utils::isIdentifier($type);
$columnDef = $this->strictType === Maestro::SQL_STRICT
? "\"{$sanitizedColumnName}\" {$this->getColumnType($type)}"
: "{$sanitizedColumnName} {$this->getColumnType($type)}";
if (in_array($name, $notNullColumns) || $isIdentifier) {
$columnDef .= ' NOT NULL';
} elseif ($this->strictType === Maestro::SQL_STRICT) {
$columnDef .= ' NULL';
}
if (isset($primaryColumn[$name])) {
$columnDef .= ' ' . implode(' ', self::$idCreationPattern);
}
$defaultValue = $this->getPropertyDefaultValue($reflectionClass, $name);
if ($defaultValue !== null) {
$columnDef .= is_array($type) && $type[1] === Expression::class
? " DEFAULT {$defaultValue}"
: " DEFAULT {$this->formatDefaultValue($defaultValue)}";
}
if (in_array($name, $uniqueColumns) || $isIdentifier) {
$columnDef .= ' UNIQUE';
}
$columnDefs[] = $columnDef;
}
$query = $this->strictType === Maestro::SQL_STRICT
? "CREATE TABLE IF NOT EXISTS \"$schemaName\".\"$tableName\""
: "CREATE TABLE \"$schemaName\".\"$tableName\"";
$query .= " (\n\t" . implode(",\n\t", $columnDefs) . "\n);";
return $query;
}
}
Example: Maestro Class
<?php
namespace Ilias\Maestro\Core;
final class Maestro
{
public const SQL_STRICT = 'STRICT';
public const SQL_PREDICT = 'PREDICT';
public const SQL_NO_PREDICT = 'NO_PREDICT';
public const DOC_PRIMARY = '@primary';
public const DOC_FOREIGN = '@foreign';
public const DOC_UNIQUE = '@unique';
public const DOC_NUABLE = '@nuable';
public const DOC_NOT_NUABLE = '@not_nuable';
public const DOC_COMMENT = '@comment';
public const MAETRO_DOC_CLAUSES = [
self::DOC_UNIQUE,
self::DOC_NUABLE,
self::DOC_NOT_NUABLE,
self::DOC_PRIMARY,
self::DOC_FOREIGN,
];
public const PREFER_DEFAULT = 0;
public const PREFER_DOC = 1;
}
1.1.1 Query builders update
Select
The Select
class allows you to build and execute SELECT queries.
use Ilias\Maestro\Database\Select;
use Ilias\Maestro\Database\PDOConnection;
$select = new Select(PDOConnection::getInstance());
$select->from(['u' => 'users'], ['u.id', 'u.name'])
->where(['u.active' => true])
->order('u.name', 'ASC')
->limit(10);
$sql = $select->getSql();
$params = $select->getParameters();
Insert
The Insert
class allows you to build and execute INSERT queries.
use Ilias\Maestro\Database\Insert;
use Ilias\Maestro\Database\PDOConnection;
use Maestro\Example\User;
$user = new User('John Doe', 'john@example.com', md5('password'), true, new Timestamp('now'));
$insert = new Insert(PDOConnection::getInstance());
$insert->into(User::class)
->values($user)
->returning(['id']);
$sql = $insert->getSql();
$params = $insert->getParameters();
Update
The Update
class allows you to build and execute UPDATE queries.
use Ilias\Maestro\Database\Update;
use Ilias\Maestro\Database\PDOConnection;
$update = new Update(PDOConnection::getInstance());
$update->table('users')
->set('name', 'Jane Doe')
->where(['id' => 1]);
$sql = $update->getSql();
$params = $update->getParameters();
Delete
The Delete
class allows you to build and execute DELETE queries.
use Ilias\Maestro\Database\Delete;
use Ilias\Maestro\Database\PDOConnection;
$delete = new Delete(PDOConnection::getInstance());
$delete->from('users')
->where(['id' => 1]);
$sql = $delete->getSql();
$params = $delete->getParameters();