1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2014-06-30 00:04:32 -04:00
parent 85594d3cdd
commit bae88e739c
2482 changed files with 198730 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Bry_comparer_fld_last implements gplx.lists.ComparerAble {
public int compare(Object lhsObj, Object rhsObj) {
byte[] lhs = (byte[])lhsObj, rhs = (byte[])rhsObj;
int lhs_bgn = Bry_finder.Find_bwd(lhs, Byte_ascii.Pipe); if (lhs_bgn == Bry_.NotFound) lhs_bgn = -1;
int rhs_bgn = Bry_finder.Find_bwd(rhs, Byte_ascii.Pipe); if (rhs_bgn == Bry_.NotFound) rhs_bgn = -1;
return Bry_.Compare(lhs, lhs_bgn + 1, lhs.length, rhs, rhs_bgn + 1, rhs.length);
}
public static final Bry_comparer_fld_last _ = new Bry_comparer_fld_last();
}

View File

@@ -0,0 +1,38 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class ByteAry_fil {
public ListAdp Itms() {return itms;} ListAdp itms = ListAdp_.new_();
public Io_url Fil() {return fil;} Io_url fil;
public byte[] Raw_bry() {return raw_bry;} private byte[] raw_bry = Bry_.Empty;
public int Raw_len() {return raw_len.Val();} Int_obj_ref raw_len = Int_obj_ref.zero_();
public int Raw_max() {return raw_max;} private int raw_max = Io_mgr.Len_mb;
public ByteAry_fil Ini_file(Io_url fil) {
this.fil = fil;
raw_bry = Io_mgr._.LoadFilBry_reuse(fil, raw_bry, raw_len);
return this;
}
public Object Xto_itms(Class<?> itm_type) {
Object rv = itms.XtoAry(itm_type);
itms.Clear();
if (raw_bry.length > raw_max) raw_bry = Bry_.Empty;
raw_len.Val_zero_();
return rv;
}
public static final ByteAry_fil _ = new ByteAry_fil(); ByteAry_fil() {}
}

View File

@@ -0,0 +1,67 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
interface Io_txn_itm {
byte Txn_tid();
Io_url Txn_url();
boolean Txn_init(Io_url tmp_dir);
boolean Txn_exec(Io_url tmp_dir);
boolean Txn_term(Io_url tmp_dir);
}
class Io_txn_itm_save {
public byte Txn_tid() {return 0;}
public Io_url Txn_url() {return null;}
public boolean Txn_init(Io_url tmp_dir) {
// save to tmp_dir
return true;
}
public boolean Txn_exec(Io_url tmp_dir) {
// move temp to actl
// move actl to temp
return true;
}
public boolean Txn_term(Io_url tmp_dir) {
// delete temp
return true;
}
}
class Io_txn_mgr {
public Io_txn_mgr(Io_url tmp_dir) {this.tmp_dir = tmp_dir;}
public Io_url Tmp_dir() {return tmp_dir;} Io_url tmp_dir;
public void Add(Io_txn_itm itm) {
list.Add(itm);
}
public boolean Commit() {
int len = list.Count();
Io_txn_itm[] itms = (Io_txn_itm[])list.XtoAry(Io_txn_itm.class);
for (int i = 0; i < len; i++) {
Io_txn_itm itm = itms[i];
itm.Txn_init(tmp_dir);
}
for (int i = 0; i < len; i++) {
Io_txn_itm itm = itms[i];
itm.Txn_exec(tmp_dir);
}
for (int i = 0; i < len; i++) {
Io_txn_itm itm = itms[i];
itm.Txn_term(tmp_dir);
}
return true;
}
ListAdp list = ListAdp_.new_();
}

View File

