#!/usr/bin/env python3 import sqlite3 import argparse def main(main_db, merged_db): print(f"Merging {merged_db} into {main_db}") connection = sqlite3.connect(main_db) connection.row_factory = sqlite3.Row connection.text_factory = bytes cursor = connection.cursor() cursor.execute("ATTACH ? AS merged_db", (merged_db,)) print("Gathering database statistics:") cursor.execute("SELECT count(*) from merged_db.torrents") total_merged = cursor.fetchone()[0] cursor.execute( "SELECT name FROM pragma_table_info('files') " "WHERE name not in ('id', 'torrent_id')" ) remaining_file_colums = [row[0].decode() for row in cursor] cursor.execute( "SELECT name FROM pragma_table_info('torrents')" "WHERE name not in ('id')" ) remaining_torrent_colums = [row[0].decode() for row in cursor] print(f"{total_merged} torrents to merge.") insert_files_statement = ( f"INSERT INTO files (torrent_id, {','.join(remaining_file_colums)}) " f"SELECT ?, {','.join(remaining_file_colums)} " f"FROM merged_db.files WHERE torrent_id = ?" ) insert_torrents_statement = ( f"INSERT INTO torrents ({','.join(remaining_torrent_colums)})" f"VALUES ({','.join('?' * len(remaining_torrent_colums))})" ) failed_count = 0 cursor.execute("BEGIN") merged = cursor.execute("SELECT * FROM merged_db.torrents") for i, row in enumerate(merged): try: torrent_merge = connection.execute( insert_torrents_statement, (*row[1:],)) # Now merge files connection.execute( insert_files_statement, (torrent_merge.lastrowid, row["id"])) except sqlite3.IntegrityError: failed_count += 1 print("Comitting… ", end="") connection.commit() print("OK." f"{total_merged} torrents processed.", f"{total_merged - failed_count} new torrents added.", sep="\n") connection.close() if __name__ == "__main__": parser = argparse.ArgumentParser(description="Tool to merge magnetico DBs") parser.add_argument("main", type=str, help="main dabatase") parser.add_argument("merge", type=str, help="dabatase to merge into main") args = parser.parse_args() main(args.main, args.merge)