mirror of https://github.com/gnosygnu/xowa
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
414 lines
20 KiB
414 lines
20 KiB
/*
|
|
XOWA: the XOWA Offline Wiki Application
|
|
Copyright (C) 2012-2020 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.wikis.data.tbls; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.data.*;
|
|
import gplx.core.primitives.*; import gplx.core.criterias.*;
|
|
import gplx.dbs.*; import gplx.xowa.*; import gplx.xowa.wikis.dbs.*; import gplx.dbs.qrys.*;
|
|
import gplx.xowa.wikis.nss.*;
|
|
public class Xowd_page_tbl implements Db_tbl {
|
|
private final Object thread_lock = new Object();
|
|
public final boolean schema_is_1;
|
|
private String fld_id, fld_ns, fld_title, fld_is_redirect, fld_touched, fld_len, fld_random_int, fld_score, fld_text_db_id, fld_html_db_id, fld_redirect_id, fld_cat_db_id;
|
|
private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
|
|
private Db_stmt stmt_select_all_by_ttl, stmt_select_all_by_id, stmt_select_id_by_ttl, stmt_insert;
|
|
private final String[] flds_select_all, flds_select_idx;
|
|
public Xowd_page_tbl(Db_conn conn, boolean schema_is_1) {
|
|
this.conn = conn; this.schema_is_1 = schema_is_1;
|
|
String fld_text_db_id_name = "";
|
|
String fld_cat_db_id_name = Dbmeta_fld_itm.Key_null;
|
|
if (schema_is_1) {fld_text_db_id_name = "page_file_idx";}
|
|
else {
|
|
fld_text_db_id_name = "page_text_db_id";
|
|
if (conn.Meta_fld_exists(tbl_name, "page_cat_db_id"))
|
|
fld_cat_db_id_name = "page_cat_db_id";
|
|
}
|
|
fld_id = flds.Add_int_pkey("page_id"); // int(10); unsigned -- MW:same
|
|
fld_ns = flds.Add_int("page_namespace"); // int(11); -- MW:same
|
|
fld_title = flds.Add_str("page_title", 255); // varbinary(255); -- MW:blob
|
|
fld_is_redirect = flds.Add_int("page_is_redirect"); // tinyint(3); -- MW:same
|
|
fld_touched = flds.Add_str("page_touched", 14); // binary(14); -- MW:blob; NOTE: should be revision!rev_timestamp, but needs extra join
|
|
fld_len = flds.Add_int("page_len"); // int(10); unsigned -- MW:same except NULL REF: WikiPage.php!updateRevisionOn;"
|
|
fld_random_int = flds.Add_int("page_random_int"); // MW:XOWA
|
|
fld_text_db_id = flds.Add_int(fld_text_db_id_name); // MW:XOWA
|
|
fld_html_db_id = flds.Add_int_dflt("page_html_db_id", -1); // MW:XOWA
|
|
fld_redirect_id = flds.Add_int_dflt("page_redirect_id", -1); // MW:XOWA
|
|
fld_score = flds.Add_int_dflt(Fld__page_score__key, -1); // MW:XOWA
|
|
if (fld_cat_db_id_name != Dbmeta_fld_itm.Key_null)
|
|
fld_cat_db_id = flds.Add_int_dflt(fld_cat_db_id_name, -1);// MW:XOWA
|
|
flds_select_all = String_.Ary_wo_null(fld_id, fld_ns, fld_title, fld_touched, fld_is_redirect, fld_len, fld_random_int, fld_text_db_id, fld_html_db_id, fld_redirect_id, fld_score, fld_cat_db_id);
|
|
flds_select_idx = String_.Ary_wo_null(fld_ns, fld_title, fld_id, fld_len, fld_score);
|
|
conn.Rls_reg(this);
|
|
}
|
|
public Db_conn Conn() {return conn;} private final Db_conn conn;
|
|
public String Tbl_name() {return tbl_name;} private final String tbl_name = TBL_NAME;
|
|
public Dbmeta_fld_list Flds__all() {return flds;}
|
|
public String Fld_page_id() {return fld_id;}
|
|
public String Fld_page_ns() {return fld_ns;}
|
|
public String Fld_page_title() {return fld_title;}
|
|
public String Fld_page_len() {return fld_len;}
|
|
public String Fld_page_score() {return fld_score;} public static final String Fld__page_score__key = "page_score";
|
|
public String Fld_text_db_id() {return fld_text_db_id;}
|
|
public String Fld_html_db_id() {return fld_html_db_id;}
|
|
public String Fld_is_redirect() {return fld_is_redirect;}
|
|
public String Fld_random_int() {return fld_random_int;}
|
|
public String Fld_modified_on() {return fld_touched;}
|
|
public String Fld_redirect_id() {return fld_redirect_id;}
|
|
public String[] Flds_select_idx() {return flds_select_idx;}
|
|
public String[] Flds_select_all() {return flds_select_all;}
|
|
public void Flds__assert() {
|
|
conn.Meta_fld_assert(tbl_name, this.Fld_html_db_id() , Dbmeta_fld_tid.Itm__int, -1);
|
|
conn.Meta_fld_assert(tbl_name, this.Fld_redirect_id() , Dbmeta_fld_tid.Itm__int, -1);
|
|
conn.Meta_fld_assert(tbl_name, Fld__page_score__key , Dbmeta_fld_tid.Itm__int, -1);
|
|
}
|
|
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds.To_fld_ary()));}
|
|
public void Insert(int page_id, int ns_id, byte[] ttl_wo_ns, boolean page_is_redirect, DateAdp modified_on, int page_len, int random_int, int text_db_id, int html_db_id) {
|
|
this.Insert_bgn();
|
|
this.Insert_cmd_by_batch(page_id, ns_id, ttl_wo_ns, page_is_redirect, modified_on, page_len, random_int, text_db_id, html_db_id, -1);
|
|
this.Insert_end();
|
|
}
|
|
public void Insert_bgn() {conn.Txn_bgn("page__insert_bulk"); stmt_insert = conn.Stmt_insert(tbl_name, flds);}
|
|
public void Insert_end() {conn.Txn_end(); stmt_insert = Db_stmt_.Rls(stmt_insert);}
|
|
public void Insert_cmd_by_batch
|
|
(int page_id, int ns_id, byte[] ttl_wo_ns, boolean page_is_redirect, DateAdp modified_on, int page_len, int random_int
|
|
, int text_db_id, int html_db_id, int cat_db_id) {
|
|
stmt_insert.Clear()
|
|
.Val_int(fld_id, page_id)
|
|
.Val_int(fld_ns, ns_id)
|
|
.Val_bry_as_str(fld_title, ttl_wo_ns)
|
|
.Val_bool_as_byte(fld_is_redirect, page_is_redirect)
|
|
.Val_str(fld_touched, modified_on.XtoStr_fmt(Page_touched_fmt))
|
|
.Val_int(fld_len, page_len)
|
|
.Val_int(fld_random_int, random_int)
|
|
.Val_int(fld_text_db_id, text_db_id)
|
|
.Val_int(fld_html_db_id, html_db_id)
|
|
.Val_int(fld_redirect_id, -1)
|
|
.Val_int(fld_score, -1)
|
|
.Val_int(fld_cat_db_id, cat_db_id)
|
|
.Exec_insert();
|
|
}
|
|
public void Insert_by_itm(Db_stmt stmt, Xowd_page_itm itm, int html_db_id) {
|
|
stmt.Clear()
|
|
.Val_int (fld_id , itm.Id())
|
|
.Val_int (fld_ns , itm.Ns_id())
|
|
.Val_bry_as_str (fld_title , itm.Ttl_page_db())
|
|
.Val_bool_as_byte (fld_is_redirect , itm.Redirected())
|
|
.Val_str (fld_touched , itm.Modified_on().XtoStr_fmt(Xowd_page_tbl.Page_touched_fmt))
|
|
.Val_int (fld_len , itm.Text_len())
|
|
.Val_int (fld_random_int , itm.Random_int())
|
|
.Val_int (fld_text_db_id , itm.Text_db_id())
|
|
.Val_int (fld_html_db_id , html_db_id)
|
|
.Val_int (fld_redirect_id , itm.Redirect_id())
|
|
.Val_int (fld_score , itm.Score())
|
|
.Val_int (fld_cat_db_id , -1)
|
|
.Exec_insert();
|
|
}
|
|
public Xowd_page_itm Select_by_ttl_as_itm_or_null(Xoa_ttl ttl) {
|
|
Xowd_page_itm rv = new Xowd_page_itm();
|
|
return Select_by_ttl(rv, ttl) ? rv : null;
|
|
}
|
|
public boolean Select_by_ttl(Xowd_page_itm rv, Xoa_ttl ttl) {return Select_by_ttl(rv, ttl.Ns(), ttl.Page_db());}
|
|
public boolean Select_by_ttl(Xowd_page_itm rv, Xow_ns ns, byte[] ttl) {
|
|
if (stmt_select_all_by_ttl == null) stmt_select_all_by_ttl = conn.Stmt_select(tbl_name, flds, String_.Ary(fld_ns, fld_title));
|
|
synchronized (thread_lock) { // LOCK:stmt-rls; DATE:2016-07-06
|
|
Db_rdr rdr = stmt_select_all_by_ttl.Clear().Crt_int(fld_ns, ns.Id()).Crt_bry_as_str(fld_title, ttl).Exec_select__rls_manual();
|
|
try {
|
|
if (rdr.Move_next()) {
|
|
Read_page__all(rv, rdr);
|
|
return true;
|
|
}
|
|
}
|
|
finally {rdr.Rls();}
|
|
return false;
|
|
}
|
|
}
|
|
public Xowd_page_itm Select_by_id_or_null(int page_id) {
|
|
Xowd_page_itm rv = new Xowd_page_itm();
|
|
boolean exists = Select_by_id(rv, page_id);
|
|
return exists ? rv : null;
|
|
}
|
|
public boolean Select_by_id(Xowd_page_itm rv, int page_id) {
|
|
if (stmt_select_all_by_id == null) stmt_select_all_by_id = conn.Stmt_select(tbl_name, flds_select_all, fld_id);
|
|
Db_rdr rdr = stmt_select_all_by_id.Clear().Crt_int(fld_id, page_id).Exec_select__rls_manual();
|
|
try {
|
|
if (rdr.Move_next()) {
|
|
Read_page__all(rv, rdr);
|
|
return true;
|
|
}
|
|
}
|
|
finally {rdr.Rls();}
|
|
return false;
|
|
}
|
|
public Db_rdr Select_all__id__ttl() {
|
|
Db_qry__select_cmd qry = new Db_qry__select_cmd().From_(tbl_name).Cols_(fld_id, fld_title).Order_asc_(fld_id);
|
|
return conn.Stmt_new(qry).Exec_select__rls_auto();
|
|
}
|
|
public int Select_id(int ns_id, byte[] ttl) {
|
|
if (stmt_select_id_by_ttl == null) stmt_select_id_by_ttl = conn.Stmt_select(tbl_name, flds_select_all, fld_ns, fld_title);
|
|
Db_rdr rdr = stmt_select_id_by_ttl.Clear().Crt_int(fld_ns, ns_id).Crt_bry_as_str(fld_title, ttl).Exec_select__rls_manual();
|
|
try {
|
|
return rdr.Move_next() ? rdr.Read_int(fld_id) : Xowd_page_itm.Id_null;
|
|
} finally {rdr.Rls();}
|
|
}
|
|
public void Select_in__id(Select_in_cbk cbk) {
|
|
int pos = 0;
|
|
Bry_bfr bfr = Bry_bfr_.New();
|
|
Select_in_wkr wkr = Select_in_wkr.New(bfr, tbl_name, Flds_select_all(), fld_id);
|
|
while (true) {
|
|
pos = wkr.Make_sql_or_null(bfr, cbk, pos);
|
|
if (pos == -1) break;
|
|
Db_rdr rdr = conn.Stmt_sql(bfr.To_str_and_clear()).Exec_select__rls_auto();
|
|
try {
|
|
while (rdr.Move_next())
|
|
cbk.Read_data(rdr);
|
|
} finally {rdr.Rls();}
|
|
}
|
|
}
|
|
public void Select_in__ttl(Cancelable cancelable, Ordered_hash rv, int ns_id, int bgn, int end) {
|
|
Xowd_page_tbl__ttl wkr = new Xowd_page_tbl__ttl();
|
|
wkr.Ctor(this, tbl_name, fld_title);
|
|
wkr.Init(rv, ns_id);
|
|
wkr.Select_in(cancelable, conn, bgn, end);
|
|
}
|
|
public void Select_in__ns_ttl(Cancelable cancelable, Ordered_hash rv, Xow_ns_mgr ns_mgr, boolean fill_idx_fields_only, int bgn, int end) {
|
|
Xowd_page_tbl__ttl_ns wkr = new Xowd_page_tbl__ttl_ns();
|
|
wkr.Fill_idx_fields_only_(fill_idx_fields_only);
|
|
wkr.Ctor(this, tbl_name, fld_title);
|
|
wkr.Init(this, ns_mgr, rv);
|
|
wkr.Select_in(cancelable, conn, bgn, end);
|
|
}
|
|
public boolean Select_in__id(Cancelable cancelable, boolean show_progress, List_adp rv) {return Select_in__id(cancelable, false, show_progress, rv, 0, rv.Count());}
|
|
public boolean Select_in__id(Cancelable cancelable, boolean skip_table_read, boolean show_progress, List_adp rv, int bgn, int end) {
|
|
Xowd_page_itm[] page_ary = (Xowd_page_itm[])rv.To_ary(Xowd_page_itm.class);
|
|
int len = page_ary.length; if (len == 0) return false;
|
|
Ordered_hash hash = Ordered_hash_.New();
|
|
for (int i = 0; i < len; i++) {
|
|
if (cancelable.Canceled()) return false;
|
|
Xowd_page_itm p = page_ary[i];
|
|
if (!hash.Has(p.Id_val())) // NOTE: must check if file already exists b/c dynamicPageList currently allows dupes; DATE:2013-07-22
|
|
hash.Add(p.Id_val(), p);
|
|
}
|
|
hash.Sort_by(Xowd_page_itm_sorter.IdAsc); // sort by ID to reduce disk thrashing; DATE:2015-03-31
|
|
Xowd_page_tbl__id wkr = new Xowd_page_tbl__id(rv, hash, show_progress);
|
|
wkr.Ctor(this, tbl_name, fld_id);
|
|
wkr.Select_in(cancelable, conn, bgn, end);
|
|
return true;
|
|
}
|
|
public byte[] Select_random(Xow_ns ns) {// ns should be ns_main
|
|
int random_int = RandomAdp_.new_().Next(ns.Count());
|
|
Db_rdr rdr = conn.Stmt_select(tbl_name, String_.Ary(fld_title), fld_random_int, fld_ns)
|
|
.Crt_int(fld_random_int, random_int).Crt_int(fld_ns, ns.Id())
|
|
.Exec_select__rls_auto();
|
|
try {return rdr.Move_next() ? rdr.Read_bry_by_str(fld_title) : null;}
|
|
finally {rdr.Rls();}
|
|
}
|
|
public void Select_by_search(Cancelable cancelable, List_adp rv, byte[] search, int results_max) {
|
|
if (Bry_.Len_eq_0(search)) return; // do not allow empty search
|
|
Criteria crt = Criteria_.And_many(Db_crt_.New_eq(fld_ns, Xow_ns_.Tid__main), Db_crt_.New_like(fld_title, ""));
|
|
Db_qry__select_cmd qry = Db_qry_.select_().From_(tbl_name).Cols_(fld_id, fld_len, fld_ns, fld_title).Where_(crt); // NOTE: use fields from main index only
|
|
search = Bry_.Replace(search, Byte_ascii.Star, Byte_ascii.Percent);
|
|
Db_rdr rdr = conn.Stmt_new(qry).Clear().Crt_int(fld_ns, Xow_ns_.Tid__main).Val_bry_as_str(fld_title, search).Exec_select__rls_auto();
|
|
try {
|
|
while (rdr.Move_next()) {
|
|
if (cancelable.Canceled()) return;
|
|
Xowd_page_itm page = new Xowd_page_itm();
|
|
this.Read_page__idx(page, rdr);
|
|
rv.Add(page);
|
|
}
|
|
} finally {rdr.Rls();}
|
|
}
|
|
public void Select_for_search_suggest(Cancelable cancelable, List_adp rslt_list, Xow_ns ns, byte[] key, int max_results, int min_page_len, int browse_len, boolean include_redirects, boolean fetch_prv_item) {
|
|
String search_bgn = String_.new_u8(key);
|
|
String search_end = String_.new_u8(gplx.core.intls.Utf8_.Increment_char_at_last_pos(key));
|
|
String sql = String_.Format
|
|
( "SELECT {0}, {1}, {2}, {3} FROM {4} INDEXED BY {4}__title WHERE {1} = {5} AND {2} BETWEEN '{6}' AND '{7}' ORDER BY {3} DESC LIMIT {8};"
|
|
, fld_id, fld_ns, fld_title, fld_len
|
|
, tbl_name
|
|
, Int_.To_str(ns.Id()), search_bgn, search_end, Int_.To_str(max_results)
|
|
);
|
|
Db_qry qry = Db_qry_sql.rdr_(sql);
|
|
Db_rdr rdr = conn.Stmt_new(qry).Exec_select__rls_auto();
|
|
try {
|
|
while (rdr.Move_next()) {
|
|
if (cancelable.Canceled()) return;
|
|
Xowd_page_itm page = new Xowd_page_itm();
|
|
Read_page__idx(page, rdr);
|
|
rslt_list.Add(page);
|
|
}
|
|
rslt_list.Sort_by(Xowd_page_itm_sorter.TitleAsc);
|
|
}
|
|
finally {rdr.Rls();}
|
|
}
|
|
public int Select_count_all() {return conn.Exec_select_count_as_int(tbl_name, -1);}
|
|
private Db_rdr Load_ttls_starting_with_rdr(int ns_id, byte[] ttl_frag, boolean include_redirects, int max_results, int min_page_len, int browse_len, boolean fwd, boolean search_suggest) {
|
|
String ttl_frag_str = String_.new_u8(ttl_frag);
|
|
Criteria crt_ttl = fwd ? Db_crt_.New_mte(fld_title, ttl_frag_str) : Db_crt_.New_lt(fld_title, ttl_frag_str);
|
|
Criteria crt = Criteria_.And_many(Db_crt_.New_eq(fld_ns, ns_id), crt_ttl, Db_crt_.New_mte(fld_len, (Integer)min_page_len));
|
|
if (!include_redirects)
|
|
crt = Criteria_.And(crt, Db_crt_.New_eq(fld_is_redirect, Byte_.Zero));
|
|
String[] cols = search_suggest
|
|
? flds_select_idx
|
|
: flds_select_all
|
|
;
|
|
int limit = fwd ? max_results + 1 : max_results; // + 1 to get next item
|
|
Db_qry__select_cmd qry = Db_qry_.select_cols_(tbl_name, crt, cols).Limit_(limit).Order_(fld_title, fwd);
|
|
Db_stmt stmt = conn.Stmt_new(qry).Crt_int(fld_ns, ns_id).Crt_str(fld_title, ttl_frag_str).Crt_int(fld_len, min_page_len);
|
|
if (!include_redirects)
|
|
stmt.Crt_bool_as_byte(fld_is_redirect, include_redirects);
|
|
return stmt.Exec_select__rls_auto();
|
|
}
|
|
public void Select_for_special_all_pages(Cancelable cancelable, List_adp rslt_list, Xowd_page_itm rslt_nxt, Xowd_page_itm rslt_prv, Int_obj_ref rslt_count, Xow_ns ns, byte[] key, int max_results, int min_page_len, int browse_len, boolean include_redirects, boolean fetch_prv_item) {
|
|
Xowd_page_itm nxt_itm = null;
|
|
int rslt_idx = 0;
|
|
boolean max_val_check = max_results == Int_.Max_value;
|
|
Db_rdr rdr = Load_ttls_starting_with_rdr(ns.Id(), key, include_redirects, max_results, min_page_len, browse_len, true, true);
|
|
try {
|
|
while (rdr.Move_next()) {
|
|
if (cancelable.Canceled()) return;
|
|
Xowd_page_itm page = new Xowd_page_itm();
|
|
Read_page__idx(page, rdr);
|
|
if (max_val_check && !Bry_.Has_at_bgn(page.Ttl_page_db(), key)) break;
|
|
nxt_itm = page;
|
|
if (rslt_idx == max_results) {} // last item which is not meant for rslts, but only for nxt itm
|
|
else {
|
|
rslt_list.Add(page);
|
|
++rslt_idx;
|
|
}
|
|
}
|
|
if (rslt_nxt != null && nxt_itm != null) // occurs when range is empty; EX: "Module:A" in simplewikibooks
|
|
rslt_nxt.Copy(nxt_itm);
|
|
if (fetch_prv_item) { // NOTE: Special:AllPages passes in true, but Search_suggest passes in false
|
|
if (cancelable.Canceled()) return;
|
|
rdr = Load_ttls_starting_with_rdr(ns.Id(), key, include_redirects, max_results, min_page_len, browse_len, false, false);
|
|
Xowd_page_itm prv_itm = new Xowd_page_itm();
|
|
boolean found = false;
|
|
while (rdr.Move_next()) {
|
|
Read_page__all(prv_itm, rdr);
|
|
found = true;
|
|
}
|
|
if (found)
|
|
rslt_prv.Copy(prv_itm);
|
|
else { // at beginning of range, so no items found; EX: "Module:A" is search, but 1st Module is "Module:B"
|
|
if (rslt_list.Count() > 0) // use 1st item
|
|
rslt_prv.Copy((Xowd_page_itm)rslt_list.Get_at(0));
|
|
}
|
|
}
|
|
}
|
|
finally {rdr.Rls();}
|
|
rslt_count.Val_(rslt_idx);
|
|
}
|
|
public void Read_page__idx(Xowd_page_itm page, Db_rdr rdr) {
|
|
page.Init_by_load__idx
|
|
( rdr.Read_int(fld_id)
|
|
, rdr.Read_int(fld_ns)
|
|
, rdr.Read_bry_by_str(fld_title)
|
|
, rdr.Read_int(fld_len)
|
|
);
|
|
}
|
|
public void Read_page__all(Xowd_page_itm page, Db_rdr rdr) {
|
|
// handle page_score defaulting to page_len
|
|
int page_len = rdr.Read_int(fld_len);
|
|
int page_score = fld_score == Dbmeta_fld_itm.Key_null ? page_len : rdr.Read_int(fld_score);
|
|
int cat_db_id = fld_cat_db_id == Dbmeta_fld_itm.Key_null ? -1 : rdr.Read_int(fld_cat_db_id);
|
|
|
|
page.Init_by_load__all
|
|
( rdr.Read_int(fld_id)
|
|
, rdr.Read_int(fld_ns)
|
|
, rdr.Read_bry_by_str(fld_title)
|
|
, DateAdp_.parse_fmt(rdr.Read_str(fld_touched), Page_touched_fmt)
|
|
, rdr.Read_bool_by_byte(fld_is_redirect)
|
|
, page_len
|
|
, rdr.Read_int(fld_random_int)
|
|
, rdr.Read_int(fld_text_db_id)
|
|
, rdr.Read_int(fld_html_db_id)
|
|
, rdr.Read_int(fld_redirect_id)
|
|
, page_score
|
|
, cat_db_id
|
|
);
|
|
}
|
|
public void Update__html_db_id(int page_id, int html_db_id) {
|
|
Db_stmt stmt = conn.Stmt_update(tbl_name, String_.Ary(fld_id), fld_html_db_id);
|
|
stmt.Val_int(fld_html_db_id, html_db_id).Crt_int(fld_id, page_id).Exec_update();
|
|
}
|
|
public void Update__cat_db_id(int page_id, int cat_db_id) {
|
|
Db_stmt stmt = conn.Stmt_update(tbl_name, String_.Ary(fld_id), fld_cat_db_id);
|
|
stmt.Val_int(fld_cat_db_id, cat_db_id).Crt_int(fld_id, page_id).Exec_update();
|
|
}
|
|
public void Update__ns__ttl(int page_id, int trg_ns, byte[] trg_ttl) {
|
|
for (int i = 0; i < 2; ++i) {
|
|
try {
|
|
conn.Stmt_update(tbl_name, String_.Ary(fld_id), fld_ns, fld_title)
|
|
.Val_int(fld_ns, trg_ns).Val_bry_as_str(fld_title, trg_ttl)
|
|
.Crt_int(fld_id, page_id)
|
|
.Exec_update();
|
|
break;
|
|
} catch (Exception exc) {
|
|
if (String_.Has(Err_.Message_gplx_full(exc), "columns page_namespace, page_random_int are not unique")) { // HACK: terrible hack, but moving pages across ns will break UNIQUE index
|
|
conn.Exec_sql_args("DROP INDEX {0}__name_random;", tbl_name); // is UNIQUE by default
|
|
conn.Exec_sql_args("CREATE INDEX {0}__name_random ON {0} ({1}, {2});", tbl_name, fld_ns, fld_random_int);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
public void Update__redirect__modified(int page_id, boolean redirect, DateAdp modified) {
|
|
conn.Stmt_update(tbl_name, String_.Ary(fld_id), fld_is_redirect, fld_touched)
|
|
.Val_int(fld_is_redirect, redirect ? 1 : 0)
|
|
.Val_str(fld_touched, modified.XtoStr_fmt(Page_touched_fmt))
|
|
.Crt_int(fld_id, page_id)
|
|
.Exec_update()
|
|
;
|
|
}
|
|
public void Update__redirect(int redirect_to_id, int page_id) {
|
|
conn.Stmt_update(tbl_name, String_.Ary(fld_id), fld_is_redirect, fld_redirect_id)
|
|
.Val_int(fld_is_redirect, Bool_.Y_int)
|
|
.Val_int(fld_redirect_id, redirect_to_id)
|
|
.Crt_int(fld_id, page_id)
|
|
.Exec_update()
|
|
;
|
|
}
|
|
|
|
public void Delete(int page_id) {
|
|
Gfo_usr_dlg_.Instance.Log_many("", "", "db.page: delete started: page_id=~{0}", page_id);
|
|
conn.Stmt_delete(tbl_name, fld_id).Crt_int(fld_id, page_id).Exec_delete();
|
|
Gfo_usr_dlg_.Instance.Log_many("", "", "db.page: delete done");
|
|
}
|
|
public void Update_page_id(int old_id, int new_id) {
|
|
Gfo_usr_dlg_.Instance.Log_many("", "", "db.page: update page_id started: old_id=~{0} new_id=~{1}", old_id, new_id);
|
|
conn.Stmt_update(tbl_name, String_.Ary(fld_id), fld_id).Val_int(fld_id, new_id).Crt_int(fld_id, old_id).Exec_update();
|
|
Gfo_usr_dlg_.Instance.Log_many("", "", "db.page: update page_id done");
|
|
}
|
|
public void Create_idx() {
|
|
conn.Meta_idx_create(Xoa_app_.Usr_dlg()
|
|
, Dbmeta_idx_itm.new_normal_by_tbl(tbl_name, "title" , fld_title, fld_ns)
|
|
, Dbmeta_idx_itm.new_normal_by_tbl(tbl_name, "random" , fld_random_int)
|
|
);
|
|
}
|
|
public int Fld_page_score_eval(Db_rdr rdr, int page_len) {
|
|
return fld_score == Dbmeta_fld_itm.Key_null ? page_len : rdr.Read_int(fld_score);
|
|
}
|
|
public void Rls() {
|
|
synchronized (thread_lock) {// LOCK:stmt-rls; DATE:2016-07-06
|
|
stmt_select_all_by_ttl = Db_stmt_.Rls(stmt_select_all_by_ttl);
|
|
stmt_select_all_by_id = Db_stmt_.Rls(stmt_select_all_by_id);
|
|
stmt_select_id_by_ttl = Db_stmt_.Rls(stmt_select_id_by_ttl);
|
|
stmt_insert = Db_stmt_.Rls(stmt_insert);
|
|
}
|
|
}
|
|
public static final String Page_touched_fmt = "yyyyMMddHHmmss";
|
|
public static final String TBL_NAME = "page", FLD__page_cat_db_id = "page_cat_db_id";
|
|
public static Xowd_page_tbl Get_by_key(Db_tbl_owner owner) {return (Xowd_page_tbl)owner.Tbls__get_by_key(TBL_NAME);}
|
|
public static final int INVALID_PAGE_ID = -1;
|
|
public static final int REDIRECT_IS_NULL = -1;
|
|
}
|