mirror of
https://github.com/orangecoding/fredy.git
synced 2026-06-16 12:31:07 +00:00
* init map view * switching off 3d buildings when sattelite view is on * rename menu items * upgrading dependencies, adding provider to popups * adding screenshot for map view * fixing readme * next release version
123 lines
4.0 KiB
JavaScript
123 lines
4.0 KiB
JavaScript
/*
|
|
* Copyright (c) 2026 by Christian Kellner.
|
|
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
|
|
*/
|
|
|
|
// Migration: Create fredy's base structure (users, jobs and listings) import initial
|
|
// data from JSON files if present. (This applies only for jobs and users, for the old jobListingData,
|
|
// I cannot migrate the data as the new format is totally different.
|
|
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { toJson } from '../../../../utils.js';
|
|
|
|
export function up(db) {
|
|
// 1) Create tables
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS users
|
|
(
|
|
id TEXT PRIMARY KEY,
|
|
username TEXT NOT NULL,
|
|
password TEXT NOT NULL,
|
|
last_login INTEGER,
|
|
is_admin INTEGER NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_username ON users (username);
|
|
|
|
CREATE TABLE IF NOT EXISTS jobs
|
|
(
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
enabled INTEGER NOT NULL DEFAULT 1,
|
|
name TEXT,
|
|
blacklist JSONB NOT NULL DEFAULT '[]',
|
|
provider JSONB NOT NULL DEFAULT '[]',
|
|
notification_adapter JSONB NOT NULL DEFAULT '[]',
|
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_jobs_user_id ON jobs (user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_jobs_enabled ON jobs (enabled);
|
|
|
|
CREATE TABLE IF NOT EXISTS listings
|
|
(
|
|
id TEXT PRIMARY KEY,
|
|
created_at INTEGER,
|
|
hash TEXT,
|
|
provider TEXT,
|
|
job_id TEXT,
|
|
price INTEGER,
|
|
size INTEGER,
|
|
title TEXT,
|
|
image_url TEXT,
|
|
description TEXT,
|
|
address TEXT,
|
|
link TEXT,
|
|
FOREIGN KEY (job_id) REFERENCES jobs (id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_listings_hash ON listings (hash);
|
|
`);
|
|
|
|
// 2) Optionally import data from JSON files if present for users and jobs
|
|
const ROOT = path.resolve('.');
|
|
const usersJsonPath = path.join(ROOT, 'db', 'users.json');
|
|
const jobsJsonPath = path.join(ROOT, 'db', 'jobs.json');
|
|
|
|
// Insert users
|
|
if (fs.existsSync(usersJsonPath)) {
|
|
try {
|
|
const raw = fs.readFileSync(usersJsonPath, 'utf8');
|
|
const json = JSON.parse(raw);
|
|
const arr = Array.isArray(json?.user) ? json.user : [];
|
|
if (arr.length > 0) {
|
|
const stmt = db.prepare(
|
|
`INSERT INTO users (id, username, password, last_login, is_admin)
|
|
VALUES (@id, @username, @password, @last_login, @is_admin)`,
|
|
);
|
|
for (const u of arr) {
|
|
stmt.run({
|
|
id: u.id,
|
|
username: u.username,
|
|
password: u.password,
|
|
last_login: u.lastLogin ?? null,
|
|
is_admin: u.isAdmin ? 1 : 0,
|
|
});
|
|
}
|
|
}
|
|
} catch (e) {
|
|
// If parsing fails, let it throw to rollback the migration
|
|
throw new Error(`Failed to import users from ${usersJsonPath}: ${e.message}`);
|
|
}
|
|
}
|
|
|
|
// Insert jobs
|
|
if (fs.existsSync(jobsJsonPath)) {
|
|
try {
|
|
const raw = fs.readFileSync(jobsJsonPath, 'utf8');
|
|
const json = JSON.parse(raw);
|
|
const arr = Array.isArray(json?.jobs) ? json.jobs : [];
|
|
if (arr.length > 0) {
|
|
const stmt = db.prepare(
|
|
`INSERT INTO jobs (id, user_id, enabled, name, blacklist, provider, notification_adapter)
|
|
VALUES (@id, @user_id, @enabled, @name, @blacklist, @provider, @notification_adapter)`,
|
|
);
|
|
for (const j of arr) {
|
|
stmt.run({
|
|
id: j.id,
|
|
user_id: j.userId,
|
|
enabled: j.enabled ? 1 : 0,
|
|
name: j.name ?? null,
|
|
blacklist: toJson(j.blacklist ?? []),
|
|
provider: toJson(j.provider ?? []),
|
|
notification_adapter: toJson(j.notificationAdapter ?? []),
|
|
});
|
|
}
|
|
}
|
|
} catch (e) {
|
|
throw new Error(`Failed to import jobs from ${jobsJsonPath}: ${e.message}`);
|
|
}
|
|
}
|
|
}
|