entityClass = $entityClass; } public function select($field) : self { if ( $select = $this->has(Query\Select::class) ) { $select->add($field); } else { $select = new Query\Select(); $select->set($field); $this->push($select); } return $this; } public function from($table, $alias = null, $database = null) : self { if ( $database ) { $table = "`$database`.".$table; } if ( $from = $this->has(Query\From::class) ) { $from->add($alias ? [ $alias => $table ] : $table); } else { $from = new Query\From(); $this->push($from); $from->set($alias ? [ $alias => $table ] : $table); } return $this; } public function open(string $condition = Query\Where::CONDITION_AND) : self { if ( false !== ($this->where ?? false) ) { $this->where->conditionList[] = $new = new Query\Where($this, $condition); $this->where = $new; } return $this; } public function close() : self { if ( false !== ($this->where ?? false) && $this->where->parent ) { $this->where = $this->where->parent; } return $this; } public function where($field, $value, string $operator = Query\Where::OPERATOR_EQUAL, string $condition = Query\Where::CONDITION_AND, bool $not = false) : self { if ( $this->where ?? false ) { $where = $this->where; } elseif ( false === $where = $this->has(Query\Where::class) ) { $this->where = $where = new Query\Where($this); $this->push($where); } $this->conditionOperator = $operator; $where->add($field, $value, $operator, $condition, $not); return $this; } public function notWhere($field, $value, string $operator = Query\Where::CONDITION_AND) : self { return $this->where($field, $value, $operator, true); } public function groupBy() : self { //$this->queryBuilder->groupBy(); return $this; } public function limit(int $value) : self { if ( false === $limit = $this->has(Query\Limit::class) ) { $limit = new Query\Limit(); $this->push($limit); } $limit->set($value); return $this; } public function offset(int $value) : self { if ( false === $offset = $this->has(Query\Offset::class) ) { $offset = new Query\Offset(); $this->push($offset); } $offset->set($value); return $this; } public function orderBy(string $field, ? string $direction = null) : self { if ( false === $orderBy = $this->has(Query\OrderBy::class) ) { $orderBy = new Query\OrderBy(); $this->push($orderBy); } $orderBy->add($field, $direction); return $this; } public function push(Query\Fragment $queryFragment) : self { $this->queryStack[] = $queryFragment; return $this; } public function render() : string { $sql = []; usort($this->queryStack, function($q1, $q2) { return $q1->order <=> $q2->order; }); foreach($this->queryStack as $fragment) { $sql[] = $fragment->render(); } return implode(" ", $sql); } public function has($class) { foreach($this->queryStack as $item) { if ( get_class($item) === $class ) { return $item; } } return false; } public function __toString() : string { return $this->render(); } public function addParameter($value, $key = null) { if ( $key === null ) { $key = ":p" . $this->parameterIndex++; } $this->parameters[$key] = $value; return $key; } }