@@ -0,0 +1,193 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.specials.*; import gplx.xowa.specials.allPages.*;
public class Xob_hive_mgr {
public Xob_hive_mgr(Xow_wiki wiki) {this.wiki = wiki; this.fsys_mgr = wiki.Fsys_mgr();} private Xow_wiki wiki; Xow_fsys_mgr fsys_mgr;
public void Clear() {regy.Clear(); xdat.Clear();}
public void Special_allpages_query(Xows_page_allpages mgr, Xow_ns ns, byte[] key, int count, boolean include_redirects) {
byte dir_tid = Xow_dir_info_.Tid_ttl;
int xdat_idx = Regy__find_file_ns(key, dir_tid, ns.Num_str());
Xob_xdat_file xdat_main = new Xob_xdat_file();
xdat_main = xdat_load_(xdat_main, dir_tid, ns, xdat_idx);
xdat_main.Find(xdat_itm, key, Xodb_page_.Txt_ttl_pos, Byte_ascii.Tab, false);
int itm_idx = xdat_itm.Itm_idx();
Special_allpages_query_fwd(mgr, dir_tid, ns, include_redirects, count, xdat_idx, itm_idx , xdat_main);
Special_allpages_query_bwd(mgr, dir_tid, ns, include_redirects, count, xdat_idx, itm_idx - 1, xdat_main);
}
Xob_xdat_file xdat_load_(Xob_xdat_file xdat, byte dir_tid, Xow_ns ns, int fil_idx) {
Io_url xdat_url = fsys_mgr.Url_ns_fil(dir_tid, ns.Id(), fil_idx);
byte[] xdat_bry = gplx.ios.Io_stream_rdr_.Load_all(xdat_url);
xdat.Parse(xdat_bry, xdat_bry.length, xdat_url);
return xdat;
}
private void Special_allpages_query_fwd(Xows_page_allpages mgr, byte dir_tid, Xow_ns ns, boolean include_redirects, int total, int fil_idx, int row_idx, Xob_xdat_file xdat_file) {
int count = 0; ++total;
boolean loop = true;
int regy_len = regy.Files_ary().length;
int rslt_list_len = mgr.Rslt_list_len();
Xodb_page[] rslt_list_ttls = mgr.Rslt_list_ttls();
Xodb_page nxt_itm = null;
while (loop) {
if (fil_idx == regy_len) break;
if (xdat_file == null) {
xdat_file = xdat_load_(this.xdat, dir_tid, ns, fil_idx);
row_idx = 0;
}
int rows_len = xdat_file.Count();
for (; row_idx < rows_len; row_idx++) {
xdat_file.GetAt(xdat_itm, row_idx);
Xodb_page ttl_itm = Xodb_page_.Txt_ttl_load(Bry_.Mid(xdat_itm.Src(), xdat_itm.Itm_bgn(), xdat_itm.Itm_end()));
if (!include_redirects && ttl_itm.Type_redirect()) continue;
++count;
nxt_itm = ttl_itm;
if (count == total) {
loop = false;
break;
}
else
rslt_list_ttls[rslt_list_len++] = ttl_itm;
}
xdat_file = null;
++fil_idx;
}
mgr.Rslt_list_len_(rslt_list_len);
mgr.Rslt_nxt_(nxt_itm);
}
private void Special_allpages_query_bwd(Xows_page_allpages mgr, byte dir_tid, Xow_ns ns, boolean include_redirects, int total, int fil_idx, int row_idx, Xob_xdat_file xdat_file) {
if (row_idx < 0) {
--fil_idx;
row_idx = -1;
}
int count = 0;
boolean loop = true;
Xodb_page prv_itm = null;
while (loop) {
if (fil_idx == -1) break;
if (xdat_file == null) {
xdat_file = xdat_load_(this.xdat, dir_tid, ns, fil_idx);
row_idx = -1;
}
if (row_idx == -1)
row_idx = xdat_file.Count() - 1;
for (; row_idx > -1; row_idx--) {
xdat_file.GetAt(xdat_itm, row_idx);
Xodb_page ttl_itm = Xodb_page_.Txt_ttl_load(Bry_.Mid(xdat_itm.Src(), xdat_itm.Itm_bgn(), xdat_itm.Itm_end()));
if (!include_redirects && ttl_itm.Type_redirect()) continue;
// list.Add(ttl_itm);
++count;
prv_itm = ttl_itm;
if (count == total) {
loop = false;
break;
}
else {
// rslt_list_ttls[rslt_list_len++] = ttl_itm;
}
}
xdat_file = null;
--fil_idx;
}
if (prv_itm == null) prv_itm = mgr.Rslt_list_ttls()[0];
mgr.Rslt_prv_(prv_itm);
}
public void Find_bgn(ListAdp list, Xow_ns ns, byte[] key, int count, boolean include_redirects) {
byte dir_tid = Xow_dir_info_.Tid_ttl;
int xdat_idx = Regy__find_file_ns(key, dir_tid, ns.Num_str());
Io_url xdat_url = fsys_mgr.Url_ns_fil(dir_tid, ns.Id(), xdat_idx);
byte[] xdat_bry = gplx.ios.Io_stream_rdr_.Load_all(xdat_url);
xdat.Parse(xdat_bry, xdat_bry.length, xdat_url);
xdat.Find(xdat_itm, key, Xodb_page_.Txt_ttl_pos, Byte_ascii.Tab, false);
Find_nearby_add_fwd(list, dir_tid, ns, include_redirects, count, xdat_idx, xdat_itm.Itm_idx());
} private Xob_xdat_itm xdat_itm = new Xob_xdat_itm(); //Int_2_ref find_nearby_rslt = new Int_2_ref();
// private void Find_nearby_add_bwd(ListAdp list, byte dir_tid, Xow_ns ns, boolean include_redirects, int total, int fil_bgn, int row_bgn) {
// if (--row_bgn < 0) {
// --fil_bgn;
// row_bgn = -1;
// }
// int fil_idx = fil_bgn;
// boolean first = true;
// int count = 0;
// boolean loop = true;
// while (loop) {
// if (fil_idx == -1) break;
// Io_url xdat_url = fsys_mgr.Url_ns_fil(dir_tid, ns.Id(), fil_idx);
// byte[] xdat_bry = gplx.ios.Io_stream_rdr_.Load_all(xdat_url);
// xdat.Parse(xdat_bry, xdat_bry.length, xdat_url);
// int row_idx = first && row_bgn != -1 ? row_bgn : xdat.Count() - 1;
// first = false;
// for (; row_idx > -1; row_idx--) {
// xdat.GetAt(xdat_itm, row_idx);
// Xodb_page ttl_itm = Xodb_page_.Txt_ttl_load(Bry_.Mid(xdat_itm.Src(), xdat_itm.Itm_bgn(), xdat_itm.Itm_end()));
// if (!include_redirects && ttl_itm.Type_redirect()) continue;
// list.Add(ttl_itm);
// if (++count == total) {loop = false; break;}
// }
// --fil_idx;
// }
// }
private void Find_nearby_add_fwd(ListAdp list, byte dir_tid, Xow_ns ns, boolean include_redirects, int total, int fil_bgn, int row_bgn) {
int fil_idx = fil_bgn;
boolean first = true;
int count = 0;
boolean loop = true;
int regy_len = regy.Files_ary().length;
while (loop) {
if (fil_idx == regy_len) break;
Io_url xdat_url = fsys_mgr.Url_ns_fil(dir_tid, ns.Id(), fil_idx);
byte[] xdat_bry = gplx.ios.Io_stream_rdr_.Load_all(xdat_url);
xdat.Parse(xdat_bry, xdat_bry.length, xdat_url);
int row_idx = first ? row_bgn : 0;
int rows_len = xdat.Count();
first = false;
for (; row_idx < rows_len; row_idx++) {
xdat.GetAt(xdat_itm, row_idx);
Xodb_page ttl_itm = Xodb_page_.Txt_ttl_load(Bry_.Mid(xdat_itm.Src(), xdat_itm.Itm_bgn(), xdat_itm.Itm_end()));
if (!include_redirects && ttl_itm.Type_redirect()) continue;
list.Add(ttl_itm);
if (++count == total) {loop = false; break;}
}
++fil_idx;
}
}
public void Create(byte dir_tid, byte[] key, byte[] row) { // Ctg_0; Ctg_0|!!!!"|!!!!#
int xdat_idx = Regy__find_file(key, dir_tid);
if (xdat_idx == Xowd_regy_mgr.Regy_null) { // no entries in regy; create at least one; EX: "" -> "0|A|A|1"
regy.Create(key);
xdat_idx = 0;
}
else
regy.Update_add(0, key);
regy.Save();
Xdat__create_row(dir_tid, key, row, xdat_idx);
}
int Regy__find_file(byte[] key, byte dir_tid) {return Regy__find_file_by_url(key, fsys_mgr.Url_site_reg(dir_tid));}
int Regy__find_file_ns(byte[] key, byte dir_tid, String ns_num) {return Regy__find_file_by_url(key, fsys_mgr.Url_ns_reg(ns_num, Xow_dir_info_.Tid_ttl));}
int Regy__find_file_by_url(byte[] key, Io_url regy_url) {regy.Init(regy_url); return regy.Files_find(key);} private Xowd_regy_mgr regy = new Xowd_regy_mgr();
private void Xdat__create_row(byte dir_tid, byte[] key, byte[] row, int xdat_idx) {
Io_url xdat_url = fsys_mgr.Url_site_fil(dir_tid, xdat_idx);
byte[] xdat_bry = gplx.ios.Io_stream_rdr_.Load_all(xdat_url);
Xob_xdat_file xdat_fil = new Xob_xdat_file();
if (xdat_bry.length > 0) // if file is not empty, load it and parse it
xdat_fil.Parse(xdat_bry, xdat_bry.length, xdat_url);
Bry_bfr tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_m001();
xdat_fil.Insert(tmp_bfr, row);
xdat_fil.Save(xdat_url);
tmp_bfr.Mkr_rls();
} private Xob_xdat_file xdat = new Xob_xdat_file(); Io_zip_mgr zip_mgr = Io_zip_mgr_base._;
}

View File

@@ -0,0 +1,43 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*;
public class Xob_hive_mgr_tst {
Xow_hive_mgr_fxt fxt = new Xow_hive_mgr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Drilldown() {
// fxt.Files_create_range(10, 10);
// fxt.Drilldown("A00", "J09", "A00", "B09", "C00", "D09", "E00", "F09", "G00", "H09", "I00", "J09");
// fxt.Drilldown("E00", "F09", "E00", "E03", "E04", "E07", "E08", "F01", "F02", "F05", "F06", "F09");
// fxt.Drilldown("E08", "F01", "E08", "E09", "F00", "F01");
}
}
class Xob_reg_wtr {
Bry_bfr bfr = Bry_bfr.new_(); int fil_count = 0;
public void Add(byte[] bgn, byte[] end, int itm_count) {
bfr
.Add_int_variable(fil_count++).Add_byte(Byte_ascii.Pipe)
.Add(bgn).Add_byte(Byte_ascii.Pipe)
.Add(end).Add_byte(Byte_ascii.Pipe)
.Add_int_variable(itm_count).Add_byte(Byte_ascii.NewLine);
}
public void Flush(Io_url url) {
Io_mgr._.SaveFilBfr(url, bfr);
// Tfds.Write(url.Raw() + "\n" + Io_mgr._.LoadFilStr(url));
}
}

View File

@@ -0,0 +1,21 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public interface Xobl_data_itm {
void Srl_save(Bry_bfr bfr);
}

View File

