From 0d98c527c6c64c3e24331a6681ef9bb3de6eddaa Mon Sep 17 00:00:00 2001 From: ske087 Date: Thu, 13 Nov 2025 03:59:27 +0200 Subject: [PATCH] Fix config file parsing and improve backup/restore functionality - Fix external_server.conf parsing to skip comment lines and empty lines - Update routes.py get_db_connection() to handle comments - Update settings.py get_external_db_connection() to handle comments - Improve restore_backup() to use mariadb command instead of Python parsing - Remove SQLite database creation (MariaDB only) - Add environment detection for dump command (mariadb-dump vs mysqldump) - Add conditional SSL flag based on Docker environment - Fix database restore to handle MariaDB sandbox mode comments --- py_app/app/database_backup.py | 74 ++++++++++--------- .../setup_complete_database.py | 20 ++--- py_app/app/routes.py | 9 ++- py_app/app/settings.py | 18 ++++- 4 files changed, 72 insertions(+), 49 deletions(-) diff --git a/py_app/app/database_backup.py b/py_app/app/database_backup.py index 2b9f9d0..3d8883d 100644 --- a/py_app/app/database_backup.py +++ b/py_app/app/database_backup.py @@ -415,7 +415,7 @@ class DatabaseBackupManager: def restore_backup(self, filename): """ - Restore database from a backup file + Restore database from a backup file using mariadb command Args: filename (str): Name of the backup file to restore @@ -439,43 +439,51 @@ class DatabaseBackupManager: 'message': 'Backup file not found' } - # Read SQL file and execute using Python mariadb library - import mariadb - + # Use mariadb command to restore (more reliable than Python parsing) + # First, read the file and skip problematic first line if needed with open(file_path, 'r') as f: sql_content = f.read() - # Connect to database - conn = mariadb.connect( - user=self.config['user'], - password=self.config['password'], - host=self.config['host'], - port=int(self.config['port']), - database=self.config['database'] + # Remove problematic MariaDB sandbox mode comment from first line + lines = sql_content.split('\n') + if lines and lines[0].startswith('/*M!999999'): + sql_content = '\n'.join(lines[1:]) + + # Build mariadb restore command + cmd = [ + 'mariadb', + f"--host={self.config['host']}", + f"--port={self.config['port']}", + f"--user={self.config['user']}", + f"--password={self.config['password']}", + ] + + # Add SSL args if needed (Docker environment) + cmd.extend(self._get_ssl_args()) + + # Add database name + cmd.append(self.config['database']) + + # Execute restore with stdin + result = subprocess.run( + cmd, + input=sql_content, + capture_output=True, + text=True ) - cursor = conn.cursor() - - # Split SQL into statements and execute - statements = sql_content.split(';') - executed = 0 - - for statement in statements: - statement = statement.strip() - if statement: - try: - cursor.execute(statement) - executed += 1 - except Exception as stmt_error: - print(f"Warning executing statement: {stmt_error}") - - conn.commit() - conn.close() - - return { - 'success': True, - 'message': f'Database restored successfully from {filename} ({executed} statements executed)' - } + if result.returncode == 0: + return { + 'success': True, + 'message': f'Database restored successfully from {filename}' + } + else: + error_msg = result.stderr + print(f"Restore error: {error_msg}") + return { + 'success': False, + 'message': f'Restore failed: {error_msg}' + } except Exception as e: print(f"Exception during restore: {e}") diff --git a/py_app/app/db_create_scripts/setup_complete_database.py b/py_app/app/db_create_scripts/setup_complete_database.py index f3ca639..eaaeaf4 100755 --- a/py_app/app/db_create_scripts/setup_complete_database.py +++ b/py_app/app/db_create_scripts/setup_complete_database.py @@ -680,14 +680,14 @@ def verify_database_setup(): cursor.close() conn.close() - # Check SQLite database - instance_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../instance')) - sqlite_path = os.path.join(instance_folder, 'users.db') - - if os.path.exists(sqlite_path): - print_success("SQLite database 'users.db' exists") - else: - print_error("SQLite database 'users.db' missing") + # SQLite check disabled - using MariaDB only + # instance_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../instance')) + # sqlite_path = os.path.join(instance_folder, 'users.db') + # + # if os.path.exists(sqlite_path): + # print_success("SQLite database 'users.db' exists") + # else: + # print_error("SQLite database 'users.db' missing") return True @@ -707,7 +707,7 @@ def main(): create_warehouse_locations_table, create_permissions_tables, create_users_table_mariadb, - create_sqlite_tables, + # create_sqlite_tables, # Disabled - using MariaDB only create_database_triggers, populate_permissions_data, update_external_config, @@ -731,7 +731,7 @@ def main(): print(f"šŸ“… Completed at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print("\nšŸ“‹ Setup Summary:") print(" • MariaDB tables created with triggers") - print(" • SQLite user database initialized") + print(" • MariaDB users table initialized") print(" • Permissions system fully configured") print(" • Default superadmin user created (username: superadmin, password: superadmin123)") print(" • Configuration files updated") diff --git a/py_app/app/routes.py b/py_app/app/routes.py index 7dc34f5..f9ec80c 100755 --- a/py_app/app/routes.py +++ b/py_app/app/routes.py @@ -169,8 +169,13 @@ def get_db_connection(): settings = {} with open(settings_file, 'r') as f: for line in f: - key, value = line.strip().split('=', 1) - settings[key] = value + line = line.strip() + # Skip empty lines and comments + if not line or line.startswith('#'): + continue + if '=' in line: + key, value = line.split('=', 1) + settings[key] = value # Create a database connection return mariadb.connect( diff --git a/py_app/app/settings.py b/py_app/app/settings.py index a62ce5d..105311d 100755 --- a/py_app/app/settings.py +++ b/py_app/app/settings.py @@ -214,8 +214,13 @@ def settings_handler(): if os.path.exists(settings_file): with open(settings_file, 'r') as f: for line in f: - key, value = line.strip().split('=', 1) - external_settings[key] = value + line = line.strip() + # Skip empty lines and comments + if not line or line.startswith('#'): + continue + if '=' in line: + key, value = line.split('=', 1) + external_settings[key] = value return render_template('settings.html', users=users, external_settings=external_settings, current_user={'role': session.get('role', '')}) @@ -230,8 +235,13 @@ def get_external_db_connection(): settings = {} with open(settings_file, 'r') as f: for line in f: - key, value = line.strip().split('=', 1) - settings[key] = value + line = line.strip() + # Skip empty lines and comments + if not line or line.startswith('#'): + continue + if '=' in line: + key, value = line.split('=', 1) + settings[key] = value # Create a database connection return mariadb.connect(