Skip to content

Commit

Permalink
added registrations sqlite and updated examples
Browse files Browse the repository at this point in the history
  • Loading branch information
Smef committed Jun 8, 2024
1 parent 3851f46 commit e5b77d3
Show file tree
Hide file tree
Showing 17 changed files with 833 additions and 66 deletions.
12 changes: 12 additions & 0 deletions drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { Config } from "drizzle-kit";
import "dotenv/config";

export default {
schema: "./playground/database/schema/",
out: "./playground/database/migrations/",
dialect: "sqlite",
verbose: true,
dbCredentials: {
url: "./playground/database/sqlite.db",
},
} satisfies Config;
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,16 @@
"lint": "eslint .",
"test": "vitest run",
"test:watch": "vitest watch",
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
"db:studio": "drizzle-kit studio",
"db:dev-push": "drizzle-kit push",
"db:make-migration": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate"
},
"dependencies": {
"@nuxt/kit": "^3.11.2",
"better-sqlite3": "^11.0.0",
"drizzle-orm": "^0.31.2",
"lodash-es": "^4.17.21",
"zod": "^3.23.8"
},
Expand All @@ -55,6 +61,7 @@
"@types/node": "^20.12.11",
"autoprefixer": "^10.4.19",
"changelogen": "^0.5.5",
"drizzle-kit": "^0.22.6",
"eslint": "^9.2.0",
"eslint-config-prettier": "^9.1.0",
"nuxt": "^3.11.2",
Expand Down
13 changes: 13 additions & 0 deletions playground/database/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { drizzle, BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import registrations from "./schema/registrations";

const sqlite = new Database("./playground/database/sqlite.db");

const config = {
schema: { registrations },
fileMustExist: true,
};
const db: BetterSQLite3Database = drizzle(sqlite, config);

export default db;
8 changes: 8 additions & 0 deletions playground/database/migrations/0000_deep_naoko.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE `registrations` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`name` text(255),
`email` text(255),
`created_at` text DEFAULT (CURRENT_TIMESTAMP)
);
--> statement-breakpoint
CREATE UNIQUE INDEX `registrations_email_unique` ON `registrations` (`email`);
63 changes: 63 additions & 0 deletions playground/database/migrations/meta/0000_snapshot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"version": "6",
"dialect": "sqlite",
"id": "3e843d89-52e3-4405-a94d-8b135dbf2d3f",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"registrations": {
"name": "registrations",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": true
},
"name": {
"name": "name",
"type": "text(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"email": {
"name": "email",
"type": "text(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
}
},
"indexes": {
"registrations_email_unique": {
"name": "registrations_email_unique",
"columns": [
"email"
],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}
13 changes: 13 additions & 0 deletions playground/database/migrations/meta/_journal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "sqlite",
"entries": [
{
"idx": 0,
"version": "6",
"when": 1717878275568,
"tag": "0000_deep_naoko",
"breakpoints": true
}
]
}
30 changes: 30 additions & 0 deletions playground/database/migrations/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { migrate } from "drizzle-orm/mysql2/migrator";
import mysql from "mysql2/promise";
import { drizzle } from "drizzle-orm/mysql2";

// get the database configuration from dotenv
import "dotenv/config";

async function run() {
const connection = await mysql.createConnection({
host: process.env.DB_HOST,
port: process.env.DB_PORT ?? 3306,
database: process.env.DB_DATABASE,
user: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
});
const db = drizzle(connection);

// This will run migrations on the database, skipping the ones already applied
await migrate(db, { migrationsFolder: "./database/migrations" });
// Don't forget to close the connection, otherwise the script will hang
await connection.end();
}

run()
.catch((e) => {
console.error("Migrations failed");
console.error(e);
process.exit(1);
})
.then(() => console.log("Migrations ran successfully"));
9 changes: 9 additions & 0 deletions playground/database/schema/registrations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { sql } from "drizzle-orm";
import { sqliteTable, integer, text } from "drizzle-orm/sqlite-core";