@@ -0,0 +1,100 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xodb_page implements Xobl_data_itm {
public Xodb_page() {this.Clear();}
public int Id() {return id;} public Xodb_page Id_(int v) {id = v; id_val = null; return this;} private int id;
public Int_obj_val Id_val() {if (id_val == null) id_val = Int_obj_val.new_(id); return id_val;} Int_obj_val id_val;
public int Ns_id() {return ns_id;} public Xodb_page Ns_id_(int v) {ns_id = v; return this;} private int ns_id;
public byte[] Ttl_wo_ns() {return ttl_wo_ns;} public Xodb_page Ttl_wo_ns_(byte[] v) {ttl_wo_ns = v; return this;} private byte[] ttl_wo_ns;
public boolean Type_redirect() {return type_redirect;} public Xodb_page Type_redirect_(boolean v) {type_redirect = v; return this;} private boolean type_redirect;
public int Text_len() {return text_len;} public Xodb_page Text_len_(int v) {text_len = v; return this;} private int text_len;
public byte[] Text() {return text;} public Xodb_page Text_(byte[] v) {text = v; if (v != null) text_len = v.length; return this;} private byte[] text;
public boolean Exists() {return exists;} public Xodb_page Exists_(boolean v) {exists = v; return this;} private boolean exists;
public int Db_file_idx() {return db_file_idx;} public Xodb_page Db_file_idx_(int v) {db_file_idx = v; return this;} private int db_file_idx;
public int Db_row_idx() {return db_row_idx;} public Xodb_page Db_row_idx_(int v) {db_row_idx = v; return this;} private int db_row_idx;
public DateAdp Modified_on() {return modified_on;} public Xodb_page Modified_on_(DateAdp v) {modified_on = v; return this;} DateAdp modified_on;
public Xow_ns Ns() {return ns;} private Xow_ns ns;
public Object Xtn() {return xtn;} public Xodb_page Xtn_(Object v) {this.xtn = v; return this;} Object xtn;
public byte[] Ttl_w_ns() {return ttl_w_ns;} private byte[] ttl_w_ns;
public Xodb_page Ttl_(Xow_ns ns, byte[] ttl_wo_ns) {
this.ns = ns;
ns_id = ns.Id();
this.ttl_wo_ns = ttl_wo_ns;
this.ttl_w_ns = ns.Gen_ttl(ttl_wo_ns);
return this;
}
public Xodb_page Ttl_(Xoa_ttl ttl) {
ttl_w_ns = ttl.Full_txt();
ttl_wo_ns = ttl.Page_db();
ns = ttl.Ns();
ns_id = ns.Id();
return this;
}
public Xodb_page Ttl_(byte[] v, Xow_ns_mgr ns_mgr) {
ttl_w_ns = v;
Object o = ns_mgr.Names_get_w_colon(v, 0, v.length);
if (o == null) {
ns = ns_mgr.Ns_main();
ttl_wo_ns = v;
}
else {
ns = (Xow_ns)o;
ttl_wo_ns = Bry_.Mid(v, ns.Name_txt_w_colon().length, v.length); // EX: "Template:A" -> "Template:" + "A"
}
ns_id = ns.Id();
return this;
}
public void Clear() {
id = Id_null; text_len = 0; // text_len should be 0 b/c text defaults to 0;
db_file_idx = db_row_idx = 0; // default to 0, b/c some tests do not set and will fail at -1
ns_id = Int_.MinValue;
ttl_w_ns = ttl_wo_ns = null; text = Bry_.Empty; // default to Ary_empty for entries that have <text />
ns = null;
type_redirect = exists = false;
modified_on = DateAdp_.MinValue;
id_val = null;
}
public void Copy(Xodb_page orig) {
this.id = orig.id;
this.text_len = orig.text_len;
this.db_file_idx = orig.db_file_idx;
this.db_row_idx = orig.db_row_idx;
this.ns_id = orig.ns_id;
this.ttl_w_ns = orig.ttl_w_ns;
this.ttl_wo_ns = orig.ttl_wo_ns;
this.text = orig.text;
this.ns = orig.ns;
this.type_redirect = orig.type_redirect;
this.exists = orig.exists;
this.modified_on = orig.modified_on;
this.id_val = null;
}
public Xodb_page Set_all_(int id, int db_file_idx, int db_row_idx, boolean redirect, int text_len, byte[] ttl_wo_ns) {
this.id = id; this.db_file_idx = db_file_idx; this.db_row_idx = db_row_idx; this.type_redirect = redirect; this.text_len = text_len; this.ttl_wo_ns = ttl_wo_ns;
id_val = null;
return this;
}
public void Srl_save(Bry_bfr bfr) {Xodb_page_.Txt_id_save(bfr, this);}
public static Xodb_page tmp_() {return new Xodb_page();}
public static Xodb_page srch_(int id, int text_len) {return new Xodb_page().Id_(id).Text_len_(text_len);}
public static final Xodb_page[] Ary_empty = new Xodb_page[0];
public static final int Timestamp_null = 0;
public static final int Id_null = -1;
public static final Xodb_page Null = null;
}

View File

@@ -0,0 +1,82 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xodb_page_ {
static final int Txt_len_id = 5, Txt_len_fil_idx = 5, Txt_len_row_idx = 5, Txt_len_type = 1, Txt_len_text_len = 5;
public static final int Txt_ttl_pos = Txt_len_id + Txt_len_fil_idx + Txt_len_row_idx + Txt_len_type + Txt_len_text_len + 5;
public static final int Txt_ttl_len__fixed = Txt_len_id + Txt_len_fil_idx + Txt_len_row_idx + Txt_len_type + Txt_len_text_len + 5 + 1; // 5=| 1=\n
public static Xodb_page Txt_ttl_load(byte[] bry) {
Xodb_page rv = new Xodb_page();
Txt_ttl_load(rv, bry, 0, bry.length);
return rv;
}
public static void Txt_ttl_load(Xodb_page page, byte[] bry) {Txt_ttl_load(page, bry, 0, bry.length);}
private static void Txt_ttl_load(Xodb_page page, byte[] bry, int bgn, int end) {
try {
page.Id_ (Base85_utl.XtoIntByAry (bry, bgn + 0, bgn + 4));
page.Db_file_idx_ (Base85_utl.XtoIntByAry (bry, bgn + 6, bgn + 10));
page.Db_row_idx_ (Base85_utl.XtoIntByAry (bry, bgn + 12, bgn + 16));
page.Type_redirect_ (bry[18] == Byte_ascii.Num_1);
page.Text_len_ (Base85_utl.XtoIntByAry (bry, bgn + 20, bgn + 24));
page.Ttl_wo_ns_ (Bry_.Mid (bry, bgn + 26, end));
} catch (Exception e) {throw Err_.err_(e, "parse_by_ttl failed: {0}", String_.new_utf8_(bry, bgn, end));}
}
public static void Txt_ttl_save(Bry_bfr bfr, Xodb_page page) {Txt_ttl_save(bfr, page.Id(), page.Db_file_idx(), page.Db_row_idx(), page.Type_redirect(), page.Text_len(), page.Ttl_wo_ns());}
public static void Txt_ttl_save(Bry_bfr bfr, int id, int file_idx, int row_idx, boolean redirect, int text_len, byte[] ttl_wo_ns) {
bfr .Add_base85_len_5(id) .Add_byte_pipe()
.Add_base85_len_5(file_idx) .Add_byte_pipe()
.Add_base85_len_5(row_idx) .Add_byte_pipe()
.Add_byte(redirect ? Byte_ascii.Num_1 : Byte_ascii.Num_0).Add_byte_pipe()
.Add_base85_len_5(text_len) .Add_byte_pipe()
.Add(ttl_wo_ns) .Add_byte_nl()
;
}
public static void Txt_id_load(Xodb_page page, byte[] bry) {Txt_id_load(page, bry, 0, bry.length);}
private static void Txt_id_load(Xodb_page page, byte[] bry, int bgn, int end) {
try {
page.Clear();
page.Id_ (Base85_utl.XtoIntByAry (bry, bgn + 0, bgn + 4));
page.Db_file_idx_(Base85_utl.XtoIntByAry (bry, bgn + 6, bgn + 10));
page.Db_row_idx_ (Base85_utl.XtoIntByAry (bry, bgn + 12, bgn + 16));
page.Type_redirect_ (bry[18] == Byte_ascii.Num_1);
page.Text_len_ (Base85_utl.XtoIntByAry (bry, bgn + 20, bgn + 24));
page.Ns_id_ (Base85_utl.XtoIntByAry (bry, bgn + 26, bgn + 30));
page.Ttl_wo_ns_ (Bry_.Mid (bry, bgn + 32, end));
} catch (Exception e) {throw Err_.err_(e, "parse_by_id failed: {0}", String_.new_utf8_(bry, bgn, end));}
}
public static void Txt_id_save(Bry_bfr bfr, Xodb_page page) {
bfr .Add_base85_len_5(page.Id()) .Add_byte_pipe()
.Add_base85_len_5(page.Db_file_idx()) .Add_byte_pipe()
.Add_base85_len_5(page.Db_row_idx()) .Add_byte_pipe()
.Add_byte(page.Type_redirect() ? Byte_ascii.Num_1 : Byte_ascii.Num_0).Add_byte_pipe()
.Add_base85_len_5(page.Text_len()) .Add_byte_pipe()
.Add_base85_len_5(page.Ns_id()) .Add_byte_pipe()
.Add(page.Ttl_wo_ns()) .Add_byte_nl();
}
public static void Txt_page_save(Bry_bfr bfr, int id, DateAdp modified_on, byte[] title, byte[] text, boolean add_nl) {
int ts = Bit_.Xto_int_date_short(modified_on.XtoSegAry());
bfr .Add_base85(id , Base85_utl.Len_int) .Add_byte(Txt_page_dlm) // needed for mass template load
.Add_base85(ts , Base85_utl.Len_int) .Add_byte(Txt_page_dlm)
.Add(title) .Add_byte(Txt_page_dlm) // needed for rebuilding ttl files
.Add(text) .Add_byte(Txt_page_dlm);
if (add_nl)
bfr.Add_byte_nl(); // NOTE: each page row is separated by \t\n
}
public static final byte Txt_page_dlm = Byte_ascii.Tab;
public static final int Txt_page_len__fixed = 1 + 5 + 1 + 5 + 1 + 1 + 1; // \tid|date|title|text\n
}

