builder = $builder; } public function __call($method, $arguments) { $arguments = $this->normalizeTableArgument($method, $arguments); $result = $this->builder->$method(...$arguments); if ($result instanceof QueryBuilder) { $this->builder = $result; return $this; } return $result; } public function where($column, $operator = null, $value = null, $boolean = 'and') { if ($operator !== null && $value === null && preg_match('/^(.*)\s(>=|<=|<>|!=|>|<)$/', $column, $matches)) { return $this->where(trim($matches[1]), $matches[2], $operator, $boolean); } $this->builder = $this->builder->where($column, $operator, $value, $boolean); return $this; } public function like($column, $match, string $side = 'both') { $pattern = $this->wrapLike($match, $side); $this->builder = $this->builder->where($column, 'like', $pattern); return $this; } public function set($key, $value = null, bool $escape = true) { if (is_array($key)) { $this->setData = array_merge($this->setData, $key); } else { $this->setData[$key] = $value; } return $this; } public function update($values = []) { $data = $values ?: $this->setData; $this->setData = []; return $this->builder->update($data); } public function findAll(int $limit = 0, int $offset = 0) { if ($limit > 0) { $this->builder = $this->builder->limit($limit); } if ($offset > 0) { $this->builder = $this->builder->offset($offset); } return $this->getResultArray(); } public function get($columns = ['*']) { $collection = $this->builder->get($columns); return new CiQueryResult($collection); } public function getResultArray(): array { return $this->get()->getResultArray(); } public function getRowArray(): ?array { return $this->get()->getRowArray(); } public function getRow(?string $column = null) { return $this->get()->getRow($column); } public function countAllResults(): int { return $this->builder->count(); } protected function wrapLike($match, string $side): string { $pattern = "%{$match}%"; switch (strtolower($side)) { case 'before': return "%{$match}"; case 'after': return "{$match}%"; default: return $pattern; } } protected function normalizeTableArgument(string $method, array $arguments): array { if (in_array($method, $this->tableMethods, true) && isset($arguments[0]) && is_string($arguments[0])) { $arguments[0] = $this->normalizeTableName($arguments[0]); } return $arguments; } protected function normalizeTableName(string $table): string { $normalized = trim($table); if (stripos($normalized, ' as ') !== false) { return $normalized; } if (strpos($normalized, ' ') !== false) { [$name, $alias] = preg_split('/\s+/', $normalized, 2); return "{$name} as {$alias}"; } return $normalized; } }