pdo->prepare( self::SELECT . ' WHERE p.owner_id = :owner ORDER BY p.title COLLATE NOCASE ASC, p.id ASC' ); $stmt->execute(['owner' => $ownerId]); return array_map($this->cast(...), $stmt->fetchAll()); } public function countForOwner(int $ownerId): int { $stmt = $this->pdo->prepare('SELECT COUNT(*) FROM projects WHERE owner_id = :owner'); $stmt->execute(['owner' => $ownerId]); return (int) $stmt->fetchColumn(); } /** * @return ProjectRow|null */ public function findOwnedBy(int $id, int $ownerId): ?array { $stmt = $this->pdo->prepare(self::SELECT . ' WHERE p.id = :id AND p.owner_id = :owner'); $stmt->execute(['id' => $id, 'owner' => $ownerId]); $row = $stmt->fetch(); return $row === false ? null : $this->cast($row); } /** * @return ProjectRow */ public function create(int $ownerId, string $title, string $description): array { $stmt = $this->pdo->prepare( 'INSERT INTO projects (owner_id, title, description) VALUES (:owner, :title, :description)' ); $stmt->execute([ 'owner' => $ownerId, 'title' => $title, 'description' => $description, ]); /** @var ProjectRow $project */ $project = $this->findOwnedBy((int) $this->pdo->lastInsertId(), $ownerId); return $project; } /** * @param array{title?: string, description?: string} $fields * @return ProjectRow */ public function update(int $id, int $ownerId, array $fields): array { $sets = ['updated_at = ' . $this->nowExpr()]; $params = ['id' => $id]; foreach (['title', 'description'] as $column) { if (array_key_exists($column, $fields)) { $sets[] = "{$column} = :{$column}"; $params[$column] = $fields[$column]; } } $stmt = $this->pdo->prepare('UPDATE projects SET ' . implode(', ', $sets) . ' WHERE id = :id'); $stmt->execute($params); /** @var ProjectRow $project */ $project = $this->findOwnedBy($id, $ownerId); return $project; } public function delete(int $id): void { $this->pdo->prepare('DELETE FROM projects WHERE id = :id')->execute(['id' => $id]); } /** Bump updated_at, e.g. when the project's cards change. */ public function touch(int $id): void { $this->pdo->prepare('UPDATE projects SET updated_at = ' . $this->nowExpr() . ' WHERE id = :id') ->execute(['id' => $id]); } private function nowExpr(): string { return "strftime('%Y-%m-%dT%H:%M:%SZ', 'now')"; } /** * @param array $row * @return ProjectRow */ private function cast(array $row): array { $row['id'] = (int) $row['id']; $row['owner_id'] = (int) $row['owner_id']; $row['card_count'] = (int) $row['card_count']; $row['completed_count'] = (int) $row['completed_count']; /** @var ProjectRow $row */ return $row; } }