Database added

This commit is contained in:
2026-03-20 11:21:04 -04:00
parent 2dec1f1f93
commit 821cf379a9
4 changed files with 263 additions and 28 deletions

110
server.js
View File

@ -3,13 +3,35 @@ import cors from 'cors';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import pg from 'pg';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
const PORT = 3001;
const DATA_FILE = path.join(__dirname, 'quotes.json');
// Use DATA_DIR from environment if available (for Dokploy volumes), otherwise fallback to the current directory
const DATA_DIR = process.env.DATA_DIR || __dirname;
const DATA_FILE = path.join(DATA_DIR, 'quotes.json');
// Database Setup
const { Pool } = pg;
const pool = process.env.DATABASE_URL ? new Pool({
connectionString: process.env.DATABASE_URL,
ssl: process.env.PG_SSL === 'true' ? { rejectUnauthorized: false } : false
}) : null;
if (pool) {
pool.query(`
CREATE TABLE IF NOT EXISTS quotes (
id SERIAL PRIMARY KEY,
quote_id VARCHAR(255) UNIQUE NOT NULL,
data JSONB NOT NULL
)
`).then(() => console.log("PostgreSQL Connected & Table Verified"))
.catch(err => console.error("Could not create PostgreSQL table:", err));
}
app.use(cors());
app.use(express.json());
@ -20,7 +42,7 @@ app.use((req, res, next) => {
next();
});
// Helper to read data
// Helper to read data (legacy JSON mode)
const readData = () => {
try {
if (!fs.existsSync(DATA_FILE)) {
@ -34,7 +56,7 @@ const readData = () => {
}
};
// Helper to write data
// Helper to write data (legacy JSON mode)
const writeData = (data) => {
try {
fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2), 'utf8');
@ -44,40 +66,72 @@ const writeData = (data) => {
};
// GET all quotes
app.get('/api/quotes', (req, res) => {
const quotes = readData();
res.json(quotes);
app.get('/api/quotes', async (req, res) => {
if (pool) {
try {
const result = await pool.query('SELECT data FROM quotes ORDER BY id ASC');
res.json(result.rows.map(row => row.data));
} catch (err) {
console.error(err);
res.status(500).json({ error: "Failed to fetch from database" });
}
} else {
const quotes = readData();
res.json(quotes);
}
});
// POST a new or updated quote
app.post('/api/quotes', (req, res) => {
app.post('/api/quotes', async (req, res) => {
const newQuote = req.body;
let quotes = readData();
const existingIndex = quotes.findIndex(q => q.id === newQuote.id);
if (existingIndex >= 0) {
quotes[existingIndex] = newQuote; // Update
if (pool) {
try {
await pool.query(
'INSERT INTO quotes (quote_id, data) VALUES ($1, $2) ON CONFLICT (quote_id) DO UPDATE SET data = $2',
[String(newQuote.id), newQuote]
);
res.status(201).json(newQuote);
} catch (err) {
console.error(err);
res.status(500).json({ error: "Failed to save to database" });
}
} else {
quotes.push(newQuote); // Add new
let quotes = readData();
const existingIndex = quotes.findIndex(q => q.id === newQuote.id);
if (existingIndex >= 0) {
quotes[existingIndex] = newQuote; // Update
} else {
quotes.push(newQuote); // Add new
}
writeData(quotes);
res.status(201).json(newQuote);
}
writeData(quotes);
res.status(201).json(newQuote);
});
// DELETE a quote
app.delete('/api/quotes/:id', (req, res) => {
const idToDelete = parseInt(req.params.id) || req.params.id; // Handle number or string
let quotes = readData();
const initialLength = quotes.length;
quotes = quotes.filter(q => q.id != idToDelete);
if (quotes.length < initialLength) {
writeData(quotes);
res.status(200).json({ message: "Quote deleted successfully" });
app.delete('/api/quotes/:id', async (req, res) => {
const idToDelete = req.params.id;
if (pool) {
try {
const result = await pool.query('DELETE FROM quotes WHERE quote_id = $1', [String(idToDelete)]);
if (result.rowCount > 0) res.status(200).json({ message: "Quote deleted successfully" });
else res.status(404).json({ message: "Quote not found" });
} catch (err) {
console.error(err);
res.status(500).json({ error: "Failed to delete from database" });
}
} else {
res.status(404).json({ message: "Quote not found" });
const idToDeleteFallback = parseInt(idToDelete) || idToDelete; // Handle number or string
let quotes = readData();
const initialLength = quotes.length;
quotes = quotes.filter(q => q.id != idToDeleteFallback);
if (quotes.length < initialLength) {
writeData(quotes);
res.status(200).json({ message: "Quote deleted successfully" });
} else {
res.status(404).json({ message: "Quote not found" });
}
}
});
@ -91,4 +145,6 @@ app.get(/(.*)/, (req, res) => {
app.listen(PORT, '0.0.0.0', () => {
console.log(`Backend server running on port ${PORT}`);
if (pool) console.log(`[INFO] DATABASE_URL detected. Running in PostgreSQL mode.`);
else console.log(`[INFO] No DATABASE_URL detected. Running in legacy JSON file mode.`);
});