DB things
This commit is contained in:
parent
3d33e72f42
commit
0fc6b1b8a8
13
db-migrations.ts
Normal file
13
db-migrations.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { query } from "./db.ts";
|
||||||
|
|
||||||
|
await query(`
|
||||||
|
create extension if not exists "uuid-ossp";
|
||||||
|
|
||||||
|
drop table if exists notes;
|
||||||
|
create table if not exists notes (
|
||||||
|
id uuid primary key default uuid_generate_v4(),
|
||||||
|
content text not null,
|
||||||
|
created_at timestamptz not null default now(),
|
||||||
|
updated_at timestamptz not null default now()
|
||||||
|
);
|
||||||
|
`);
|
25
db.ts
Normal file
25
db.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import * as postgres from "https://deno.land/x/postgres@v0.16.1/mod.ts";
|
||||||
|
import { type QueryArguments } from "https://deno.land/x/postgres@v0.16.1/query/query.ts?s=QueryArguments";
|
||||||
|
|
||||||
|
export { type QueryObjectResult } from "https://deno.land/x/postgres@v0.16.1/query/query.ts?s=QueryArguments";
|
||||||
|
|
||||||
|
const databaseUrl = Deno.env.get("DATABASE_URL") ||
|
||||||
|
"postgresql://danielflanagan:@127.0.0.1:5432/lyricscreen";
|
||||||
|
const pool = new postgres.Pool(databaseUrl, 3, true);
|
||||||
|
|
||||||
|
export async function query(sql: string, ...args: QueryArguments[]) {
|
||||||
|
let result = null;
|
||||||
|
try {
|
||||||
|
const connection = await pool.connect();
|
||||||
|
try {
|
||||||
|
result = await connection.queryObject(sql, ...args);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error querying database:", err);
|
||||||
|
} finally {
|
||||||
|
connection.release();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error connecting to database:", err);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
10
fresh.gen.ts
10
fresh.gen.ts
|
@ -13,8 +13,9 @@ import * as $6 from "./routes/api/random-uuid.ts";
|
||||||
import * as $7 from "./routes/countdown.tsx";
|
import * as $7 from "./routes/countdown.tsx";
|
||||||
import * as $8 from "./routes/github/[username].tsx";
|
import * as $8 from "./routes/github/[username].tsx";
|
||||||
import * as $9 from "./routes/index.tsx";
|
import * as $9 from "./routes/index.tsx";
|
||||||
import * as $10 from "./routes/route-config-example.tsx";
|
import * as $10 from "./routes/note.tsx";
|
||||||
import * as $11 from "./routes/search.tsx";
|
import * as $11 from "./routes/route-config-example.tsx";
|
||||||
|
import * as $12 from "./routes/search.tsx";
|
||||||
import * as $$0 from "./islands/Countdown.tsx";
|
import * as $$0 from "./islands/Countdown.tsx";
|
||||||
import * as $$1 from "./islands/Counter.tsx";
|
import * as $$1 from "./islands/Counter.tsx";
|
||||||
|
|
||||||
|
@ -30,8 +31,9 @@ const manifest = {
|
||||||
"./routes/countdown.tsx": $7,
|
"./routes/countdown.tsx": $7,
|
||||||
"./routes/github/[username].tsx": $8,
|
"./routes/github/[username].tsx": $8,
|
||||||
"./routes/index.tsx": $9,
|
"./routes/index.tsx": $9,
|
||||||
"./routes/route-config-example.tsx": $10,
|
"./routes/note.tsx": $10,
|
||||||
"./routes/search.tsx": $11,
|
"./routes/route-config-example.tsx": $11,
|
||||||
|
"./routes/search.tsx": $12,
|
||||||
},
|
},
|
||||||
islands: {
|
islands: {
|
||||||
"./islands/Countdown.tsx": $$0,
|
"./islands/Countdown.tsx": $$0,
|
||||||
|
|
|
@ -10,6 +10,6 @@ export async function handler(
|
||||||
) {
|
) {
|
||||||
ctx.state.data = "myData";
|
ctx.state.data = "myData";
|
||||||
const resp = await ctx.next();
|
const resp = await ctx.next();
|
||||||
resp.headers.set("server", "fresh server");
|
if (resp) resp.headers.set("server", "fresh server");
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
48
routes/note.tsx
Normal file
48
routes/note.tsx
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import { Handlers, PageProps } from "$fresh/server.ts";
|
||||||
|
import { query, type QueryObjectResult } from "../db.ts";
|
||||||
|
|
||||||
|
interface Note {
|
||||||
|
id: string;
|
||||||
|
created_at: Date;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const handler: Handlers<Note[] | null> = {
|
||||||
|
async GET(request, context) {
|
||||||
|
console.debug({ request, context });
|
||||||
|
const result = await query("select * from notes");
|
||||||
|
if (result == null) throw "unable to fetch from database";
|
||||||
|
const notes = result.rows;
|
||||||
|
console.debug(notes);
|
||||||
|
return await context.render(notes);
|
||||||
|
},
|
||||||
|
async POST(request, context) {
|
||||||
|
console.debug({ request, context });
|
||||||
|
if (request.headers.get("content-type") != "application/json") {
|
||||||
|
throw "content-type must be application/json";
|
||||||
|
}
|
||||||
|
const body = await request.json();
|
||||||
|
console.log({ body });
|
||||||
|
if (!("content" in body)) {
|
||||||
|
throw "no content field present in body";
|
||||||
|
}
|
||||||
|
const result = await query(
|
||||||
|
"insert into notes (content) values ($1) returning id",
|
||||||
|
body.content,
|
||||||
|
);
|
||||||
|
if (result == null) throw "failed to fetch notes";
|
||||||
|
const { rows: [{ id }] } = result as QueryObjectResult<Note>;
|
||||||
|
console.debug(id);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Page({ data }: PageProps<Note[] | null>) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>Yo!</p>
|
||||||
|
<pre>
|
||||||
|
{JSON.stringify(data, null, 2)}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in a new issue