diff --git a/Conditionable.php b/Conditionable.php new file mode 100644 index 0000000..648aed6 --- /dev/null +++ b/Conditionable.php @@ -0,0 +1,73 @@ +addCondition($col, $operator, $val, "AND"); + } + + /** + * Adds a WHERE condition with an "AND" prefix. + * @param string $col Column name. + * @param string|ConditionOperator $operator Comparison operator as string or enum. + * @param mixed $val Value to compare. + * @return self Current instance for chaining. + * @throws InvalidArgumentException + */ + public function andWhere(string $col, string|ConditionOperator $operator, mixed $val): self { + return $this->addCondition($col, $operator, $val, "AND"); + } + + /** + * Adds a WHERE condition with an "OR" prefix. + * @param string $col Column name. + * @param string|ConditionOperator $operator Comparison operator as string or enum. + * @param mixed $val Value to compare. + * @return self Current instance for chaining. + * @throws InvalidArgumentException + */ + public function orWhere(string $col, string|ConditionOperator $operator, mixed $val): self { + return $this->addCondition($col, $operator, $val, "OR"); + } + + protected function addCondition(string $col, string|ConditionOperator $operator, mixed $val, string $prefix): self { + if (!$this->table->existsColumn($col)) + throw new InvalidArgumentException("Unknown column: $col"); + + // Convert the operator string to a ConditionOperator enum if needed. + if (is_string($operator)) + $operator = ConditionOperator::fromString($operator); + + $columnType = $this->table->columnType($col); + $castedValue = $columnType->dbCast($val); + + if (!empty($this->conditions)) + $this->conditions[] = $prefix; + $this->conditions[] = "$col " . $operator->toString() . " $castedValue"; + + return $this; + } + + protected function combineConditions(): string { + if (!empty($this->conditions)) + return implode(" ", $this->conditions); + return ""; + } +} diff --git a/Database.php b/Database.php index 6cff276..f3a07d0 100644 --- a/Database.php +++ b/Database.php @@ -6,35 +6,35 @@ class Database /** * Creates a new TableBlueprint instance for the specified table name. * @param string $tableName The name of the table to create. - * @return Table A blueprint instance representing the table. + * @return Table instance supporting method chaining */ public static function makeTable(string $tableName): Table { return new Table($tableName); } - public static function makeMigration(Table $table): Migration { + public static function makeMigration(Schema $table): Migration { // TODO: Implement makeMigration() method. } /** * Creates a new QueryBuilder instance for the specified table. - * @param Table $table The table to query on. + * @param Schema $table The table to query on. * @return Query instance supporting method chaining. */ - public static function makeQuery(Table $table): Query { + public static function makeQuery(Schema $table): Query { return new Query($table); } - public static function makeDeletion(Table $table): Deletion { + public static function makeDeletion(Schema $table): Deletion { // TODO: Implement makeDeletion() method. } - public static function makeInsertion(Table $table): Insertion { - // TODO: Implement makeInsertion() method. + public static function makeInsertion(Schema $table): Insertion { + return new Insertion($table); } - public static function makeUpdate(Table $table): Update { + public static function makeUpdate(Schema $table): Update { // TODO: Implement makeUpdate() method. } diff --git a/Query.php b/Query.php index 70d18e5..f99053b 100644 --- a/Query.php +++ b/Query.php @@ -6,9 +6,10 @@ use InvalidArgumentException; class Query { - private Schema $table; - private array $columns = ['*']; - private array $conditions = []; + use Conditionable; + + protected Schema $table; + protected array $columns = ['*']; public function __construct(Schema $table) { $this->table = $table; @@ -26,37 +27,11 @@ class Query return $this; } - public function where(string $col, string $operator, mixed $val): Query { - return $this->addCondition($col, $operator, $val, "AND"); - } - - public function andWhere(string $col, string $operator, mixed $val): Query { - return $this->addCondition($col, $operator, $val, "AND"); - } - - public function orWhere(string $col, string $operator, mixed $val): Query { - return $this->addCondition($col, $operator, $val, "OR"); - } - - private function addCondition(string $col, string $operator, mixed $val, string $prefix): Query { - if ($this->table->existsColumn($col)) - throw new InvalidArgumentException("Unknown column: $col"); - - $columnType = $this->table->columnType($col); - $castedValue = $columnType->dbCast($val); - - if (!empty($this->conditions)) - $this->conditions[] = $prefix; - $this->conditions[] = "$col $operator $castedValue"; - - return $this; - } - public function toSql(): string { $columns = implode(", ", $this->columns); $table = $this->table->name; - $whereClause = !empty($this->conditions) ? " WHERE " . implode(" ", $this->conditions) : ""; - return esc_sql("SELECT $columns FROM $table$whereClause"); + $whereClause = $this->combineConditions(); + return esc_sql("SELECT $columns FROM $table WHERE $whereClause"); } public function query(): array { @@ -66,7 +41,7 @@ class Query return $this->castResults($results); } - private function castResults(array $results): array { + protected function castResults(array $results): array { foreach ($results as &$row) foreach ($row as $column => &$value) if (isset($this->columnTypes[$column])) diff --git a/Schema.php b/Schema.php index d812cdd..a47e579 100644 --- a/Schema.php +++ b/Schema.php @@ -3,7 +3,7 @@ namespace DatabaseHelper; use DatabaseHelper\enums\CharsetTypes; use DatabaseHelper\enums\CollationTypes; -use DatabaseHelper\enums\EngineTypes; +use DatabaseHelper\enums\DatabaseEngines; class Schema { @@ -13,7 +13,7 @@ class Schema public array $primaryKey = []; public array $foreignKeys = []; - public EngineTypes $engine = EngineTypes::INNODB; + public DatabaseEngines $engine = DatabaseEngines::INNODB; public CharsetTypes $charset = CharsetTypes::UTF8; public CollationTypes $collation = CollationTypes::UTF8_GENERAL_CI; diff --git a/Table.php b/Table.php index 353d8fa..842d055 100644 --- a/Table.php +++ b/Table.php @@ -5,7 +5,7 @@ use DatabaseHelper\enums\CascadeTypes; use DatabaseHelper\enums\CharsetTypes; use DatabaseHelper\enums\CollationTypes; use DatabaseHelper\enums\ColumnTypes; -use DatabaseHelper\enums\EngineTypes; +use DatabaseHelper\enums\DatabaseEngines; use InvalidArgumentException; class Table @@ -60,7 +60,7 @@ class Table return $this; } - public function engine(EngineTypes $engine): Table { + public function engine(DatabaseEngines $engine): Table { $this->table->engine = $engine; return $this; } diff --git a/enums/ConditionOperators.php b/enums/ConditionOperators.php new file mode 100644 index 0000000..524041d --- /dev/null +++ b/enums/ConditionOperators.php @@ -0,0 +1,37 @@ + self::EQUAL, + '!=' => self::NOT_EQUAL, + '>' => self::GREATER, + '>=' => self::GREATER_EQUAL, + '<' => self::LESS, + '<=' => self::LESS_EQUAL, + default => throw new InvalidArgumentException("Invalid operator: $operator"), + }; + } + + public function toString(): string { + return match ($this) { + self::EQUAL => '=', + self::NOT_EQUAL => '!=', + self::GREATER => '>', + self::GREATER_EQUAL => '>=', + self::LESS => '<', + self::LESS_EQUAL => '<=', + }; + } +} diff --git a/enums/EngineTypes.php b/enums/DatabaseEngines.php similarity index 91% rename from enums/EngineTypes.php rename to enums/DatabaseEngines.php index e1c7b08..7494161 100644 --- a/enums/EngineTypes.php +++ b/enums/DatabaseEngines.php @@ -1,7 +1,7 @@