View File

@@ -0,0 +1,53 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.lists.*; /*ComparerAble*/
public class Xodb_page_sorter implements ComparerAble {
public int compare(Object lhsObj, Object rhsObj) {
Xodb_page lhs = (Xodb_page)lhsObj, rhs = (Xodb_page)rhsObj;
return order * Compare_rows(compareType, lhs, rhs);
}
private static int Compare_rows(byte compareType, Xodb_page lhs, Xodb_page rhs) {
switch (compareType) {
case Tid_ns_ttl: {
int rv = Int_.Compare(lhs.Ns_id(), rhs.Ns_id());
return rv == CompareAble_.Same ? Bry_.Compare(lhs.Ttl_wo_ns(), rhs.Ttl_wo_ns()) : rv;
}
case Tid_itm_len: return Int_.Compare(lhs.Text_len(), rhs.Text_len());
case Tid_id: return Int_.Compare(lhs.Id(), rhs.Id());
case Tid_ttl: return Bry_.Compare(lhs.Ttl_wo_ns(), rhs.Ttl_wo_ns());
case Tid_ctg_tid_sortkey:
gplx.xowa.ctgs.Xoctg_page_xtn lhs_xtn = (gplx.xowa.ctgs.Xoctg_page_xtn)lhs.Xtn();
gplx.xowa.ctgs.Xoctg_page_xtn rhs_xtn = (gplx.xowa.ctgs.Xoctg_page_xtn)rhs.Xtn();
if (lhs_xtn == null || rhs_xtn == null) return CompareAble_.Same;
int tid_comparable = Byte_.Compare(lhs_xtn.Tid(), rhs_xtn.Tid());
if (tid_comparable != CompareAble_.Same) return tid_comparable;
return Bry_.Compare(lhs_xtn.Sortkey(), rhs_xtn.Sortkey());
default: throw Err_.unhandled(compareType);
}
}
Xodb_page_sorter(byte compareType, int order) {this.compareType = compareType; this.order = order;}
byte compareType; int order;
static final byte Tid_ns_ttl = 0, Tid_itm_len = 2, Tid_id = 3, Tid_ttl = 4, Tid_ctg_tid_sortkey = 5;
static final int Asc = 1, Dsc = -1;
public static final Xodb_page_sorter TitleAsc = new Xodb_page_sorter(Tid_ttl , Asc);
public static final Xodb_page_sorter EnyLenDsc = new Xodb_page_sorter(Tid_itm_len , Dsc);
public static final Xodb_page_sorter IdAsc = new Xodb_page_sorter(Tid_id , Asc);
public static final Xodb_page_sorter Ns_id_TtlAsc = new Xodb_page_sorter(Tid_ns_ttl , Asc);
public static final Xodb_page_sorter Ctg_tid_sortkey_asc = new Xodb_page_sorter(Tid_ctg_tid_sortkey , Asc);
}

View File

@@ -0,0 +1,42 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*;
public class Xodb_page_tst {
@Before public void init() {fxt.Init();} private Xodb_page_fxt fxt = new Xodb_page_fxt();
@Test public void Ttl_() {
fxt.Test_ttl_("User_talk:A", Xow_ns_.Id_user_talk, "A");
fxt.Test_ttl_("User talk:A", Xow_ns_.Id_user_talk, "A");
}
}
class Xodb_page_fxt {
public void Init() {
if (ns_mgr == null) {
ns_mgr = new Xow_ns_mgr();
ns_mgr.Add_new(Xow_ns_.Id_main, "");
ns_mgr.Add_new(Xow_ns_.Id_user_talk, "User talk");
ns_mgr.Init_w_defaults();
tmp_page = new Xodb_page();
}
} private Xow_ns_mgr ns_mgr; Xodb_page tmp_page;
public void Test_ttl_(String ttl, int expd_ns, String expd_ttl) {
tmp_page.Ttl_(Bry_.new_ascii_(ttl), ns_mgr);
Tfds.Eq(expd_ns, tmp_page.Ns_id());
Tfds.Eq(expd_ttl, String_.new_ascii_(tmp_page.Ttl_wo_ns()));
}
}

View File

@@ -0,0 +1,90 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.lists.*; /*ComparerAble*/ import gplx.xowa.bldrs.imports.ctgs.*;
import gplx.xowa.dbs.*; import gplx.xowa.wikis.*;
public class Xow_data_mgr implements GfoInvkAble {
public Xow_data_mgr(Xow_wiki wiki) {
this.wiki = wiki; this.redirect_mgr = wiki.Redirect_mgr();
} private Xop_redirect_mgr redirect_mgr;
private Xoa_url tmp_url = new Xoa_url();
public Xow_wiki Wiki() {return wiki;} private Xow_wiki wiki;
public Xoa_page Get_page(Xoa_ttl ttl, boolean called_from_tmpl) {wiki.App().Url_parser().Parse(tmp_url, ttl.Raw()); return Get_page(tmp_url, ttl, called_from_tmpl, false);}
public Xoa_page Get_page_from_msg(Xoa_ttl ttl) {wiki.App().Url_parser().Parse(tmp_url, ttl.Raw()); return Get_page(tmp_url, ttl, false, true);}
public Xoa_page Get_page(Xoa_url url, Xoa_ttl ttl, boolean called_from_tmpl, boolean called_from_msg) {
Xow_ns ns = ttl.Ns();
Xoa_page rv = Xoa_page.new_(wiki, ttl); rv.Url_(url); // NOTE: must update page.Url(); should combine with Xoa_page.new_()
switch (ns.Id()) {
case Xow_ns_.Id_special:
wiki.Special_mgr().Special_gen(url, rv, wiki, ttl);
return rv;
case Xow_ns_.Id_mediaWiki:
if ( !called_from_msg // if called from msg, fall through to actual data retrieval below, else infinite loop; DATE:2014-05-09
&& Xow_page_tid.Identify_by_ttl(ttl.Page_db()) == Xow_page_tid.Tid_wikitext // skip ".js" and ".css" pages in MediaWiki; DATE:2014-06-13
) {
Xol_lang lang = wiki.Lang();
byte[] msg_key = ttl.Page_db();
Bry_bfr tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_b512();
msg_key = lang.Case_mgr().Case_build_1st_lower(tmp_bfr, msg_key, 0, msg_key.length);
byte[] msg_val = Pf_msg_mgr.Get_msg_itm(tmp_bfr, wiki, wiki.Lang(), msg_key).Val(); // NOTE: do not change to Get_msg_val; Get_msg_val, also replaces $1 with values, and $1 needs to be preserved for callers;
rv.Data_raw_(msg_val);
tmp_bfr.Mkr_rls();
return rv;
}
break;
}
return Get_page(rv, url, ns, ttl, called_from_tmpl);
}
private Xoa_page Get_page(Xoa_page rv, Xoa_url url, Xow_ns ns, Xoa_ttl ttl, boolean called_from_tmpl) {
int redirects = 0;
Xodb_page db_page = Xodb_page.tmp_();
while (true) {
boolean exists = wiki.Db_mgr().Load_mgr().Load_by_ttl(db_page, ns, ttl.Page_db());
if (!exists) return rv.Missing_();
if (wiki.App().Mode() == Xoa_app_.Mode_gui) // NOTE: must check if gui, else will write during mass build; DATE:2014-05-03
wiki.App().Gui_wtr().Prog_many(GRP_KEY, "file_load", "loading page for ~{0}", String_.new_utf8_(ttl.Raw()));
wiki.Db_mgr().Load_mgr().Load_page(db_page, ns, !called_from_tmpl);
byte[] bry = db_page.Text();
rv.Data_raw_(bry).Revision_data().Modified_on_(db_page.Modified_on()).Id_(db_page.Id());
if (url != null && url.Redirect_force()) return rv;
Xoa_ttl redirect_ttl = redirect_mgr.Extract_redirect(bry, bry.length);
if ( redirect_ttl == null // not a redirect
|| redirects++ > 4) // too many redirects; something went wrong
break;
rv.Redirect_list().Add(ttl.Full_url()); // NOTE: must be url_encoded; EX: "en.wikipedia.org/?!" should generate link of "en.wikipedia.org/%3F!?redirect=no"
rv.Ttl_(redirect_ttl);
ns = redirect_ttl.Ns();
ttl = redirect_ttl;
}
return rv;
}
public Xoa_page Redirect(Xoa_page page, byte[] page_bry) {
Xoa_ttl trg_ttl = Xoa_ttl.parse_(wiki, page_bry);
Xoa_url trg_url = Xoa_url.new_(wiki.Domain_bry(), page_bry);
page.Ttl_(trg_ttl).Url_(trg_url).Redirected_(true);
return wiki.Data_mgr().Get_page(page, trg_url, trg_ttl.Ns(), trg_ttl, false);
}
public static final int File_idx_unknown = -1;
static final String GRP_KEY = "xowa.wiki.data";
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_create_enabled_)) wiki.Db_mgr().Save_mgr().Create_enabled_(m.ReadYn("v"));
else if (ctx.Match(k, Invk_update_modified_on_enabled_)) wiki.Db_mgr().Save_mgr().Update_modified_on_enabled_(m.ReadYn("v"));
else return GfoInvkAble_.Rv_unhandled;
return this;
} private static final String Invk_create_enabled_ = "create_enabled_", Invk_update_modified_on_enabled_ = "update_modified_on_enabled_";
}

