mirror of
https://github.com/Amor-Aprca/WPGSKD.git
synced 2026-09-16 12:01:30 +02:00
155 lines
4.8 KiB
Python
155 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import sqlite3
|
|
import os
|
|
import sys
|
|
|
|
# Add path to import AtomicSQL
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
from wpgskd.core.atomic_sql import AtomicSQL
|
|
|
|
"""
|
|
Merge multiple Key Store DBs into one.
|
|
Correctly handles multi-table structure (one table per service).
|
|
Dynamically handles missing 'title' columns in input DB.
|
|
"""
|
|
|
|
parser = argparse.ArgumentParser(
|
|
"Key Store DB merger",
|
|
description="Script to merge one key store db into another"
|
|
)
|
|
parser.add_argument(
|
|
"-i", "--input",
|
|
help="key store db that will send keys (Source)",
|
|
required=True)
|
|
parser.add_argument(
|
|
"-o", "--output",
|
|
help="key store db that will receive keys (Target)",
|
|
required=True)
|
|
args = parser.parse_args()
|
|
|
|
if not os.path.exists(args.input):
|
|
print(f"Input file not found: {args.input}")
|
|
sys.exit(1)
|
|
|
|
# Ensure output dir exists
|
|
os.makedirs(os.path.dirname(os.path.abspath(args.output)), exist_ok=True)
|
|
|
|
input_db = AtomicSQL()
|
|
input_id = input_db.load(sqlite3.connect(args.input))
|
|
|
|
output_db = AtomicSQL()
|
|
output_id = output_db.load(sqlite3.connect(args.output))
|
|
|
|
# 1. Get all table names from input DB
|
|
tables = input_db.safe_execute(
|
|
input_id,
|
|
lambda db, cursor: cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
|
|
).fetchall()
|
|
|
|
tables = [t[0] for t in tables]
|
|
print(f"Found tables in input DB: {tables}")
|
|
|
|
total_added = 0
|
|
total_updated = 0
|
|
total_skipped = 0
|
|
|
|
for table in tables:
|
|
print(f"\nProcessing table: {table}...")
|
|
|
|
# 2. Ensure table exists in output DB
|
|
# Get columns from input table
|
|
input_cols_info = input_db.safe_execute(
|
|
input_id,
|
|
lambda db, cursor: cursor.execute(f"PRAGMA table_info(`{table}`)")
|
|
).fetchall()
|
|
input_cols = [col[1] for col in input_cols_info]
|
|
|
|
# Check if table exists in output
|
|
out_table_exists = output_db.safe_execute(
|
|
output_id,
|
|
lambda db, cursor: cursor.execute("SELECT count(name) FROM sqlite_master WHERE type='table' AND name=?", [table])
|
|
).fetchone()[0] == 1
|
|
|
|
if not out_table_exists:
|
|
print(f" - Creating table {table} in output DB...")
|
|
output_db.safe_execute(
|
|
output_id,
|
|
lambda db, cursor: cursor.execute(
|
|
f"""
|
|
CREATE TABLE IF NOT EXISTS `{table}` (
|
|
"id" INTEGER NOT NULL UNIQUE,
|
|
"kid" TEXT NOT NULL COLLATE NOCASE,
|
|
"key_" TEXT NOT NULL COLLATE NOCASE,
|
|
"title" TEXT,
|
|
PRIMARY KEY("id" AUTOINCREMENT),
|
|
UNIQUE("kid", "key_")
|
|
);
|
|
"""
|
|
)
|
|
)
|
|
|
|
# 3. Fetch all rows from input table dynamically (handle missing title)
|
|
has_title = "title" in input_cols
|
|
|
|
if has_title:
|
|
select_query = f"SELECT kid, key_, title FROM `{table}`"
|
|
else:
|
|
select_query = f"SELECT kid, key_ FROM `{table}`"
|
|
print(f" - Notice: No 'title' column in source table '{table}', defaulting to None.")
|
|
|
|
rows = input_db.safe_execute(
|
|
input_id,
|
|
lambda db, cursor: cursor.execute(select_query)
|
|
).fetchall()
|
|
|
|
for row in rows:
|
|
kid = row[0]
|
|
key = row[1]
|
|
title = row[2] if has_title else None
|
|
|
|
# Check existence in output
|
|
exists = output_db.safe_execute(
|
|
output_id,
|
|
lambda db, cursor: cursor.execute(
|
|
f"SELECT title FROM `{table}` WHERE kid=? AND key_=?",
|
|
[kid, key]
|
|
)
|
|
).fetchone()
|
|
|
|
if exists:
|
|
# Update title if missing
|
|
current_title = exists[0]
|
|
if title and not current_title:
|
|
output_db.safe_execute(
|
|
output_id,
|
|
lambda db, cursor: cursor.execute(
|
|
f"UPDATE `{table}` SET title=? WHERE kid=? AND key_=?",
|
|
(title, kid, key)
|
|
)
|
|
)
|
|
total_updated += 1
|
|
else:
|
|
total_skipped += 1
|
|
else:
|
|
# Insert
|
|
output_db.safe_execute(
|
|
output_id,
|
|
lambda db, cursor: cursor.execute(
|
|
f"INSERT INTO `{table}` (kid, key_, title) VALUES (?, ?, ?)",
|
|
(kid, key, title)
|
|
)
|
|
)
|
|
total_added += 1
|
|
# print(f" Added {kid}")
|
|
|
|
output_db.commit(output_id)
|
|
|
|
print("\n" + "="*30)
|
|
print(f"Merge Complete!")
|
|
print(f"Added: {total_added}")
|
|
print(f"Updated: {total_updated}")
|
|
print(f"Skipped: {total_skipped}")
|
|
print("="*30)
|