124 lines
4.7 KiB
JavaScript
124 lines
4.7 KiB
JavaScript
// Imports
|
|
const sqlite3 = require('sqlite3').verbose();
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// Configuration Constants
|
|
const DB_PATH = "database/backend.db";
|
|
const SCHEMA_PATH = "database/backend.schema";
|
|
const BOOK_PATH = "../frontend/public/books";
|
|
|
|
// PDF Database Manager - Manages SQLite database for storing PDF metadata
|
|
// Also handles scanning book directory and building DB
|
|
class PDFDatabaseManager {
|
|
constructor() {
|
|
if (fs.existsSync(DB_PATH)) {
|
|
fs.unlinkSync(DB_PATH);
|
|
}
|
|
this.db = new sqlite3.Database(DB_PATH);
|
|
this.createDatabase();
|
|
this.scanAndPopulateDatabase();
|
|
}
|
|
|
|
// Scans the books folder and adds all books / chapters to the database
|
|
async scanAndPopulateDatabase() {
|
|
const bookFolders = fs.readdirSync(BOOK_PATH);
|
|
bookFolders.forEach(folder => {
|
|
const bookDir = path.join(BOOK_PATH, folder);
|
|
const bookMetadataPath = path.join(bookDir, 'bookMetadata.json');
|
|
if (fs.existsSync(bookMetadataPath)) {
|
|
const bookMetadata = JSON.parse(fs.readFileSync(bookMetadataPath, 'utf-8'));
|
|
this.addBook(bookMetadata);
|
|
|
|
const chapterFiles = fs.readdirSync(bookDir).filter(file => file.endsWith('.json') && file !== 'bookMetadata.json');
|
|
|
|
chapterFiles.forEach(async chapterFile => {
|
|
const chapterMetadataPath = path.join(bookDir, chapterFile);
|
|
const chapterMetadata = JSON.parse(fs.readFileSync(chapterMetadataPath, 'utf-8'));
|
|
chapterMetadata.book_id = await this.getBookIdByFolderName(folder);
|
|
this.addChapter(chapterMetadata);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Adds chapter metadata from FS to db
|
|
addChapter(chapterMetadata) {
|
|
let chapterQuery = `INSERT INTO chapters (chapter_number, display_name, filename, book_id) VALUES (?, ?, ?, ?)`;
|
|
this.db.run(chapterQuery, [chapterMetadata.chapter_number, chapterMetadata.display_name, chapterMetadata.filename, chapterMetadata.book_id]);
|
|
}
|
|
|
|
// Adds book metadata from FS to db
|
|
addBook(bookMetadata) {
|
|
let bookQuery = `INSERT INTO books (folder_name, display_name, author) VALUES (?, ?, ?)`;
|
|
this.db.run(bookQuery, [bookMetadata.folder_name, bookMetadata.display_name, bookMetadata.author]);
|
|
}
|
|
|
|
// Retrieves book ID by folder name
|
|
getBookIdByFolderName(folderName) {
|
|
return new Promise((resolve) => {
|
|
let query = `SELECT id FROM books WHERE folder_name = ?`;
|
|
this.db.get(query, [folderName], (err, row) => {
|
|
if (err) {
|
|
resolve(null);
|
|
} else {
|
|
resolve(row ? row.id : null);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Creates the database if it doesn't exist
|
|
createDatabase() {
|
|
// Load DB schema from file and initialize database
|
|
const schema = fs.readFileSync(SCHEMA_PATH, 'utf-8');
|
|
this.db.exec(schema, (err) => {
|
|
if (err) {
|
|
console.error('Error creating database schema:', err.message);
|
|
} else {
|
|
console.log('Database schema created successfully.');
|
|
}
|
|
});
|
|
}
|
|
|
|
// List all books in the database
|
|
loadBooks() {
|
|
return new Promise((resolve, reject) => {
|
|
const query = 'SELECT id, folder_name, display_name, author FROM books ORDER BY display_name';
|
|
this.db.all(query, [], (err, rows) => {
|
|
const books = rows.map(row => ({
|
|
id: row.id,
|
|
name: row.folder_name,
|
|
displayName: row.display_name,
|
|
author: row.author
|
|
}));
|
|
resolve(books);
|
|
});
|
|
});
|
|
}
|
|
|
|
// List all chapters for a specific book
|
|
loadChapters(bookName) {
|
|
return new Promise((resolve, reject) => {
|
|
const query = `
|
|
SELECT c.id, c.chapter_number, c.display_name, c.filename, b.folder_name
|
|
FROM chapters c
|
|
JOIN books b ON c.book_id = b.id
|
|
WHERE b.folder_name = ?
|
|
ORDER BY c.chapter_number
|
|
`;
|
|
this.db.all(query, [bookName], (err, rows) => {
|
|
const chapters = rows.map(row => ({
|
|
id: row.id,
|
|
chapterNumber: row.chapter_number,
|
|
filename: row.filename,
|
|
displayName: row.display_name,
|
|
url: `/pdf/${row.folder_name}/${row.filename}`
|
|
}));
|
|
resolve(chapters);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = PDFDatabaseManager; |