View File

@@ -0,0 +1,163 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*;
public class Xow_data_mgr_tst {
Xow_data_mgr_fxt fxt = new Xow_data_mgr_fxt();
@Before public void init() {fxt.Clear(); Tfds.Now_enabled_y_();}
@After public void term() {Tfds.Now_enabled_n_();}
@Test public void Create() {
fxt .Create("A1", "A1 data")
.Create("B12", "B12 data")
.Create("C123", "C123 data")
.Tst_regy_title("0|A1|C123|3\n")
.Tst_data_title(String_.Concat_lines_nl
( "!!!!>|!!!!?|!!!!@|"
, "!!!!!|!!!!!|!!!!!|0|!!!!(|A1"
, "!!!!\"|!!!!!|!!!!\"|0|!!!!)|B12"
, "!!!!#|!!!!!|!!!!#|0|!!!!*|C123"
))
.Tst_data_page(String_.Concat_lines_nl
( "!!!!9|!!!!;|!!!!=|"
, "!!!!!\t##PX+\tA1\tA1 data\t"
, "!!!!\"\t##PX/\tB12\tB12 data\t"
, "!!!!#\t##PX0\tC123\tC123 data\t"
))
;
}
@Test public void Update() {
fxt .Create("A1", "A1 data")
.Create("B12", "B12 data")
.Create("C123", "C123 data")
.Update("B12", "B12 changed")
.Tst_regy_title("0|A1|C123|3\n")
.Tst_data_title(String_.Concat_lines_nl
( "!!!!>|!!!!?|!!!!@|"
, "!!!!!|!!!!!|!!!!!|0|!!!!(|A1"
, "!!!!\"|!!!!!|!!!!\"|0|!!!!,|B12"
, "!!!!#|!!!!!|!!!!#|0|!!!!*|C123"
))
.Tst_data_page(String_.Concat_lines_nl
( "!!!!9|!!!!>|!!!!=|"
, "!!!!!\t##PX+\tA1\tA1 data\t"
, "!!!!\"\t##PX/\tB12\tB12 changed\t"
, "!!!!#\t##PX0\tC123\tC123 data\t"
))
;
}
@Test public void Update_zip() {
// fxt.Wiki().Fsys_mgr().Dir_regy()[Xow_ns_.Id_main].Ext_tid_(gplx.ios.Io_stream_.Tid_zip);
// fxt.Wiki().Data_mgr().Zip_mgr_(new Io_zip_mgr_mok());
// fxt .Create("A1", "A1 data")
// .Create("B12", "B12 data")
// .Create("C123", "C123 data")
// .Update("B12", "B12 changed")
// .Tst_regy_title("0|A1|C123|3\n")
// .Tst_data_title(String_.Concat_lines_nl
// ( "!!!!>|!!!!?|!!!!@|"
// , "!!!!!|!!!!!|!!!!!|0|!!!!(|A1"
// , "!!!!\"|!!!!!|!!!!\"|0|!!!!,|B12"
// , "!!!!#|!!!!!|!!!!#|0|!!!!*|C123"
// ))
// .Tst_data_page(String_.Concat_lines_nl
// ( "zipped:!!!!9|!!!!>|!!!!=|"
// , "!!!!!\t##PX+\tA1\tA1 data\t"
// , "!!!!\"\t##PX/\tB12\tB12 changed\t"
// , "!!!!#\t##PX0\tC123\tC123 data\t"
// ))
// ;
}
@Test public void Create_out_of_order() {
fxt .Create("C123", "C123 data")
.Create("B12", "B12 data")
.Create("A1", "A1 data")
.Tst_regy_title("0|A1|C123|3\n")
.Tst_data_title(String_.Concat_lines_nl
( "!!!!>|!!!!?|!!!!@|"
, "!!!!#|!!!!!|!!!!#|0|!!!!(|A1"
, "!!!!\"|!!!!!|!!!!\"|0|!!!!)|B12"
, "!!!!!|!!!!!|!!!!!|0|!!!!*|C123"
))
.Tst_data_page(String_.Concat_lines_nl
( "!!!!=|!!!!;|!!!!9|"
, "!!!!!\t##PX+\tC123\tC123 data\t"
, "!!!!\"\t##PX/\tB12\tB12 data\t"
, "!!!!#\t##PX0\tA1\tA1 data\t"
))
;
}
@Test public void Rename() {
fxt .Create("A1", "A1 data")
.Create("B12", "B12 data")
.Create("C123", "C123 data")
.Rename("C123", "C1234")
.Tst_regy_title("0|A1|C123|3\n")
.Tst_data_title(String_.Concat_lines_nl
( "!!!!>|!!!!?|!!!!@|"
, "!!!!!|!!!!!|!!!!!|0|!!!!(|A1"
, "!!!!\"|!!!!!|!!!!\"|0|!!!!)|B12"
, "!!!!#|!!!!!|!!!!#|0|!!!!*|C123"
))
.Tst_data_page(String_.Concat_lines_nl
( "!!!!9|!!!!;|!!!!=|"
, "!!!!!\t##PX+\tA1\tA1 data\t"
, "!!!!\"\t##PX/\tB12\tB12 data\t"
, "!!!!#\t##PX0\tC123\tC123 data\t"
))
;
}
}
class Xow_data_mgr_fxt {
Xoa_app app;
public Xow_wiki Wiki() {return wiki;} private Xow_wiki wiki;
public void Clear() {
app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
wiki.Db_mgr().Save_mgr().Page_id_next_(0);
}
public Xow_data_mgr_fxt Create(String ttl_str, String data) {
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_utf8_(ttl_str));
wiki.Db_mgr().Save_mgr().Data_create(ttl, Bry_.new_utf8_(data));
return this;
}
public Xow_data_mgr_fxt Update(String ttl_str, String data) {
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_utf8_(ttl_str));
Xoa_page page = Xoa_page.test_(wiki, ttl);
wiki.Db_mgr().Save_mgr().Data_update(page, Bry_.new_utf8_(data));
return this;
}
public Xow_data_mgr_fxt Rename(String old_ttl, String new_ttl) {
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_utf8_(old_ttl));
Xoa_page page = Xoa_page.test_(wiki, ttl);
wiki.Db_mgr().Save_mgr().Data_rename(page, ttl.Ns().Id(), Bry_.new_utf8_(new_ttl));
return this;
}
public Xow_data_mgr_fxt Tst_regy_title(String expd) {return Tst_regy(Xow_dir_info_.Name_title, expd);}
Xow_data_mgr_fxt Tst_regy(String name, String expd) {
Io_url file_orig = Io_url_.mem_fil_("mem/xowa/wiki/en.wikipedia.org/ns/000/" + name + "/reg.csv");
Tfds.Eq_str_lines(expd, Io_mgr._.LoadFilStr(file_orig));
return this;
}
public Xow_data_mgr_fxt Tst_data_page(String expd) {return Tst_data(Xow_dir_info_.Tid_page , Xow_ns_.Id_main, 0, expd);}
public Xow_data_mgr_fxt Tst_data_title(String expd) {return Tst_data(Xow_dir_info_.Tid_ttl, Xow_ns_.Id_main, 0, expd);}
public Xow_data_mgr_fxt Tst_data(byte dir_tid, int ns_id, int fil, String expd) {
Io_url url = wiki.Fsys_mgr().Url_ns_fil(dir_tid, ns_id, fil);
Tfds.Eq_str_lines(expd, Io_mgr._.LoadFilStr(url));
return this;
}
}

