prefix . "wpaw_conversations"; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE IF NOT EXISTS {$table_name} ( id BIGINT AUTO_INCREMENT PRIMARY KEY, session_id VARCHAR(32) NOT NULL UNIQUE, user_id BIGINT NOT NULL, post_id BIGINT DEFAULT 0, title VARCHAR(255) DEFAULT '', focus_keyword VARCHAR(255) DEFAULT '', messages LONGTEXT, context LONGTEXT, status ENUM('active', 'completed', 'archived') DEFAULT 'active', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_user_status (user_id, status), INDEX idx_post_id (post_id), INDEX idx_session_id (session_id) ) {$charset_collate};"; require_once ABSPATH . "wp-admin/includes/upgrade.php"; dbDelta($sql); // Migrate session_id column width for UUID support (UUID v4 is 36 chars vs old MD5 32) $wpdb->query( "ALTER TABLE {$table_name} MODIFY session_id VARCHAR(36) NOT NULL", ); // Store conversation table migration version (don't override main db version) $existing_version = get_option("wpaw_conversations_db_version", "0"); if (version_compare($existing_version, "0.1.4", "<")) { update_option("wpaw_conversations_db_version", "0.1.4"); } } /** * Drop the conversations table (for testing/reset) * * @since 0.1.4 */ function wpaw_drop_conversations_table() { global $wpdb; $table_name = $wpdb->prefix . "wpaw_conversations"; $wpdb->query("DROP TABLE IF EXISTS {$table_name}"); delete_option("wpaw_conversations_db_version"); } /** * Run migrations on plugin activation * * @since 0.1.4 */ function wpaw_run_migrations() { $current_version = get_option("wpaw_conversations_db_version", "0"); if (version_compare($current_version, "0.1.4", "<")) { wpaw_create_conversations_table(); } if (version_compare($current_version, "0.2.0", "<")) { wpaw_add_edit_lock_column(); } } /** * Cleanup old orphaned sessions (cron job) * Archives sessions inactive for 30+ days * * @since 0.1.4 */ function wpaw_cleanup_old_sessions() { global $wpdb; $table_name = $wpdb->prefix . "wpaw_conversations"; // Archive sessions with no post_id and inactive for 30 days $wpdb->query( $wpdb->prepare( "UPDATE {$table_name} SET status = 'archived' WHERE status = 'active' AND post_id = 0 AND updated_at < %s", date("Y-m-d H:i:s", strtotime("-30 days")), ), ); } /** * Add edit_lock column to conversations table. * * @since 0.2.0 */ function wpaw_add_edit_lock_column() { global $wpdb; $table_name = $wpdb->prefix . "wpaw_conversations"; // Check if column already exists (idempotent). $column_exists = $wpdb->get_results( $wpdb->prepare("SHOW COLUMNS FROM {$table_name} LIKE %s", "edit_lock"), ); if (empty($column_exists)) { $wpdb->query( "ALTER TABLE {$table_name} ADD COLUMN edit_lock VARCHAR(64) DEFAULT NULL", ); } update_option("wpaw_conversations_db_version", "0.2.0"); } // Register cron job for cleanup add_action("wpaw_cleanup_old_sessions", "wpaw_cleanup_old_sessions"); if (!wp_next_scheduled("wpaw_cleanup_old_sessions")) { wp_schedule_event(time(), "daily", "wpaw_cleanup_old_sessions"); }