Mostly works
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const sqlite3 = require('sqlite3').verbose();
|
||||
const { open } = require('sqlite');
|
||||
|
||||
const target = process.argv[2];
|
||||
const dbPath = path.resolve(__dirname, '..', 'storage', 'storage.db');
|
||||
|
||||
const GROUPS = {
|
||||
all: {
|
||||
tables: ['shulker_items', 'chest_loose_items', 'shulkers', 'chests',
|
||||
'item_index', 'trades', 'invite_permissions', 'invite_sites',
|
||||
'maps', 'permissions'],
|
||||
label: 'ALL tables'
|
||||
},
|
||||
storage: {
|
||||
tables: ['shulker_items', 'chest_loose_items', 'shulkers', 'chests', 'item_index'],
|
||||
label: 'storage tables (chests, shulkers, items, index)'
|
||||
},
|
||||
permissions: {
|
||||
tables: ['permissions'],
|
||||
label: 'permissions table'
|
||||
},
|
||||
maps: {
|
||||
tables: ['maps'],
|
||||
label: 'maps table'
|
||||
},
|
||||
invites: {
|
||||
tables: ['invite_permissions', 'invite_sites'],
|
||||
label: 'invite tables'
|
||||
},
|
||||
trades: {
|
||||
tables: ['trades'],
|
||||
label: 'trades table'
|
||||
}
|
||||
};
|
||||
|
||||
function usage() {
|
||||
console.log('Usage: node scripts/db-reset.js <target>');
|
||||
console.log('Targets:');
|
||||
for (const [name, group] of Object.entries(GROUPS)) {
|
||||
console.log(` ${name.padEnd(14)} ${group.label}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!target || !GROUPS[target]) {
|
||||
usage();
|
||||
}
|
||||
|
||||
const group = GROUPS[target];
|
||||
|
||||
async function main() {
|
||||
console.log(`Database: ${dbPath}`);
|
||||
console.log(`Resetting ${group.label}...`);
|
||||
|
||||
const db = await open({
|
||||
filename: dbPath,
|
||||
driver: sqlite3.Database
|
||||
});
|
||||
|
||||
try {
|
||||
await db.run('PRAGMA foreign_keys = OFF');
|
||||
|
||||
for (const table of group.tables) {
|
||||
console.log(` DROP TABLE IF EXISTS ${table}`);
|
||||
await db.run(`DROP TABLE IF EXISTS ${table}`);
|
||||
}
|
||||
|
||||
await db.run('PRAGMA foreign_keys = ON');
|
||||
|
||||
// Recreate tables and re-insert defaults
|
||||
await recreateTables(db, group);
|
||||
|
||||
console.log('Done.');
|
||||
} finally {
|
||||
await db.close();
|
||||
}
|
||||
}
|
||||
|
||||
async function recreateTables(db, group) {
|
||||
const tables = group.tables;
|
||||
const recreate = (t) => tables.includes(t);
|
||||
|
||||
if (recreate('permissions')) {
|
||||
await db.exec(`CREATE TABLE permissions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
player_name TEXT UNIQUE NOT NULL,
|
||||
role TEXT DEFAULT 'team' NOT NULL CHECK(role IN ('owner', 'team', 'readonly')),
|
||||
joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`);
|
||||
console.log(' Recreated permissions');
|
||||
await insertDefaultPermissions(db);
|
||||
}
|
||||
|
||||
if (recreate('chests')) {
|
||||
await db.exec(`CREATE TABLE chests (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
pos_x INTEGER NOT NULL,
|
||||
pos_y INTEGER NOT NULL,
|
||||
pos_z INTEGER NOT NULL,
|
||||
chest_type TEXT NOT NULL CHECK(chest_type IN ('single', 'double')),
|
||||
row INTEGER NOT NULL,
|
||||
column INTEGER NOT NULL,
|
||||
category TEXT,
|
||||
last_scan TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(pos_x, pos_y, pos_z)
|
||||
)`);
|
||||
console.log(' Recreated chests');
|
||||
}
|
||||
|
||||
if (recreate('shulkers')) {
|
||||
await db.exec(`CREATE TABLE shulkers (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
chest_id INTEGER NOT NULL,
|
||||
slot INTEGER NOT NULL,
|
||||
shulker_type TEXT DEFAULT 'shulker_box',
|
||||
category TEXT,
|
||||
item_focus TEXT,
|
||||
slot_count INTEGER DEFAULT 0,
|
||||
total_items INTEGER DEFAULT 0,
|
||||
last_scan TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (chest_id) REFERENCES chests(id) ON DELETE CASCADE,
|
||||
UNIQUE(chest_id, slot)
|
||||
)`);
|
||||
console.log(' Recreated shulkers');
|
||||
}
|
||||
|
||||
if (recreate('shulker_items')) {
|
||||
await db.exec(`CREATE TABLE shulker_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
shulker_id INTEGER NOT NULL,
|
||||
item_name TEXT NOT NULL,
|
||||
item_id INTEGER NOT NULL,
|
||||
slot INTEGER NOT NULL,
|
||||
count INTEGER NOT NULL,
|
||||
nbt_data TEXT,
|
||||
FOREIGN KEY (shulker_id) REFERENCES shulkers(id) ON DELETE CASCADE,
|
||||
UNIQUE(shulker_id, slot),
|
||||
CHECK(slot >= 0 AND slot <= 26),
|
||||
CHECK(count > 0 AND count <= 64)
|
||||
)`);
|
||||
console.log(' Recreated shulker_items');
|
||||
}
|
||||
|
||||
if (recreate('trades')) {
|
||||
await db.exec(`CREATE TABLE trades (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
player_name TEXT NOT NULL,
|
||||
action TEXT NOT NULL CHECK(action IN ('deposit', 'withdraw')),
|
||||
items TEXT NOT NULL,
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`);
|
||||
console.log(' Recreated trades');
|
||||
}
|
||||
|
||||
if (recreate('chest_loose_items')) {
|
||||
await db.exec(`CREATE TABLE chest_loose_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
chest_id INTEGER NOT NULL,
|
||||
slot INTEGER NOT NULL,
|
||||
item_name TEXT NOT NULL,
|
||||
item_id INTEGER NOT NULL,
|
||||
count INTEGER NOT NULL,
|
||||
FOREIGN KEY (chest_id) REFERENCES chests(id) ON DELETE CASCADE,
|
||||
UNIQUE(chest_id, slot)
|
||||
)`);
|
||||
console.log(' Recreated chest_loose_items');
|
||||
}
|
||||
|
||||
if (recreate('item_index')) {
|
||||
await db.exec(`CREATE TABLE item_index (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
item_id INTEGER UNIQUE NOT NULL,
|
||||
item_name TEXT NOT NULL,
|
||||
total_count INTEGER DEFAULT 0,
|
||||
shulker_ids TEXT,
|
||||
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`);
|
||||
console.log(' Recreated item_index');
|
||||
}
|
||||
|
||||
if (recreate('maps')) {
|
||||
await db.exec(`CREATE TABLE maps (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
map_id INTEGER UNIQUE NOT NULL,
|
||||
image_data TEXT,
|
||||
pixel_data TEXT,
|
||||
captured_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`);
|
||||
console.log(' Recreated maps');
|
||||
}
|
||||
|
||||
if (recreate('invite_sites')) {
|
||||
await db.exec(`CREATE TABLE invite_sites (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
label TEXT NOT NULL,
|
||||
bot_name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`);
|
||||
console.log(' Recreated invite_sites');
|
||||
}
|
||||
|
||||
if (recreate('invite_permissions')) {
|
||||
await db.exec(`CREATE TABLE invite_permissions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
site_id INTEGER NOT NULL,
|
||||
player_name TEXT NOT NULL,
|
||||
FOREIGN KEY (site_id) REFERENCES invite_sites(id) ON DELETE CASCADE,
|
||||
UNIQUE(site_id, player_name)
|
||||
)`);
|
||||
console.log(' Recreated invite_permissions');
|
||||
}
|
||||
}
|
||||
|
||||
async function insertDefaultPermissions(db) {
|
||||
const conf = require('../conf/base');
|
||||
const defaultPlayers = conf.storage?.defaultPlayers || [];
|
||||
|
||||
for (const player of defaultPlayers) {
|
||||
try {
|
||||
await db.run(
|
||||
'INSERT OR IGNORE INTO permissions (player_name, role) VALUES (?, ?)',
|
||||
[player.name, player.role]
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(` Error inserting ${player.name}:`, e.message);
|
||||
}
|
||||
}
|
||||
if (defaultPlayers.length > 0) {
|
||||
console.log(` Inserted ${defaultPlayers.length} default players`);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error('Fatal:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user