jevstrudel.git / worker / src / votes-store.ts
1// The votes' storage: the `votes` table in the site's D1 database (the DB
2// binding; its schema is worker/migrations/0001_votes.sql). votes.ts
3// validates a vote before it arrives here, and reads the counts back.
4import type { Count, Vote, VoteStore } from './votes';
5
6export function d1Votes(db: D1Database): VoteStore {
7  return {
8    async add({ a, b, pick }: Vote): Promise<void> {
9      await db
10        .prepare(
11          'INSERT INTO votes (a, b, pick, n) VALUES (?, ?, ?, 1) ON CONFLICT (a, b, pick) DO UPDATE SET n = n + 1',
12        )
13        .bind(a, b, pick)
14        .run();
15    },
16    async counts(): Promise<Count[]> {
17      const { results } = await db.prepare('SELECT a, b, pick, n FROM votes ORDER BY a, b, pick').all<Count>();
18      return results;
19    },
20  };
21}