Add server/src/db.js
This commit is contained in:
101
server/src/db.js
Normal file
101
server/src/db.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import pg from 'pg';
|
||||
import bcrypt from 'bcryptjs';
|
||||
|
||||
const { Pool } = pg;
|
||||
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL
|
||||
});
|
||||
|
||||
export async function query(q, params) {
|
||||
const client = await pool.connect();
|
||||
try {
|
||||
return await client.query(q, params);
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
// init DB from schema + seed
|
||||
export async function init() {
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const schema = fs.readFileSync(path.join(__dirname, 'schema.sql'), 'utf8');
|
||||
await query(schema);
|
||||
const seed = fs.readFileSync(path.join(__dirname, 'seed.sql'), 'utf8');
|
||||
await query(seed);
|
||||
console.log('DB initialized.');
|
||||
}
|
||||
|
||||
// Models (simple)
|
||||
|
||||
export const Users = {
|
||||
async create(username, password) {
|
||||
const passhash = await bcrypt.hash(password, 10);
|
||||
const { rows } = await query(
|
||||
'INSERT INTO users (username, passhash) VALUES ($1,$2) RETURNING id, username',
|
||||
[username, passhash]
|
||||
);
|
||||
// create character with same name
|
||||
await query(
|
||||
'INSERT INTO characters (user_id, name) VALUES ($1,$2)',
|
||||
[rows[0].id, username]
|
||||
);
|
||||
return rows[0];
|
||||
},
|
||||
async verify(username, password) {
|
||||
const { rows } = await query(
|
||||
'SELECT * FROM users WHERE username=$1',
|
||||
[username]
|
||||
);
|
||||
if (!rows[0]) return null;
|
||||
const ok = await bcrypt.compare(password, rows[0].passhash);
|
||||
return ok ? rows[0] : null;
|
||||
}
|
||||
};
|
||||
|
||||
export const Characters = {
|
||||
async getByUserId(userId) {
|
||||
const { rows } = await query(
|
||||
'SELECT * FROM characters WHERE user_id=$1 LIMIT 1',
|
||||
[userId]
|
||||
);
|
||||
return rows[0] || null;
|
||||
},
|
||||
async addXP(id, amount) {
|
||||
await query('UPDATE characters SET xp = xp + $1 WHERE id=$2', [amount, id]);
|
||||
}
|
||||
};
|
||||
|
||||
export const Inventory = {
|
||||
async all(characterId) {
|
||||
const { rows } = await query(
|
||||
'SELECT item_key, qty FROM inventory WHERE character_id=$1',
|
||||
[characterId]
|
||||
);
|
||||
return rows;
|
||||
},
|
||||
async add(characterId, itemKey, qty) {
|
||||
// upsert
|
||||
const text = `
|
||||
INSERT INTO inventory (character_id, item_key, qty)
|
||||
VALUES ($1,$2,$3)
|
||||
ON CONFLICT (character_id, item_key)
|
||||
DO UPDATE SET qty = inventory.qty + EXCLUDED.qty
|
||||
`;
|
||||
await query(text, [characterId, itemKey, qty]);
|
||||
}
|
||||
};
|
||||
|
||||
// allow manual init: node src/db.js init
|
||||
if (process.argv[2] === 'init') {
|
||||
init()
|
||||
.then(() => process.exit(0))
|
||||
.catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user