Feed the database

This commit is contained in:
2026-03-06 19:11:41 +02:00
parent 1b31f3194d
commit d8be1c0a69
5 changed files with 346 additions and 3 deletions

View File

@@ -0,0 +1,16 @@
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;

View File

@@ -0,0 +1,204 @@
{
"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": {}
}
}

View File

@@ -8,6 +8,13 @@
"when": 1772727834477,
"tag": "0000_living_oracle",
"breakpoints": true
},
{
"idx": 1,
"version": "6",
"when": 1772816922744,
"tag": "0001_round_husk",
"breakpoints": true
}
]
}

View File

@@ -9,9 +9,9 @@ export const users = sqliteTable("users", {
country: text("country"),
sex: text("sex"),
weight: integer("weight"),
createdAt: integer("created_at", { mode: "timestamp" })
.notNull()
.$defaultFn(() => new Date()),
createdAt: integer("created_at", { mode: "timestamp" }).$defaultFn(
() => new Date(),
),
});
export const preferences = sqliteTable("preferences", {

116
server/plugins/feed.ts Normal file
View File

@@ -0,0 +1,116 @@
import { drizzle } from "drizzle-orm/bun-sqlite";
import { existsSync } from "node:fs";
import { readFileSync } from "node:fs";
import * as schema from "../database/schema";
interface FeedItem {
user: {
id: number;
name: string;
avatar: string | null;
city: string | null;
country: string | null;
sex: string | null;
weight: number | null;
created_at: string;
};
token: {
id: number;
user_id: number;
refresh_token: string;
access_token: string;
expires_at: string;
};
preferences: {
tone: string[];
units: "Imperial" | "Metric";
enabled: boolean;
language: string;
};
}
export default defineNitroPlugin(async () => {
const config = useRuntimeConfig();
const feedPath = "tmp/feed.json";
if (!existsSync(feedPath)) {
return;
}
console.log("Processing feed.json...");
const db = drizzle(config.databaseUrl, { schema });
const feed: FeedItem[] = JSON.parse(readFileSync(feedPath, "utf-8"));
for (const item of feed) {
const userId = String(item.user.id);
await db
.insert(schema.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: schema.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(schema.tokens)
.values({
userId: userId,
refreshToken: item.token.refresh_token,
accessToken: item.token.access_token,
expiresAt: new Date(item.token.expires_at),
})
.onConflictDoUpdate({
target: schema.tokens.userId,
set: {
refreshToken: item.token.refresh_token,
accessToken: item.token.access_token,
expiresAt: new Date(item.token.expires_at),
},
});
await db
.insert(schema.preferences)
.values({
userId: userId,
data: {
enabled: item.preferences.enabled,
language: item.preferences.language,
units: item.preferences.units,
tone: item.preferences.tone,
highlights: [],
},
})
.onConflictDoUpdate({
target: schema.preferences.userId,
set: {
data: {
enabled: item.preferences.enabled,
language: item.preferences.language,
units: item.preferences.units,
tone: item.preferences.tone,
highlights: [],
},
},
});
}
console.log(`Processed ${feed.length} feed items`);
});