ice/services/DatabaseService.js
Claude Code a0fffcf4f0 Refactor architecture: Add models/services layer and refactor frontend
Major architectural improvements:
- Created models/services layer for better separation of concerns
  - Location model with async methods for database operations
  - ProfanityWord model for content moderation
  - DatabaseService for centralized database management
  - ProfanityFilterService refactored to use models
- Refactored frontend map implementations to share common code
  - MapBase class extracts 60-70% of duplicate functionality
  - Refactored implementations extend MapBase for specific features
  - Maintained unique geocoding capabilities per implementation
- Updated server.js to use new service architecture
- All routes now use async/await with models instead of raw queries
- Enhanced error handling and maintainability

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-05 19:21:51 -04:00

93 lines
No EOL
2.4 KiB
JavaScript

const sqlite3 = require('sqlite3').verbose();
const path = require('path');
const Location = require('../models/Location');
const ProfanityWord = require('../models/ProfanityWord');
class DatabaseService {
constructor() {
this.mainDb = null;
this.profanityDb = null;
this.locationModel = null;
this.profanityWordModel = null;
}
async initialize() {
await this.initializeMainDatabase();
await this.initializeProfanityDatabase();
}
async initializeMainDatabase() {
return new Promise((resolve, reject) => {
const dbPath = path.join(__dirname, '..', 'icewatch.db');
this.mainDb = new sqlite3.Database(dbPath, async (err) => {
if (err) {
console.error('Could not connect to main database', err);
return reject(err);
}
console.log('Connected to main SQLite database.');
this.locationModel = new Location(this.mainDb);
try {
await this.locationModel.initializeTable();
resolve();
} catch (error) {
reject(error);
}
});
});
}
async initializeProfanityDatabase() {
return new Promise((resolve, reject) => {
const dbPath = path.join(__dirname, '..', 'profanity.db');
this.profanityDb = new sqlite3.Database(dbPath, async (err) => {
if (err) {
console.error('Could not connect to profanity database', err);
return reject(err);
}
console.log('Connected to profanity SQLite database.');
this.profanityWordModel = new ProfanityWord(this.profanityDb);
try {
await this.profanityWordModel.initializeTable();
resolve();
} catch (error) {
reject(error);
}
});
});
}
getLocationModel() {
if (!this.locationModel) {
throw new Error('Database not initialized. Call initialize() first.');
}
return this.locationModel;
}
getProfanityWordModel() {
if (!this.profanityWordModel) {
throw new Error('Database not initialized. Call initialize() first.');
}
return this.profanityWordModel;
}
getMainDb() {
return this.mainDb;
}
getProfanityDb() {
return this.profanityDb;
}
close() {
if (this.mainDb) {
this.mainDb.close();
}
if (this.profanityDb) {
this.profanityDb.close();
}
}
}
module.exports = DatabaseService;