Initialize database. Document it. Hate life.
This commit is contained in:
parent
c52ac44f3c
commit
850149ebcb
@ -2,19 +2,11 @@
|
||||
description: Time to actually do shit.
|
||||
---
|
||||
|
||||
# Packages and Turbo
|
||||
# Repo Hygiene
|
||||
|
||||
So you got a project started and wasted some time writing documentation. Great!
|
||||
|
||||
Now, how do we get some actual functionality in this shit?
|
||||
|
||||
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".
|
||||
Now, let's move on to "actually building software that does something" and "everything else other than running a generator and writing useless documentation".
|
||||
|
||||
## 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
|
||||
|
||||
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.
|
||||
:::
|
||||
56
apps/docs/docs/how-i-built-this/03-database.md
Normal file
56
apps/docs/docs/how-i-built-this/03-database.md
Normal 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.
|
||||
@ -5,7 +5,9 @@
|
||||
"build": "turbo build",
|
||||
"dev": "turbo dev",
|
||||
"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": {
|
||||
"prettier": "^3.2.5",
|
||||
|
||||
14
packages/db/drizzle.config.ts
Normal file
14
packages/db/drizzle.config.ts
Normal 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
20
packages/db/drizzle.ts
Normal 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;
|
||||
}
|
||||
4
packages/db/drizzle/0000_worried_may_parker.sql
Normal file
4
packages/db/drizzle/0000_worried_may_parker.sql
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE TABLE `events` (
|
||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`description` text NOT NULL
|
||||
);
|
||||
40
packages/db/drizzle/meta/0000_snapshot.json
Normal file
40
packages/db/drizzle/meta/0000_snapshot.json
Normal 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": {}
|
||||
}
|
||||
}
|
||||
13
packages/db/drizzle/meta/_journal.json
Normal file
13
packages/db/drizzle/meta/_journal.json
Normal 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
17
packages/db/index.ts
Normal 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
BIN
packages/db/lifetracker.db
Normal file
Binary file not shown.
4
packages/db/migrate.ts
Normal file
4
packages/db/migrate.ts
Normal 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
32
packages/db/package.json
Normal 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
10
packages/db/schema.ts
Normal 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
4154
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user