Skip to content

Commit

Permalink
[update] - updated conditionals, added group and custom operations
Browse files Browse the repository at this point in the history
  • Loading branch information
iloElias committed Oct 5, 2024
1 parent b934377 commit d46a4b8
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 41 deletions.
6 changes: 3 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DB_SQL=pgsql
DB_HOST=localhost
DB_HOST=127.0.0.3
DB_PORT=5432
DB_NAME=maestrodb
DB_NAME=maestro_db
DB_USER=postgres
DB_PASS=dbpass
DB_PASS=password
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ 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 = new Select(PDOConnection::get());
$select->from(['u' => 'users'], ['u.id', 'u.name'])
->where(['u.active' => true])
->order('u.name', 'ASC')
Expand All @@ -111,7 +111,7 @@ use Maestro\Example\User;

$user = new User('John Doe', 'john@example.com', md5('password'), true, new Timestamp('now'));

$insert = new Insert(PDOConnection::getInstance());
$insert = new Insert(PDOConnection::get());
$insert->into(User::class)
->values($user)
->returning(['id']);
Expand All @@ -128,7 +128,7 @@ 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 = new Update(PDOConnection::get());
$update->table('users')
->set('name', 'Jane Doe')
->where(['id' => 1]);
Expand All @@ -145,7 +145,7 @@ 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 = new Delete(PDOConnection::get());
$delete->from('users')
->where(['id' => 1]);

Expand Down Expand Up @@ -241,7 +241,7 @@ use Maestro\Example\Hr;
use PDO;

// Initialize PDO with environment variables
$pdo = PDOConnection::getInstance();
$pdo = PDOConnection::get();

