prepared queries
This commit is contained in:
parent
d10a9e2bde
commit
0348b07325
3 changed files with 90 additions and 39 deletions
107
src/index.ts
107
src/index.ts
|
@ -1,11 +1,11 @@
|
|||
import homepage from '@routes/index.html';
|
||||
import { drizzleDB } from "@server/db";
|
||||
import { entry } from "@server/db/schema";
|
||||
import { drizzleDB } from '@server/db';
|
||||
import { entry } from '@server/db/schema';
|
||||
import favicon from '@static/favicon.png';
|
||||
import robotsTxt from '@static/robots.txt';
|
||||
import sitemapTxt from '@static/sitemap.txt';
|
||||
import { env } from "bun";
|
||||
import { desc, eq } from "drizzle-orm";
|
||||
import { env } from 'bun';
|
||||
import { desc, eq, sql } from 'drizzle-orm';
|
||||
|
||||
const development = env.NODE_ENV !== 'production';
|
||||
|
||||
|
@ -26,6 +26,58 @@ function etagResponse(etag: string, cacheControl?: string) {
|
|||
let entriesETag = '';
|
||||
let entriesNotModified = false;
|
||||
|
||||
const fetchEntries = drizzleDB
|
||||
.select({
|
||||
id: entry.id,
|
||||
name: entry.name,
|
||||
href: entry.href,
|
||||
finished: entry.finished,
|
||||
updated_at: entry.updatedAt,
|
||||
})
|
||||
.from(entry)
|
||||
.orderBy(desc(entry.updatedAt))
|
||||
.prepare();
|
||||
|
||||
const entryExists = drizzleDB
|
||||
.select({ id: entry.id })
|
||||
.from(entry)
|
||||
.where(eq(entry.name, sql.placeholder('name')))
|
||||
.prepare();
|
||||
|
||||
const insertEntry = drizzleDB
|
||||
.insert(entry)
|
||||
.values({
|
||||
name: sql.placeholder('name'),
|
||||
href: sql.placeholder('href'),
|
||||
})
|
||||
.prepare();
|
||||
|
||||
const updateEntry = drizzleDB
|
||||
.update(entry)
|
||||
.set({
|
||||
name: sql.placeholder('name') as any,
|
||||
href: sql.placeholder('href') as any,
|
||||
})
|
||||
.where(eq(entry.id, sql.placeholder('id')))
|
||||
.prepare();
|
||||
|
||||
const fetchEntryById = drizzleDB
|
||||
.select()
|
||||
.from(entry)
|
||||
.where(eq(entry.id, sql.placeholder('id')))
|
||||
.prepare();
|
||||
|
||||
const deleteEntry = drizzleDB
|
||||
.delete(entry)
|
||||
.where(eq(entry.id, sql.placeholder('id')))
|
||||
.prepare();
|
||||
|
||||
const updateEntryFinished = drizzleDB
|
||||
.update(entry)
|
||||
.set({ finished: sql.placeholder('finished') as any })
|
||||
.where(eq(entry.id, sql.placeholder('id')))
|
||||
.prepare();
|
||||
|
||||
Bun.serve({
|
||||
routes: {
|
||||
'/': homepage,
|
||||
|
@ -46,16 +98,13 @@ Bun.serve({
|
|||
}
|
||||
|
||||
entriesNotModified = true;
|
||||
const entries = await drizzleDB
|
||||
.select({ id: entry.id, name: entry.name, href: entry.href, finished: entry.finished, updated_at: entry.updatedAt })
|
||||
.from(entry)
|
||||
.orderBy(desc(entry.updatedAt));
|
||||
const entries = await fetchEntries.execute();
|
||||
|
||||
const body = JSON.stringify(entries);
|
||||
entriesETag = getEtag(body);
|
||||
|
||||
return new Response(body, {
|
||||
headers: { 'Content-Type': 'application/json', 'ETag': entriesETag }
|
||||
headers: { 'Content-Type': 'application/json', ETag: entriesETag },
|
||||
});
|
||||
},
|
||||
async PUT(req) {
|
||||
|
@ -64,23 +113,27 @@ Bun.serve({
|
|||
const body = await getEntryFromReq(req);
|
||||
if (!body) return new Response('Invalid data', { status: 400 });
|
||||
|
||||
const result = await drizzleDB.select({ id: entry.id }).from(entry).where(eq(entry.name, body.name));
|
||||
const result = await entryExists.execute({ name: body.name });
|
||||
|
||||
let created = true;
|
||||
|
||||
if (result.length === 0) {
|
||||
await drizzleDB.insert(entry).values(body).execute();
|
||||
await insertEntry.execute(body);
|
||||
} else if (result.length === 1) {
|
||||
const row = result[0] as NonNullable<typeof result[number]>;
|
||||
const row = result[0] as NonNullable<(typeof result)[number]>;
|
||||
created = false;
|
||||
await drizzleDB.update(entry).set(body).where(eq(entry.id, row.id)).execute();
|
||||
await updateEntry.execute({
|
||||
id: row.id,
|
||||
name: body.name,
|
||||
href: body.href,
|
||||
});
|
||||
} else {
|
||||
return new Response('Invalid data, multiple matches?', { status: 400 });
|
||||
}
|
||||
|
||||
entriesNotModified = false;
|
||||
return new Response(JSON.stringify({ created }), {
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
},
|
||||
},
|
||||
|
@ -91,10 +144,10 @@ Bun.serve({
|
|||
const id = Number.parseInt(req.params.id, 10);
|
||||
if (Number.isNaN(id)) return new Response('Invalid id', { status: 400 });
|
||||
|
||||
const result = await drizzleDB.select().from(entry).where(eq(entry.id, id));
|
||||
const result = await fetchEntryById.execute({ id });
|
||||
|
||||
return new Response(JSON.stringify(result), {
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
},
|
||||
async PUT(req) {
|
||||
|
@ -106,13 +159,15 @@ Bun.serve({
|
|||
const body = await getEntryFromReq(req);
|
||||
if (!body) return new Response('Invalid data', { status: 400 });
|
||||
|
||||
await drizzleDB.update(entry).set(body).where(eq(entry.id, id)).execute();
|
||||
|
||||
let created = false;
|
||||
await updateEntry.execute({
|
||||
id,
|
||||
name: body.name,
|
||||
href: body.href,
|
||||
});
|
||||
|
||||
entriesNotModified = false;
|
||||
return new Response(JSON.stringify({ created: false }), {
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
},
|
||||
async DELETE(req) {
|
||||
|
@ -121,7 +176,7 @@ Bun.serve({
|
|||
const id = Number.parseInt(req.params.id, 10);
|
||||
if (Number.isNaN(id)) return new Response('Invalid id', { status: 400 });
|
||||
|
||||
await drizzleDB.delete(entry).where(eq(entry.id, id)).execute();
|
||||
await deleteEntry.execute({ id });
|
||||
|
||||
entriesNotModified = false;
|
||||
return new Response('OK');
|
||||
|
@ -135,11 +190,7 @@ Bun.serve({
|
|||
if (Number.isNaN(id)) return new Response('Invalid id', { status: 400 });
|
||||
const finished = req.params.finished === 'true';
|
||||
|
||||
await drizzleDB
|
||||
.update(entry)
|
||||
.set({ finished: finished })
|
||||
.where(eq(entry.id, id))
|
||||
.execute();
|
||||
await updateEntryFinished.execute({ id, finished });
|
||||
|
||||
entriesNotModified = false;
|
||||
return new Response('OK');
|
||||
|
@ -159,7 +210,7 @@ console.log('Server started on port:', env.PORT ? Number.parseInt(env.PORT, 10)
|
|||
|
||||
async function getEntryFromReq(req: Request) {
|
||||
const json = await req.json();
|
||||
const body = json as { name: string, href: string }
|
||||
const body = json as { name: string; href: string };
|
||||
if (!body.name || !body.href || typeof body.name !== 'string' || typeof body.href !== 'string') {
|
||||
return null;
|
||||
}
|
||||
|
@ -180,7 +231,7 @@ function isAuthenticated(req: Request) {
|
|||
}
|
||||
|
||||
const unauthorizedHeaders = new Headers({
|
||||
'WWW-Authenticate': `Bearer realm='sign', error="invalid_request"`
|
||||
'WWW-Authenticate': `Bearer realm='sign', error="invalid_request"`,
|
||||
});
|
||||
|
||||
function unauthorizedResp() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue