You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.4 KiB
JavaScript
117 lines
3.4 KiB
JavaScript
const express = require('express');
|
|
|
|
const { Pool } = require('pg');
|
|
const db = new Pool({
|
|
host: 'postgres',
|
|
database: 'pastebin',
|
|
user: 'pastebin',
|
|
password: 'buginoo'
|
|
});
|
|
|
|
|
|
// initialize app:
|
|
const app = express();
|
|
const port = 80;
|
|
|
|
db.query("CREATE TABLE IF NOT EXISTS bin (id VARCHAR PRIMARY KEY);"
|
|
+ "CREATE TABLE IF NOT EXISTS note (id VARCHAR PRIMARY KEY, text TEXT, modified TIMESTAMPTZ);"
|
|
+ "CREATE TABLE IF NOT EXISTS bin_note (bin_id VARCHAR REFERENCES bin (id), note_id VARCHAR REFERENCES note (id), PRIMARY KEY (bin_id, note_id));"
|
|
);
|
|
|
|
|
|
const router = express.Router();
|
|
|
|
router.get('/', (req, res)=>{
|
|
res.send('Feh')
|
|
});
|
|
|
|
const load_notes_stmt =
|
|
"SELECT n.id, n.text, n.modified FROM bin_note AS bn"
|
|
+" JOIN note AS n"
|
|
+" ON n.id = bn.note_id"
|
|
+" WHERE bn.bin_id = $1";
|
|
// {bin_id}
|
|
router.post('/load-notes', (req, res)=>{
|
|
const bin_id = req.body.bind_id;
|
|
db.query(load_notes_stmt, [bin_id])
|
|
.then(result => {
|
|
res.json({status: 'ok', bin:{id:bin_id}, notes:result.rows})
|
|
});
|
|
// {status: 'ok', bin:{id:bin.id}, notes: bin.notes}
|
|
});
|
|
|
|
const search_stmt =
|
|
"SELECT n.id FROM note AS n"
|
|
+" WHERE n.text LIKE '%$1%'"
|
|
+" ORDER BY n.modified DESC";
|
|
// {search_term, sorting, bin_id}
|
|
router.post('/search', (req, res)=>{
|
|
const search_term = req.body.search_term;
|
|
db.query(search_stmt, [search_term])
|
|
.then(result => {
|
|
res.json({status:'ok', notes:result.rows.map(n=>n.id)});
|
|
});
|
|
// {status: 'ok', notes}
|
|
});
|
|
|
|
const upsert_note_stmt =
|
|
"INSERT INTO note (id, text, modified) VALUES ($1, $2, NOW())"
|
|
+" ON CONFLICT (id)"
|
|
+" DO UPDATE SET text = EXCLUDED.text, modified = EXCLUDED.modified";
|
|
const upsert_bin_stmt =
|
|
"INSERT INTO bin (id) VALUES ($1)"
|
|
+" ON CONFLICT (id)"
|
|
+" DO NOTHING";
|
|
const upsert_bin_note_stmt =
|
|
"INSERT INTO bin_note (bin_id, note_id) VALUES ($1, $2)"
|
|
+" ON CONFLICT (bin_id, note_id)"
|
|
+" DO NOTHING";
|
|
|
|
// {bin_id, note_id, text}
|
|
router.post('/save', (req, res)=>{
|
|
const {bin_id, note_id, text} = req.body;
|
|
db.connect().then(async (client)=>{
|
|
await client.query(upsert_note_stmt, [note_id, text]);
|
|
await client.query(upsert_bin_stmt, [bin_id]);
|
|
await client.query(upsert_bin_note_stmt, [bin_id, note_id]);
|
|
// don't forget to release back into the Pool:
|
|
client.release();
|
|
res.json({status: 'ok'});
|
|
});
|
|
// {status: 'ok'}
|
|
});
|
|
|
|
app.use('/', express.json(), router);
|
|
|
|
|
|
// run app:
|
|
const server = app.listen(port, () => {
|
|
console.log(`Pastebin app listening at http://localhost:${port}`)
|
|
});
|
|
|
|
|
|
|
|
|
|
// Ruthlessly copied from [https://medium.com/@becintec/building-graceful-node-applications-in-docker-4d2cd4d5d392]:
|
|
// The signals we want to handle
|
|
// NOTE: although it is tempting, the SIGKILL signal (9) cannot be intercepted and handled
|
|
var signals = {
|
|
'SIGHUP': 1,
|
|
'SIGINT': 2,
|
|
'SIGTERM': 15
|
|
};
|
|
// Do any necessary shutdown logic for our application here
|
|
const shutdown = (signal, value) => {
|
|
console.log("shutdown!");
|
|
server.close(() => {
|
|
console.log(`server stopped by ${signal} with value ${value}`);
|
|
process.exit(128 + value);
|
|
});
|
|
};
|
|
// Create a listener for each of the signals that we want to handle
|
|
Object.keys(signals).forEach((signal) => {
|
|
process.on(signal, () => {
|
|
console.log(`process received a ${signal} signal`);
|
|
shutdown(signal, signals[signal]);
|
|
});
|
|
}); |