5 use Friendica\Database\Database;
6 use Friendica\Database\DBA;
7 use Friendica\Network\HTTPException;
8 use Psr\Log\LoggerInterface;
11 * Repositories are Factories linked to one or more database tables.
16 abstract class BaseRepository extends BaseFactory
24 protected static $table_name;
27 protected static $model_class;
29 /** @var BaseCollection */
30 protected static $collection_class;
32 public function __construct(Database $dba, LoggerInterface $logger)
34 parent::__construct($logger);
37 $this->logger = $logger;
41 * Fetches a single model record. The condition array is expected to contain a unique index (primary or otherwise).
45 * @param array $condition
47 * @throws HTTPException\NotFoundException
49 public function selectFirst(array $condition)
51 $data = $this->dba->selectFirst(static::$table_name, [], $condition);
54 throw new HTTPException\NotFoundException(static::class . ' record not found.');
57 return $this->create($data);
61 * Populates a Collection according to the condition.
65 * @param array $condition
66 * @param array $params
67 * @return BaseCollection
70 public function select(array $condition = [], array $params = [])
72 $models = $this->selectModels($condition, $params);
74 return new static::$collection_class($models);
78 * Populates the collection according to the condition. Retrieves a limited subset of models depending on the boundaries
79 * and the limit. The total count of rows matching the condition is stored in the collection.
83 * @param array $condition
84 * @param array $params
86 * @param int? $since_id
88 * @return BaseCollection
91 public function selectByBoundaries(array $condition = [], array $params = [], int $max_id = null, int $since_id = null, int $limit = self::LIMIT)
93 $condition = DBA::collapseCondition($condition);
95 $boundCondition = $condition;
98 $boundCondition[0] .= " AND `id` < ?";
99 $boundCondition[] = $max_id;
102 if (isset($since_id)) {
103 $boundCondition[0] .= " AND `id` > ?";
104 $boundCondition[] = $since_id;
107 $params['limit'] = $limit;
109 $models = $this->selectModels($boundCondition, $params);
111 $totalCount = DBA::count(static::$table_name, $condition);
113 return new static::$collection_class($models, $totalCount);
117 * This method updates the database row from the model.
119 * @param BaseModel $model
123 public function update(BaseModel $model)
125 return $this->dba->update(static::$table_name, $model->toArray(), ['id' => $model->id], true);
129 * This method creates a new database row and returns a model if it was successful.
131 * @param array $fields
132 * @return BaseModel|bool
135 public function insert(array $fields)
137 $return = $this->dba->insert(static::$table_name, $fields);
140 $fields['id'] = $this->dba->lastInsertId();
141 $return = $this->create($fields);
148 * Deletes the model record from the database.
150 * @param BaseModel $model
154 public function delete(BaseModel &$model)
156 if ($success = $this->dba->delete(static::$table_name, ['id' => $model->id])) {
164 * Base instantiation method, can be overriden to add specific dependencies
169 protected function create(array $data)
171 return new static::$model_class($this->dba, $this->logger, $data);
175 * @param array $condition Query condition
176 * @param array $params Additional query parameters
177 * @return BaseModel[]
180 protected function selectModels(array $condition, array $params = [])
182 $result = $this->dba->select(static::$table_name, [], $condition, $params);
184 /** @var BaseModel $prototype */
189 while ($record = $this->dba->fetch($result)) {
190 if ($prototype === null) {
191 $prototype = $this->create($record);
192 $models[] = $prototype;
194 $models[] = static::$model_class::createFromPrototype($prototype, $record);