entityClass = $entity; $this->alias = $alias; $this->adapter = $adapter; $this->queryBuilder = new QueryBuilder(); $this->entityResolver = Ulmus::resolveEntity($entity); } public function loadOne() : EntityCollection { return $this->limit(1)->collectionFromQuery(); } public function loadAll() : EntityCollection { return $this->collectionFromQuery(); } public function loadFromPk($value, $primaryKey = "id") : EntityCollection { # var_dump("
", $primaryKey);die();
        return $this->where($primaryKey, $value)->loadOne();
    }

    public function loadFromField($field, $value) : EntityCollection
    {
        return $this->where($field, $value)->collectionFromQuery();
    }

    public function deleteOne() 
    {    
        return $this->limit(1)->deleteSqlQuery()->runQuery();
    }
    
    public function deleteAll() 
    {    
        return $this->deleteSqlQuery()->runQuery();
    }

    public function deleteFromPk($value, $primaryKey = "id") 
    {    
        return $this->where($primaryKey, $value)->deleteOne();
    }
    
    public function yieldAll() : \Generator
    {

    }

    public function select($fields) : self
    {
        $this->queryBuilder->select($fields);
        return $this;
    }

    public function delete() : self
    {
        $this->queryBuilder->delete($this->alias);
        return $this;
    }

    public function from($table) : self
    {
        foreach((array) $table as $alias => $table) {
            $this->queryBuilder->from($table, is_numeric($alias) ? null : $alias);
        }

        return $this;
    }

    public function join(string $type, $table, $field, $value) : self
    {
        return $this;
    }

    public function open(string $condition = Query\Where::CONDITION_AND) : self
    {
        $this->queryBuilder->open($condition);
        return $this;
    }

    public function orOpen() : self
    {
        return $this->open(Query\Where::CONDITION_OR);
    }

    public function close() : self
    {
        $this->queryBuilder->close();
        return $this;
    }

    public function where($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
    {
        $this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_AND);
        return $this;
    }

    public function and($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
    {
        return $this->where($field, $value, $operator);
    }

    public function or($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
    {
        $this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_OR);
        return $this;
    }

    public function notWhere(array $condition) : self
    {
        $this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_AND, true);
        return $this;
    }

    public function orNot($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
    {
        $this->queryBuilder->notWhere($condition, Query\Where::CONDITION_OR, true);
        return $this;
    }

    public function having() : self
    {
        return $this;
    }

    public function notHaving() : self
    {
        return $this;
    }

    public function in($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
    {
        $this->queryBuilder->where($field, $value, $operator);
        return $this;
    }

    public function orIn($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
    {
        $this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_OR);
        return $this;
    }

    public function notIn($field, $value) : self
    {
        $this->queryBuilder->where($field, $value, Query\Where::OPERATOR_NOT_EQUAL);
        return $this;
    }

    public function orNotIn($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
    {
        return $this->orNot($field, $value, Query\Where::OPERATOR_NOT_EQUAL, Query\Where::CONDITION_OR);
    }

    public function like($field, $value) : self
    {
        $this->queryBuilder->where($field, $value, Query\Where::OPERATOR_LIKE, Query\Where::CONDITION_AND);
        return $this;
    }

    public function notLike($field, $value) : self
    {
        $this->queryBuilder->where($field, $value, Query\Where::OPERATOR_LIKE, Query\Where::CONDITION_AND, true);
        return $this;
    }

    public function match() : self
    {

    }

    public function notMatch() : self
    {

    }

    public function between() : self
    {

    }

    public function notBetween() : self
    {

    }

    public function groupBy() : self
    {
        #$this->queryBuilder->groupBy();
        return $this;
    }

    public function orderBy(string $field, ? string $direction = null) : self
    {
        $this->queryBuilder->orderBy($field, $direction);
        return $this;
    }

    public function limit(int $value) : self
    {
        $this->queryBuilder->limit($value);
        return $this;
    }

    public function offset(int $value) : self
    {
        $this->queryBuilder->offset($value);
        return $this;
    }

    public function commit() : self
    {
        return $this;
    }

    public function rollback() : self
    {
        return $this;
    }

    protected function collectionFromQuery() : EntityCollection
    {
        $class = $this->entityClass;

        $entityCollection = new EntityCollection();

        foreach(Ulmus::iterateQueryBuilder($this->selectSqlQuery()->queryBuilder) as $entityData) {
            $entityCollection->append( ( new $class() )->entityFillFromDataset($entityData) );
        }

        return $entityCollection;
    }

    public function runQuery()
    {
        return Ulmus::runQuery($this->queryBuilder);
    }
    
    protected function selectSqlQuery() : self
    {
        if ( ! $this->queryBuilder->has(Query\Select::class) ) {
            $this->select("{$this->alias}.*");
        }

        if ( ! $this->queryBuilder->has(Query\From::class) ) {
            $this->from([ $this->alias => $this->entityResolver->tableName() ]);
        }

        return $this;
    }

    protected function deleteSqlQuery() : self
    {
        if ( ! $this->queryBuilder->has(Query\Delete::class) ) {
            $this->delete();
        }

        if ( ! $this->queryBuilder->has(Query\From::class) ) {
            $this->from([ $this->alias => $this->entityResolver->tableName() ]);
        }

        return $this;
    }
    
    protected function fromRow($row) : self
    {

    }

    protected function fromCollection($rows) : self
    {

    }
}