diff --git a/deno.json b/deno.json index f739e7a..2a138be 100644 --- a/deno.json +++ b/deno.json @@ -2,8 +2,8 @@ "tasks": { "jetstream:prod": "deno run --allow-net --allow-read --allow-write --allow-env jetstream.ts", "jetstream": "deno run --watch --allow-net --allow-read --allow-write --allow-env jetstream.ts", - "server": "deno run --watch --allow-net server.ts", - "server:prod": "deno run --allow-net server.ts", + "server": "deno run --watch --allow-net --allow-read --allow-write --allow-env server.ts", + "server:prod": "deno run --allow-net --allow-read --allow-write --allow-env server.ts", "migrate": "deno run --allow-read --allow-write src/migrations/init.ts" }, "imports": { diff --git a/server.ts b/server.ts index 7080cf8..87bb140 100644 --- a/server.ts +++ b/server.ts @@ -1,4 +1,5 @@ import { Application, Router } from "@oak/oak"; +import { getNotes, getNotesByDid } from "./src/data/db.ts"; const router = new Router(); @@ -6,6 +7,19 @@ router.get("/", (ctx) => { ctx.response.body = "Hello world"; }); +router.get("/notes", (ctx) => { + const cursor = ctx.request.url.searchParams.get("cursor") ?? undefined; + const limit = Number(ctx.request.url.searchParams.get("limit")) || 20; + ctx.response.body = getNotes(cursor, limit); +}); + +router.get("/:did/notes", (ctx) => { + const { did } = ctx.params; + const cursor = ctx.request.url.searchParams.get("cursor") ?? undefined; + const limit = Number(ctx.request.url.searchParams.get("limit")) || 20; + ctx.response.body = getNotesByDid(did, cursor, limit); +}); + const app = new Application(); app.use(router.routes()); app.use(router.allowedMethods()); diff --git a/src/data/db.ts b/src/data/db.ts index 159a97b..b8421eb 100644 --- a/src/data/db.ts +++ b/src/data/db.ts @@ -3,6 +3,58 @@ import type { Note } from "./note.ts"; export const db = new DB(Deno.env.get("SQLITE_PATH") ?? "notes.db"); +export const getNotes = (cursor?: string, limit = 20) => { + const rows = cursor + ? db.query<[string, string, string, string, string, string]>( + "SELECT did, rkey, title, content, publishedAt, createdAt FROM note WHERE rkey < ? ORDER BY rkey DESC LIMIT ?", + [cursor, limit], + ) + : db.query<[string, string, string, string, string, string]>( + "SELECT did, rkey, title, content, publishedAt, createdAt FROM note ORDER BY rkey DESC LIMIT ?", + [limit], + ); + + const notes = rows.map(([did, rkey, title, content, publishedAt, createdAt]) => ({ + did, + rkey, + title, + content, + publishedAt, + createdAt, + })); + + return { + notes, + cursor: notes.length === limit ? notes[notes.length - 1].rkey : undefined, + }; +}; + +export const getNotesByDid = (did: string, cursor?: string, limit = 20) => { + const rows = cursor + ? db.query<[string, string, string, string, string, string]>( + "SELECT did, rkey, title, content, publishedAt, createdAt FROM note WHERE did = ? AND rkey < ? ORDER BY rkey DESC LIMIT ?", + [did, cursor, limit], + ) + : db.query<[string, string, string, string, string, string]>( + "SELECT did, rkey, title, content, publishedAt, createdAt FROM note WHERE did = ? ORDER BY rkey DESC LIMIT ?", + [did, limit], + ); + + const notes = rows.map(([did, rkey, title, content, publishedAt, createdAt]) => ({ + did, + rkey, + title, + content, + publishedAt, + createdAt, + })); + + return { + notes, + cursor: notes.length === limit ? notes[notes.length - 1].rkey : undefined, + }; +}; + export const upsertNote = (note: Note) => { db.query( `