Move to better sqlite3
This commit is contained in:
@@ -24,5 +24,5 @@ CREATE TABLE `users` (
|
||||
`country` text,
|
||||
`sex` text,
|
||||
`weight` integer,
|
||||
`created_at` integer NOT NULL
|
||||
`created_at` integer
|
||||
);
|
||||
@@ -1,16 +0,0 @@
|
||||
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
||||
CREATE TABLE `__new_users` (
|
||||
`id` numeric PRIMARY KEY NOT NULL,
|
||||
`name` text NOT NULL,
|
||||
`avatar` text,
|
||||
`city` text,
|
||||
`country` text,
|
||||
`sex` text,
|
||||
`weight` integer,
|
||||
`created_at` integer
|
||||
);
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `__new_users`("id", "name", "avatar", "city", "country", "sex", "weight", "created_at") SELECT "id", "name", "avatar", "city", "country", "sex", "weight", "created_at" FROM `users`;--> statement-breakpoint
|
||||
DROP TABLE `users`;--> statement-breakpoint
|
||||
ALTER TABLE `__new_users` RENAME TO `users`;--> statement-breakpoint
|
||||
PRAGMA foreign_keys=ON;
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "d9537942-cba2-4af4-8396-533366512937",
|
||||
"id": "347ea848-a216-4fff-910a-90ba2f9aa91c",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"tables": {
|
||||
"preferences": {
|
||||
@@ -180,7 +180,7 @@
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "80d98e5a-f977-4e9c-889b-ae77c99d8238",
|
||||
"prevId": "d9537942-cba2-4af4-8396-533366512937",
|
||||
"tables": {
|
||||
"preferences": {
|
||||
"name": "preferences",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "numeric",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"data": {
|
||||
"name": "data",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"preferences_user_id_unique": {
|
||||
"name": "preferences_user_id_unique",
|
||||
"columns": [
|
||||
"user_id"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"preferences_user_id_users_id_fk": {
|
||||
"name": "preferences_user_id_users_id_fk",
|
||||
"tableFrom": "preferences",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "numeric",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"refresh_token": {
|
||||
"name": "refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"access_token": {
|
||||
"name": "access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"tokens_user_id_unique": {
|
||||
"name": "tokens_user_id_unique",
|
||||
"columns": [
|
||||
"user_id"
|
||||
],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"tokens_user_id_users_id_fk": {
|
||||
"name": "tokens_user_id_users_id_fk",
|
||||
"tableFrom": "tokens",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "numeric",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"city": {
|
||||
"name": "city",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"country": {
|
||||
"name": "country",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"sex": {
|
||||
"name": "sex",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"weight": {
|
||||
"name": "weight",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,8 @@
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "6",
|
||||
"when": 1772727834477,
|
||||
"tag": "0000_living_oracle",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "6",
|
||||
"when": 1772816922744,
|
||||
"tag": "0001_round_husk",
|
||||
"when": 1772879556762,
|
||||
"tag": "0000_groovy_rachel_grey",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
import { migrate } from "drizzle-orm/bun-sqlite/migrator";
|
||||
import path from "node:path";
|
||||
|
||||
export default defineNitroPlugin(async (nitroApp) => {
|
||||
const db = useDrizzle();
|
||||
const migrationsFolder = path.resolve("server/database/migrations");
|
||||
|
||||
console.log("Running database migrations...");
|
||||
console.log(`Migrations folder: ${migrationsFolder}`);
|
||||
migrate(db, { migrationsFolder });
|
||||
|
||||
console.log("Database migrations complete");
|
||||
|
||||
const feedFile = Bun.file(path.resolve("tmp/feed.json"));
|
||||
const feedData = await feedFile.json().catch((err) => {
|
||||
console.log(err.message);
|
||||
|
||||
return [];
|
||||
});
|
||||
|
||||
for (const item of feedData) {
|
||||
const userId = String(item.user.id);
|
||||
|
||||
await db
|
||||
.insert(tables.users)
|
||||
.values({
|
||||
id: userId,
|
||||
name: item.user.name,
|
||||
avatar: item.user.avatar,
|
||||
city: item.user.city,
|
||||
country: item.user.country,
|
||||
sex: item.user.sex,
|
||||
weight: item.user.weight,
|
||||
createdAt: new Date(item.user.created_at),
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: tables.users.id,
|
||||
set: {
|
||||
name: item.user.name,
|
||||
avatar: item.user.avatar,
|
||||
city: item.user.city,
|
||||
country: item.user.country,
|
||||
sex: item.user.sex,
|
||||
weight: item.user.weight,
|
||||
},
|
||||
});
|
||||
|
||||
await db
|
||||
.insert(tables.tokens)
|
||||
.values({
|
||||
userId: userId,
|
||||
refreshToken: item.token.refresh_token,
|
||||
accessToken: item.token.access_token,
|
||||
expiresAt: new Date(item.token.expires_at),
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: tables.tokens.userId,
|
||||
set: {
|
||||
refreshToken: item.token.refresh_token,
|
||||
accessToken: item.token.access_token,
|
||||
expiresAt: new Date(item.token.expires_at),
|
||||
},
|
||||
});
|
||||
|
||||
await db
|
||||
.insert(tables.preferences)
|
||||
.values({
|
||||
userId: userId,
|
||||
data: {
|
||||
enabled: item.preferences.enabled,
|
||||
language: item.preferences.language,
|
||||
units: item.preferences.units,
|
||||
tone: item.preferences.tone,
|
||||
highlights: [],
|
||||
},
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: tables.preferences.userId,
|
||||
set: {
|
||||
data: {
|
||||
enabled: item.preferences.enabled,
|
||||
language: item.preferences.language,
|
||||
units: item.preferences.units,
|
||||
tone: item.preferences.tone,
|
||||
highlights: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Processed ${feedData.length} feed items`);
|
||||
});
|
||||
88
server/plugins/migrations.ts
Normal file
88
server/plugins/migrations.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
||||
import Database from "better-sqlite3";
|
||||
import { users, tokens, preferences } from "../database/schema";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
|
||||
export default defineNitroPlugin(async () => {
|
||||
const db = useDrizzle();
|
||||
|
||||
migrate(db, { migrationsFolder: "./server/database/migrations" });
|
||||
console.log("Database migrations applied");
|
||||
|
||||
const feedPath = "./tmp/feed.json";
|
||||
|
||||
if (existsSync(feedPath)) {
|
||||
const feed = JSON.parse(readFileSync(feedPath, "utf-8"));
|
||||
console.log(`Importing ${feed.length} users from feed.json`);
|
||||
|
||||
for (const entry of feed) {
|
||||
const userId = String(entry.user.id);
|
||||
const createdAt =
|
||||
entry.user.created_at && entry.user.created_at !== "\r"
|
||||
? new Date(entry.user.created_at)
|
||||
: new Date();
|
||||
|
||||
const userData = {
|
||||
id: userId,
|
||||
name: entry.user.name || "Unknown",
|
||||
avatar: entry.user.avatar || null,
|
||||
city: entry.user.city || null,
|
||||
country:
|
||||
typeof entry.user.country === "string" && entry.user.country !== "\r"
|
||||
? entry.user.country
|
||||
: null,
|
||||
sex:
|
||||
typeof entry.user.sex === "string" && entry.user.sex !== "\r"
|
||||
? entry.user.sex
|
||||
: null,
|
||||
weight: Number(entry.user.weight) || null,
|
||||
createdAt,
|
||||
};
|
||||
|
||||
await db
|
||||
.insert(users)
|
||||
.values(userData)
|
||||
.onConflictDoUpdate({
|
||||
target: users.id,
|
||||
set: { ...userData },
|
||||
});
|
||||
|
||||
const tokenData = {
|
||||
userId: userId,
|
||||
refreshToken: entry.token.refresh_token || null,
|
||||
accessToken: entry.token.access_token || null,
|
||||
expiresAt: new Date(entry.token.expires_at),
|
||||
};
|
||||
|
||||
await db
|
||||
.insert(tokens)
|
||||
.values(tokenData)
|
||||
.onConflictDoUpdate({
|
||||
target: tokens.userId,
|
||||
set: { ...tokenData },
|
||||
});
|
||||
|
||||
const prefsData = {
|
||||
userId,
|
||||
data: {
|
||||
enabled: entry.preferences.enabled ?? true,
|
||||
language: entry.preferences.language || "English",
|
||||
units: entry.preferences.units || "Metric",
|
||||
tone: entry.preferences.tone || [],
|
||||
highlights: entry.preferences.highlights || [],
|
||||
},
|
||||
};
|
||||
|
||||
await db
|
||||
.insert(preferences)
|
||||
.values(prefsData)
|
||||
.onConflictDoUpdate({
|
||||
target: preferences.userId,
|
||||
set: { ...prefsData },
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Successfully imported ${feed.length} users`);
|
||||
}
|
||||
});
|
||||
@@ -1,11 +1,4 @@
|
||||
import { drizzle } from "drizzle-orm/bun-sqlite";
|
||||
import { eq as _eq, and as _and, or as _or, sql as _sql } from "drizzle-orm";
|
||||
|
||||
export const sql = _sql;
|
||||
export const eq = _eq;
|
||||
export const and = _and;
|
||||
export const or = _or;
|
||||
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
import * as schema from "../database/schema";
|
||||
|
||||
export const tables = schema;
|
||||
@@ -13,7 +6,7 @@ export const tables = schema;
|
||||
export function useDrizzle() {
|
||||
const config = useRuntimeConfig();
|
||||
|
||||
return drizzle(config.databaseUrl, { schema });
|
||||
return drizzle(config.databaseUrl);
|
||||
}
|
||||
|
||||
export type User = typeof schema.users.$inferSelect;
|
||||
|
||||
Reference in New Issue
Block a user