From 4b2a76e9c148c58763270765bfc2ccc820228d4d Mon Sep 17 00:00:00 2001 From: Hermes Date: Wed, 12 Aug 2026 08:17:20 +0000 Subject: [PATCH] =?UTF-8?q?v2.0:=20SQLite=20statt=20PostgreSQL=20(keine=20?= =?UTF-8?q?externe=20DB=20n=C3=B6tig)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 6 +++++ package.json | 6 ++--- server.js | 76 +++++++++++++++++++++------------------------------- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/Dockerfile b/Dockerfile index 02f3f11..8fe75da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,8 @@ FROM node:22-alpine +# better-sqlite3 braucht build tools +RUN apk add --no-cache python3 make g++ + WORKDIR /app COPY package*.json ./ @@ -7,6 +10,9 @@ RUN npm install --production COPY . . +# Datenverzeichnis für SQLite +RUN mkdir -p /data + EXPOSE 3000 CMD ["node", "server.js"] diff --git a/package.json b/package.json index 7350273..f598180 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,14 @@ { "name": "techno-todo", - "version": "1.0.0", - "description": "⚡ 90s Techno-Style Todo App", + "version": "2.0.0", + "description": "⚡ 90s Techno-Style Todo App (SQLite edition)", "main": "server.js", "scripts": { "start": "node server.js" }, "dependencies": { "express": "^4.21.0", - "pg": "^8.13.0", + "better-sqlite3": "^11.7.0", "ejs": "^3.1.10" } } diff --git a/server.js b/server.js index 9964897..aaabfe2 100644 --- a/server.js +++ b/server.js @@ -1,33 +1,22 @@ const express = require('express'); -const { Pool } = require('pg'); +const Database = require('better-sqlite3'); const path = require('path'); const app = express(); const PORT = process.env.PORT || 3000; -// PostgreSQL connection -const pool = new Pool({ - connectionString: process.env.DATABASE_URL, - ssl: process.env.DB_SSL === 'true' ? { rejectUnauthorized: false } : false, -}); - -// Initialize DB table -async function initDB() { - const client = await pool.connect(); - try { - await client.query(` - CREATE TABLE IF NOT EXISTS todos ( - id SERIAL PRIMARY KEY, - text TEXT NOT NULL, - done BOOLEAN DEFAULT FALSE, - created_at TIMESTAMP DEFAULT NOW() - ) - `); - console.log('⚡ DATABASE ONLINE ⚡'); - } finally { - client.release(); - } -} +// SQLite – keine externe DB nötig +const db = new Database('/data/todos.db'); +db.pragma('journal_mode = WAL'); +db.exec(` + CREATE TABLE IF NOT EXISTS todos ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + text TEXT NOT NULL, + done INTEGER DEFAULT 0, + created_at TEXT DEFAULT (datetime('now')) + ) +`); +console.log('⚡ DATABASE ONLINE (SQLite) ⚡'); app.use(express.urlencoded({ extended: true })); app.use(express.static(path.join(__dirname, 'public'))); @@ -35,44 +24,39 @@ app.set('view engine', 'ejs'); app.set('views', path.join(__dirname, 'views')); // Routes -app.get('/', async (req, res) => { +app.get('/', (req, res) => { try { - const result = await pool.query('SELECT * FROM todos ORDER BY created_at DESC'); - res.render('index', { todos: result.rows, error: null }); + const todos = db.prepare('SELECT * FROM todos ORDER BY created_at DESC').all(); + res.render('index', { todos, error: null }); } 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; 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('/'); }); -app.post('/toggle/:id', async (req, res) => { - await pool.query('UPDATE todos SET done = NOT done WHERE id = $1', [req.params.id]); +app.post('/toggle/:id', (req, res) => { + db.prepare('UPDATE todos SET done = NOT done WHERE id = ?').run(req.params.id); res.redirect('/'); }); -app.post('/delete/:id', async (req, res) => { - await pool.query('DELETE FROM todos WHERE id = $1', [req.params.id]); +app.post('/delete/:id', (req, res) => { + db.prepare('DELETE FROM todos WHERE id = ?').run(req.params.id); res.redirect('/'); }); -// Health check -app.get('/health', (req, res) => res.json({ status: 'ONLINE', db: 'CONNECTED' })); +app.get('/health', (req, res) => res.json({ status: 'ONLINE', db: 'SQLITE' })); -initDB().then(() => { - app.listen(PORT, () => { - console.log(`╔══════════════════════════════════════╗`); - console.log(`║ ⚡ TECHNO-TODO v1.0 ONLINE ⚡ ║`); - console.log(`║ PORT: ${PORT} ║`); - console.log(`╚══════════════════════════════════════╝`); - }); -}).catch(err => { - console.error('Failed to init DB:', err); - process.exit(1); +app.listen(PORT, () => { + console.log(`╔══════════════════════════════════════╗`); + console.log(`║ ⚡ TECHNO-TODO v2.0 ONLINE ⚡ ║`); + console.log(`║ PORT: ${PORT} ║`); + console.log(`║ DB: SQLite (no externals) ║`); + console.log(`╚══════════════════════════════════════╝`); });