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 ""; } }