v2.0: SQLite statt PostgreSQL (keine externe DB nötig)

This commit is contained in:
Hermes
2026-08-12 08:17:20 +00:00
parent 7088e5e879
commit 4b2a76e9c1
3 changed files with 39 additions and 49 deletions
+6
View File
@@ -1,5 +1,8 @@
FROM node:22-alpine FROM node:22-alpine
# better-sqlite3 braucht build tools
RUN apk add --no-cache python3 make g++
WORKDIR /app WORKDIR /app
COPY package*.json ./ COPY package*.json ./
@@ -7,6 +10,9 @@ RUN npm install --production
COPY . . COPY . .
# Datenverzeichnis für SQLite
RUN mkdir -p /data
EXPOSE 3000 EXPOSE 3000
CMD ["node", "server.js"] CMD ["node", "server.js"]
+3 -3
View File
@@ -1,14 +1,14 @@
{ {
"name": "techno-todo", "name": "techno-todo",
"version": "1.0.0", "version": "2.0.0",
"description": "⚡ 90s Techno-Style Todo App", "description": "⚡ 90s Techno-Style Todo App (SQLite edition)",
"main": "server.js", "main": "server.js",
"scripts": { "scripts": {
"start": "node server.js" "start": "node server.js"
}, },
"dependencies": { "dependencies": {
"express": "^4.21.0", "express": "^4.21.0",
"pg": "^8.13.0", "better-sqlite3": "^11.7.0",
"ejs": "^3.1.10" "ejs": "^3.1.10"
} }
} }
+22 -38
View File
@@ -1,33 +1,22 @@
const express = require('express'); const express = require('express');
const { Pool } = require('pg'); const Database = require('better-sqlite3');
const path = require('path'); const path = require('path');
const app = express(); const app = express();
const PORT = process.env.PORT || 3000; const PORT = process.env.PORT || 3000;
// PostgreSQL connection // SQLite – keine externe DB nötig
const pool = new Pool({ const db = new Database('/data/todos.db');
connectionString: process.env.DATABASE_URL, db.pragma('journal_mode = WAL');
ssl: process.env.DB_SSL === 'true' ? { rejectUnauthorized: false } : false, db.exec(`
});
// Initialize DB table
async function initDB() {
const client = await pool.connect();
try {
await client.query(`
CREATE TABLE IF NOT EXISTS todos ( CREATE TABLE IF NOT EXISTS todos (
id SERIAL PRIMARY KEY, id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT NOT NULL, text TEXT NOT NULL,
done BOOLEAN DEFAULT FALSE, done INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW() created_at TEXT DEFAULT (datetime('now'))
) )
`); `);
console.log('⚡ DATABASE ONLINE ⚡'); console.log('⚡ DATABASE ONLINE (SQLite) ⚡');
} finally {
client.release();
}
}
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public'))); app.use(express.static(path.join(__dirname, 'public')));
@@ -35,44 +24,39 @@ app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views')); app.set('views', path.join(__dirname, 'views'));
// Routes // Routes
app.get('/', async (req, res) => { app.get('/', (req, res) => {
try { try {
const result = await pool.query('SELECT * FROM todos ORDER BY created_at DESC'); const todos = db.prepare('SELECT * FROM todos ORDER BY created_at DESC').all();
res.render('index', { todos: result.rows, error: null }); res.render('index', { todos, error: null });
} catch (err) { } catch (err) {
res.render('index', { todos: [], error: 'DATABASE CONNECTION LOST ⚠' }); res.render('index', { todos: [], error: 'DATABASE ERROR ⚠' });
} }
}); });
app.post('/add', async (req, res) => { app.post('/add', (req, res) => {
const { text } = req.body; const { text } = req.body;
if (text && text.trim()) { if (text && text.trim()) {
await pool.query('INSERT INTO todos (text) VALUES ($1)', [text.trim()]); db.prepare('INSERT INTO todos (text) VALUES (?)').run(text.trim());
} }
res.redirect('/'); res.redirect('/');
}); });
app.post('/toggle/:id', async (req, res) => { app.post('/toggle/:id', (req, res) => {
await pool.query('UPDATE todos SET done = NOT done WHERE id = $1', [req.params.id]); db.prepare('UPDATE todos SET done = NOT done WHERE id = ?').run(req.params.id);
res.redirect('/'); res.redirect('/');
}); });
app.post('/delete/:id', async (req, res) => { app.post('/delete/:id', (req, res) => {
await pool.query('DELETE FROM todos WHERE id = $1', [req.params.id]); db.prepare('DELETE FROM todos WHERE id = ?').run(req.params.id);
res.redirect('/'); res.redirect('/');
}); });
// Health check app.get('/health', (req, res) => res.json({ status: 'ONLINE', db: 'SQLITE' }));
app.get('/health', (req, res) => res.json({ status: 'ONLINE', db: 'CONNECTED' }));
initDB().then(() => {
app.listen(PORT, () => { app.listen(PORT, () => {
console.log(`╔══════════════════════════════════════╗`); console.log(`╔══════════════════════════════════════╗`);
console.log(`║ ⚡ TECHNO-TODO v1.0 ONLINE ⚡ ║`); console.log(`║ ⚡ TECHNO-TODO v2.0 ONLINE ⚡ ║`);
console.log(`║ PORT: ${PORT} ║`); console.log(`║ PORT: ${PORT} ║`);
console.log(`║ DB: SQLite (no externals) ║`);
console.log(`╚══════════════════════════════════════╝`); console.log(`╚══════════════════════════════════════╝`);
}); });
}).catch(err => {
console.error('Failed to init DB:', err);
process.exit(1);
});