// Initialize DatabaseManager
$dbManager = new DatabaseManager($pdo);
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ilias/maestro",
"type": "library",
"version": "1.2.3",
"version": "1.2.4",
"description": "A PHP object-oriented postgres database manager",
"keywords": [
"postgres",
Expand Down
4 changes: 2 additions & 2 deletions maestro.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@

// print implode("\n", $coreDatabase->createDatabase($agrofastDB, true)) . "\n";

$insert = new Insert(Maestro::SQL_NO_PREDICT, PDOConnection::getInstance());
$insert = new Insert(Maestro::SQL_NO_PREDICT, PDOConnection::get());
$user = new User("nickname'-- drop table", 'John', 'Doe', 'email@example.com', 'password', true, new Timestamp());
$result = $insert->into($user)->values($user)->returning(['id'])->execute();
var_dump($result);

$delete = new Delete(Maestro::SQL_NO_PREDICT, PDOConnection::getInstance());
$delete = new Delete(Maestro::SQL_NO_PREDICT, PDOConnection::get());
$delete->from($user)->where(['id' => $result[0]['id']])->execute();

16 changes: 12 additions & 4 deletions src/Abstract/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ abstract class Query
private ?PDOStatement $stmt = null;
private bool $isBinded = false;
protected string $query = '';
public const AND = 'AND';
public const OR = 'OR';

public function __construct(
protected string $behavior = Maestro::SQL_STRICT,
Expand All @@ -30,19 +32,23 @@ public function __construct(
* @param array $conditions An associative array of conditions for the WHERE clause.
* @return $this Returns the current instance for method chaining.
*/
public function where(array $conditions): static
public function where(array $conditions, string $operation = Select::AND, bool $group = false): static
{
$where = [];
foreach ($conditions as $column => $value) {
$columnWhere = Utils::sanitizeForPostgres($column);
$paramName = str_replace('.', '_', ":where_{$columnWhere}");
$this->storeParameter($paramName, $value);
$this->where[] = "{$column} = {$paramName}";
$where[] = "{$column} = {$paramName}";
}
$clauses = implode(" {$operation} ", $where);
$this->where[] = ($group ? "({$clauses})" : $clauses);
return $this;
}

public function in(array $conditions): static
public function in(array $conditions, string $operation = Select::AND, bool $group = false): static
{
$where = [];
foreach ($conditions as $column => $value) {
$inParams = array_map(function ($v, $k) use ($column) {
$columnIn = Utils::sanitizeForPostgres($column);
Expand All @@ -51,8 +57,10 @@ public function in(array $conditions): static
return $paramName;
}, $value, array_keys($value));
$inList = implode(",", $inParams);
$this->where[] = "{$column} IN({$inList})";
$where[] = "{$column} IN({$inList})";
}
$clauses = implode(" {$operation} ", $where);
$this->where[] = ($group ? "({$clauses})" : $clauses);
return $this;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Core/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Manager
public function __construct(
private string $strictType = Maestro::SQL_STRICT
) {
$this->pdo = PDOConnection::getInstance();
$this->pdo = PDOConnection::get();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Synchronizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Synchronizer
public function __construct()
{
$this->manager = new Manager();
$this->pdo = PDOConnection::getInstance();
$this->pdo = PDOConnection::get();
}

public function synchronize(Database $ormDb): void
Expand Down
4 changes: 2 additions & 2 deletions src/Database/Insert.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function values(Table|array $data): Insert
* @param array $conditions An associative array of conditions for the WHERE clause.
* @return Insert Returns the current Insert instance.
*/
public function where(array $conditions): static
public function where(array $conditions, string $operation = \Ilias\Maestro\Database\Select::AND, bool $group = false): static
{
return $this;
}
Expand All @@ -53,7 +53,7 @@ public function where(array $conditions): static
* @param array $conditions An associative array of conditions for the WHERE clause.
* @return Insert Returns the current Insert instance.
*/
public function in(array $conditions): static
public function in(array $conditions, string $operation = \Ilias\Maestro\Database\Select::AND, bool $group = false): static
{
return $this;
}
Expand Down
46 changes: 36 additions & 10 deletions src/Database/PDOConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,51 @@ public function __wakeup()
{
}

public static function getInstance(?\PDO $pdoMock = null): \PDO
/**
* Retrieves a PDO connection instance.
*
* This method returns a singleton instance of the PDO connection. If the connection has not been established yet, it will create a new one using the provided parameters or environment variables. If a PDO mock object is provided, it will be used instead.
*
* @param string|null $dbSql The SQL driver (e.g., mysql, pgsql). Defaults to environment variable DB_SQL.
* @param string|null $dbName The name of the database. Defaults to environment variable DB_NAME.
* @param string|null $dbHost The database host. Defaults to environment variable DB_HOST.
* @param string|null $dbPort The database port. Defaults to environment variable DB_PORT.
* @param string|null $dbUser The database user. Defaults to environment variable DB_USER.
* @param string|null $dbPass The database password. Defaults to environment variable DB_PASS.
* @param \PDO|null $pdoMock An optional PDO mock object for testing purposes.
* @return \PDO The PDO connection instance.
*/
public static function get(string $dbSql = null, string $dbName = null, string $dbHost = null, string $dbPort = null, string $dbUser = null, string $dbPass = null, ?\PDO $pdoMock = null): \PDO
{
if (self::$pdo === null) {
if ($pdoMock) {
self::$pdo = $pdoMock;
} else {
$sqlDatabase = Helper::env("DB_SQL");
$host = Helper::env("DB_HOST");
$port = Helper::env("DB_PORT");
$databaseName = Helper::env("DB_NAME");
$username = Helper::env("DB_USER");
$password = Helper::env("DB_PASS");

$dns = "{$sqlDatabase}:host={$host};port={$port};dbname={$databaseName}";
self::$pdo = new \PDO($dns, $username, $password);
$dbSql = Helper::env("DB_SQL", $dbSql);
$dbName = Helper::env("DB_NAME", $dbName);
$dbHost = Helper::env("DB_HOST", $dbHost);
$dbPort = Helper::env("DB_PORT", $dbPort);
$dbUser = Helper::env("DB_USER", $dbUser);
$dbPass = Helper::env("DB_PASS", $dbPass);

$dns = "{$dbSql}:host={$dbHost};port={$dbPort};dbname={$dbName}";
self::$pdo = new \PDO($dns, $dbUser, $dbPass);
self::$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
}
}

return self::$pdo;
}

/**
* Get an instance of the PDO connection.
*
* @param \PDO|null $pdoMock Optional PDO mock object for testing.
* @return \PDO The PDO connection instance.
* @deprecated This method is deprecated and will be removed in a future version. Use self::get() directly instead.
*/
public static function getInstance(?\PDO $pdoMock = null): \PDO
{
return self::get(pdoMock: $pdoMock);
}
}
13 changes: 8 additions & 5 deletions src/Database/Select.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class Select extends Query
const INNER = 'INNER';
const LEFT = 'LEFT';
const RIGHT = 'RIGHT';
const ORDER_ASC = 'ASC';
const ORDER_DESC = 'DESC';
const ASC = 'ASC';
const DESC = 'DESC';

private string $from;
private ?string $alias;
Expand Down Expand Up @@ -93,18 +93,21 @@ public function group(array $columns): Select
return $this;
}

public function having(array $conditions): Select
public function having(array $conditions, string $operation = Select::AND, $group = false): Select
{
$having = [];
foreach ($conditions as $column => $value) {
$columnHaving = Utils::sanitizeForPostgres($column);
$paramName = ":having_{$columnHaving}";
$this->storeParameter($paramName, $value);
$this->having[] = "{$column} = {$paramName}";
$having[] = "{$column} = {$paramName}";
}
$clauses = implode(" {$operation} ", $having);
$this->having[] = ($group ? "({$clauses})" : $clauses);
return $this;
}

public function order(string $column, string $direction = 'ASC'): Select
public function order(string $column, string $direction = Select::ASC): Select
{
$this->order[] = "{$column} {$direction}";
return $this;
Expand Down
2 changes: 1 addition & 1 deletion src/Database/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Transaction
public function __construct(?PDO $pdo = null)
{
if (empty($pdo)) {
$pdo = PDOConnection::getInstance();
$pdo = PDOConnection::get();
}
$this->pdo = $pdo;
}
Expand Down
20 changes: 15 additions & 5 deletions src/Database/Update.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,22 @@ public function table(string $table): Update
return $this;
}

public function set(string $column, $value): Update
public function set(string|array $column, $value = null): Update
{
$column = Utils::sanitizeForPostgres($column);
$paramName = ":$column";
$this->set[$column] = $paramName;
$this->parameters[$paramName] = $value;
if (is_array($column)) {
foreach ($column as $col => $val) {
$this->set($col, $val);
}
}
if (is_string($column)) {
if (is_int($column) || is_numeric($column)) {
throw new \InvalidArgumentException("Column name must be a string");
}
$column = Utils::sanitizeForPostgres($column);
$paramName = ":$column";
$this->set[$column] = $paramName;
$this->parameters[$paramName] = $value;
}
return $this;
}

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/unit/ManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ManagerTest extends TestCase
protected function setUp(): void
{
$this->pdoMock = $this->createMock(\PDO::class);
PDOConnection::getInstance($this->pdoMock);
PDOConnection::get(pdoMock: $this->pdoMock);
$this->manager = new Manager();
}

Expand Down

0 comments on commit d46a4b8

Please sign in to comment.