Initialize database. Document it. Hate life.

This commit is contained in:
Ryan Pandya 2024-10-04 23:39:04 -07:00
parent c52ac44f3c
commit 850149ebcb
14 changed files with 4368 additions and 18 deletions

View File

@ -2,19 +2,11 @@
description: Time to actually do shit. description: Time to actually do shit.
--- ---
# Packages and Turbo # Repo Hygiene
So you got a project started and wasted some time writing documentation. Great! So you got a project started and wasted some time writing documentation. Great!
Now, how do we get some actual functionality in this shit? Now, let's move on to "actually building software that does something" and "everything else other than running a generator and writing useless documentation".
Here's what I want to get done in this chapter:
- Get typescript installed, and have its settings propagate to several different apps
- Have Baby's First Landing Page set up in the web app, inheriting the Typescript config
- Do the same for Tailwind, ESLint, Prettier???
Then, we can worry about things like "actually building software that does something" and "everything else other than running a generator and writing useless documentation".
## But first, wtf is @repo? ## But first, wtf is @repo?
@ -33,5 +25,9 @@ Yes, everything worked fine as soon as I made the ~31 edits, ran `pnpm install`,
## Another side-quest: Git Repository ## Another side-quest: Git Repository
There's really no reason to document this. I already have a git repo initialized; I created one on `git.ryanpandya.com` and synced all this crap with it. There's really no reason to document this. I already had a local a git repo initialized (can't remember if this happens by default in my `init-nix` script, or if I ran `git init`, you're on your own); I created a cloud copy on `git.ryanpandya.com` and synced all this crap with it.
:::note
Make sure you de-select "Initialize repository" so that the first commit from VSCode actually goes through instead of causing a mountain of sync conflicts and merge headaches.
:::

View File

@ -0,0 +1,56 @@
---
description: The scary stuff.
---
# Database
The scary part.
This is where my casual fucking around is about to slam face-first into a brick wall.
It's time to:
- Create a database package.
- ~Connect to a postgres database.~ JK, Fuck postgres, I'll use SQLite to keep things easy for now.
I'll worry about formalizing these things later (like, how can I configure these through environment variables, make things multi-user... etc. Not my problem right now. This is single-user and mostly for learning).
## Setting Up Drizzle
Continuing my copy-catting from Hoarder, it looks like Drizzle is the thing to use for database schema type shit in Javascript/Typescript/Node land.
Let's see how that works.
### Create folder
`mkdir packages/db`.
`pnpm init`.
Shamelessly copy code from Hoarder.
### Set up SQLite with Drizzle
```
pnpm add -D drizzle-kit
```
Create `drizzle.config.ts`.
Honestly. just copy the code from the following files:
- drizzle.config.ts
- drizzle.ts
- index.ts
- migrate.ts
- package.json
- schema.ts (PLACEHOLDER SHIT FROM TUTORIAL)
Then, *from the db directory*, run `pnpm drizzle-kit generate` and it'll make the fucking database file, after which, from the workspace project root, `pnpm db:migrate` will do the goddamn migration, after which, `pnpm db:studio` will load Drizzle Studio at some arcane Avahi `local.drizzle.studio` URL and you'll see the fucking table it made.
I hate Javascript development.
But, it's starting to work, goddamn it.
### Load all this crap from the web app
TODO tomorrow.

View File

@ -5,7 +5,9 @@
"build": "turbo build", "build": "turbo build",
"dev": "turbo dev", "dev": "turbo dev",
"lint": "turbo lint", "lint": "turbo lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\"" "format": "prettier --write \"**/*.{ts,tsx,md}\"",
"db:studio": "pnpm --filter @lifetracker/db studio",
"db:migrate": "pnpm --filter @lifetracker/db run migrate"
}, },
"devDependencies": { "devDependencies": {
"prettier": "^3.2.5", "prettier": "^3.2.5",

View File

@ -0,0 +1,14 @@
import "dotenv/config";
import type { Config } from "drizzle-kit";
const databaseURL = "./lifetracker.db";
export default {
dialect: "sqlite",
schema: "./schema.ts",
out: "./drizzle",
dbCredentials: {
url: databaseURL,
},
verbose: true,
} satisfies Config;

20
packages/db/drizzle.ts Normal file
View File

@ -0,0 +1,20 @@
import "dotenv/config";
import { drizzle } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import * as schema from "./schema";
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import path from "path";
import dbConfig from "./drizzle.config";
const sqlite = new Database(dbConfig.dbCredentials.url);
export const db = drizzle(sqlite, { schema });
export function getInMemoryDB(runMigrations: boolean) {
const mem = new Database(":memory:");
const db = drizzle(mem, { schema, logger: true });
if (runMigrations) {
migrate(db, { migrationsFolder: path.resolve(__dirname, "./drizzle") });
}
return db;
}

View File

@ -0,0 +1,4 @@
CREATE TABLE `events` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`description` text NOT NULL
);

View File

@ -0,0 +1,40 @@
{
"version": "6",
"dialect": "sqlite",
"id": "74097c41-1958-4fc8-8371-6e31b3071eb9",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"events": {
"name": "events",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}

View File

@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "sqlite",
"entries": [
{
"idx": 0,
"version": "6",
"when": 1728109876982,
"tag": "0000_worried_may_parker",
"breakpoints": true
}
]
}

17
packages/db/index.ts Normal file
View File

@ -0,0 +1,17 @@
import Database from "better-sqlite3";
import { ExtractTablesWithRelations } from "drizzle-orm";
import { SQLiteTransaction } from "drizzle-orm/sqlite-core";
import * as schema from "./schema";
export { db } from "./drizzle";
export * as schema from "./schema";
export { SqliteError } from "better-sqlite3";
// This is exported here to avoid leaking better-sqlite types outside of this package.
export type LifetrackerDBTransaction = SQLiteTransaction<
"sync",
Database.RunResult,
typeof schema,
ExtractTablesWithRelations<typeof schema>
>;

BIN
packages/db/lifetracker.db Normal file

Binary file not shown.

4
packages/db/migrate.ts Normal file
View File

@ -0,0 +1,4 @@
import { db } from "./drizzle";
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
migrate(db, { migrationsFolder: "./drizzle" });

32
packages/db/package.json Normal file
View File

@ -0,0 +1,32 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@lifetracker/db",
"version": "0.0.1",
"private": true,
"main": "index.ts",
"scripts": {
"typecheck": "tsc --noEmit",
"migrate": "tsx migrate.ts",
"studio": "drizzle-kit studio"
},
"dependencies": {
"better-sqlite3": "^9.4.3",
"dotenv": "^16.4.1",
"drizzle-orm": "^0.33.0",
"expo-sqlite": "^14.0.6",
"tsx": "^4.7.1"
},
"devDependencies": {
"@lifetracker/eslint-config": "workspace:*",
"@lifetracker/typescript-config": "workspace:*",
"@tsconfig/node21": "^21.0.1",
"@types/better-sqlite3": "^7.6.9",
"drizzle-kit": "^0.24.2"
},
"eslintConfig": {
"root": true,
"extends": [
"@lifetracker/eslint-config/base"
]
}
}

10
packages/db/schema.ts Normal file
View File

@ -0,0 +1,10 @@
import {
sqliteTable,
integer,
text,
} from "drizzle-orm/sqlite-core";
export const events = sqliteTable("events", {
id: integer("id").primaryKey({ autoIncrement: true }),
description: text("description").notNull(),
});

4154
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff