feat: initial commit at project root
This commit is contained in:
119
internal/db/db.js
Normal file
119
internal/db/db.js
Normal file
@@ -0,0 +1,119 @@
|
||||
import mysql from 'mysql2/promise';
|
||||
import { config } from '../config/config.js';
|
||||
import { logger } from '../logger/logger.js';
|
||||
|
||||
let pool = null;
|
||||
|
||||
/**
|
||||
* Initializes the MySQL database pool and ensures schema exists.
|
||||
*/
|
||||
export async function initializeDatabase() {
|
||||
if (!config.dbUsername) {
|
||||
logger.warn('db_disabled', { reason: 'No DB_USERNAME configured, database logging is disabled' });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
pool = mysql.createPool({
|
||||
host: config.dbHost,
|
||||
port: config.dbPort,
|
||||
database: config.dbDatabase,
|
||||
user: config.dbUsername,
|
||||
password: config.dbPassword,
|
||||
waitForConnections: true,
|
||||
connectionLimit: 10,
|
||||
queueLimit: 0
|
||||
});
|
||||
|
||||
// Test connection and auto-create the table if not exists
|
||||
const conn = await pool.getConnection();
|
||||
await conn.query(`
|
||||
CREATE TABLE IF NOT EXISTS \`call_logs\` (
|
||||
\`id\` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
\`session_id\` VARCHAR(36) NOT NULL UNIQUE,
|
||||
\`ride_id\` VARCHAR(255) NOT NULL,
|
||||
\`driver_id\` VARCHAR(255) NOT NULL,
|
||||
\`passenger_id\` VARCHAR(255) NOT NULL,
|
||||
\`driver_ip\` VARCHAR(45) NULL DEFAULT NULL,
|
||||
\`passenger_ip\` VARCHAR(45) NULL DEFAULT NULL,
|
||||
\`driver_conn_ip\` VARCHAR(45) NULL DEFAULT NULL,
|
||||
\`passenger_conn_ip\` VARCHAR(45) NULL DEFAULT NULL,
|
||||
\`status\` VARCHAR(50) NOT NULL DEFAULT 'created',
|
||||
\`initiated_by\` VARCHAR(255) NULL DEFAULT NULL,
|
||||
\`end_reason\` VARCHAR(255) NULL DEFAULT NULL,
|
||||
\`created_at\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`connected_at\` TIMESTAMP NULL DEFAULT NULL,
|
||||
\`ended_at\` TIMESTAMP NULL DEFAULT NULL,
|
||||
INDEX \`idx_session_id\` (\`session_id\`),
|
||||
INDEX \`idx_ride_id\` (\`ride_id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
`);
|
||||
conn.release();
|
||||
logger.info('db_initialized', { host: config.dbHost, database: config.dbDatabase });
|
||||
} catch (err) {
|
||||
logger.error('db_initialization_failed', { error: err.message });
|
||||
// Soft fallback: log the failure but do not crash the signaling server
|
||||
pool = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs session creation to the database with pre-registered client IPs.
|
||||
*/
|
||||
export async function logSessionCreated(sessionID, rideID, driverID, passengerID, driverIP = null, passengerIP = null) {
|
||||
if (!pool) return;
|
||||
try {
|
||||
await pool.query(
|
||||
`INSERT INTO call_logs (session_id, ride_id, driver_id, passenger_id, driver_ip, passenger_ip, status, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, 'created', NOW())`,
|
||||
[sessionID, rideID, driverID, passengerID, driverIP, passengerIP]
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error('db_log_session_created_failed', { session_id: sessionID, error: err.message });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs session status transition to active and records the connection IPs.
|
||||
*/
|
||||
export async function logSessionActive(sessionID, driverConnIP = null, passengerConnIP = null) {
|
||||
if (!pool) return;
|
||||
try {
|
||||
await pool.query(
|
||||
`UPDATE call_logs SET status = 'active', connected_at = NOW(), driver_conn_ip = ?, passenger_conn_ip = ? WHERE session_id = ?`,
|
||||
[driverConnIP, passengerConnIP, sessionID]
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error('db_log_session_active_failed', { session_id: sessionID, error: err.message });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the initiator (caller) of the call when the first SDP offer is received.
|
||||
*/
|
||||
export async function logSessionInitiator(sessionID, initiatorID) {
|
||||
if (!pool) return;
|
||||
try {
|
||||
await pool.query(
|
||||
`UPDATE call_logs SET initiated_by = ? WHERE session_id = ? AND initiated_by IS NULL`,
|
||||
[initiatorID, sessionID]
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error('db_log_session_initiator_failed', { session_id: sessionID, initiator_id: initiatorID, error: err.message });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs call termination reason and end time.
|
||||
*/
|
||||
export async function logSessionEnded(sessionID, endReason) {
|
||||
if (!pool) return;
|
||||
try {
|
||||
await pool.query(
|
||||
`UPDATE call_logs SET status = 'ended', ended_at = NOW(), end_reason = ? WHERE session_id = ?`,
|
||||
[endReason, sessionID]
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error('db_log_session_ended_failed', { session_id: sessionID, error: err.message });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user