setConnection($connection) ->setQueryBuilder($builder) ->setFactory($factory) ->setup(); } protected Connection $connection; public function setConnection(Connection $connection): Repository { $this->connection = $connection; return $this; } public function getConnection(): Connection { return $this->connection; } protected QueryBuilder $builder; public function setQueryBuilder(QueryBuilder $builder): RepositoryInterface { $this->builder = $builder; return $this; } public function getQueryBuilder(): QueryBuilder { return $this->builder; } protected Factory $factory; public function setFactory(Factory $factory): RepositoryInterface { $this->factory = $factory; return $this; } public function getFactory(): Factory { return $this->factory; } protected string $table; public function setTable(string $table): RepositoryInterface { $this->table = $table; return $this; } public function getTable(): string { return $this->table; } protected array $columns; public function setColumns(array $columns): RepositoryInterface { foreach ($columns as $column) { $this->addColumn($column); } return $this; } public function addColumn(string $column): RepositoryInterface { $this->columns []= $column; return $this; } public function getColumns(): array { return $this->columns; } public function save(Model $model): void { if (!$model->isDirty() and !$model->isNew()) { return; } $cols = []; $values = []; foreach ($this->getColumns() as $column) { $m = 'get' . ucwords($column); $cols []= '?'; $values []= $model->{$m}(); } $query = $this->getQueryBuilder()->insert($this->getTable())->columns($this->getColumns())->values($cols); $this->getConnection()->execute($query, $values); } public function edit(Model $model, array $data): Model { foreach ($this->getColumns() as $col) { if (isset($data[$col])) { $m = 'set' . ucwords($col); $model->{$m}($data[$col]); } } return $model; } public function fetchById(int $id): Model { $query = $this->getQueryBuilder() ->select() ->from($this->getTable()) ->where([['id', '?']]) ->limit(1); return $this->load($this->getConnection()->execute($query, [$id])->getAsArray()[0]); } public function fetchAll(): array { $query = $this->getQueryBuilder() ->select() ->from($this->getTable()); return array_map([$this, 'load'], $this->getConnection()->query($query)->getAsArray()); } }