Skip to content

Commit

Permalink
refactor(db): migrate to postgres
Browse files Browse the repository at this point in the history
  • Loading branch information
AsyncFox committed Sep 21, 2024
1 parent e09a127 commit a61fcf1
Show file tree
Hide file tree
Showing 14 changed files with 71 additions and 83 deletions.
Binary file modified bun.lockb
Binary file not shown.
14 changes: 4 additions & 10 deletions drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import type { Config } from 'drizzle-kit';
import { env } from './server/env';

const dbCredentials = (() => {
switch (env.DATABASE_CONNECTION_TYPE) {
case 'local': return { url: 'file:local.sqlite' };
case 'remote': return { url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN };
}
})();

export default {
schema: './server/db/schema/index.ts',
out: './drizzle',
driver: 'turso',
dbCredentials,
tablesFilter: ['!libsql_wasm_func_table'],
dialect: 'postgresql',
dbCredentials: {
url: env.DATABASE_URL,
},
} satisfies Config;
2 changes: 1 addition & 1 deletion nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default defineNuxtConfig({
devtools: { enabled: true },
devtools: { enabled: true, componentInspector: false },

modules: [
'@pinia/nuxt',
Expand Down
40 changes: 20 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,59 @@
"auth:genKey": "tsx ./scripts/createKeyPairs.ts",
"db:createAdmin": "tsx ./scripts/createDefaultUser.ts",
"db:studio": "drizzle-kit studio",
"db:push": "drizzle-kit push:sqlite"
"db:push": "drizzle-kit push"
},
"dependencies": {
"@libsql/client": "^0.5.6",
"@nuxt/image": "^1.7.0",
"@nuxt/image": "^1.8.0",
"@pinia/nuxt": "^0.5.4",
"@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2",
"@vee-validate/nuxt": "^4.13.2",
"@vee-validate/zod": "^4.13.2",
"@vueuse/core": "^10.11.1",
"@vueuse/core": "^11.1.0",
"@vueuse/gesture": "2.0.0-beta.1",
"@vueuse/integrations": "^10.11.1",
"@vueuse/nuxt": "^10.11.1",
"@vueuse/integrations": "^11.1.0",
"@vueuse/nuxt": "^11.1.0",
"bcrypt": "^5.1.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
"drizzle-orm": "^0.30.10",
"drizzle-orm": "^0.33.0",
"fuse.js": "^7.0.0",
"jose": "^5.7.0",
"jose": "^5.9.2",
"lucide-vue-next": "^0.292.0",
"nanoid": "^5.0.7",
"pinia": "^2.2.2",
"radix-vue": "^1.9.4",
"postgres": "^3.4.4",
"radix-vue": "^1.9.6",
"superjson": "^2.2.1",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7",
"trpc-nuxt": "^0.10.22",
"v-calendar": "^3.1.2",
"vee-validate": "^4.13.2",
"vue-draggable-plus": "^0.3.5",
"vue-sonner": "^1.1.4",
"vue-sonner": "^1.1.5",
"zod": "^3.23.8"
},
"devDependencies": {
"@antfu/eslint-config": "^2.27.0",
"@iconify-json/radix-icons": "^1.1.15",
"@iconify-json/tabler": "^1.1.120",
"@antfu/eslint-config": "^2.27.3",
"@iconify-json/radix-icons": "^1.2.0",
"@iconify-json/tabler": "^1.2.3",
"@iconify/tailwind": "^0.1.4",
"@nuxt/devtools": "latest",
"@nuxtjs/tailwindcss": "^6.12.1",
"@pinia-plugin-persistedstate/nuxt": "^1.2.1",
"@tailwindcss/typography": "^0.5.14",
"@tailwindcss/typography": "^0.5.15",
"@types/bcrypt": "^5.0.2",
"@types/bun": "^1.1.6",
"@types/bun": "^1.1.10",
"dotenv": "^16.4.5",
"drizzle-kit": "^0.20.18",
"eslint": "^8.57.0",
"drizzle-kit": "^0.24.2",
"eslint": "^8.57.1",
"nuxt": "^3.12.4",
"trpc-panel": "^1.3.4",
"typescript": "^5.5.4",
"vue": "^3.4.38",
"vue-router": "^4.4.3"
"typescript": "^5.6.2",
"vue": "^3.5.7",
"vue-router": "^4.4.5"
}
}
14 changes: 4 additions & 10 deletions server/db/db.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@libsql/client';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';

import { env } from '../env';
import type { arrangements, refreshTokens, songs, users } from './schema';
import type { times } from './schema/time';

const options = (() => {
switch (env.DATABASE_CONNECTION_TYPE) {
case 'local': return { url: 'file:local.sqlite' };
case 'remote': return { url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN };
}
})();

const client = createClient(options);
const client = postgres(env.DATABASE_URL);
export const db = drizzle(client);

export type TRawUser = typeof users.$inferSelect;
Expand Down
10 changes: 5 additions & 5 deletions server/db/schema/arrangement.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { boolean, json, pgTable, text } from 'drizzle-orm/pg-core';

export const arrangements = sqliteTable('arrangements', {
date: text('date', { mode: 'text' }).primaryKey(),
songIds: text('song_ids', { mode: 'json' }).$type<string[]>(),
isPublic: integer('is_public', { mode: 'boolean' }).notNull().default(false),
export const arrangements = pgTable('arrangements', {
date: text('date').primaryKey(),
songIds: json('song_ids').$type<string[]>(),
isPublic: boolean('is_public').notNull().default(false),
});
20 changes: 10 additions & 10 deletions server/db/schema/song.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { integer, pgTable, text, timestamp, varchar } from 'drizzle-orm/pg-core';
import { useNanoID } from '../../../composables/useNanoID';

export const songs = sqliteTable('songs', {
id: text('id', { mode: 'text' }).primaryKey().$defaultFn(() => useNanoID()),
name: text('name', { mode: 'text' }).notNull(),
creator: text('creator', { mode: 'text' }).notNull(),
submitterName: text('submitter_name', { mode: 'text' }).notNull(),
submitterGrade: integer('submitter_grade', { mode: 'number' }).notNull(), // 1: 高一 | 2: 高二 | 3: 国体高一 | 4: 国体高二 | 5: 国体高三
submitterClass: integer('submitter_class', { mode: 'number' }).notNull(),
export const songs = pgTable('songs', {
id: varchar('id', { length: 20 }).primaryKey().$defaultFn(() => useNanoID()),
name: text('name').notNull(),
creator: text('creator').notNull(),
submitterName: text('submitter_name').notNull(),
submitterGrade: integer('submitter_grade').notNull(), // 1: 高一 | 2: 高二 | 3: 国体高一 | 4: 国体高二 | 5: 国体高三
submitterClass: integer('submitter_class').notNull(),
status: text('status', { enum: ['unset', 'approved', 'rejected', 'used'] }).notNull().default('unset'),
type: text('type', { enum: ['normal', 'withMsg'] }).notNull(),
message: text('message', { mode: 'text' }),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
message: text('message'),
createdAt: timestamp('created_at').notNull().$defaultFn(() => new Date()),
});
16 changes: 8 additions & 8 deletions server/db/schema/time.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { boolean, pgTable, text, timestamp, varchar } from 'drizzle-orm/pg-core';
import { useNanoID } from '../../../composables/useNanoID';

export const times = sqliteTable('times', {
id: text('id', { mode: 'text' }).primaryKey().$defaultFn(() => useNanoID()),
name: text('name', { mode: 'text' }).notNull(),
startAt: integer('start_at', { mode: 'timestamp' }).notNull(),
endAt: integer('end_at', { mode: 'timestamp' }).notNull(),
repeats: integer('repeats', { mode: 'boolean' }).notNull().default(false),
isActive: integer('is_active', { mode: 'boolean' }).notNull().default(true),
export const times = pgTable('times', {
id: varchar('id', { length: 20 }).primaryKey().$defaultFn(() => useNanoID()),
name: text('name').notNull(),
startAt: timestamp('start_at').notNull(),
endAt: timestamp('end_at').notNull(),
repeats: boolean('repeats').notNull().default(false),
isActive: boolean('is_active').notNull().default(true),
});
18 changes: 9 additions & 9 deletions server/db/schema/user.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { pgTable, text, timestamp, varchar } from 'drizzle-orm/pg-core';
import { useNanoID } from '../../../composables/useNanoID';

export const users = sqliteTable('users', {
id: text('id', { mode: 'text' }).primaryKey().$defaultFn(() => useNanoID()),
password: text('password', { mode: 'text' }).notNull(),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().$defaultFn(() => new Date()),
export const users = pgTable('users', {
id: varchar('id', { length: 20 }).primaryKey().$defaultFn(() => useNanoID()),
password: text('password').notNull(),
createdAt: timestamp('created_at').notNull().$defaultFn(() => new Date()),
});

export const refreshTokens = sqliteTable('refresh_tokens', {
id: text('id', { mode: 'text' }).primaryKey().$defaultFn(() => useNanoID()),
token: text('token', { mode: 'text' }).notNull(),
owner: text('owner', { mode: 'text' }).references(() => users.id).notNull(),
export const refreshTokens = pgTable('refresh_tokens', {
id: varchar('id', { length: 20 }).primaryKey().$defaultFn(() => useNanoID()),
token: text('token').notNull(),
owner: text('owner').references(() => users.id).notNull(),
});
4 changes: 2 additions & 2 deletions server/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ dotenv.config();
dotenv.config({ path: '.env.local', override: true });
const envSchema = z.object({
DATABASE_URL: z.string().url(),
DATABASE_CONNECTION_TYPE: z.enum(['remote', 'local']),
DATABASE_AUTH_TOKEN: z.string(),
// DATABASE_CONNECTION_TYPE: z.enum(['remote', 'local']),
// DATABASE_AUTH_TOKEN: z.string(),
NODE_ENV: z.enum(['development', 'production']),
SIGN_PUBLIC_KEY: z.string(),
SIGN_PRIVATE_KEY: z.string(),
Expand Down
4 changes: 2 additions & 2 deletions server/trpc/controllers/arrangement.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { LibsqlError } from '@libsql/client';
import { and, eq, gt } from 'drizzle-orm';
import postgres from 'postgres';
import type { TNewArrangement, TRawSong } from '../../db/db';
import { db } from '../../db/db';
import { SongController } from './song';
Expand All @@ -14,7 +14,7 @@ export class ArrangementController {
await db.insert(arrangements).values(newArrangement);
return { success: true, message: '创建成功!' };
} catch (err) {
if (err instanceof LibsqlError && err.code === 'SQLITE_CONSTRAINT_PRIMARYKEY')
if (err instanceof postgres.PostgresError && err.code === '23505')
return { success: false, message: '排歌表ID出现重复' };
else return { success: false, message: '服务器内部错误' };
}
Expand Down
4 changes: 2 additions & 2 deletions server/trpc/controllers/song.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LibsqlError } from '@libsql/client';
import postgres from 'postgres';
import { and, eq, gt, inArray, or } from 'drizzle-orm';
import { type TNewSong, db } from '../../db/db';
import { songs } from '~/server/db/schema';
Expand Down Expand Up @@ -40,7 +40,7 @@ export class SongController {
const id = (await db.insert(songs).values(newSong).returning({ id: songs.id }))[0].id;
return { success: true, res: id, message: '创建成功!' };
} catch (err) {
if (err instanceof LibsqlError && err.code === 'SQLITE_CONSTRAINT_PRIMARYKEY')
if (err instanceof postgres.PostgresError && err.code === '23505')
return { success: false, message: '歌曲ID出现重复' };
else return { success: false, message: '服务器内部错误' };
}
Expand Down
4 changes: 2 additions & 2 deletions server/trpc/controllers/time.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { LibsqlError } from '@libsql/client';
import { eq } from 'drizzle-orm';
import postgres from 'postgres';
import { type TNewTime, db } from '../../db/db';
import { times } from '~/server/db/schema/time';

Expand All @@ -9,7 +9,7 @@ export class TimeController {
const id = (await db.insert(times).values(newTime).returning({ id: times.id }))[0].id;
return { success: true, res: id, message: '创建成功!' };
} catch (err) {
if (err instanceof LibsqlError && err.code === 'SQLITE_CONSTRAINT_PRIMARYKEY')
if (err instanceof postgres.PostgresError && err.code === '23505')
return { success: false, message: '时间段ID出现重复' };
else return { success: false, message: '服务器内部错误' };
}
Expand Down
4 changes: 2 additions & 2 deletions server/trpc/controllers/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import bcrypt from 'bcrypt';
import { and, eq } from 'drizzle-orm';
import { LibsqlError } from '@libsql/client';
import postgres from 'postgres';
import { type TNewUser, type TRawUser, db } from '../../db/db';
import { refreshTokens, users } from '../../db/schema/';
import { Auth } from '../utils/auth';
Expand All @@ -20,7 +20,7 @@ export class UserController {
await db.insert(users).values(user);
return { success: true, message: '注册成功!' };
} catch (err) {
if (err instanceof LibsqlError)
if (err instanceof postgres.PostgresError && err.code === '23505')
return { success: false, message: '用户名出现重复' };
else return { success: false, message: '服务器内部错误' };
}
Expand Down

0 comments on commit a61fcf1

Please sign in to comment.