mirror of
https://github.com/Amor-Aprca/WPGSKD.git
synced 2026-10-13 20:02:25 +02:00
150 lines
4.9 KiB
Python
150 lines
4.9 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.utils.AtomicSQL import AtomicSQL
|
|
|
|
"""
|
|
Merge multiple Key Store DBs into one.
|
|
Correctly handles multi-table structure (one table per service).
|
|
"""
|
|
|
|
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
|
|
# We copy the schema from input if it doesn't exist in output
|
|
# But standard vault schema is: id, kid, key_, title
|
|
# To support 'type' column in future, we should check input columns
|
|
|
|
# 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...")
|
|
# Standard creation from vaults.py, but let's try to be dynamic if we want 'type' support later
|
|
# For now, stick to standard schema to ensure compatibility with wpgskd
|
|
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_")
|
|
);
|
|
"""
|
|
)
|
|
)
|
|
# If input has 'type' column, we might want to add it?
|
|
# Let's handle Requirement 2 separately.
|
|
|
|
# 3. Fetch all rows from input table
|
|
rows = input_db.safe_execute(
|
|
input_id,
|
|
lambda db, cursor: cursor.execute(f"SELECT kid, key_, title FROM `{table}`")
|
|
).fetchall()
|
|
|
|
for kid, key, title in rows:
|
|
# 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
|
|
# print(f" Updated {kid}")
|
|
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) |