diff --git a/src/db/initializeDatabase.ts b/src/db/initializeDatabase.ts index 192df15..2c82566 100644 --- a/src/db/initializeDatabase.ts +++ b/src/db/initializeDatabase.ts @@ -7,7 +7,7 @@ import * as path from 'path'; * Singleton class responsible for initializing and setting up the SQLite database. * It ensures that only one instance of the database is created and utilized throughout the application. */ -class DatabaseInitializer { +export class DatabaseInitializer { private static instance: DatabaseInitializer; private db: Database | undefined; @@ -30,6 +30,17 @@ class DatabaseInitializer { return DatabaseInitializer.instance; } + /** + * Retrieves the initialized database instance. + * + * @returns {Database | undefined} The initialized database instance, or `undefined` if the + * database has not been initialized or if initialization failed. + */ + public getDbInstance(): Database | undefined { + return this.db; + } + + /** * Initializes the SQLite database. If the database file does not exist, it will be created. * @param dbPath The path to the SQLite database file. diff --git a/src/db/services/database.ts b/src/db/services/database.ts new file mode 100644 index 0000000..45e645e --- /dev/null +++ b/src/db/services/database.ts @@ -0,0 +1,71 @@ +import { Database, open } from 'sqlite'; +import sqlite3 from 'sqlite3'; +import { Comment } from '../../rdrama/models/Comment'; + +/** + * Service for interacting with the SQLite database for operations related to comments and user mentions. + */ +export class DatabaseService { + private db: Database; + + private constructor(db: Database) { + this.db = db; + } + + /** + * Asynchronously initializes the database and returns an instance of DatabaseService. + * + * @returns {Promise} An instance of the DatabaseService with an initialized database connection. + */ + public static async initialize(): Promise { + const db = await open({ + filename: './src/db/appData.db', + driver: sqlite3.Database, + }); + return new DatabaseService(db); + } + + /** + * Inserts a new comment into the database. + * + * @param {Comment} comment - The comment object to insert. + */ + public async insertComment(comment: Comment): Promise { + const sql = `INSERT INTO comments (author_id, author_name, body, body_html, created_utc, permalink) VALUES (?, ?, ?, ?, ?, ?)`; + await this.db.run(sql, [comment.author_id, comment.author_name, comment.body, comment.body_html, comment.created_utc, comment.permalink]); + } + + /** + * Inserts a new user mention into the database. + * + * @param {Object} mention - The user mention object to insert, containing rdrama_comment_id, username, and optionally message. + */ + public async insertUserMention(mention: { rdrama_comment_id: string; username: string; message?: string }): Promise { + const sql = `INSERT INTO user_mentions (rdrama_comment_id, username, message) VALUES (?, ?, ?)`; + await this.db.run(sql, [mention.rdrama_comment_id, mention.username, mention.message]); + } + + /** + * Queries the database for an existing comment. + * + * @param {string} commentId - The ID of the comment to search for. + * @returns {Promise} A boolean indicating whether the comment exists. + */ + public async commentExists(commentId: string): Promise { + const sql = `SELECT 1 FROM comments WHERE id = ?`; + const result = await this.db.get(sql, [commentId]); + return !!result; + } + + /** + * Queries the database for existing mentions of a username. + * + * @param {string} username - The username to search for. + * @returns {Promise} A boolean indicating whether the username has been mentioned. + */ + public async userMentionExists(username: string): Promise { + const sql = `SELECT 1 FROM user_mentions WHERE username = ?`; + const result = await this.db.get(sql, [username]); + return !!result; + } +} diff --git a/src/index.ts b/src/index.ts index a49922e..fa3a19a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,7 @@ import WorkflowOrchestrator from './workflows/WorkflowOrchestrator'; import SessionManager from './rdrama/session/SessionManager'; import { CommentFetcher } from './rdrama/services/CommentFetcher'; import { CommentParser } from './rdrama/services/CommentParser'; +import { DatabaseInitializer } from './db/initializeDatabase'; // Import other necessary services or configurations async function startApplication() { @@ -15,12 +16,22 @@ async function startApplication() { } sessionManager.setAuthorizationToken(process.env.RDRAMA_API_KEY); + const databaseInitializer = DatabaseInitializer.getInstance(); + const db = databaseInitializer.getDbInstance() + if (!db) { + throw new Error('Failed to initialize the database.'); + } + // Initialize services with any required dependencies const commentFetcher = new CommentFetcher(); const commentParser = new CommentParser(); // Initialize and start your workflow - const workflowOrchestrator = new WorkflowOrchestrator(commentFetcher, commentParser); + const workflowOrchestrator = new WorkflowOrchestrator( + commentFetcher, + commentParser, + db + ); await workflowOrchestrator.executeWorkflow(); } diff --git a/src/workflows/WorkflowOrchestrator.ts b/src/workflows/WorkflowOrchestrator.ts index e3c5240..43feef0 100644 --- a/src/workflows/WorkflowOrchestrator.ts +++ b/src/workflows/WorkflowOrchestrator.ts @@ -1,14 +1,15 @@ import { CommentFetcher } from "../rdrama/services/CommentFetcher"; import { CommentParser } from "../rdrama/services/CommentParser"; +import { Database } from 'sqlite'; //import { Comment } from "../rdrama/models/Comment"; class WorkflowOrchestrator { constructor( - private commentFetcher: CommentFetcher, - private commentParser: CommentParser, - //private databaseService: DatabaseService, // Responsible for DB operations + private commentFetcher: CommentFetcher, + private commentParser: CommentParser, + private db: Database //private redditNotifier: RedditNotifier // Handles notifications to Reddit users - ) {} + ) { } /** * Executes the defined workflow for processing comments. @@ -27,11 +28,11 @@ class WorkflowOrchestrator { //// Query user information based on usernames //const userInfo = await this.databaseService.queryUsersInfo(uniqueUsernames); //console.log(`Queried information for ${userInfo.length} users`); -// + // //// Filter users who should be notified //const usersToNotify = userInfo.filter(user => this.shouldNotifyUser(user)); //console.log(`Identified ${usersToNotify.length} users to notify`); -// + // //// Notify users //for (const user of usersToNotify) { // await this.redditNotifier.notifyUser(user);