export default sqliteTable("registrations", {
id: integer("id", { mode: "number" }).primaryKey({ autoIncrement: true }),
name: text("name", { length: 255 }),
email: text("email", { length: 255 }).unique(),
createdAt: text("created_at").default(sql`(CURRENT_TIMESTAMP)`),
});
Binary file added playground/database/sqlite.db
Binary file not shown.
25 changes: 18 additions & 7 deletions playground/pages/register-precog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
const entries = ref([]);
const form = usePrecognitionForm("post", "/api/register-precog", {
name: "",
email: "",
age: null,
});
const { data: registrations, refresh } = await useFetch("/api/registrations");
const submitForm = async () => {
await form.submit({
onSuccess: (response) => {
console.log("onSuccess callback", response);
entries.value.push(response._data);
onSuccess: () => {
refresh();
},
});
};
Expand All @@ -20,6 +22,15 @@ const submitForm = async () => {
<div>
<div class="flex gap-x-8">
<form class="space-y-4" @submit.prevent="submitForm">
<LabeledInput
id="name"
v-model="form.name"
label="Name"
type="text"
name="name"
:errors="form.errors.name"
@change="form.validate('name')"
/>
<LabeledInput
id="email"
v-model="form.email"
Expand All @@ -46,10 +57,10 @@ const submitForm = async () => {
<pre>{{ form }}</pre>
</div>
<div class="pt-12">
<pre />
<div class="text-lg font-bold uppercase">Entries</div>
<div v-for="(entry, index) in entries" :key="index">
{{ entry.description }}
<div class="text-lg font-bold uppercase">Registrations</div>
<div v-for="registration in registrations" :key="registration.id" class="flex gap-x-4">
<div class="w-56">{{ registration.name }}</div>
<div>{{ registration.email }}</div>
</div>
</div>
</div>
Expand Down
19 changes: 11 additions & 8 deletions playground/pages/register.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
<script setup lang="ts">
const entries = ref([]);
const form = useForm({
name: "",
email: "",
age: null,
});
const { data: registrations, refresh } = await useFetch("/api/registrations");
const submitForm = async () => {
await form.post("/api/register", {
onSuccess: (response) => {
entries.value.push(response._data);
await form.post("/api/registrations", {
onSuccess: () => {
refresh();
},
});
};
Expand All @@ -18,6 +20,7 @@ const submitForm = async () => {
<div>
<div class="flex gap-x-8">
<form class="space-y-4" @submit.prevent="submitForm">
<LabeledInput id="name" v-model="form.name" label="Name" type="text" name="name" :errors="form.errors.name" />
<LabeledInput
id="email"
v-model="form.email"
Expand All @@ -35,10 +38,10 @@ const submitForm = async () => {
<pre>{{ form }}</pre>
</div>
<div class="pt-12">
<pre />
<div class="text-lg font-bold uppercase">Registered Users</div>
<div v-for="(entry, index) in entries" :key="index">
{{ entry.email }}
<div class="text-lg font-bold uppercase">Registrations</div>
<div v-for="registration in registrations" :key="registration.id" class="flex gap-x-4">
<div class="w-56">{{ registration.name }}</div>
<div>{{ registration.email }}</div>
</div>
</div>
</div>
Expand Down
27 changes: 23 additions & 4 deletions playground/server/api/register-precog/index.post.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
import { z } from "zod";
import db from "~/database";
import { eq, sql } from "drizzle-orm";
import registrations from "~/database/schema/registrations";

const registrationSchema = z.object({
email: z.string().trim().email(),
name: z.string().min(2, "Name must be at least 2 characters"),
email: z
.string()
.trim()
.email()
.refine((val) => checkIfEmailExists(val), "This email is already in use"),
age: z.number().min(18, "You must be at least 18 years old"),
});

function checkIfEmailExists(email: string) {
const result = db
.select({ count: sql<number>`count(*)` })
.from(registrations)
.where(eq(registrations.email, email))
.get();
return result.count == 0;
}

export default definePrecognitionEventHandler(registrationSchema, async (event) => {
// This handler function won't run on precognition requests!
// It will only run on actual form submissions.
Expand All @@ -14,15 +31,17 @@ export default definePrecognitionEventHandler(registrationSchema, async (event)
const validated = await getValidatedInput(event, registrationSchema);

// do something with the body
const newUser = {
id: 1,
const newRegistration = {
name: validated.name,
email: validated.email,
};

const creatredRegistration = db.insert(registrations).values(newRegistration).returning();

// simulate a slow response to show the loading state o the front-end
await sleep(1000);

return newUser;
return creatredRegistration;
});

function sleep(ms: number) {
Expand Down
27 changes: 0 additions & 27 deletions playground/server/api/register/index.post.ts

This file was deleted.

8 changes: 8 additions & 0 deletions playground/server/api/registrations/index.get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import db from "~/database";

export default defineEventHandler(async (event) => {
// get the list of registrations from the database
const results = await db.query.registrations.findMany();

return results;
});
Loading

0 comments on commit e5b77d3

Please sign in to comment.