wp-host
Version:
Automated WordPress hosting deployment tool for bulk site creation with MySQL database management
274 lines โข 13.5 kB
JavaScript
;
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