fix: comprehensive PostgreSQL/SQLite compatibility fixes
Mirror to GitHub / mirror (push) Successful in 19s
Test and Lint / backend-test (push) Successful in 1m8s
Test and Lint / frontend-test (push) Successful in 2m11s
Version and Release / version-bump (push) Successful in 34s
Version and Release / trigger-drone (push) Successful in 3s
continuous-integration/drone/push Build is passing

Critical fixes for database compatibility issues:

INSERT operations:
- Fix all INSERT queries to use .returning('id')
- Handle both PostgreSQL (returns objects) and SQLite (returns IDs)
- Fixed in: events.js, adminArchives.js, adminEvents-enhanced.js, create-test-event.js

Date operations:
- Replace SQLite-specific db.raw("datetime('now', '+30 days')")
- Use JavaScript Date objects for cross-database compatibility
- Fixed in: adminArchives.js

Database utilities:
- Add dbCompat.js utility for handling database differences
- Provides consistent API for inserts, dates, booleans, and DB-specific operations
- Centralized database compatibility logic

Migration:
- Add migration 023 documenting PostgreSQL compatibility requirements
- Ensures future developers are aware of compatibility needs

This resolves all 'not iterable' errors and ensures the application
works correctly with both PostgreSQL (production) and SQLite (development).
This commit is contained in:
2025-07-14 20:38:19 +02:00
parent dc17e7d59d
commit f053f42b6d
9 changed files with 173 additions and 90 deletions
+8 -3
View File
@@ -211,12 +211,14 @@ router.post('/:id/restore', adminAuth, async (req, res) => {
categoriesMap.set(categoryName, existingCategory.id);
} else {
// Create the category if it doesn't exist
const [newCategoryId] = await db('photo_categories').insert({
const insertResult = await db('photo_categories').insert({
event_id: archive.id,
name: categoryName,
slug: categoryName.toLowerCase().replace(/[^a-z0-9]/g, '-'),
created_at: new Date()
});
}).returning('id');
const newCategoryId = insertResult[0]?.id || insertResult[0];
categoriesMap.set(categoryName, newCategoryId);
}
}
@@ -266,6 +268,9 @@ router.post('/:id/restore', adminAuth, async (req, res) => {
}
// Update event status
const thirtyDaysFromNow = new Date();
thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);
await db('events')
.where('id', req.params.id)
.update({
@@ -273,7 +278,7 @@ router.post('/:id/restore', adminAuth, async (req, res) => {
is_active: true,
archive_path: null,
archived_at: null,
expires_at: db.raw("datetime('now', '+30 days')") // Reset expiration
expires_at: thirtyDaysFromNow.toISOString() // Reset expiration - works on both DBs
});
// Log activity
+5 -2
View File
@@ -83,7 +83,7 @@ router.post('/', adminAuth, [
await fs.mkdir(path.join(eventPath, 'individual'), { recursive: true });
// Insert into database
const [eventId] = await db('events').insert({
const insertResult = await db('events').insert({
slug,
event_type,
event_name,
@@ -99,7 +99,10 @@ router.post('/', adminAuth, [
created_at: new Date().toISOString(),
allow_user_uploads,
upload_category_id
});
}).returning('id');
// Handle both PostgreSQL (returns array of objects) and SQLite (returns array of IDs)
const eventId = insertResult[0]?.id || insertResult[0];
// Log activity
await logActivity('event_created',
+5 -2
View File
@@ -64,7 +64,7 @@ router.post('/', adminAuth, [
await fs.mkdir(path.join(eventPath, 'individual'), { recursive: true });
// Insert into database
const [eventId] = await db('events').insert({
const insertResult = await db('events').insert({
slug,
event_type,
event_name,
@@ -76,7 +76,10 @@ router.post('/', adminAuth, [
color_theme,
share_link: shareLink,
expires_at
});
}).returning('id');
// Handle both PostgreSQL (returns array of objects) and SQLite (returns array of IDs)
const eventId = insertResult[0]?.id || insertResult[0];
// Queue creation email
const { queueEmail } = require('../services/emailProcessor');