/* XOWA: the XOWA Offline Wiki Application Copyright (C) 2012-2017 gnosygnu@gmail.com XOWA is licensed under the terms of the General Public License (GPL) Version 3, or alternatively under the terms of the Apache License Version 2.0. You may use XOWA according to either of these licenses as is most appropriate for your project on a case-by-case basis. The terms of each license can be found in the source code repository: GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt */ package gplx.xowa.addons.bldrs.updates.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.bldrs.*; import gplx.xowa.addons.bldrs.updates.*; import gplx.core.progs.*; import gplx.dbs.*; import gplx.dbs.cfgs.*; import gplx.xowa.wikis.data.*; import gplx.xowa.bldrs.*; import gplx.xowa.files.fsdb.*; import gplx.fsdb.meta.*; public class Xodel_exec_mgr { public void Exec_delete(Gfo_prog_ui prog_ui, Xob_bldr bldr, Io_url deletion_db_url) { // get domain bry from deletion_conn's cfg_tbl Db_conn deletion_conn = Db_conn_bldr.Instance.Get_or_fail(deletion_db_url); Db_cfg_tbl cfg_tbl = Xowd_cfg_tbl_.Get_or_fail(deletion_conn); byte[] domain_bry = cfg_tbl.Select_bry("", Xodel_exec_mgr.Cfg__deletion_db__domain); // get wiki; init it; do delete Xowe_wiki wiki = bldr.App().Wiki_mgr().Get_by_or_make(domain_bry); wiki.Init_assert(); Delete_by_url(prog_ui, wiki, deletion_conn, cfg_tbl); // cleanup deletion_conn.Rls_conn(); Io_mgr.Instance.DeleteFil(deletion_db_url); } public void Exec_cleanup(Io_url deletion_db_url) { Db_conn deletion_conn = Db_conn_bldr.Instance.Get_or_fail(deletion_db_url); Db_cfg_tbl cfg_tbl = Xowd_cfg_tbl_.Get_or_fail(deletion_conn); cfg_tbl.Delete_val("", Xodel_exec_mgr.Cfg__deletion_db__db_bgn); } private void Delete_by_url(Gfo_prog_ui prog_ui, Xowe_wiki wiki, Db_conn deletion_conn, Db_cfg_tbl cfg_tbl) { // get fsdb_mgr Xof_fsdb_mgr fsdb_mgr = wiki.File_mgr().Fsdb_mgr(); Fsm_mnt_itm mnt_itm = fsdb_mgr.Mnt_mgr().Mnts__get_main(); Db_conn core_conn = mnt_itm.Atr_mgr().Db__core().Conn(); try { core_conn.Env_db_attach("delete_db", deletion_conn); // loop dbs int dbs_len = mnt_itm.Bin_mgr().Dbs__len(); String dbs_len_str = Int_.To_str(dbs_len - Int_.Base1); int db_bgn = cfg_tbl.Select_int_or("", Cfg__deletion_db__db_bgn, 0); for (int i = db_bgn; i < dbs_len; ++i) { if (prog_ui.Prog_notify_and_chk_if_suspended(i, dbs_len)) return; Fsm_bin_fil bin_db = mnt_itm.Bin_mgr().Dbs__get_at(i); Delete_by_db(core_conn, bin_db, dbs_len_str); cfg_tbl.Upsert_int("", Cfg__deletion_db__db_bgn, i + 1); } } finally {core_conn.Env_db_detach("delete_db");} } private void Delete_by_db(Db_conn deletion_conn, Fsm_bin_fil bin_db, String dbs_len_str) { Gfo_usr_dlg usr_dlg = Xoa_app_.Usr_dlg(); // get rows to delete in db List_adp list = List_adp_.New(); int bin_db_id = bin_db.Id(); String bin_db_id_str = Int_.To_str(bin_db_id); usr_dlg.Prog_many("", "", "processing files for deletion in database " + bin_db_id_str + " of " + dbs_len_str); Db_rdr rdr = deletion_conn.Exec_rdr(String_.Concat_lines_nl ( "SELECT ff.fil_id AS item_id" , ", 1 AS item_is_orig" , "FROM fsdb_fil ff" , "JOIN delete_db.delete_regy dr ON ff.fil_id = dr.fil_id AND dr.thm_id = -1" , "WHERE ff.fil_bin_db_id = " + bin_db_id_str , "UNION" , "SELECT ft.thm_id AS item_id" , ", 0 AS item_is_orig" , "FROM fsdb_thm ft" , " JOIN delete_db.delete_regy dr ON ft.thm_owner_id = dr.fil_id AND ft.thm_id = dr.thm_id" , "WHERE ft.thm_bin_db_id = " + bin_db_id_str )); try { while (rdr.Move_next()) { int item_id = rdr.Read_int("item_id"); int item_is_orig = rdr.Read_int("item_is_orig"); list.Add(new Xodel_prune_itm(item_id, item_is_orig == 1)); } } finally {rdr.Rls();} int len = list.Count(); if (len == 0) return; // no files; exit, else will vacuum below deletion_conn.Env_db_attach("bin_db", bin_db.Conn()); deletion_conn.Txn_bgn("img_prune__" + bin_db_id_str); // delete bin Db_stmt delete_bin_stmt = deletion_conn.Stmt_sql("DELETE FROM bin_db.fsdb_bin WHERE bin_owner_id = ?"); for (int i = 0; i < len; ++i) { Xodel_prune_itm itm = (Xodel_prune_itm)list.Get_at(i); delete_bin_stmt.Clear().Crt_int("bin_owner_id", itm.Item_id); delete_bin_stmt.Exec_delete(); if (i % 10000 == 0) usr_dlg.Prog_many("", "", "deleting data in database " + bin_db_id_str + " of " + dbs_len_str); } delete_bin_stmt.Rls(); // delete meta Db_stmt delete_fil_stmt = deletion_conn.Stmt_sql("DELETE FROM fsdb_fil WHERE fil_id = ?"); Db_stmt delete_thm_stmt = deletion_conn.Stmt_sql("DELETE FROM fsdb_thm WHERE thm_id = ?"); for (int i = 0; i < len; ++i) { Xodel_prune_itm itm = (Xodel_prune_itm)list.Get_at(i); if (itm.Item_is_orig) { delete_fil_stmt.Clear().Crt_int("fil_id", itm.Item_id); delete_fil_stmt.Exec_delete(); } else { delete_thm_stmt.Clear().Crt_int("thm_id", itm.Item_id); delete_thm_stmt.Exec_delete(); } if (i % 10000 == 0) usr_dlg.Prog_many("", "", "deleting meta in database " + bin_db_id_str + " of " + dbs_len_str); } delete_fil_stmt.Rls(); delete_thm_stmt.Rls(); // cleanup deletion_conn.Txn_end(); deletion_conn.Env_db_detach("bin_db"); bin_db.Conn().Env_vacuum(); } public static final String Cfg__deletion_db__domain = "file.deletion_db.domain", Cfg__deletion_db__db_bgn = "file.deletion_db.db_bgn"; }