View File

@@ -0,0 +1,97 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xow_hive_mgr_fxt {
public void Clear() {
if (hive_mgr == null) {
app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
hive_mgr = new Xob_hive_mgr(wiki);
}
hive_mgr.Clear();
Io_mgr._.InitEngine_mem();
} private Xob_hive_mgr hive_mgr; Xoa_app app;
public Xow_wiki Wiki() {return wiki;} private Xow_wiki wiki;
public void Find_nearby(String key, int count, boolean include_redirects, String... expd) {
ListAdp list = ListAdp_.new_();
wiki.Hive_mgr().Find_bgn(list, wiki.Ns_mgr().Ns_main(), Bry_.new_ascii_(key), count, include_redirects);
int actl_len = list.Count();
String[] actl = new String[actl_len];
for (int i = 0; i < actl_len; i++) {
Xodb_page itm = (Xodb_page)list.FetchAt(i);
actl[i] = String_.new_ascii_(itm.Ttl_wo_ns());
}
Tfds.Eq_ary_str(expd, actl);
}
public static void Ttls_create_rng(Xow_wiki wiki, int files, int ttls_per_file) {Ttls_create_rng(wiki, wiki.Ns_mgr().Ns_main(), files, ttls_per_file);}
public static void Ttls_create_rng(Xow_wiki wiki, Xow_ns ns, int files, int ttls_per_file) {
Xob_reg_wtr reg_wtr = new Xob_reg_wtr();
byte dir_tid = Xow_dir_info_.Tid_ttl;
int id = 0;
int ttl_bry_len = Int_.DigitCount(ttls_per_file);
Xob_xdat_file_wtr xdat_wtr = Xob_xdat_file_wtr.new_file_(ttls_per_file * 8, wiki.Fsys_mgr().Url_ns_dir(ns.Num_str(), Xow_dir_info_.Tid_ttl));
Bry_bfr tmp_bfr = Bry_bfr.new_();
byte ltr = Byte_ascii.Ltr_A; byte[] ttl_0 = Bry_.Empty, ttl_n = Bry_.Empty;
for (int fil_idx = 0; fil_idx < files; fil_idx++) {
for (int ttl_idx = 0; ttl_idx < ttls_per_file; ttl_idx++) {
tmp_bfr.Add_byte(ltr).Add_int_fixed(ttl_idx, ttl_bry_len);
byte[] ttl_bry = tmp_bfr.XtoAryAndClear();
if (ttl_idx == 0) ttl_0 = ttl_bry;
else if (ttl_idx == ttls_per_file - 1) ttl_n = ttl_bry;
Xodb_page_.Txt_ttl_save(xdat_wtr.Bfr(), id++, 0, ttl_idx, ttl_idx % 2 == 1, 1, ttl_bry);
xdat_wtr.Add_idx(Byte_ascii.Nil);
}
xdat_wtr.Flush(wiki.App().Usr_dlg());
reg_wtr.Add(ttl_0, ttl_n, ttls_per_file);
++ltr;
}
reg_wtr.Flush(wiki.Fsys_mgr().Url_ns_reg(ns.Num_str(), dir_tid));
}
public Xow_hive_mgr_fxt Create_ctg(String key_str, int... pages) {Create_ctg(app, hive_mgr, key_str, pages); return this;}
public static void Create_ctg(Xoa_app app, Xob_hive_mgr hive_mgr, String key_str, int... pages) {
byte[] key_bry = Bry_.new_ascii_(key_str);
Bry_bfr bfr = app.Utl_bry_bfr_mkr().Get_b512();
bfr.Add(key_bry);
int pages_len = pages.length;
for (int i = 0; i < pages_len; i++)
bfr.Add_byte_pipe().Add_base85_len_5(pages[i]);
bfr.Add_byte_nl();
byte[] row = bfr.Mkr_rls().XtoAryAndClear();
hive_mgr.Create(Xow_dir_info_.Tid_category, key_bry, row);
}
public Xow_hive_mgr_fxt Create_id(int id, int fil_idx, int row_idx, boolean type_redirect, int itm_len, int ns_id, String ttl) {Create_id(app, hive_mgr, id, fil_idx, row_idx, type_redirect, itm_len, ns_id, ttl); return this;}
public static void Create_id(Xoa_app app, Xob_hive_mgr hive_mgr, int id, int fil_idx, int row_idx, boolean type_redirect, int itm_len, int ns_id, String ttl) {
Bry_bfr bfr = app.Utl_bry_bfr_mkr().Get_b512();
byte[] key_bry = Base85_utl.XtoStrByAry(id, 5);
bfr .Add(key_bry) .Add_byte_pipe()
.Add_base85_len_5(fil_idx) .Add_byte_pipe()
.Add_base85_len_5(row_idx) .Add_byte_pipe()
.Add_byte(type_redirect ? Byte_ascii.Num_1 : Byte_ascii.Num_0).Add_byte_pipe()
.Add_base85_len_5(itm_len) .Add_byte_pipe()
.Add_base85_len_5(ns_id) .Add_byte_pipe()
.Add_str(ttl) .Add_byte_nl();
byte[] row = bfr.XtoAryAndClear();
bfr.Mkr_rls();
hive_mgr.Create(Xow_dir_info_.Tid_id, key_bry, row);
}
public Xow_hive_mgr_fxt Load(String url, String... expd) {
String actl = Io_mgr._.LoadFilStr(url);
Tfds.Eq_ary_str(expd, String_.SplitLines_nl(actl));
return this;
}
}

View File

@@ -0,0 +1,94 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xowd_hive_mgr {
public Xowd_hive_mgr(Xow_wiki wiki, byte dir_tid) {
this.wiki = wiki; fsys_mgr = wiki.Fsys_mgr(); this.dir_tid = dir_tid;
dir_tid_reg = dir_tid == Xow_dir_info_.Tid_page ? Xow_dir_info_.Tid_ttl : dir_tid;
} Xow_wiki wiki; Xow_fsys_mgr fsys_mgr; Xowd_regy_mgr reg_mgr; byte dir_tid;
byte dir_tid_reg;
public void Create(Xow_ns ns, byte[] key, byte[] data, gplx.lists.ComparerAble comparer) {
if (reg_mgr == null) reg_mgr = new Xowd_regy_mgr(fsys_mgr.Url_ns_reg(ns.Num_str(), dir_tid_reg));
int fil_idx = 0;
if (reg_mgr.Files_ary().length == 0) {
reg_mgr.Create(key);
fil_idx = 0;
}
else {
fil_idx = reg_mgr.Files_find(key);
reg_mgr.Update_add(fil_idx, key);
}
Io_url url = fsys_mgr.Url_ns_fil(dir_tid, ns.Id(), fil_idx);
byte[] bry = Io_mgr._.LoadFilBry(url);
Xob_xdat_file xdat = new Xob_xdat_file();
if (bry != Bry_.Empty)
xdat.Parse(bry, bry.length, url);
Bry_bfr tmp = wiki.Utl_bry_bfr_mkr().Get_m001();
xdat.Insert(tmp, data);
if (comparer != null)
xdat.Sort(tmp, comparer);
tmp.Mkr_rls();
xdat.Save(url);
reg_mgr.Save();
}
public void Create(byte[] key, byte[] data, gplx.lists.ComparerAble comparer) {
if (reg_mgr == null) reg_mgr = new Xowd_regy_mgr(fsys_mgr.Url_site_reg(dir_tid));
int fil_idx = 0;
if (reg_mgr.Files_ary().length == 0) {
reg_mgr.Create(key);
fil_idx = 0;
}
else {
fil_idx = reg_mgr.Files_find(key);
reg_mgr.Update_add(fil_idx, key);
}
Io_url url = fsys_mgr.Url_site_fil(dir_tid, fil_idx);
byte[] bry = Io_mgr._.LoadFilBry(url);
Xob_xdat_file xdat = new Xob_xdat_file();
if (bry != Bry_.Empty)
xdat.Parse(bry, bry.length, url);
Bry_bfr tmp = wiki.Utl_bry_bfr_mkr().Get_m001();
xdat.Insert(tmp, data);
if (comparer != null)
xdat.Sort(tmp, comparer);
tmp.Mkr_rls();
xdat.Save(url);
reg_mgr.Save();
}
public void Update(Xow_ns ns, byte[] old_key, byte[] new_key, byte[] data, int lkp_bgn, byte lkp_dlm, boolean exact, boolean sort) {
if (reg_mgr == null) reg_mgr = new Xowd_regy_mgr(fsys_mgr.Url_ns_reg(ns.Num_str(), Xow_dir_info_.Tid_ttl));
int fil_idx = reg_mgr.Files_find(old_key);
boolean reg_save = false;
if (new_key != null)
reg_save = reg_mgr.Update_change(fil_idx, old_key, new_key);
Io_url url = fsys_mgr.Url_ns_fil(dir_tid, ns.Id(), fil_idx);
byte[] bry = Io_mgr._.LoadFilBry(url);
Xob_xdat_file xdat = new Xob_xdat_file();
if (bry != Bry_.Empty)
xdat.Parse(bry, bry.length, url);
Bry_bfr tmp = wiki.Utl_bry_bfr_mkr().Get_m001();
Xob_xdat_itm itm = new Xob_xdat_itm();
xdat.Find(itm, old_key, lkp_bgn, lkp_dlm, exact);
if (itm.Missing()) return;
xdat.Update(tmp, itm, data);
if (sort) xdat.Sort(tmp, new Bry_comparer_bgn_eos(lkp_bgn));
tmp.Mkr_rls();
xdat.Save(url);
if (reg_save) reg_mgr.Save();
}
}

