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 $order An optional array with order information
67 * @param int|array $limit Optional limit information
69 * @return BaseCollection
72 public function select(array $condition = [], array $order = [], $limit = null)
74 $models = $this->selectModels($condition, $order, $limit);
76 return new static::$collection_class($models);
80 * Populates the collection according to the condition. Retrieves a limited subset of models depending on the boundaries
81 * and the limit. The total count of rows matching the condition is stored in the collection.
85 * @param array $condition
88 * @param int? $since_id
91 * @return BaseCollection
94 public function selectByBoundaries(array $condition = [], array $order = [], int $max_id = null, int $since_id = null, int $limit = self::LIMIT)
96 $condition = DBA::collapseCondition($condition);
98 $boundCondition = $condition;
100 if (isset($max_id)) {
101 $boundCondition[0] .= " AND `id` < ?";
102 $boundCondition[] = $max_id;
105 if (isset($since_id)) {
106 $boundCondition[0] .= " AND `id` > ?";
107 $boundCondition[] = $since_id;
110 $models = $this->selectModels($boundCondition, $order, $limit);
112 $totalCount = DBA::count(static::$table_name, $condition);
114 return new static::$collection_class($models, $totalCount);
118 * This method updates the database row from the model.
120 * @param BaseModel $model
124 public function update(BaseModel $model)
126 return $this->dba->update(static::$table_name, $model->toArray(), ['id' => $model->id], $model->getOriginalData());
130 * This method creates a new database row and returns a model if it was successful.
132 * @param array $fields
133 * @return BaseModel|bool
136 public function insert(array $fields)
138 $return = $this->dba->insert(static::$table_name, $fields);
141 throw new HTTPException\InternalServerErrorException('Unable to insert new row in table "' . static::$table_name . '"');
144 $fields['id'] = $this->dba->lastInsertId();
145 $return = $this->create($fields);
151 * Deletes the model record from the database.
153 * @param BaseModel $model
157 public function delete(BaseModel &$model)
159 if ($success = $this->dba->delete(static::$table_name, ['id' => $model->id])) {
167 * Base instantiation method, can be overriden to add specific dependencies
172 protected function create(array $data)
174 return new static::$model_class($this->dba, $this->logger, $data);
178 * @param array $condition Query condition
179 * @param array $order An optional array with order information
180 * @param int|array $limit Optional limit information
182 * @return BaseModel[]
185 protected function selectModels(array $condition, array $order = [], $limit = null)
189 if (!empty($order)) {
190 $params['order'] = $order;
193 if (!empty($limit)) {
194 $params['limit'] = $limit;
197 $result = $this->dba->select(static::$table_name, [], $condition, $params);
199 /** @var BaseModel $prototype */
204 while ($record = $this->dba->fetch($result)) {
205 if ($prototype === null) {
206 $prototype = $this->create($record);
207 $models[] = $prototype;
209 $models[] = static::$model_class::createFromPrototype($prototype, $record);
217 * @param BaseCollection $collection
219 public function saveCollection(BaseCollection $collection)
221 $collection->map([$this, 'update']);