UNPKG

wp-host

Version:

Automated WordPress hosting deployment tool for bulk site creation with MySQL database management

274 lines โ€ข 13.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DatabaseManager = void 0; const mysql_manager_1 = require("./mysql-manager"); class DatabaseManager { constructor(config) { this.config = config; this.mysqlManager = new mysql_manager_1.MySQLManager(config.mysql); } /** * Initialize database manager and establish MySQL connection */ async initialize() { console.log("๐Ÿ—„๏ธ Initializing Database Manager..."); await this.mysqlManager.connect(); // Get and display server information const serverInfo = await this.mysqlManager.getServerInfo(); console.log(`โœ… Connected to MySQL ${serverInfo.version} at ${serverInfo.host}:${serverInfo.port}`); } /** * Create databases and users for all sites in the configuration */ async createAllDatabases(useExisting = true) { console.log(`\n๐Ÿš€ Starting database ${useExisting ? "setup" : "creation"} for ${this.config.sites.length} site(s)...`); if (useExisting) { console.log("โœ… Safe mode: Existing databases will be preserved"); console.log("โ„น๏ธ Use --force-recreate to drop and recreate databases"); } else { console.log("๐Ÿ”ฅ Destructive mode: Databases will be dropped and recreated"); } const results = []; for (let i = 0; i < this.config.sites.length; i++) { const site = this.config.sites[i]; console.log(`\n๐Ÿ“ฆ [${i + 1}/${this.config.sites.length}] Processing: ${site.site_name}`); try { const result = await this.createSiteDatabase(site, useExisting); results.push(result); if (result.status === "success") { console.log(`โœ… ${site.site_name}: Database setup completed successfully`); } else { console.log(`โš ๏ธ ${site.site_name}: Database setup completed with warnings`); } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(`โŒ ${site.site_name}: Database setup failed - ${errorMessage}`); results.push({ site_name: site.site_name, status: "failed", errors: [errorMessage], }); } } return results; } /** * Create database and user for a single site */ async createSiteDatabase(site, useExisting = false) { const databaseName = site.database_name; // Auto-generated by config parser const username = site.db_user; // Auto-generated by config parser const isUsingRoot = username === this.config.mysql.rootUser; const password = isUsingRoot ? this.config.mysql.rootPassword : this.config.mysql.sharedDbPassword; try { if (isUsingRoot) { // When using root, only create/manage the database, not the user if (useExisting) { // Just check if database exists, create if not const dbExists = await this.mysqlManager.databaseExists(databaseName); if (!dbExists) { await this.mysqlManager.executeQuery(`CREATE DATABASE \`${databaseName}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`); console.log(` โœ… Database ${databaseName} created (new)`); } else { console.log(` โœ… Database ${databaseName} exists - using existing data (safe mode)`); console.log(` โ„น๏ธ Your existing data is preserved and untouched`); } } else { // Drop and recreate database only (root user already exists) console.log(` ๐Ÿ”ฅ Dropping database ${databaseName} (destructive mode)...`); await this.mysqlManager.executeQuery(`DROP DATABASE IF EXISTS \`${databaseName}\``); await this.mysqlManager.executeQuery(`CREATE DATABASE \`${databaseName}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`); console.log(` โœ… Database ${databaseName} recreated fresh (all previous data deleted)`); } } else { // Standard isolated user approach if (useExisting) { // Use existing database or create if it doesn't exist await this.mysqlManager.createOrUseDatabase(databaseName, username, password, "localhost"); } else { // Use clean slate approach: drop and recreate everything fresh await this.mysqlManager.createDatabaseAndUserClean(databaseName, username, password, "localhost"); } } // Test the connection const connectionTest = await this.mysqlManager.testDatabaseConnection(username, password, databaseName, "localhost"); if (!connectionTest) { throw new Error("Database connection test failed after creation"); } return { site_name: site.site_name, status: "success", database_info: { database_name: databaseName, username: username, password: password, host: this.config.mysql.host, port: this.config.mysql.port, }, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); throw new Error(`Database ${useExisting ? "setup" : "creation"} failed: ${errorMessage}`); } } /** * Check if database and user already exist for a site */ async checkSiteDatabase(site) { const databaseName = site.database_name; const username = site.db_user; const password = this.config.mysql.sharedDbPassword; try { const databaseExists = await this.mysqlManager.databaseExists(databaseName); const userExists = await this.mysqlManager.userExists(username, "localhost"); let canConnect = false; if (databaseExists && userExists) { canConnect = await this.mysqlManager.testDatabaseConnection(username, password, databaseName, "localhost"); } return { databaseExists, userExists, canConnect }; } catch (error) { console.error(`Error checking site database: ${error instanceof Error ? error.message : String(error)}`); return { databaseExists: false, userExists: false, canConnect: false }; } } /** * Generate database creation report */ async generateReport() { console.log("\n๐Ÿ“Š Database Status Report"); console.log("========================"); for (let i = 0; i < this.config.sites.length; i++) { const site = this.config.sites[i]; console.log(`\n${i + 1}. ${site.site_name}`); try { const status = await this.checkSiteDatabase(site); console.log(` Database (${site.database_name}): ${status.databaseExists ? "โœ… Exists" : "โŒ Missing"}`); console.log(` User (${site.db_user}@localhost): ${status.userExists ? "โœ… Exists" : "โŒ Missing"}`); console.log(` Connection Test: ${status.canConnect ? "โœ… Success" : "โŒ Failed"}`); if (status.databaseExists && status.userExists && status.canConnect) { console.log(` Status: ๐ŸŸข Ready for WordPress`); } else if (status.databaseExists || status.userExists) { console.log(` Status: ๐ŸŸก Partially configured`); } else { console.log(` Status: ๐Ÿ”ด Not configured`); } } catch (error) { console.log(` Status: โŒ Error checking status`); console.log(` Error: ${error instanceof Error ? error.message : String(error)}`); } } } /** * Reset WordPress tables in all databases (keeps databases and users intact) * This is safer than full cleanup as it only removes WordPress data */ async resetWordPressTables() { console.log("\n๐Ÿ”„ Resetting WordPress tables in all databases..."); console.log("โš ๏ธ WARNING: This will delete all WordPress data but keep databases and users!"); for (const site of this.config.sites) { const databaseName = site.database_name; try { console.log(`\n๐Ÿ—‘๏ธ Resetting WordPress tables for ${site.site_name}:`); // Check if database exists const dbExists = await this.mysqlManager.databaseExists(databaseName); if (!dbExists) { console.log(` โ„น๏ธ Database ${databaseName} doesn't exist, skipping`); continue; } // Connect to the specific database const mysql = require("mysql2/promise"); const connection = await mysql.createConnection({ host: this.config.mysql.host, port: this.config.mysql.port, user: this.config.mysql.rootUser, password: this.config.mysql.rootPassword, database: databaseName, }); // Get all tables that start with 'wp_' const [tables] = await connection.execute("SHOW TABLES LIKE 'wp_%'"); if (Array.isArray(tables) && tables.length > 0) { console.log(` ๐Ÿ“Š Found ${tables.length} WordPress tables to remove`); // Disable foreign key checks to avoid dependency issues await connection.execute("SET FOREIGN_KEY_CHECKS = 0"); // Drop each WordPress table for (const tableRow of tables) { const tableName = Object.values(tableRow)[0]; await connection.execute(`DROP TABLE IF EXISTS \`${tableName}\``); console.log(` โœ… Dropped table: ${tableName}`); } // Re-enable foreign key checks await connection.execute("SET FOREIGN_KEY_CHECKS = 1"); console.log(` โœ… All WordPress tables removed from ${databaseName}`); } else { console.log(` โ„น๏ธ No WordPress tables found in ${databaseName}`); } await connection.end(); } catch (error) { console.error(` โŒ Error resetting ${site.site_name}: ${error instanceof Error ? error.message : String(error)}`); } } console.log("\nโœ… WordPress table reset completed."); } /** * Clean up (remove) databases and users for all sites * WARNING: This will delete all data! */ async cleanupAllDatabases() { console.log("\n๐Ÿงน Cleaning up databases and users..."); console.log("โš ๏ธ WARNING: This will permanently delete all databases and users!"); for (const site of this.config.sites) { const databaseName = site.database_name; const username = site.db_user; try { console.log(`\n๐Ÿ—‘๏ธ Cleaning up ${site.site_name}:`); // Drop database if it exists - using IF EXISTS to avoid errors await this.mysqlManager.executeQuery(`DROP DATABASE IF EXISTS \`${databaseName}\``); console.log(` โœ… Database ${databaseName} dropped (if it existed)`); // Drop user if it exists - using IF EXISTS to avoid errors await this.mysqlManager.executeQuery(`DROP USER IF EXISTS \`${username}\`@\`localhost\``); console.log(` โœ… User ${username}@localhost dropped (if it existed)`); } catch (error) { console.error(` โŒ Error cleaning up ${site.site_name}: ${error instanceof Error ? error.message : String(error)}`); } } // Flush privileges after cleanup await this.mysqlManager.executeQuery("FLUSH PRIVILEGES"); console.log("\nโœ… Cleanup completed. Privileges flushed."); } /** * Close database manager and disconnect from MySQL */ async close() { await this.mysqlManager.disconnect(); console.log("โœ… Database Manager closed"); } /** * Get database creation summary */ getSummary(results) { const total = results.length; const successful = results.filter((r) => r.status === "success").length; const failed = results.filter((r) => r.status === "failed").length; const skipped = results.filter((r) => r.status === "skipped").length; return { total, successful, failed, skipped }; } } exports.DatabaseManager = DatabaseManager; //# sourceMappingURL=database-manager.js.map