View File

@@ -0,0 +1,98 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*;
public class Xowd_hive_mgr_tst {
Xowd_hive_mgr_fxt fxt = new Xowd_hive_mgr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Create() {
fxt.Create("A", "A|A data\n")
.Tst_reg(String_.Concat_lines_nl("0|A|A|1"))
.Tst_fil(0, String_.Concat("!!!!*|\n", "A|A data\n"))
;
}
@Test public void Create_2() {
fxt .Create("A", "A|1\n")
.Create("B", "B|12\n")
.Tst_reg(String_.Concat_lines_nl("0|A|B|2"))
.Tst_fil(0, String_.Concat("!!!!%|!!!!&|\n", "A|1\n", "B|12\n"))
;
}
@Test public void Create_3() {
fxt .Create("A", "A|1\n")
.Create("B", "B|12\n")
.Create("C", "C|123\n")
.Tst_reg(String_.Concat_lines_nl("0|A|C|3"))
.Tst_fil(0, String_.Concat("!!!!%|!!!!&|!!!!'|\n", "A|1\n", "B|12\n", "C|123\n"))
;
}
@Test public void Create_sort() {
fxt .Create_and_sort("C", "C|1\n")
.Create_and_sort("A", "A|12\n")
.Create_and_sort("B", "B|123\n")
.Tst_reg(String_.Concat_lines_nl("0|A|C|3"))
.Tst_fil(0, String_.Concat("!!!!&|!!!!'|!!!!%|\n", "A|12\n", "B|123\n", "C|1\n"))
;
}
@Test public void Update() {
fxt .Create("A", "A|A data\n")
.Create("B", "B|B data\n")
.Create("C", "C|C data\n")
.Tst_reg(String_.Concat_lines_nl("0|A|C|3"))
.Tst_fil(0, String_.Concat("!!!!*|!!!!*|!!!!*|\n", "A|A data\n", "B|B data\n", "C|C data\n"))
.Update("B", "B|changed\n")
.Tst_reg(String_.Concat_lines_nl("0|A|C|3"))
.Tst_fil(0, String_.Concat("!!!!*|!!!!+|!!!!*|\n", "A|A data\n", "B|changed\n", "C|C data\n"))
;
}
}
class Xowd_hive_mgr_fxt {
Xoa_app app; Xow_wiki wiki; Xowd_hive_mgr mgr;
public void Clear() {
app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
mgr = new Xowd_hive_mgr(wiki, Xow_dir_info_.Tid_page);
}
public Xowd_hive_mgr_fxt Tst_reg(String expd) {
Io_url file_orig = Io_url_.mem_fil_("mem/xowa/wiki/en.wikipedia.org/ns/000/title/reg.csv");
Tfds.Eq_str_lines(expd, Io_mgr._.LoadFilStr(file_orig));
return this;
}
public Xowd_hive_mgr_fxt Tst_fil(int fil, String expd) {
Io_url url = wiki.Fsys_mgr().Url_ns_fil(Xow_dir_info_.Tid_page, Xow_ns_.Id_main, fil);
Tfds.Eq_str_lines(expd, Io_mgr._.LoadFilStr(url));
return this;
}
public Xowd_hive_mgr_fxt Update(String key, String data) {
mgr.Update(wiki.Ns_mgr().Ns_main(), Bry_.new_ascii_(key), null, Bry_.new_ascii_(data), 0, Byte_ascii.Pipe, true, true);
return this;
}
public Xowd_hive_mgr_fxt Create(String key, String data) {
mgr.Create(wiki.Ns_mgr().Ns_main(), Bry_.new_ascii_(key), Bry_.new_ascii_(data), null);
return this;
}
public Xowd_hive_mgr_fxt Create_and_sort(String key, String data) {
mgr.Create(wiki.Ns_mgr().Ns_main(), Bry_.new_ascii_(key), Bry_.new_ascii_(data), new Bry_comparer_bgn_eos(0));
return this;
}
// public void Get(String ttl_str, boolean exists) {
// Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_utf8_(ttl_str));
// Xodb_page row = mgr.Get(ttl.Ns(), ttl.Full_txt());
// Tfds.Eq(exists, row != null);
// }
}

View File

@@ -0,0 +1,61 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xowd_hive_regy_itm {// csv file with the format of "idx|bgn|end|count"; EX: "0|AA|AZ|120\n1|BA|BZ|110"
public Xowd_hive_regy_itm(int idx) {this.idx = idx;}
public int Idx() {return idx;} private int idx;
public byte[] Bgn() {return bgn;} public Xowd_hive_regy_itm Bgn_(byte[] v) {bgn = v; return this;} private byte[] bgn;
public byte[] End() {return end;} public Xowd_hive_regy_itm End_(byte[] v) {end = v; return this;} private byte[] end;
public int Count() {return count;} public Xowd_hive_regy_itm Count_(int v) {this.count = v; return this;} private int count;
public static Xowd_hive_regy_itm[] parse_fil_(ByteAry_fil utl) {
ListAdp rv = utl.Itms();
byte[] ary = utl.Raw_bry();
int ary_len = utl.Raw_len(); if (ary_len == 0) return Xowd_hive_regy_itm.Ary_empty; //throw Err_mgr._.fmt_("xowa.wiki.data", "title_registry_file_not_found", "title_registry file not found: ~{0}", utl.Fil().Xto_api());
Int_obj_ref pos = Int_obj_ref.zero_();
while (pos.Val() < ary_len) {
Xowd_hive_regy_itm file = new Xowd_hive_regy_itm();
file.idx = Bry_.ReadCsvInt(ary, pos, Bry_.Dlm_fld);
file.bgn = Bry_.ReadCsvBry(ary, pos, Bry_.Dlm_fld); // skip bgn
file.end = Bry_.ReadCsvBry(ary, pos, Bry_.Dlm_fld);
file.count = Bry_.ReadCsvInt(ary, pos, Bry_.Dlm_row);
rv.Add(file);
}
return (Xowd_hive_regy_itm[])utl.Xto_itms(Xowd_hive_regy_itm.class);
}
public Xowd_hive_regy_itm() {}
public Xowd_hive_regy_itm(int id, byte[] bgn, byte[] end, int count) {
this.idx = id; this.bgn = bgn; this.end = end; this.count = count;
}
public void Srl_save(Bry_bfr bfr) {
bfr .Add_int_variable(idx).Add_byte_pipe()
.Add(bgn).Add_byte_pipe()
.Add(end).Add_byte_pipe()
.Add_int_variable(count).Add_byte_nl();
}
public static Xowd_hive_regy_itm tmp_() {return new Xowd_hive_regy_itm();}
public static final Xowd_hive_regy_itm[] Ary_empty = new Xowd_hive_regy_itm[0];
}
class Xowd_ttl_file_comparer_end implements gplx.lists.ComparerAble {
public int compare(Object lhsObj, Object rhsObj) {
Xowd_hive_regy_itm lhs = (Xowd_hive_regy_itm)lhsObj, rhs = (Xowd_hive_regy_itm)rhsObj;
if (lhs.Count() == 0) return Bry_.Compare(rhs.End(), lhs.Bgn());
//else if (rhs.Count() == 0) return Bry_.Compare(lhs.End(), rhs.End()); // NOTE: this line mirrors the top, but is actually covered by below
else return Bry_.Compare(lhs.End(), rhs.End());
}
public static final Xowd_ttl_file_comparer_end _ = new Xowd_ttl_file_comparer_end(); Xowd_ttl_file_comparer_end() {}
}

