Skip to content

Releases: iloElias/maestro

1.2.0 Table creation update

26 Sep 11:27
Compare
Choose a tag to compare

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

24 Sep 12:54
3bec76b
Compare
Choose a tag to compare

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();

1.1.0

26 Aug 17:41
Compare
Choose a tag to compare
[pre] - sql query bulder

1.0.0

06 Aug 12:29
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: https://github.com/iloElias/maestro/commits/1.0.0