View File

@@ -0,0 +1,76 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.lists.*;
public class Xowd_regy_mgr {
public static final int Not_found = -1;
public Xowd_regy_mgr() {}
public Xowd_regy_mgr(Io_url fil) {this.Init(fil);}
public Io_url Fil() {return fil;} Io_url fil;
public void Init(Io_url fil) {this.fil = fil; files_ary = Xowd_hive_regy_itm.parse_fil_(ByteAry_fil._.Ini_file(fil));}
public Xowd_hive_regy_itm[] Files_ary() {return files_ary;} private Xowd_hive_regy_itm[] files_ary;
public void Clear() {files_ary = Xowd_hive_regy_itm.Ary_empty;}
public int Files_find(byte[] key) {
if (files_ary.length == 0) return Xowd_regy_mgr.Regy_null; // NOTE: FindSlot does not accept empty ary; returning 0, b/c Find returns likely file_idx; EX: regy of 0|B|D and 1|F|H; A returns 0; Z returns 1
return CompareAble_.FindSlot(comparer, files_ary, comparer_itm.End_(key));
} ComparerAble comparer = Xowd_ttl_file_comparer_end._; Xowd_hive_regy_itm comparer_itm = Xowd_hive_regy_itm.tmp_().Count_(1);
public Xowd_hive_regy_itm Create(byte[] key) {
int itm_idx = files_ary.length;
files_ary = (Xowd_hive_regy_itm[])Array_.Resize(files_ary, itm_idx + 1);
Xowd_hive_regy_itm rv = new Xowd_hive_regy_itm(itm_idx).Bgn_(key).End_(key).Count_(1);
files_ary[itm_idx] = rv;
return rv;
}
public Xowd_hive_regy_itm Update_add(int fil_idx, byte[] key) {
Xowd_hive_regy_itm rv = files_ary[fil_idx];
rv.Count_(rv.Count() + 1);
if (Bry_.Compare(key, rv.Bgn()) < CompareAble_.Same)
rv.Bgn_(key);
else if (Bry_.Compare(key, rv.End()) > CompareAble_.Same)
rv.End_(key);
return rv;
}
public boolean Update_change(int fil_idx, byte[] old_key, byte[] new_key) {
Xowd_hive_regy_itm rv = files_ary[fil_idx];
boolean changed = false;
if (Bry_.Eq(old_key, rv.Bgn())) {
rv.Bgn_(new_key);
changed = true;
}
else if (Bry_.Eq(old_key, rv.End())) {
rv.End_(new_key);
changed = true;
}
return changed;
}
public Xowd_hive_regy_itm Update_del(int fil_idx, byte[] key) {
Xowd_hive_regy_itm itm = files_ary[fil_idx];
itm.Count_(itm.Count() - 1);
throw Err_.not_implemented_(); // FUTURE: note that deletes are harder; rng ends could be deleted, so would need to open file and get new rng end
}
public void Save() {
Bry_bfr bfr = Bry_bfr.new_();
int len = files_ary.length;
for (int i = 0; i < len; i++) {
Xowd_hive_regy_itm itm = files_ary[i];
itm.Srl_save(bfr);
}
Io_mgr._.SaveFilBfr(fil, bfr);
}
public static final int Regy_null = -1;
}

View File

@@ -0,0 +1,88 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*;
public class Xowd_regy_mgr_tst {
Xowd_regy_mgr_fxt fxt = new Xowd_regy_mgr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Create_cur_is_empty() {fxt.Create("A").Save().Tst_file(String_.Concat_lines_nl("0|A|A|1"));}
@Test public void Create_cur_has_one() {fxt.Load(String_.Concat_lines_nl("0|A|A|1")).Create("B").Save().Tst_file(String_.Concat_lines_nl("0|A|A|1", "1|B|B|1"));}
@Test public void Update_1st_end() {fxt.Load(String_.Concat_lines_nl("0|B|B|1")).Update_add(0, "C").Save().Tst_file(String_.Concat_lines_nl("0|B|C|2"));}
@Test public void Update_1st_bgn() {fxt.Load(String_.Concat_lines_nl("0|B|B|1")).Update_add(0, "A").Save().Tst_file(String_.Concat_lines_nl("0|A|B|2"));}
@Test public void Update_mid() {fxt.Load(String_.Concat_lines_nl("0|B|D|2")).Update_add(0, "C").Save().Tst_file(String_.Concat_lines_nl("0|B|D|3"));}
@Test public void Update_bgn() {fxt.Load(String_.Concat_lines_nl("0|B|D|2")).Update_add(0, "A").Save().Tst_file(String_.Concat_lines_nl("0|A|D|3"));}
@Test public void Update_end() {fxt.Load(String_.Concat_lines_nl("0|B|D|2")).Update_add(0, "E").Save().Tst_file(String_.Concat_lines_nl("0|B|E|3"));}
@Test public void Update_change_bgn() {fxt.Load(String_.Concat_lines_nl("0|B|D|2")).Update_change(0, "B", "A").Save().Tst_file(String_.Concat_lines_nl("0|A|D|2"));}
@Test public void Update_change_end() {fxt.Load(String_.Concat_lines_nl("0|B|D|2")).Update_change(0, "D", "E").Save().Tst_file(String_.Concat_lines_nl("0|B|E|2"));}
@Test public void Update_change_mid() {fxt.Load(String_.Concat_lines_nl("0|B|D|2")).Update_change(0, "C1", "C2").Save().Tst_file(String_.Concat_lines_nl("0|B|D|2"));}
@Test public void Find_none() {fxt.Tst_find("A", Xowd_regy_mgr.Regy_null);}
@Test public void Find_existing() {
fxt.Load(String_.Concat_lines_nl
( "0|B|D|3"
, "1|E|G|3"
, "2|H|J|3"
))
.Tst_find("B", 0).Tst_find("C", 0).Tst_find("D", 0)
.Tst_find("A", 0)
.Tst_find("Z", 2)
.Tst_find("Da", 1)
;
}
@Test public void Find_existing_null() {
fxt.Load(String_.Concat_lines_nl
( "0|B|D|3"
, "1|D|H|0"
, "2|H|J|3"
))
.Tst_find("B", 0).Tst_find("C", 0).Tst_find("D", 0)
.Tst_find("A", 0)
.Tst_find("Z", 2)
.Tst_find("Da", 1) // rely on
;
}
}
class Xowd_regy_mgr_fxt {
Xowd_regy_mgr mgr; Io_url mgr_url;
public void Clear() {
if (mgr == null) {
mgr_url = Io_url_.mem_fil_("mem/hive_regy.csv");
Io_mgr._.DeleteFil(mgr_url);
mgr = new Xowd_regy_mgr(mgr_url);
}
else {
mgr.Clear();
}
}
public Xowd_regy_mgr_fxt Create(String key) {mgr.Create(Bry_.new_ascii_(key)); return this;}
public Xowd_regy_mgr_fxt Update_add(int fil_idx, String key) {mgr.Update_add(fil_idx, Bry_.new_ascii_(key)); return this;}
public Xowd_regy_mgr_fxt Update_change(int fil_idx, String old_key, String new_key) {mgr.Update_change(fil_idx, Bry_.new_ascii_(old_key), Bry_.new_ascii_(new_key)); return this;}
public Xowd_regy_mgr_fxt Load(String lines) {
Io_mgr._.SaveFilStr(mgr_url, lines);
mgr = new Xowd_regy_mgr(mgr_url);
return this;
}
public Xowd_regy_mgr_fxt Save() {mgr.Save(); return this;}
public Xowd_regy_mgr_fxt Tst_file(String expd) {
Tfds.Eq_str_lines(expd, Io_mgr._.LoadFilStr(mgr_url));
return this;
}
public Xowd_regy_mgr_fxt Tst_find(String find, int expd) {
Tfds.Eq(expd, mgr.Files_find(Bry_.new_ascii_(find)));
return this;
}
}