v3.3.4 v3.1.3.1
gnosygnu 8 years ago
parent 096045614c
commit 235228976e

@ -23,6 +23,7 @@ public class Bry_ {
public static final byte[] Empty = new byte[0];
public static final byte[][] Ary_empty = new byte[0][];
public static final Class<?> Cls_ref_type = byte[].class;
public static byte[] cast(Object val) {return (byte[])val;}
public static byte[] New_by_byte(byte b) {return new byte[] {b};}
public static byte[] New_by_ints(int... ary) {
int len = ary.length;
@ -833,13 +834,16 @@ public class Bry_ {
if (src[i] == find) src[i] = replace;
}
}
public static byte[] Replace(byte[] src, byte find, byte replace) {
public static byte[] Replace(byte[] src, byte find, byte replace) {return Replace(src, 0, src.length, find, replace);}
public static byte[] Replace(byte[] src, int bgn, int end, byte find, byte replace) {
int src_len = src.length;
byte[] rv = new byte[src_len];
for (int i = 0; i < src_len; i++) {
for (int i = bgn; i < end; ++i) {
byte b = src[i];
rv[i] = b == find ? replace : b;
}
for (int i = end; i < src_len; ++i)
rv[i] = src[i];
return rv;
}
public static byte[] Replace_safe(Bry_bfr bfr, byte[] src, byte[] find, byte[] repl) {

@ -21,16 +21,9 @@ public class Io_url implements CompareAble, ParseAble, GfoInvkAble { //_20101005
public IoUrlInfo Info() {return info;} IoUrlInfo info;
public String Raw() {return raw;} final String raw;
public byte[] RawBry() {return Bry_.new_u8(raw);}
// public byte[] Http_file_bry() {
// try {return Bry_.new_u8(String_.Concat(http_file_str, java.net.URLEncoder.encode(raw, "UTF-8")));}
// catch (Exception e) {throw Err_.err_(e, "Http_file_bry");}
// }
public String To_http_file_str() {return Http_file_str + Http_file_str_encoder.Encode_str(raw);}
public byte[] To_http_file_bry() {
return Bry_.Add(Http_file_bry, Http_file_str_encoder.Encode_bry(raw));
}
public String To_http_file_str() {return String_.Len_eq_0(raw) ? String_.Empty : String_.Concat (Http_file_str, Http_file_str_encoder.Encode_str(raw));}
public byte[] To_http_file_bry() {return String_.Len_eq_0(raw) ? Bry_.Empty : Bry_.Add (Http_file_bry, Http_file_str_encoder.Encode_bry(raw));}
public static Url_encoder_interface Http_file_str_encoder = Url_encoder_interface_same.Instance;
public static final String Http_file_str = "file:///";
public static final int Http_file_len = String_.Len(Http_file_str);
public static final byte[] Http_file_bry = Bry_.new_a7(Http_file_str);

@ -37,6 +37,7 @@ public class Object_ {
else if (lhs == null || rhs == null) return false;
else return lhs.equals(rhs);
}
public static String Xto_str_or(Object v, String or) {return v == null ? or : ToString_lang(v);}
public static String Xto_str_strict_or_null(Object v) {return v == null ? null : ToString_lang(v);}
public static String Xto_str_strict_or_null_mark(Object v) {return v == null ? String_.Null_mark : ToString_lang(v);}
public static String Xto_str_strict_or_empty(Object v) {return v == null ? String_.Empty : ToString_lang(v);}

@ -534,6 +534,13 @@ public class String_ implements GfoInvkAble {
}
return trg_ary;
}
public static boolean Ary_eq(String[] lhs, String[] rhs) {
int lhs_len = lhs.length, rhs_len = rhs.length;
if (lhs_len != rhs_len) return false;
for (int i = 0; i < lhs_len; ++i)
if (!String_.Eq(lhs[i], rhs[i])) return false;
return true;
}
public static String To_str__as_kv_ary(String... ary) {
int len = ary.length;
Bry_bfr bfr = Bry_bfr.new_();

@ -24,6 +24,12 @@ public class Bry_err_wkr {
public void Fail_throws_err_(boolean v) {this.fail_throws_err = v;} private boolean fail_throws_err = true;
public void Init_by_page(String page, byte[] src) {this.page = page; this.src = src;}
public void Init_by_sect(String sect, int sect_bgn) {this.sect = sect; this.sect_bgn = sect_bgn;}
public void Warn(String msg, Object... args) {
boolean old = fail_throws_err;
fail_throws_err = false;
this.Fail(msg, args);
fail_throws_err = old;
}
public int Fail(String msg, Object... args) {return Fail(msg, sect_bgn, sect_bgn + 255, args);}
private int Fail(String msg, int excerpt_bgn, int excerpt_end, Object[] args) {
String err_msg = Make_msg(msg, excerpt_bgn, excerpt_end, args);

@ -16,14 +16,15 @@ 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.core.brys; import gplx.*; import gplx.core.*;
import gplx.core.errs.*;
import gplx.core.errs.*; import gplx.core.btries.*;
public class Bry_rdr {
private final gplx.core.primitives.Int_obj_ref pos_ref = gplx.core.primitives.Int_obj_ref.neg1_();
public byte[] Src() {return src;} private byte[] src;
public int Src_end() {return src_end;} private int src_end;
public int Pos() {return pos;} private int pos;
public byte[] Src() {return src;} protected byte[] src;
public int Src_end() {return src_end;} protected int src_end;
public int Pos() {return pos;} protected int pos;
public Bry_rdr Dflt_dlm_(byte b) {this.dflt_dlm = b; return this;} private byte dflt_dlm;
public Bry_rdr Fail_throws_err_(boolean v) {err_wkr.Fail_throws_err_(v); return this;}
public Bry_rdr Init_by_src(byte[] src) {err_wkr.Init_by_page("", src); this.pos = 0; this.src = src; this.src_end = src.length; return this;}
public Bry_rdr Init_by_page(byte[] page, byte[] src, int src_len) {err_wkr.Init_by_page(String_.new_u8(page), src); this.pos = 0; this.src = src; this.src_end = src_len; return this;}
public Bry_rdr Init_by_sect(String sect, int sect_bgn, int pos) {err_wkr.Init_by_sect(sect, sect_bgn); this.pos = pos; return this;}
public Bry_rdr Init_by_wkr (Bry_err_wkr wkr, String sect, int pos, int src_end) {
@ -72,7 +73,8 @@ public class Bry_rdr {
byte[] bry = Read_bry_to(to_char);
return Double_.parse(String_.new_a7(bry));
}
public int Read_int_to() {return Read_int_to(dflt_dlm);}
public int Read_int_to() {return Read_int_to(dflt_dlm);}
public int Read_int_to_non_num() {return Read_int_to(Byte_ascii.Null);}
public int Read_int_to(byte to_char) {
int bgn = pos;
int rv = 0;
@ -110,7 +112,7 @@ public class Bry_rdr {
return rv * negative;
}
public int Read_hzip_int(int reqd) {
int rv = gplx.xowa.htmls.core.hzips.Xoh_hzip_int_.Decode(reqd, src, src_end, pos, pos_ref);
int rv = gplx.core.encoders.Gfo_hzip_int_.Decode(reqd, src, src_end, pos, pos_ref);
pos = pos_ref.Val();
return rv;
}
@ -142,17 +144,61 @@ public class Bry_rdr {
pos = find_end;
return pos;
}
public byte Chk(gplx.core.btries.Btrie_slim_mgr trie) {return Chk(trie, pos, src_end);}
public byte Chk_or(gplx.core.btries.Btrie_slim_mgr trie, byte or) {return Chk_or(trie, pos, src_end, or);}
public byte Chk(gplx.core.btries.Btrie_slim_mgr trie, int itm_bgn, int itm_end) {
public byte Chk(Btrie_slim_mgr trie) {return Chk(trie, pos, src_end);}
public void Chk_trie_val(Btrie_slim_mgr trie, byte val) {
byte rv = Chk_or(trie, Byte_.Max_value_127);
if (rv == Byte_.Max_value_127) err_wkr.Fail("failed trie check", "mid", String_.new_u8(Bry_.Mid_by_len_safe(src, pos, 16)));
}
public Object Chk_trie_as_obj(Btrie_slim_mgr trie) {
Object rv = trie.Match_bgn(src, pos, src_end); if (rv == null) err_wkr.Fail("failed trie check", "mid", String_.new_u8(Bry_.Mid_by_len_safe(src, pos, 16)));
return rv;
}
public byte Chk_or(Btrie_slim_mgr trie, byte or) {return Chk_or(trie, pos, src_end, or);}
public byte Chk(Btrie_slim_mgr trie, int itm_bgn, int itm_end) {
byte rv = Chk_or(trie, itm_bgn, itm_end, Byte_.Max_value_127);
if (rv == Byte_.Max_value_127) {err_wkr.Fail("failed trie check", "mid", String_.new_u8(Bry_.Mid_by_len_safe(src, pos, 16))); return Byte_.Max_value_127;}
return rv;
}
public byte Chk_or(gplx.core.btries.Btrie_slim_mgr trie, int itm_bgn, int itm_end, byte or) {
public byte Chk_or(Btrie_slim_mgr trie, int itm_bgn, int itm_end, byte or) {
Object rv_obj = trie.Match_bgn(src, itm_bgn, itm_end);
if (rv_obj == null) return or;
pos = trie.Match_pos();
return ((gplx.core.primitives.Byte_obj_val)rv_obj).Val();
}
@gplx.Virtual public Bry_rdr Skip_ws() {
while (pos < src_end) {
switch (src[pos]) {
case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr: case Byte_ascii.Space:
++pos;
break;
default:
return this;
}
}
return this;
}
public Bry_rdr Skip_alpha_num_under() {
while (pos < src_end) {
switch (src[pos]) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
case Byte_ascii.Ltr_A: case Byte_ascii.Ltr_B: case Byte_ascii.Ltr_C: case Byte_ascii.Ltr_D: case Byte_ascii.Ltr_E:
case Byte_ascii.Ltr_F: case Byte_ascii.Ltr_G: case Byte_ascii.Ltr_H: case Byte_ascii.Ltr_I: case Byte_ascii.Ltr_J:
case Byte_ascii.Ltr_K: case Byte_ascii.Ltr_L: case Byte_ascii.Ltr_M: case Byte_ascii.Ltr_N: case Byte_ascii.Ltr_O:
case Byte_ascii.Ltr_P: case Byte_ascii.Ltr_Q: case Byte_ascii.Ltr_R: case Byte_ascii.Ltr_S: case Byte_ascii.Ltr_T:
case Byte_ascii.Ltr_U: case Byte_ascii.Ltr_V: case Byte_ascii.Ltr_W: case Byte_ascii.Ltr_X: case Byte_ascii.Ltr_Y: case Byte_ascii.Ltr_Z:
case Byte_ascii.Ltr_a: case Byte_ascii.Ltr_b: case Byte_ascii.Ltr_c: case Byte_ascii.Ltr_d: case Byte_ascii.Ltr_e:
case Byte_ascii.Ltr_f: case Byte_ascii.Ltr_g: case Byte_ascii.Ltr_h: case Byte_ascii.Ltr_i: case Byte_ascii.Ltr_j:
case Byte_ascii.Ltr_k: case Byte_ascii.Ltr_l: case Byte_ascii.Ltr_m: case Byte_ascii.Ltr_n: case Byte_ascii.Ltr_o:
case Byte_ascii.Ltr_p: case Byte_ascii.Ltr_q: case Byte_ascii.Ltr_r: case Byte_ascii.Ltr_s: case Byte_ascii.Ltr_t:
case Byte_ascii.Ltr_u: case Byte_ascii.Ltr_v: case Byte_ascii.Ltr_w: case Byte_ascii.Ltr_x: case Byte_ascii.Ltr_y: case Byte_ascii.Ltr_z:
case Byte_ascii.Underline:
++pos;
break;
default:
return this;
}
}
return this;
}
}

@ -15,9 +15,9 @@ 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.htmls.core.hzips; import gplx.*; import gplx.xowa.*; import gplx.xowa.htmls.*; import gplx.xowa.htmls.core.*;
import gplx.core.primitives.*; import gplx.core.encoders.*;
public class Xoh_hzip_int_ {
package gplx.core.encoders; import gplx.*; import gplx.core.*;
import gplx.core.primitives.*;
public class Gfo_hzip_int_ {
public static final int Neg_1_adj = 1;
public static void Encode(int reqd, Bry_bfr bfr, int val) {
int bfr_len = bfr.Len();

@ -15,9 +15,10 @@ 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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Meta_idx_itm {
public Meta_idx_itm(String name, String sql) {this.name = name; this.sql = sql;}
public String Name() {return name;} private final String name;
public String Sql() {return sql;} private final String sql;
package gplx.core.srls; import gplx.*; import gplx.core.*;
public class Dbmeta_dat_itm {
public Dbmeta_dat_itm(int tid, String key, Object val) {this.Tid = tid; this.Key = key; this.Val = val;}
public int Tid;
public String Key;
public Object Val;
}

@ -15,12 +15,16 @@ 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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Meta_fld_mgr {
package gplx.core.srls; import gplx.*; import gplx.core.*;
import gplx.dbs.metas.*;
public class Dbmeta_dat_mgr {
private final Ordered_hash hash = Ordered_hash_.New();
public Dbmeta_dat_mgr Clear() {hash.Clear(); return this;}
public int Len() {return hash.Count();}
public void Add(Meta_fld_itm itm) {hash.Add(itm.Name(), itm);}
public boolean Has(String name) {return hash.Has(name);}
public Meta_fld_itm Get_by(String name) {return (Meta_fld_itm)hash.Get_by(name);}
public Meta_fld_itm Get_at(int i) {return (Meta_fld_itm)hash.Get_at(i);}
public Dbmeta_dat_itm Get_at(int idx) {return (Dbmeta_dat_itm)hash.Get_at(idx);}
public Dbmeta_dat_mgr Add_int(String key, int val) {
Dbmeta_dat_itm itm = new Dbmeta_dat_itm(Dbmeta_fld_tid.Tid__int, key, val);
hash.Add(key, itm);
return this;
}
}

@ -15,10 +15,9 @@ 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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Meta_idx_mgr {
private final Ordered_hash hash = Ordered_hash_.New();
public void Add(Meta_idx_itm itm) {hash.Add(itm.Name(), itm);}
public boolean Has(String name) {return hash.Has(name);}
public Meta_idx_itm Get(String name) {return (Meta_idx_itm)hash.Get_by(name);}
package gplx.core.srls; import gplx.*; import gplx.core.*;
public interface Gfo_srl_ctx {
Gfo_srl_mgr_wtr Wtr_bgn(String key);
Gfo_srl_mgr_rdr Rdr_bgn(String key);
Dbmeta_dat_mgr Rdr_subs(String key);
}

@ -15,10 +15,9 @@ 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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Meta_tbl_itm {
public Meta_tbl_itm(String name, String sql) {this.name = name; this.sql = sql;}
public Meta_fld_mgr Flds() {return flds;} private final Meta_fld_mgr flds = new Meta_fld_mgr();
public String Name() {return name;} private final String name;
public String Sql() {return sql;} private final String sql;
package gplx.core.srls; import gplx.*; import gplx.core.*;
public interface Gfo_srl_itm {
Gfo_srl_itm Make_new(Gfo_srl_ctx ctx);
void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_rdr rdr);
void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_wtr wtr);
}

@ -0,0 +1,26 @@
/*
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.core.srls; import gplx.*; import gplx.core.*;
public interface Gfo_srl_mgr_rdr {
void Itm_bgn(String key);
void Itm_end();
boolean Get_bool (String key);
int Get_int (String key);
String Get_str (String key);
Object Get_subs (Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_itm proto, Dbmeta_dat_mgr crt_mgr);
}

@ -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.core.srls; import gplx.*; import gplx.core.*;
public interface Gfo_srl_mgr_wtr {
int Uid_next__as_int();
void Itm_bgn(String key);
void Itm_end();
void Set_bool (String key, boolean val);
void Set_int (String key, int val);
void Set_str (String key, String val);
Object Set_subs (Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_itm proto, Object subs, Dbmeta_dat_mgr crt_mgr);
}

@ -16,41 +16,41 @@ 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.dbs; import gplx.*;
import gplx.dbs.engines.*; import gplx.dbs.qrys.*; import gplx.core.stores.*;
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.engines.*; import gplx.dbs.qrys.*;
public class Db_conn {
private final List_adp rls_list = List_adp_.new_(); private final Db_engine engine;
public Db_conn(Db_engine engine) {this.engine = engine;}
public Db_conn_info Conn_info() {return engine.Conn_info();}
public boolean Eq(Db_conn comp) {return String_.Eq(engine.Conn_info().Xto_api(), comp.Conn_info().Xto_api());}
// public void Txn_bgn() {engine.Txn_bgn("");}
public void Txn_bgn(String name) {engine.Txn_bgn(name);}
public void Txn_end() {engine.Txn_end();}
public void Txn_cxl() {engine.Txn_cxl();}
public void Txn_sav() {engine.Txn_sav();}
public Db_stmt Stmt_insert(String tbl, Db_meta_fld_list flds) {return engine.New_stmt_prep(Db_qry_insert.new_(tbl, flds.To_str_ary_wo_autonum()));}
public Db_stmt Stmt_insert(String tbl, Dbmeta_fld_list flds) {return engine.New_stmt_prep(Db_qry_insert.new_(tbl, flds.To_str_ary_wo_autonum()));}
public Db_stmt Stmt_insert(String tbl, String... cols) {return engine.New_stmt_prep(Db_qry_insert.new_(tbl, cols));}
public Db_stmt Stmt_update(String tbl, String[] where, String... cols) {return engine.New_stmt_prep(Db_qry_update.new_(tbl, where, cols));}
public Db_stmt Stmt_update_exclude(String tbl, Db_meta_fld_list flds, String... where) {return engine.New_stmt_prep(Db_qry_update.new_(tbl, where, flds.To_str_ary_exclude(where)));}
public Db_stmt Stmt_update_exclude(String tbl, Dbmeta_fld_list flds, String... where) {return engine.New_stmt_prep(Db_qry_update.new_(tbl, where, flds.To_str_ary_exclude(where)));}
public Db_stmt Stmt_delete(String tbl, String... where) {return engine.New_stmt_prep(Db_qry_delete.new_(tbl, where));}
public Db_stmt Stmt_select(String tbl, String[] cols, String... where) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, cols, null));}
public Db_stmt Stmt_select(String tbl, Db_meta_fld_list flds, String... where) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, flds.To_str_ary(), null));}
public Db_stmt Stmt_select(String tbl, Dbmeta_fld_list flds, String... where) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, flds.To_str_ary(), null));}
public Db_stmt Stmt_select_max(String tbl, String col, String... where) {
Db_qry__select_in_tbl qry = new Db_qry__select_in_tbl(tbl, String_.Ary(String_.Format("Max({0}) AS {0}", col)), where, null, null, null, null);
return engine.New_stmt_prep(qry);
}
public Db_stmt Stmt_select_order(String tbl, Db_meta_fld_list flds, String[] where, String... orderbys) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, flds.To_str_ary(), orderbys));}
public Db_stmt Stmt_select_order(String tbl, Dbmeta_fld_list flds, String[] where, String... orderbys) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, flds.To_str_ary(), orderbys));}
public Db_stmt Stmt_select_order(String tbl, String[] flds, String[] where, String... orderbys) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, flds, orderbys));}
public Db_stmt Stmt_new(Db_qry qry) {return engine.New_stmt_prep(qry);}
public void Env_db_attach(String alias, Io_url db_url) {engine.Env_db_attach(alias, db_url);}
public void Env_db_detach(String alias) {engine.Env_db_detach(alias);}
public void Env_vacuum() {Exec_sql_plog_ntx("vacuuming: url=" + this.Conn_info().Xto_api(), "VACUUM;");}
public void Ddl_create_tbl(Db_meta_tbl meta) {engine.Ddl_create_tbl(meta); engine.Ddl_create_idx(Gfo_usr_dlg_.Noop, meta.Idxs());}
public void Ddl_create_idx(Db_meta_idx... idxs) {engine.Ddl_create_idx(Gfo_usr_dlg_.Instance, idxs);}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... idxs) {engine.Ddl_create_idx(usr_dlg, idxs);}
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {engine.Ddl_append_fld(tbl, fld);}
public void Ddl_create_tbl(Dbmeta_tbl_itm meta) {engine.Ddl_create_tbl(meta); engine.Ddl_create_idx(Gfo_usr_dlg_.Noop, meta.Idxs().To_ary());}
public void Ddl_create_idx(Dbmeta_idx_itm... idxs) {engine.Ddl_create_idx(Gfo_usr_dlg_.Instance, idxs);}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... idxs) {engine.Ddl_create_idx(usr_dlg, idxs);}
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {engine.Ddl_append_fld(tbl, fld);}
public void Ddl_delete_tbl(String tbl) {engine.Ddl_delete_tbl(tbl);}
public boolean Meta_tbl_exists(String tbl) {return engine.Meta_tbl_exists(tbl);}
public boolean Meta_fld_exists(String tbl, String fld) {return engine.Meta_fld_exists(tbl, fld);}
public Dbmeta_tbl_mgr Meta_tbl_load_all() {return engine.Meta_tbl_load_all();}
public void Rls_reg(Rls_able rls) {rls_list.Add(rls);}
public void Rls_conn() {
int len = rls_list.Count();

@ -32,5 +32,11 @@ public class Db_conn_bldr {
Db_conn rv = wkr.Get(url);
return rv == null ? Db_conn_.Noop : rv;
}
public Db_conn Get_or_autocreate(boolean autocreate, Io_url url) {
boolean exists = wkr.Exists(url);
if (exists) return Get(url);
if (autocreate) return New(url);
else throw Err_.new_("dbs", "db does not exist", "url", url.Raw());
}
public static final Db_conn_bldr Instance = new Db_conn_bldr(); Db_conn_bldr() {}
}

@ -0,0 +1,54 @@
/*
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.dbs; import gplx.*;
import gplx.dbs.metas.*;
public class Db_conn_utl {
public static Db_conn Conn__new(String url_rel) {
Db_conn_bldr.Instance.Reg_default_mem();
return Db_conn_bldr.Instance.Get_or_new(Io_url_.mem_fil_("mem/" + url_rel)).Conn();
}
public static void Tbl__delete(Db_conn conn, String tbl) {
conn.Ddl_delete_tbl(tbl);
}
public static void Tbl__new(Db_conn conn, String tbl, Dbmeta_fld_itm[] flds, Object[]... rows) {
conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl, flds));
int rows_len = rows.length;
Db_stmt stmt = conn.Stmt_insert(tbl, Dbmeta_fld_itm.To_str_ary(flds));
for (int i = 0; i < rows_len; ++i) {
Object[] row = rows[i];
int dat_len = row.length;
stmt.Clear();
for (int j = 0; j < dat_len; ++j) {
Dbmeta_fld_itm fld = flds[j];
String fld_name = fld.Name();
Object val = row[j];
switch (fld.Type().Tid_ansi()) {
case Dbmeta_fld_tid.Tid__bool: stmt.Val_bool_as_byte (fld_name, Bool_.cast(val)); break;
case Dbmeta_fld_tid.Tid__byte: stmt.Val_byte (fld_name, Byte_.cast(val)); break;
case Dbmeta_fld_tid.Tid__int: stmt.Val_int (fld_name, Int_.cast(val)); break;
case Dbmeta_fld_tid.Tid__long: stmt.Val_long (fld_name, Long_.cast(val)); break;
case Dbmeta_fld_tid.Tid__float: stmt.Val_float (fld_name, Float_.cast(val)); break;
case Dbmeta_fld_tid.Tid__double: stmt.Val_double (fld_name, Double_.cast(val)); break;
case Dbmeta_fld_tid.Tid__str: stmt.Val_str (fld_name, String_.cast(val)); break;
case Dbmeta_fld_tid.Tid__bry: stmt.Val_bry (fld_name, Bry_.cast(val)); break;
}
}
stmt.Exec_insert();
}
}
}

@ -44,7 +44,7 @@ public class Db_crt_ {
int len = ary.length;
int crt_idx = 0;
for (int i = 0; i < len; i++) {
String itm = ary[i]; if (itm == Db_meta_fld.Key_null) continue;
String itm = ary[i]; if (itm == Dbmeta_fld_itm.Key_null) continue;
Criteria crt = Db_crt_.eq_(itm, null);
rv = (crt_idx == 0) ? crt : Criteria_.And(rv, crt);
++crt_idx;

@ -1,47 +0,0 @@
/*
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.dbs; import gplx.*;
public class Db_meta_fld {
public Db_meta_fld(String name, int tid, int len) {
this.name = name; this.tid = tid; this.len = len;
this.nullable = false; this.primary = false; this.autonum = false; this.default_val = Default_value_null;
}
public int Tid() {return tid;} private final int tid;
public String Name() {return name;} private final String name;
public int Len() {return len;} private final int len;
public boolean Nullable() {return nullable;} public Db_meta_fld Nullable_y_() {nullable = true; return this;} private boolean nullable;
public boolean Primary() {return primary;} public Db_meta_fld Primary_y_() {primary = true; return this;} private boolean primary;
public boolean Autonum() {return autonum;} public Db_meta_fld Autonum_y_() {autonum = true; return this;} private boolean autonum;
public Object Default() {return default_val;} public Db_meta_fld Default_(Object v) {default_val = v; return this;} private Object default_val;
public static final int Tid_bool = 0, Tid_byte = 1, Tid_short = 2, Tid_int = 3, Tid_long = 4, Tid_float = 5, Tid_double = 6, Tid_str = 7, Tid_text = 8, Tid_bry = 9, Tid_decimal = 10, Tid_date = 11;
public static final String Key_null = null;
public static final int Len_null = -1;
public static final Object Default_value_null = null;
public static final String[] Ary_empty = String_.Ary_empty;
public static Db_meta_fld new_bool(String name) {return new Db_meta_fld(name, Tid_bool , Len_null);}
public static Db_meta_fld new_byte(String name) {return new Db_meta_fld(name, Tid_byte , Len_null);}
public static Db_meta_fld new_short(String name) {return new Db_meta_fld(name, Tid_short , Len_null);}
public static Db_meta_fld new_int(String name) {return new Db_meta_fld(name, Tid_int , Len_null);}
public static Db_meta_fld new_long(String name) {return new Db_meta_fld(name, Tid_long , Len_null);}
public static Db_meta_fld new_float(String name) {return new Db_meta_fld(name, Tid_float , Len_null);}
public static Db_meta_fld new_double(String name) {return new Db_meta_fld(name, Tid_double, Len_null);}
public static Db_meta_fld new_text(String name) {return new Db_meta_fld(name, Tid_text , Len_null);}
public static Db_meta_fld new_bry(String name) {return new Db_meta_fld(name, Tid_bry , Len_null);}
public static Db_meta_fld new_str(String name, int len) {return new Db_meta_fld(name, Tid_str , len);}
}

@ -1,35 +0,0 @@
/*
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.dbs; import gplx.*;
import gplx.dbs.sqls.*;
public class Db_meta_idx {
Db_meta_idx(String tbl, String name, boolean unique, String[] flds) {this.tbl = tbl; this.name = name; this.unique = unique; this.flds = flds;}
public String Tbl() {return tbl;} private final String tbl;
public String Name() {return name;} private final String name;
public boolean Unique() {return unique;} private final boolean unique;
public String[] Flds() {return flds;} private final String[] flds;
public String To_sql_create() {return Db_sqlbldr__sqlite.Instance.Bld_create_idx(this);}
public static Db_meta_idx new_unique_by_name(String tbl, String idx_name, String... flds) {return new Db_meta_idx(tbl, idx_name, Bool_.Y, flds);}
public static Db_meta_idx new_normal_by_name(String tbl, String idx_name, String... flds) {return new Db_meta_idx(tbl, idx_name, Bool_.N, flds);}
public static Db_meta_idx new_unique_by_tbl(String tbl, String name, String... flds) {return new Db_meta_idx(tbl, Bld_idx_name(tbl, name), Bool_.Y, flds);}
public static Db_meta_idx new_normal_by_tbl(String tbl, String name, String... flds) {return new Db_meta_idx(tbl, Bld_idx_name(tbl, name), Bool_.N, flds);}
public static Db_meta_idx new_unique_by_tbl_wo_null(String tbl, String name, String... flds) {return new Db_meta_idx(tbl, Bld_idx_name(tbl, name), Bool_.Y, String_.Ary_wo_null(flds));}
public static Db_meta_idx new_normal_by_tbl_wo_null(String tbl, String name, String... flds) {return new Db_meta_idx(tbl, Bld_idx_name(tbl, name), Bool_.N, String_.Ary_wo_null(flds));}
public static String Bld_idx_name(String tbl, String suffix) {return String_.Concat(tbl, "__", suffix);}
public static final Db_meta_idx[] Ary_empty = new Db_meta_idx[0];
}

@ -1,43 +0,0 @@
/*
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.dbs; import gplx.*;
import gplx.dbs.sqls.*;
public class Db_meta_tbl {
public Db_meta_tbl(String name, Db_meta_fld[] flds, Db_meta_idx[] idxs) {
if (idxs == null) idxs = Db_meta_idx.Ary_empty; // empty params will pass idxs of null; set to idxs[0] else null ref when calling create_table
this.name = name; this.flds = flds; this.idxs = idxs;
}
public String Name() {return name;} private final String name;
public Db_meta_fld[] Flds() {return flds;} private final Db_meta_fld[] flds;
public boolean Flds_has(String fld) {
if (flds_hash == null) {
flds_hash = Ordered_hash_.New();
int len = flds.length;
for (int i = 0; i < len; ++i) {
Db_meta_fld fld_itm = flds[i];
flds_hash.Add(fld_itm.Name(), fld_itm);
}
}
return flds_hash.Has(fld);
} private Ordered_hash flds_hash;
public Db_meta_idx[] Idxs() {return idxs;} private final Db_meta_idx[] idxs;
public String To_sql_create() {return Db_sqlbldr__sqlite.Instance.Bld_create_tbl(this);}
public static Db_meta_tbl new_(String name, Db_meta_fld_list flds, Db_meta_idx... idxs) {return new Db_meta_tbl(name, flds.To_fld_ary(), idxs);}
public static Db_meta_tbl new_(String name, Db_meta_fld[] flds, Db_meta_idx... idxs) {return new Db_meta_tbl(name, flds, idxs);}
public static Db_meta_tbl new_(String name, Db_meta_fld... flds) {return new Db_meta_tbl(name, flds, null);}
}

@ -57,7 +57,7 @@ class Db_sql_col_bldr {
int ord = -1;
for (int i = 0; i < ary.length; ++i) {
String fld_key = ary[i];
if (fld_key == Db_meta_fld.Key_null) continue;
if (fld_key == Dbmeta_fld_itm.Key_null) continue;
Db_sql_col__name fld = new Db_sql_col__name(++ord, fld_key);
tmp_list.Add(fld);
}

@ -54,8 +54,8 @@ public interface Db_stmt extends Rls_able {
int Exec_update();
int Exec_delete();
DataRdr Exec_select();
Db_rdr Exec_select__rls_manual();
Db_rdr Exec_select__rls_auto();
Db_rdr Exec_select__rls_auto(); // stmt is automatically released
Db_rdr Exec_select__rls_manual(); // stmt must be released manually; for "batch" insert
Object Exec_select_val();
void Ctor_stmt(Db_engine engine, Db_qry qry);
Db_stmt Clear();

@ -19,7 +19,7 @@ package gplx.dbs; import gplx.*;
public class Db_stmt_bldr {
private Db_conn conn; private Db_stmt create, update, delete;
private String tbl_name; private String[] flds_keys, flds_vals, flds_all;
public void Conn_(Db_conn v, String tbl_name, Db_meta_fld_list flds, String... flds_keys) {
public void Conn_(Db_conn v, String tbl_name, Dbmeta_fld_list flds, String... flds_keys) {
Conn_(v, tbl_name, flds.To_str_ary(), flds.To_str_ary_exclude(flds_keys), flds_keys);
}
public void Conn_(Db_conn v, String tbl_name, String[] flds_vals, String... flds_keys) {

@ -0,0 +1,64 @@
/*
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.dbs; import gplx.*;
import gplx.dbs.metas.*;
public class Dbmeta_fld_itm {
public Dbmeta_fld_itm(String name, Dbmeta_fld_tid type) {
this.name = name; this.type = type;
this.primary = false; this.autonum = false; this.default_val = Default_value_null;
}
public String Name() {return name;} private final String name;
public Dbmeta_fld_tid Type() {return type;} private final Dbmeta_fld_tid type;
public int Nullable_tid() {return nullable_tid;} public Dbmeta_fld_itm Nullable_tid_(int v) {nullable_tid = v; return this;} private int nullable_tid;
public Dbmeta_fld_itm Nullable_y_() {return Nullable_tid_(Nullable_null);}
public boolean Primary() {return primary;} public Dbmeta_fld_itm Primary_y_() {primary = true; return this;} private boolean primary;
public boolean Autonum() {return autonum;} public Dbmeta_fld_itm Autonum_y_() {autonum = true; return this;} private boolean autonum;
public Object Default() {return default_val;} public Dbmeta_fld_itm Default_(Object v) {default_val = v; return this;} private Object default_val;
public boolean Eq(Dbmeta_fld_itm comp) {
return String_.Eq(name, comp.name)
&& type.Eq(comp.type)
&& nullable_tid == comp.nullable_tid
&& primary == comp.primary
&& autonum == comp.autonum
&& Object_.Eq(default_val, comp.default_val);
}
public static final int Nullable_unknown = 0, Nullable_null = 1, Nullable_not_null = 2;
public static final Object Default_value_null = null;
public static final String Key_null = null;
public static final String[] Str_ary_empty = String_.Ary_empty;
public static final Dbmeta_fld_itm[] Ary_empty = new Dbmeta_fld_itm[0];
public static Dbmeta_fld_itm new_bool(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__bool);}
public static Dbmeta_fld_itm new_byte(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__byte);}
public static Dbmeta_fld_itm new_short(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__short);}
public static Dbmeta_fld_itm new_int(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__int);}
public static Dbmeta_fld_itm new_long(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__long);}
public static Dbmeta_fld_itm new_float(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__float);}
public static Dbmeta_fld_itm new_double(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__double);}
public static Dbmeta_fld_itm new_text(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__text);}
public static Dbmeta_fld_itm new_bry(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__bry);}
public static Dbmeta_fld_itm new_str(String name, int len) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__str(len));}
public static String[] To_str_ary(Dbmeta_fld_itm[] ary) {
int len = ary.length;
String[] rv = new String[len];
for (int i = 0; i < len; ++i)
rv[i] = ary[i].name;
return rv;
}
}

@ -16,19 +16,19 @@ 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.dbs; import gplx.*;
public class Db_meta_fld_list {
public class Dbmeta_fld_list {
private final Ordered_hash flds = Ordered_hash_.New();
private final List_adp keys = List_adp_.new_();
public void Clear() {flds.Clear(); keys.Clear(); str_ary = null; fld_ary = null;}
public Db_meta_fld Get_by(String name) {return (Db_meta_fld)flds.Get_by(name);}
public Db_meta_fld Get_at(int idx) {return (Db_meta_fld)flds.Get_at(idx);}
public Dbmeta_fld_itm Get_by(String name) {return (Dbmeta_fld_itm)flds.Get_by(name);}
public Dbmeta_fld_itm Get_at(int idx) {return (Dbmeta_fld_itm)flds.Get_at(idx);}
public String[] To_str_ary() {if (str_ary == null) str_ary = (String[])keys.To_ary(String.class); return str_ary;} private String[] str_ary;
public Db_meta_fld[] To_fld_ary() {if (fld_ary == null) fld_ary = (Db_meta_fld[])flds.To_ary(Db_meta_fld.class); return fld_ary;} private Db_meta_fld[] fld_ary;
public Dbmeta_fld_itm[] To_fld_ary() {if (fld_ary == null) fld_ary = (Dbmeta_fld_itm[])flds.To_ary(Dbmeta_fld_itm.class); return fld_ary;} private Dbmeta_fld_itm[] fld_ary;
public String[] To_str_ary_wo_autonum() {
int len = flds.Count();
List_adp rv = List_adp_.new_();
for (int i = 0; i < len; ++i) {
Db_meta_fld fld = (Db_meta_fld)flds.Get_at(i);
Dbmeta_fld_itm fld = (Dbmeta_fld_itm)flds.Get_at(i);
if (fld.Autonum()) continue;
rv.Add(fld.Name());
}
@ -44,7 +44,7 @@ public class Db_meta_fld_list {
}
int fld_len = flds.Count();
for (int i = 0; i < fld_len; ++i) {
Db_meta_fld fld = (Db_meta_fld)flds.Get_at(i);
Dbmeta_fld_itm fld = (Dbmeta_fld_itm)flds.Get_at(i);
String fld_key = fld.Name();
if (ary_hash.Has(fld_key)) continue;
rv.Add(fld_key);
@ -52,29 +52,29 @@ public class Db_meta_fld_list {
return rv.To_str_ary();
}
public boolean Has(String key) {return flds.Has(key);}
public String Add_bool(String name) {return Add(Db_meta_fld.new_bool(name));}
public String Add_byte(String name) {return Add(Db_meta_fld.new_byte(name));}
public String Add_short(String name) {return Add(Db_meta_fld.new_short(name));}
public String Add_int(String name) {return Add(Db_meta_fld.new_int(name));}
public String Add_int_pkey(String name) {return Add(Db_meta_fld.new_int(name).Primary_y_());}
public String Add_int_pkey_autonum(String name) {return Add(Db_meta_fld.new_int(name).Primary_y_().Autonum_y_());}
public String Add_int_autonum(String name) {return Add(Db_meta_fld.new_int(name).Autonum_y_());}
public String Add_int_dflt(String name, int dflt) {return Add(Db_meta_fld.new_int(name).Default_(dflt));}
public String Add_long(String name) {return Add(Db_meta_fld.new_long(name));}
public String Add_float(String name) {return Add(Db_meta_fld.new_float(name));}
public String Add_double(String name) {return Add(Db_meta_fld.new_double(name));}
public String Add_text(String name) {return Add(Db_meta_fld.new_text(name));}
public String Add_bry(String name) {return Add(Db_meta_fld.new_bry(name));}
public String Add_str(String name, int len) {return Add(Db_meta_fld.new_str(name, len));}
public String Add_str_pkey(String name, int len) {return Add(Db_meta_fld.new_str(name, len).Primary_y_());}
public String Add_str_null(String name, int len) {return Add(Db_meta_fld.new_str(name, len).Nullable_y_());}
public String Add_bool(String name) {return Add(Dbmeta_fld_itm.new_bool(name));}
public String Add_byte(String name) {return Add(Dbmeta_fld_itm.new_byte(name));}
public String Add_short(String name) {return Add(Dbmeta_fld_itm.new_short(name));}
public String Add_int(String name) {return Add(Dbmeta_fld_itm.new_int(name));}
public String Add_int_pkey(String name) {return Add(Dbmeta_fld_itm.new_int(name).Primary_y_());}
public String Add_int_pkey_autonum(String name) {return Add(Dbmeta_fld_itm.new_int(name).Primary_y_().Autonum_y_());}
public String Add_int_autonum(String name) {return Add(Dbmeta_fld_itm.new_int(name).Autonum_y_());}
public String Add_int_dflt(String name, int dflt) {return Add(Dbmeta_fld_itm.new_int(name).Default_(dflt));}
public String Add_long(String name) {return Add(Dbmeta_fld_itm.new_long(name));}
public String Add_float(String name) {return Add(Dbmeta_fld_itm.new_float(name));}
public String Add_double(String name) {return Add(Dbmeta_fld_itm.new_double(name));}
public String Add_text(String name) {return Add(Dbmeta_fld_itm.new_text(name));}
public String Add_bry(String name) {return Add(Dbmeta_fld_itm.new_bry(name));}
public String Add_str(String name, int len) {return Add(Dbmeta_fld_itm.new_str(name, len));}
public String Add_str_pkey(String name, int len) {return Add(Dbmeta_fld_itm.new_str(name, len).Primary_y_());}
public String Add_str_null(String name, int len) {return Add(Dbmeta_fld_itm.new_str(name, len).Nullable_y_());}
public String Add_str_dflt(String name, int len, String dflt)
{return Add(Db_meta_fld.new_str(name, len).Default_(dflt));}
public String Add(Db_meta_fld fld) {
{return Add(Dbmeta_fld_itm.new_str(name, len).Default_(dflt));}
public String Add(Dbmeta_fld_itm fld) {
String name = fld.Name();
flds.Add(name, fld);
keys.Add(name);
return name;
}
public static Db_meta_fld_list new_() {return new Db_meta_fld_list();}
public static Dbmeta_fld_list new_() {return new Dbmeta_fld_list();}
}

@ -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.dbs; import gplx.*;
import gplx.dbs.sqls.*; import gplx.dbs.metas.*;
public class Dbmeta_idx_itm {
public Dbmeta_idx_itm(boolean unique, String tbl, String name, Dbmeta_idx_fld[] flds) {
this.tbl = tbl; this.name = name; this.unique = unique; this.Flds = flds;
}
public String Tbl() {return tbl;} private final String tbl;
public String Name() {return name;} private final String name;
public boolean Unique() {return unique;} private final boolean unique;
public final Dbmeta_idx_fld[] Flds;
public String To_sql_create() {return Db_sqlbldr__sqlite.Instance.Bld_create_idx(this);}
public boolean Eq(Dbmeta_idx_itm comp) {
return String_.Eq(name, comp.name)
&& unique == comp.unique
&& tbl == comp.tbl
&& Dbmeta_idx_fld.Ary_eq(Flds, comp.Flds);
}
public static Dbmeta_idx_itm new_unique_by_name (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.Y, tbl, name, To_fld_ary(flds));}
public static Dbmeta_idx_itm new_normal_by_name (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.N, tbl, name, To_fld_ary(flds));}
public static Dbmeta_idx_itm new_unique_by_tbl (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.Y, tbl, Bld_idx_name(tbl, name), To_fld_ary(flds));}
public static Dbmeta_idx_itm new_normal_by_tbl (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.N, tbl, Bld_idx_name(tbl, name), To_fld_ary(flds));}
public static Dbmeta_idx_itm new_unique_by_tbl_wo_null (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.Y, tbl, Bld_idx_name(tbl, name), To_fld_ary(flds));}
public static Dbmeta_idx_itm new_normal_by_tbl_wo_null (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.N, tbl, Bld_idx_name(tbl, name), To_fld_ary(flds));}
public static String Bld_idx_name(String tbl, String suffix) {return String_.Concat(tbl, "__", suffix);}
public static final Dbmeta_idx_itm[] Ary_empty = new Dbmeta_idx_itm[0];
public static Dbmeta_idx_fld[] To_fld_ary(String[] ary) {
int len = ary.length;
Dbmeta_idx_fld[] rv = new Dbmeta_idx_fld[len];
int order = -1;
for (int i = 0; i < len; ++i) {
String itm = ary[i]; if (itm == null) continue;
rv[i] = new Dbmeta_idx_fld(++order, itm, Dbmeta_idx_fld.Sort_tid__none);
}
return rv;
}
}

@ -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.dbs; import gplx.*;
import gplx.dbs.metas.*; import gplx.dbs.sqls.*;
public class Dbmeta_tbl_itm {
public String Name() {return name;} private String name;
public Dbmeta_idx_mgr Idxs() {return idxs;} private final Dbmeta_idx_mgr idxs = new Dbmeta_idx_mgr();
public Dbmeta_fld_mgr Flds() {return flds;} private final Dbmeta_fld_mgr flds = new Dbmeta_fld_mgr();
public String To_sql_create() {return Db_sqlbldr__sqlite.Instance.Bld_create_tbl(this);}
public static Dbmeta_tbl_itm New(String name, Dbmeta_fld_list flds, Dbmeta_idx_itm... idxs) {return New(name, flds.To_fld_ary(), idxs);}
public static Dbmeta_tbl_itm New(String name, Dbmeta_fld_itm... flds) {return New(name, flds, Dbmeta_idx_itm.Ary_empty);}
public static Dbmeta_tbl_itm New(String name, Dbmeta_fld_itm[] flds, Dbmeta_idx_itm... idxs) {
Dbmeta_tbl_itm rv = new Dbmeta_tbl_itm();
rv.name = name;
if (flds != null) {
int flds_len = flds.length;
for (int i = 0; i < flds_len; ++i)
rv.flds.Add(flds[i]);
}
if (idxs != null) {
int idxs_len = idxs.length;
for (int i = 0; i < idxs_len; ++i)
rv.idxs.Add(idxs[i]);
}
return rv;
}
}

@ -0,0 +1,58 @@
/*
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.dbs.diffs; import gplx.*; import gplx.dbs.*;
import gplx.dbs.metas.*; import gplx.dbs.diffs.builds.*;
class Gfdb_diff_cmd {
private final Gfdb_diff_wkr__db diff_bldr_wkr = new Gfdb_diff_wkr__db();
private final Gfdb_diff_bldr diff_bldr = new Gfdb_diff_bldr();
public Gfdb_diff_cmd() {
diff_bldr.Init(diff_bldr_wkr);
}
public Gfdb_diff_job New_job(Gfdb_diff_db db, String guid, String name, String made_by, String desc) {
return new Gfdb_diff_job(db);
}
public void Bld(Gfdb_diff_job job, Gfdb_diff_tbl_mgr lhs_mgr, Gfdb_diff_tbl_mgr rhs_mgr) {
diff_bldr_wkr.Init_conn(job.Db(), 1000);
int rhs_len = rhs_mgr.Len();
for (int i = 0; i < rhs_len; ++i) {
Gfdb_diff_tbl rhs_tbl = rhs_mgr.Get_at(i);
Gfdb_diff_tbl lhs_tbl = lhs_mgr.Get_by(rhs_tbl.Name);
if (lhs_tbl == null) {
// Add_cmd_tbl_create();
// Add_cmd_tbl_insert_all());
}
else {
// Compare_flds();
// Compare_idxs();
// diff_bldr.Compare(lhs_tbl, rhs_tbl);
}
}
int lhs_len = lhs_mgr.Len();
for (int i = 0; i < lhs_len; ++i) {
Gfdb_diff_tbl lhs_tbl = lhs_mgr.Get_at(i);
if (lhs_tbl == null) {
// Add_cmd_dat_delete_all());
// Add_cmd_tbl_delete();
}
}
}
}
class Gfdb_diff_job {
public Gfdb_diff_job(Gfdb_diff_db db) {this.db = db;}
public Gfdb_diff_db Db() {return db;} private Gfdb_diff_db db;
}

@ -0,0 +1,86 @@
/*
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.dbs.diffs; import gplx.*; import gplx.dbs.*;
import gplx.dbs.metas.*;
public class Gfdb_diff_tbl {
public Gfdb_diff_tbl(String name, Dbmeta_fld_itm[] flds, Dbmeta_fld_itm[] keys, Dbmeta_fld_itm[] vals) {
this.Name = name; this.Flds = flds; this.Keys = keys; this.Vals = vals;
}
public final String Name;
public final Dbmeta_fld_itm[] Flds;
public final Dbmeta_fld_itm[] Keys;
public final Dbmeta_fld_itm[] Vals;
public Db_rdr Make_rdr(Db_conn conn) {
Db_stmt stmt = conn.Stmt_select(Name, Dbmeta_fld_itm.To_str_ary(Flds));
return stmt.Exec_select__rls_auto();
}
public static Gfdb_diff_tbl New(Dbmeta_tbl_itm tbl) {
Dbmeta_fld_mgr flds = tbl.Flds();
Dbmeta_fld_mgr keys = Calc_keys(tbl);
Dbmeta_fld_mgr vals = Calc_vals(tbl.Flds(), keys);
return new Gfdb_diff_tbl(tbl.Name(), flds.To_ary(), keys.To_ary(), vals.To_ary());
}
public static Dbmeta_fld_mgr Calc_keys(Dbmeta_tbl_itm tbl) {
Dbmeta_fld_mgr rv = new Dbmeta_fld_mgr();
// try to find primary
Dbmeta_fld_mgr flds = tbl.Flds();
int flds_len = flds.Len();
for (int i = 0; i < flds_len; ++i) {
Dbmeta_fld_itm fld = flds.Get_at(i);
if (fld.Primary()) {
rv.Add(fld);
return rv;
}
}
// try to find shortest unique index
Dbmeta_idx_itm unique_idx = null; int unique_idx_len = Int_.Max_value;
Dbmeta_idx_mgr idxs = tbl.Idxs();
int idxs_len = idxs.Len();
for (int i = 0; i < idxs_len; ++i) {
Dbmeta_idx_itm idx = idxs.Get_at(i);
if (idx.Unique() && idx.Flds.length < unique_idx_len) { // get first shortest unique index; note that "<" is "get first" whereas "<=" is "get last"
unique_idx = idx;
unique_idx_len = idx.Flds.length;
break;
}
}
if (unique_idx != null) {
Dbmeta_idx_fld[] idx_flds = unique_idx.Flds;
int idx_flds_len = idx_flds.length;
for (int i = 0; i < idx_flds_len; ++i)
rv.Add(flds.Get_by(idx_flds[i].Name));
return rv;
}
// just add all
for (int i = 0; i < flds_len; ++i) {
Dbmeta_fld_itm fld = flds.Get_at(i);
rv.Add(fld);
}
return rv;
}
private static Dbmeta_fld_mgr Calc_vals(Dbmeta_fld_mgr flds, Dbmeta_fld_mgr keys) {
Dbmeta_fld_mgr rv = new Dbmeta_fld_mgr();
int flds_len = flds.Len();
for (int i = 0; i < flds_len; ++i) {
Dbmeta_fld_itm fld = flds.Get_at(i);
if (!keys.Has(fld.Name())) rv.Add(fld);
}
return rv;
}
}

@ -0,0 +1,35 @@
/*
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.dbs.diffs; import gplx.*; import gplx.dbs.*;
class Gfdb_diff_tbl_mgr {
private final Ordered_hash hash = Ordered_hash_.New();
public int Len() {return hash.Count();}
public Gfdb_diff_tbl Get_at(int idx) {return (Gfdb_diff_tbl)hash.Get_at(idx);}
public Gfdb_diff_tbl Get_by(String key) {return (Gfdb_diff_tbl)hash.Get_by(key);}
}
class Gfdb_diff_tbl_mgr__sqlite {
public void Fill(Gfdb_diff_tbl_mgr tbl_mgr, Db_conn conn) {
// String schema_str = ""; // conn.Get_schema();
}
public void Fill(Gfdb_diff_tbl_mgr tbl_mgr, String schema_str) {
/*
Db_conn conn = null;
conn.Meta_get_tbls(Gfdb_diff_tbl_mgr tbl_mgr, "");
*/
}
}

@ -0,0 +1,59 @@
/*
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.dbs.diffs; import gplx.*; import gplx.dbs.*;
import gplx.dbs.metas.*;
public class Gfdb_rdr_utl_ {
public static int Compare(Dbmeta_fld_itm[] flds, int len, Db_rdr lhs_rdr, Db_rdr rhs_rdr) {
int comp = CompareAble_.Same;
for (int i = 0; i < len; ++i) {
Dbmeta_fld_itm fld = flds[i];
String fld_name = fld.Name();
int tid = fld.Type().Tid_ansi();
switch (tid) {
case Dbmeta_fld_tid.Tid__bool: comp = Bool_.Compare (lhs_rdr.Read_bool_by_byte(fld_name), rhs_rdr.Read_bool_by_byte(fld_name)); break;
case Dbmeta_fld_tid.Tid__int: comp = Int_.Compare (lhs_rdr.Read_int(fld_name) , rhs_rdr.Read_int(fld_name)); break;
case Dbmeta_fld_tid.Tid__long: comp = Long_.Compare (lhs_rdr.Read_long(fld_name) , rhs_rdr.Read_long(fld_name)); break;
case Dbmeta_fld_tid.Tid__float: comp = Float_.Compare (lhs_rdr.Read_float(fld_name) , rhs_rdr.Read_float(fld_name)); break;
case Dbmeta_fld_tid.Tid__double: comp = Double_.Compare (lhs_rdr.Read_double(fld_name) , rhs_rdr.Read_double(fld_name)); break;
case Dbmeta_fld_tid.Tid__str: comp = String_.Compare (lhs_rdr.Read_str(fld_name) , rhs_rdr.Read_str(fld_name)); break;
case Dbmeta_fld_tid.Tid__bry: comp = Bry_.Compare (lhs_rdr.Read_bry(fld_name) , rhs_rdr.Read_bry(fld_name)); break;
default: throw Err_.new_unhandled(tid);
}
if (comp != CompareAble_.Same) return comp;
}
return CompareAble_.Same;
}
public static void Stmt_args(Db_stmt stmt, Dbmeta_fld_itm[] flds, int len, Db_rdr rdr) {
for (int i = 0; i < len; ++i) {
Dbmeta_fld_itm fld = flds[i];
String fld_name = fld.Name();
int tid = fld.Type().Tid_ansi();
switch (tid) {
case Dbmeta_fld_tid.Tid__bool: stmt.Val_bool_as_byte (fld_name, rdr.Read_bool_by_byte(fld_name)); break;
case Dbmeta_fld_tid.Tid__byte: stmt.Val_byte (fld_name, rdr.Read_byte(fld_name)); break;
case Dbmeta_fld_tid.Tid__int: stmt.Val_int (fld_name, rdr.Read_int(fld_name)); break;
case Dbmeta_fld_tid.Tid__long: stmt.Val_long (fld_name, rdr.Read_long(fld_name)); break;
case Dbmeta_fld_tid.Tid__float: stmt.Val_float (fld_name, rdr.Read_float(fld_name)); break;
case Dbmeta_fld_tid.Tid__double: stmt.Val_double (fld_name, rdr.Read_double(fld_name)); break;
case Dbmeta_fld_tid.Tid__str: stmt.Val_str (fld_name, rdr.Read_str(fld_name)); break;
case Dbmeta_fld_tid.Tid__bry: stmt.Val_bry (fld_name, rdr.Read_bry(fld_name)); break;
default: throw Err_.new_unhandled(tid);
}
}
}
}

@ -21,16 +21,17 @@ public class Gfdb_diff_bldr {
private Gfdb_diff_rdr_comparer rdr_comparer = new Gfdb_diff_rdr_comparer();
private Gfdb_diff_wkr diff_wkr;
public void Init(Gfdb_diff_wkr diff_wkr) {this.diff_wkr = diff_wkr;}
public void Compare(Gfdb_diff_tbl lhs_tbl, Gfdb_diff_tbl rhs_tbl) {
rdr_comparer.Init(lhs_tbl, rhs_tbl);
diff_wkr.Init_tbls(lhs_tbl, rhs_tbl);
public void Compare(Gfdb_diff_tbl tbl, Db_conn old_conn, Db_conn new_conn) {
Db_rdr old_rdr = tbl.Make_rdr(old_conn), new_rdr = tbl.Make_rdr(new_conn);
rdr_comparer.Init_rdrs(tbl, old_rdr, new_rdr);
diff_wkr.Init_rdrs(tbl, old_rdr, new_rdr);
boolean loop = true;
while (loop) {
int rslt = rdr_comparer.Compare();
switch (rslt) {
case Gfdb_diff_rdr_comparer.Rslt__same: diff_wkr.Handle_same(); break;
case Gfdb_diff_rdr_comparer.Rslt__lhs_missing: diff_wkr.Handle_lhs_missing(); break;
case Gfdb_diff_rdr_comparer.Rslt__rhs_missing: diff_wkr.Handle_rhs_missing(); break;
case Gfdb_diff_rdr_comparer.Rslt__old_missing: diff_wkr.Handle_old_missing(); break;
case Gfdb_diff_rdr_comparer.Rslt__new_missing: diff_wkr.Handle_new_missing(); break;
case Gfdb_diff_rdr_comparer.Rslt__done: loop = false; break;
}
}

@ -0,0 +1,105 @@
/*
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.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import org.junit.*;
import gplx.dbs.*; import gplx.dbs.metas.*; import gplx.dbs.engines.mems.*;
public class Gfdb_diff_bldr_tst {
private final Gfdb_diff_bldr_fxt fxt = new Gfdb_diff_bldr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Same() {
fxt.Init__tbl__old(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Init__tbl__cur(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Test__bld();
}
@Test public void Update() {
fxt.Init__tbl__old(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Init__tbl__cur(Object_.Ary(1, "A1") , Object_.Ary(2, "B1"));
fxt.Test__bld("U|1|A1", "U|2|B1");
}
@Test public void Insert() {
fxt.Init__tbl__old(Object_.Ary(1, "A"));
fxt.Init__tbl__cur(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Test__bld("I|2|B");
}
@Test public void Delete() {
fxt.Init__tbl__old(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Init__tbl__cur(Object_.Ary(1, "A"));
fxt.Test__bld("D|2");
}
@Test public void Basic() {
fxt.Init__tbl__old
( Object_.Ary(1, "A")
, Object_.Ary(2, "B")
, Object_.Ary(3, "C")
);
fxt.Init__tbl__cur
( Object_.Ary(1, "A")
, Object_.Ary(2, "B1")
, Object_.Ary(4, "D")
);
fxt.Test__bld("U|2|B1", "D|3", "I|4|D");
}
}
class Gfdb_diff_bldr_fxt {
private final Gfdb_diff_bldr bldr = new Gfdb_diff_bldr();
private final Db_conn old_conn, new_conn;
private final Gfdb_diff_tbl tbl;
private final Gfdb_diff_wkr__test wkr = new Gfdb_diff_wkr__test();
private final Dbmeta_fld_itm[] flds_ary;
private final String tbl_name = "tbl";
public Gfdb_diff_bldr_fxt() {
old_conn = Db_conn_utl.Conn__new("old_db");
new_conn = Db_conn_utl.Conn__new("new_db");
this.flds_ary = new Dbmeta_fld_itm[] {Dbmeta_fld_itm.new_int("id").Primary_y_(), Dbmeta_fld_itm.new_str("val", 255)};
tbl = Gfdb_diff_tbl.New(Dbmeta_tbl_itm.New(tbl_name, flds_ary));
bldr.Init(wkr);
}
public void Clear() {
Db_conn_utl.Tbl__delete(old_conn, "tbl");
Db_conn_utl.Tbl__delete(new_conn, "tbl");
}
public void Init__tbl__old(Object[]... rows) {Db_conn_utl.Tbl__new(old_conn, "tbl", flds_ary, rows);}
public void Init__tbl__cur(Object[]... rows) {Db_conn_utl.Tbl__new(new_conn, "tbl", flds_ary, rows);}
public void Test__bld(String... expd) {
bldr.Compare(tbl, old_conn, new_conn);
Tfds.Eq_ary_str(expd, wkr.To_str_ary());
}
}
class Gfdb_diff_wkr__test implements Gfdb_diff_wkr {
private final List_adp list = List_adp_.new_();
private final Bry_bfr bfr = Bry_bfr.new_();
private Db_rdr old_rdr, new_rdr;
public void Init_rdrs(Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr) {
this.old_rdr = old_rdr; this.new_rdr = new_rdr;
}
public void Term_tbls() {}
public void Handle_same() {
String old_val = old_rdr.Read_str("val");
String new_val = new_rdr.Read_str("val");
if (!String_.Eq(old_val, new_val))
list.Add(bfr.Add_str_a7("U").Add_byte_pipe().Add_obj(old_rdr.Read_obj("id")).Add_byte_pipe().Add_str_a7(new_val).To_str_and_clear());
}
public void Handle_old_missing() {
String new_val = new_rdr.Read_str("val");
list.Add(bfr.Add_str_a7("I").Add_byte_pipe().Add_obj(new_rdr.Read_obj("id")).Add_byte_pipe().Add_str_a7(new_val).To_str_and_clear());
}
public void Handle_new_missing() {
list.Add(bfr.Add_str_a7("D").Add_byte_pipe().Add_obj(old_rdr.Read_obj("id")).To_str_and_clear());
}
public String[] To_str_ary() {return list.To_str_ary_and_clear();}
}

@ -0,0 +1,66 @@
/*
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.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
class Gfdb_diff_rdr_comparer {
private Db_rdr old_rdr, new_rdr;
private boolean old_rdr_move, new_rdr_move;
private boolean old_rdr_done, new_rdr_done;
private Dbmeta_fld_itm[] key_flds; private int key_flds_len;
public void Init_rdrs(Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr) {
this.old_rdr = old_rdr; this.new_rdr = new_rdr;
this.old_rdr_move = new_rdr_move = Bool_.Y;
this.old_rdr_done = new_rdr_done = Bool_.N;
this.key_flds = tbl.Keys; key_flds_len = key_flds.length;
}
public int Compare() {
if (old_rdr_move) {
old_rdr_move = old_rdr.Move_next();
if (!old_rdr_move) old_rdr_done = true;
}
if (new_rdr_move) {
new_rdr_move = new_rdr.Move_next();
if (!new_rdr_move) new_rdr_done = true;
}
if (old_rdr_done && new_rdr_done) return Gfdb_diff_rdr_comparer.Rslt__done;
else if (old_rdr_done) {new_rdr_move = true; return Gfdb_diff_rdr_comparer.Rslt__old_missing;}
else if (new_rdr_done) {old_rdr_move = true; return Gfdb_diff_rdr_comparer.Rslt__new_missing;}
else {
int comp = Gfdb_rdr_utl_.Compare(key_flds, key_flds_len, old_rdr, new_rdr);
switch (comp) {
case CompareAble_.Same: // old == cur; move both
old_rdr_move = new_rdr_move = true;
return Gfdb_diff_rdr_comparer.Rslt__same;
case CompareAble_.Less: // old < cur; EX: old == 2; cur == 3
old_rdr_move = true;
new_rdr_move = false;
return Gfdb_diff_rdr_comparer.Rslt__new_missing;
case CompareAble_.More: // old > cur; EX: old == 4; cur == 3
old_rdr_move = false;
new_rdr_move = true;
return Gfdb_diff_rdr_comparer.Rslt__old_missing;
default: throw Err_.new_unhandled(comp);
}
}
}
public static final int
Rslt__same = 0
, Rslt__old_missing = 1
, Rslt__new_missing = 2
, Rslt__done = 3
;
}

@ -17,9 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
public interface Gfdb_diff_wkr {
void Init_tbls(Gfdb_diff_tbl lhs, Gfdb_diff_tbl rhs);
void Init_rdrs(Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr);
void Term_tbls();
void Handle_same();
void Handle_lhs_missing();
void Handle_rhs_missing();
void Handle_old_missing();
void Handle_new_missing();
}

@ -16,19 +16,21 @@ 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.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
class Gfdb_diff_wkr__db implements Gfdb_diff_wkr {
private Gfdb_diff_tbl lhs_tbl, rhs_tbl;
private Db_meta_fld[] val_flds; private int val_flds_len;
import gplx.dbs.metas.*;
public class Gfdb_diff_wkr__db implements Gfdb_diff_wkr {
private Dbmeta_fld_itm[] val_flds; private int val_flds_len;
private Gfdb_diff_tbl tbl;
private Db_conn diff_conn; private Db_stmt stmt;
private Db_rdr old_rdr, new_rdr;
private int uid__upsert, uid__delete; private int prog_interval, prog_count;
public void Init_conn(Gfdb_diff_db diff_db, int prog_interval) {this.diff_conn = diff_db.Conn(); this.prog_interval = prog_interval;}
public void Init_tbls(Gfdb_diff_tbl lhs_tbl, Gfdb_diff_tbl rhs_tbl) {
this.lhs_tbl = lhs_tbl; this.rhs_tbl = rhs_tbl;
this.val_flds = lhs_tbl.Vals(); val_flds_len = val_flds.length;
public void Init_rdrs(Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr) {
this.tbl = tbl; this.old_rdr = old_rdr; this.new_rdr = new_rdr;
this.val_flds = tbl.Vals; val_flds_len = val_flds.length;
this.uid__upsert = 0; uid__delete = 0; this.prog_count = 0;
String tbl_name = rhs_tbl.Name();
Db_meta_fld[] diff_flds = Gfdb_diff_wkr__db_.New_diff_flds(rhs_tbl.Flds());
if (!diff_conn.Meta_tbl_exists(tbl_name)) diff_conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, diff_flds));
String tbl_name = tbl.Name;
Dbmeta_fld_itm[] diff_flds = Gfdb_diff_wkr__db_.New_diff_flds(tbl.Flds);
if (!diff_conn.Meta_tbl_exists(tbl_name)) diff_conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, diff_flds));
this.stmt = diff_conn.Stmt_insert(tbl_name, Gfdb_diff_wkr__db_.To_str_ary(diff_flds));
diff_conn.Txn_bgn("diff_db");
}
@ -36,12 +38,12 @@ class Gfdb_diff_wkr__db implements Gfdb_diff_wkr {
diff_conn.Txn_end();
}
public void Handle_same() {
if (Gfdb_rdr_utl_.Compare(val_flds, val_flds_len, lhs_tbl.Rdr(), rhs_tbl.Rdr()) != CompareAble_.Same)
Insert(Gfdb_diff_db_.Tid__update, uid__upsert++, rhs_tbl.Flds(), rhs_tbl.Rdr());
if (Gfdb_rdr_utl_.Compare(val_flds, val_flds_len, old_rdr, new_rdr) != CompareAble_.Same)
Insert(Gfdb_diff_db_.Tid__update, uid__upsert++, tbl.Flds, new_rdr);
}
public void Handle_lhs_missing() {Insert(Gfdb_diff_db_.Tid__insert, uid__upsert++, rhs_tbl.Flds(), rhs_tbl.Rdr());}
public void Handle_rhs_missing() {Insert(Gfdb_diff_db_.Tid__delete, uid__delete++, lhs_tbl.Keys(), lhs_tbl.Rdr());}
private void Insert(byte diff_type, int uid, Db_meta_fld[] flds, Db_rdr rdr) {
public void Handle_old_missing() {Insert(Gfdb_diff_db_.Tid__insert, uid__upsert++, tbl.Flds, new_rdr);}
public void Handle_new_missing() {Insert(Gfdb_diff_db_.Tid__delete, uid__delete++, tbl.Keys, old_rdr);}
private void Insert(byte diff_type, int uid, Dbmeta_fld_itm[] flds, Db_rdr rdr) {
stmt.Val_int (Gfdb_diff_db_.Fld__diff_site , -1)
.Val_int (Gfdb_diff_db_.Fld__diff_time , -1)
.Val_int (Gfdb_diff_db_.Fld__diff_db_trg , -1)
@ -55,24 +57,24 @@ class Gfdb_diff_wkr__db implements Gfdb_diff_wkr {
}
}
class Gfdb_diff_wkr__db_ {
public static Db_meta_fld[] New_diff_flds(Db_meta_fld[] all_flds) {
public static Dbmeta_fld_itm[] New_diff_flds(Dbmeta_fld_itm[] all_flds) {
int len = all_flds.length;
int system_flds = 6;
Db_meta_fld[] rv = new Db_meta_fld[len + system_flds];
rv[0] = Db_meta_fld.new_int (Gfdb_diff_db_.Fld__diff_site);
rv[1] = Db_meta_fld.new_int (Gfdb_diff_db_.Fld__diff_time);
rv[2] = Db_meta_fld.new_int (Gfdb_diff_db_.Fld__diff_db_trg);
rv[3] = Db_meta_fld.new_int (Gfdb_diff_db_.Fld__diff_db_src);
rv[4] = Db_meta_fld.new_byte(Gfdb_diff_db_.Fld__diff_type);
rv[5] = Db_meta_fld.new_int (Gfdb_diff_db_.Fld__diff_uid);
Dbmeta_fld_itm[] rv = new Dbmeta_fld_itm[len + system_flds];
rv[0] = Dbmeta_fld_itm.new_int (Gfdb_diff_db_.Fld__diff_site);
rv[1] = Dbmeta_fld_itm.new_int (Gfdb_diff_db_.Fld__diff_time);
rv[2] = Dbmeta_fld_itm.new_int (Gfdb_diff_db_.Fld__diff_db_trg);
rv[3] = Dbmeta_fld_itm.new_int (Gfdb_diff_db_.Fld__diff_db_src);
rv[4] = Dbmeta_fld_itm.new_byte(Gfdb_diff_db_.Fld__diff_type);
rv[5] = Dbmeta_fld_itm.new_int (Gfdb_diff_db_.Fld__diff_uid);
for (int i = 0; i < len; ++i) {
Db_meta_fld orig_fld = all_flds[i];
Db_meta_fld diff_fld = new Db_meta_fld(orig_fld.Name(), orig_fld.Tid(), orig_fld.Len()).Nullable_y_(); // keep same name and type, but make nullable
Dbmeta_fld_itm orig_fld = all_flds[i];
Dbmeta_fld_itm diff_fld = new Dbmeta_fld_itm(orig_fld.Name(), orig_fld.Type()).Nullable_y_(); // keep same name and type, but make nullable
all_flds[i + system_flds] = diff_fld;
}
return rv;
}
public static String[] To_str_ary(Db_meta_fld[] ary) {
public static String[] To_str_ary(Dbmeta_fld_itm[] ary) {
int len = ary.length;
String[] rv = new String[len];
for (int i = 0; i < len; ++i)

@ -0,0 +1,305 @@
/*
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.dbs.diffs.cmds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import gplx.core.srls.*; import gplx.core.brys.fmtrs.*;
import gplx.dbs.metas.*;
interface Gfdb_diff_cmd {
void Merge_undo();
void Merge_exec();
}
class Gfdb_diff_ctx implements Gfo_srl_ctx {
public Gfo_srl_mgr_wtr Wtr_bgn(String key) {return null;}
public Gfo_srl_mgr_rdr Rdr_bgn(String key) {return null;}
public Dbmeta_dat_mgr Rdr_subs(String key) {return null;}
public Dbmeta_tbl_itm Tbls__get(String key) {return null;}
}
class Gfo_srl_mgr_rdr__defn {
public String Tbl = null;
public String[] Select_crt_cols = null;
public String[] Delete_crt_cols = null;
}
class Gfo_srl_mgr_rdr__db {
public Object Get_subs (Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_itm proto, String defn_key, Dbmeta_dat_mgr crt_mgr) {
List_adp list = List_adp_.new_();
Gfo_srl_mgr_rdr__defn defn = new Gfo_srl_mgr_rdr__defn(); // Get(key)
Db_conn conn = Db_conn_.Noop;
Db_stmt select = conn.Stmt_select(defn.Tbl, Dbmeta_fld_itm.Str_ary_empty, defn.Select_crt_cols);
int crt_len = crt_mgr.Len();
for (int i = 0; i < crt_len; ++i) {
Dbmeta_dat_itm crt = crt_mgr.Get_at(i);
switch (crt.Tid) {
case Dbmeta_fld_tid.Tid__int: select.Crt_int(crt.Key, Int_.cast(crt.Val)); break;
}
}
Db_rdr rdr = select.Exec_select__rls_manual();
while (rdr.Move_next()) {
Gfo_srl_itm sub = proto.Make_new(ctx);
list.Add(sub);
sub.Load(ctx, owner, null);
}
rdr.Rls();
return list.To_ary_and_clear(proto.getClass());
}
public void Set_subs (Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_itm proto, Gfo_srl_itm[] subs_ary, String defn_key, Dbmeta_dat_mgr crt_mgr) {
Gfo_srl_mgr_rdr__defn defn = new Gfo_srl_mgr_rdr__defn(); // Get(key)
Db_conn conn = Db_conn_.Noop;
Db_stmt delete = conn.Stmt_delete(defn.Tbl, defn.Delete_crt_cols);
int crt_len = crt_mgr.Len();
for (int i = 0; i < crt_len; ++i) {
Dbmeta_dat_itm crt = crt_mgr.Get_at(i);
switch (crt.Tid) {
case Dbmeta_fld_tid.Tid__int: delete.Crt_int(crt.Key, Int_.cast(crt.Val)); break;
}
}
delete.Exec_delete();
int subs_len = subs_ary.length;
for (int i = 0; i < subs_len; ++i) {
Gfo_srl_itm itm = subs_ary[i];
itm.Save(ctx, owner, null);
}
}
}
class Gfdb_diff_cmd__idx__delete {
public Gfdb_diff_cmd__idx__delete(Dbmeta_idx_itm old) {this.Old = old;}
public final Dbmeta_idx_itm Old;
}
class Gfdb_diff_cmd__idx__modify {
public Gfdb_diff_cmd__idx__modify(Dbmeta_idx_itm old, Dbmeta_idx_itm cur) {this.Old = old; this.Cur = cur;}
public final Dbmeta_idx_itm Old;
public final Dbmeta_idx_itm Cur;
}
class Gfdb_diff_txn {
public int Id = 0;
}
class Gfdb_diff_cmd__fld__create {
public Gfdb_diff_cmd__fld__create(Dbmeta_fld_itm cur) {this.cur = cur;}
private Dbmeta_fld_itm cur;
public void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner) {
Gfo_srl_mgr_wtr wtr = ctx.Wtr_bgn("cmd.fld");
wtr.Set_int ("txn_id" , ((Gfdb_diff_txn)owner).Id);
wtr.Set_str ("name" , cur.Name());
wtr.Set_int ("type_tid" , cur.Type().Tid_ansi());
wtr.Set_int ("type_len_1" , cur.Type().Len_1());
wtr.Set_int ("type_len_2" , cur.Type().Len_2());
wtr.Set_bool ("primary" , cur.Primary());
wtr.Set_int ("nullable" , cur.Nullable_tid());
wtr.Set_str ("dflt" , Object_.Xto_str_or(cur.Default(), null));
wtr.Itm_end();
}
public void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner) {
Gfo_srl_mgr_rdr rdr = ctx.Rdr_bgn("cmd.fld");
String name = rdr.Get_str("name");
int type_tid = rdr.Get_int("type_tid");
int type_len_1 = rdr.Get_int("type_len_1");
// int type_len_2 = rdr.Get_int("type_len_2");
boolean primary = rdr.Get_bool("primary");
int nullable_tid = rdr.Get_int("nullable");
String dflt_str = rdr.Get_str("dflt");
cur = new Dbmeta_fld_itm(name, Dbmeta_fld_tid.New(type_tid, type_len_1));
cur.Nullable_tid_(nullable_tid);
if (primary) cur.Primary_y_();
if (dflt_str != null) cur.Default_(dflt_str);
rdr.Itm_end();
// Gfdb_diff_cmd__idx__create idx = ((Gfdb_diff_cmd__idx__create)owner);
// Dbmeta_tbl_itm tbl = ((Gfdb_diff_ctx)ctx).Tbls__get(idx.cur.Tbl());
// Dbmeta_fld_tid tid = tbl.Flds().Get_by(name).Type();
}
}
class Gfdb_diff_cmd__fld__delete {
public Gfdb_diff_cmd__fld__delete(Dbmeta_fld_itm old) {this.Old = old;}
public final Dbmeta_fld_itm Old;
}
class Gfdb_diff_cmd__fld__modify {
public Gfdb_diff_cmd__fld__modify(Dbmeta_fld_itm old, Dbmeta_fld_itm cur) {this.Old = old; this.Cur = cur;}
public final Dbmeta_fld_itm Old;
public final Dbmeta_fld_itm Cur;
}
class Gfdb_diff_cmd__tbl__create {
public Gfdb_diff_cmd__tbl__create(Dbmeta_tbl_itm cur) {this.Cur = cur;}
public final Dbmeta_tbl_itm Cur;
}
class Gfdb_diff_cmd__tbl__delete {
public Gfdb_diff_cmd__tbl__delete(Dbmeta_tbl_itm old) {this.Old = old;}
public final Dbmeta_tbl_itm Old;
}
class Gfdb_diff_cmd_bldr {
public void Chk_tbls(List_adp rv, Dbmeta_tbl_mgr old_tbls, Dbmeta_tbl_mgr cur_tbls) {
int cur_tbls_len = cur_tbls.Len();
for (int i = 0; i < cur_tbls_len; ++i) {
Dbmeta_tbl_itm cur_tbl = cur_tbls.Get_at(i);
Dbmeta_tbl_itm old_tbl = old_tbls.Get_by(cur_tbl.Name());
if (old_tbl == null)
rv.Add(new Gfdb_diff_cmd__tbl__create(cur_tbl));
else {
Chk_idxs(rv, old_tbl, cur_tbl);
Chk_flds(rv, old_tbl, cur_tbl);
// Chk_data?
}
}
int old_tbls_len = old_tbls.Len();
for (int i = 0; i < old_tbls_len; ++i) {
Dbmeta_tbl_itm old_tbl = old_tbls.Get_at(i);
Dbmeta_tbl_itm cur_tbl = cur_tbls.Get_by(old_tbl.Name());
if (cur_tbl == null)
rv.Add(new Gfdb_diff_cmd__tbl__delete(old_tbl));
}
}
public void Chk_idxs(List_adp rv, Dbmeta_tbl_itm old_tbl, Dbmeta_tbl_itm cur_tbl) {
Dbmeta_idx_mgr old_idxs = old_tbl.Idxs(), cur_idxs = cur_tbl.Idxs();
int cur_idxs_len = cur_idxs.Len();
for (int i = 0; i < cur_idxs_len; ++i) {
Dbmeta_idx_itm cur_idx = cur_idxs.Get_at(i);
Dbmeta_idx_itm old_idx = old_idxs.Get_by(cur_idx.Name());
if (old_idx == null)
rv.Add(new Gfdb_diff_cmd__idx__create(cur_idx));
else
if (!cur_idx.Eq(old_idx))
rv.Add(new Gfdb_diff_cmd__idx__modify(old_idx, cur_idx));
}
int old_idxs_len = old_idxs.Len();
for (int i = 0; i < old_idxs_len; ++i) {
Dbmeta_idx_itm old_idx = old_idxs.Get_at(i);
Dbmeta_idx_itm cur_idx = cur_idxs.Get_by(old_idx.Name());
if (cur_idx == null)
rv.Add(new Gfdb_diff_cmd__idx__delete(old_idx));
}
}
public void Chk_flds(List_adp rv, Dbmeta_tbl_itm old_tbl, Dbmeta_tbl_itm cur_tbl) {
Dbmeta_fld_mgr old_flds = old_tbl.Flds(), cur_flds = cur_tbl.Flds();
int cur_flds_len = cur_flds.Len();
for (int i = 0; i < cur_flds_len; ++i) {
Dbmeta_fld_itm cur_fld = cur_flds.Get_at(i);
Dbmeta_fld_itm old_fld = old_flds.Get_by(cur_fld.Name());
if (old_fld == null)
rv.Add(new Gfdb_diff_cmd__fld__create(cur_fld));
else
if (!cur_fld.Eq(old_fld))
rv.Add(new Gfdb_diff_cmd__fld__modify(old_fld, cur_fld));
}
int old_flds_len = old_flds.Len();
for (int i = 0; i < old_flds_len; ++i) {
Dbmeta_fld_itm old_fld = old_flds.Get_at(i);
Dbmeta_fld_itm cur_fld = cur_flds.Get_by(old_fld.Name());
if (cur_fld == null)
rv.Add(new Gfdb_diff_cmd__fld__delete(old_fld));
}
}
}
class Gfdb_diff_cmd__insert {
// else if I
// // txn_bgn
// // audit
// INSERT INTO db_temp.page (diff_type, diff, *)
// SELECT 'D', d.page_id, *
// FROM db_diff.page d
// JOIN db_main.page m ON d.page_id = m.page_id
// WHERE d.diff_type = 0
// AND d.diff_idx BETWEEN lo and hi
//
// // update
// INSERT INTO db_main.page
// SELECT d.page_title
// FROM db_diff.page d
// JOIN db_main.page m
// // txn_end
private Db_conn conn;
private String exec_sql;
public void Init(Db_conn main_conn, Db_conn diff_conn, Db_conn temp_conn, Gfdb_diff_tbl tbl) {
this.conn = temp_conn;
this.exec_sql = "";
// this.exec_sql = String_.Format(String_.Concat_lines_nl_skip_last
// ( "INSERT INTO db_curr.{tbl}"
// ), Gfdb_diff_cmd_ctx.Alias__curr);
}
public void Merge_exec() {
conn.Exec_sql(exec_sql);
}
}
class Gfdb_diff_cmd_sql_bldr {
private final Bry_fmtr fmtr = Bry_fmtr.new_();
private final Bry_bfr tmp_bfr = Bry_bfr.new_();
public void Bld_insert(Bry_bfr bfr, String tbl_name, String[] keys, String[] vals, int rng_bgn, int rng_end) {
fmtr.Fmt_(Insert__fmt).Keys_(Insert__keys);
fmtr.Bld_bfr_many(bfr, tbl_name, Bld_flds(tmp_bfr, ", ", "d.", keys, vals), Bld_join(keys), rng_bgn, rng_end);
}
public void Bld_update(Bry_bfr bfr, String tbl_name, String[] keys, String[] vals, int rng_bgn, int rng_end) {
fmtr.Fmt_(Update__fmt).Keys_(Update__keys);
fmtr.Bld_bfr_many(bfr, tbl_name, Bld_flds(tmp_bfr, ", ", "d.", keys, vals), Bld_join(keys), rng_bgn, rng_end);
}
public void Bld_delete(Bry_bfr bfr, String tbl_name, String[] keys, int rng_bgn, int rng_end) {
fmtr.Fmt_(Delete__fmt).Keys_(Delete__keys);
fmtr.Bld_bfr_many(bfr, tbl_name, Bld_flds(tmp_bfr, " || '|' || ", "", keys, String_.Ary_empty), Bld_flds(tmp_bfr, " || '|' || ", "k.", keys, String_.Ary_empty), Bld_join(keys), rng_bgn, rng_end);
}
private static String Bld_flds(Bry_bfr tmp_bfr, String dlm, String alias, String[] keys, String[] vals) {
int keys_len = keys.length;
for (int i = 0; i < keys_len; ++i) {
String key = keys[i];
if (i != 0) tmp_bfr.Add_str_a7(dlm);
tmp_bfr.Add_str_a7(alias).Add_str_a7(key);
}
int flds_len = vals.length;
for (int i = 0; i < flds_len; ++i) {
String val = vals[i];
tmp_bfr.Add_str_a7(dlm);
tmp_bfr.Add_str_a7(alias).Add_str_a7(val);
}
return tmp_bfr.To_str_and_clear();
}
private String Bld_join(String[] keys) {
int len = keys.length;
for (int i = 0; i < len; ++i) {
String key = keys[i];
tmp_bfr.Add_str_a7(i == 0 ? " ON " : " AND ");
tmp_bfr.Add_str_a7("k.").Add_str_a7(key).Add_str_a7(" = ");
tmp_bfr.Add_str_a7("d.").Add_str_a7(key);
}
return tmp_bfr.To_str_and_clear();
}
private static final String[] Insert__keys = String_.Ary("tbl", "flds", "join", "rng_bgn", "rng_end");
private static final String Insert__fmt = String_.Concat_lines_nl_skip_last
( "INSERT INTO db_curr.~{tbl}"
, "SELECT ~{flds}"
, "FROM db_temp.~{tbl}_pkey k"
, " JOIN db_diff.~{tbl} d~{join}"
, "WHERE k.diff_type = 1"
, "AND k.diff_uid BETWEEN ~{rng_bgn} AND ~{rng_end};"
);
private static final String[] Update__keys = String_.Ary("tbl", "flds", "join", "rng_bgn", "rng_end");
private static final String Update__fmt = String_.Concat_lines_nl_skip_last
( "REPLACE INTO db_curr.~{tbl}"
, "SELECT ~{flds}"
, "FROM db_temp.~{tbl}_pkey k"
, " JOIN db_diff.~{tbl} d~{join}"
, "WHERE k.diff_type = 2"
, "AND k.diff_uid BETWEEN ~{rng_bgn} AND ~{rng_end};"
);
private static final String[] Delete__keys = String_.Ary("tbl", "pkey_where", "pkey_select", "join", "rng_bgn", "rng_end");
private static final String Delete__fmt = String_.Concat_lines_nl_skip_last
( "DELETE db_curr.~{tbl}"
, "WHERE ~{pkey_where} IN"
, "( SELECT ~{pkey_select}"
, " FROM db_temp.~{tbl}_pkey k"
, " JOIN db_diff.~{tbl} d~{join}"
, " WHERE k.diff_type = 0"
, " AND k.diff_uid BETWEEN ~{rng_bgn} AND ~{rng_end}"
, ");"
);
}

@ -0,0 +1,119 @@
/*
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.dbs.diffs.cmds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import gplx.core.srls.*; import gplx.dbs.metas.*;
class Gfdb_diff_cmd__idx__create implements Gfo_srl_itm {
public Gfdb_diff_cmd__idx__create(Dbmeta_idx_itm cur) {this.cur = cur;}
public Dbmeta_idx_itm cur;
private Gfdb_diff_cmd__idx__fld[] flds = new Gfdb_diff_cmd__idx__fld[0];
public Gfo_srl_itm Make_new(Gfo_srl_ctx ctx) {return new Gfdb_diff_cmd__idx__create();} Gfdb_diff_cmd__idx__create() {}
private int idx_uid;
// *_sdif_ddl_idx : txn_uid,idx_uid,idx_tbl,idx_name,idx_unique
public void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_wtr wtr) {
wtr.Itm_bgn("idx");
wtr.Set_int ("idx_uid" , idx_uid);
wtr.Set_str ("idx_tbl" , cur.Tbl());
wtr.Set_str ("idx_name" , cur.Name());
wtr.Set_bool ("idx_unique" , cur.Unique());
wtr.Set_subs (ctx, this, Gfdb_diff_cmd__idx__fld.Instance, flds, ctx.Rdr_subs("idx_fld").Add_int("idx_uid", idx_uid));
wtr.Itm_end();
}
public void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_rdr rdr) {
rdr.Itm_bgn("idx");
this.idx_uid = rdr.Get_int ("idx_uid");
String tbl = rdr.Get_str ("idx_tbl");
String name = rdr.Get_str ("idx_name");
boolean unique = rdr.Get_bool ("idx_unique");
this.flds = (Gfdb_diff_cmd__idx__fld[])rdr.Get_subs(ctx, this, Gfdb_diff_cmd__idx__fld.Instance, ctx.Rdr_subs("idx_fld").Add_int("idx_uid", idx_uid));
cur = new Dbmeta_idx_itm(unique, tbl, name, Dbmeta_idx_fld.Ary_empty);
rdr.Itm_end();
}
public void Exec(Db_conn conn) {
conn.Ddl_create_idx(cur);
}
}
class Gfdb_diff_cmd__idx__fld implements Gfo_srl_itm {
public Gfdb_diff_cmd__idx__fld(Dbmeta_idx_fld cur) {this.cur = cur;}
private Dbmeta_idx_fld cur;
public Gfo_srl_itm Make_new(Gfo_srl_ctx ctx) {return new Gfdb_diff_cmd__idx__fld();} Gfdb_diff_cmd__idx__fld() {}
// *_sdif_ddl_idx_fld : idx_uid,fld_order,fld_name,fld_asc
public void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_wtr wtr) {
wtr.Itm_bgn("idx_fld");
wtr.Set_int ("fld_order" , cur.Order);
wtr.Set_str ("fld_name" , cur.Name);
wtr.Set_int ("fld_asc" , cur.Sort_tid);
wtr.Itm_end();
}
public void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_rdr rdr) {
rdr.Itm_bgn("idx_fld");
int order = rdr.Get_int ("fld_order");
String name = rdr.Get_str ("fld_name");
int sort_tid = rdr.Get_int ("fld_sort");
cur = new Dbmeta_idx_fld(order, name, sort_tid);
rdr.Itm_end();
}
public static final Gfdb_diff_cmd__idx__fld Instance = new Gfdb_diff_cmd__idx__fld();
}
// class Gfdb_diff_cmd__tbl__fld : Gfo_srl_itm {
// public Gfdb_diff_cmd__tbl__fld(Dbmeta_fld_itm cur) {this.cur = cur;}
// private Dbmeta_fld_itm cur;
// public String Name;
// public int Type_tid;
// public int Len1;
// public int Len2;
// public int Nullable;
// public boolean Primary;
// public boolean Autonum;
//
// public Gfo_srl_itm Make_new(Gfo_srl_ctx ctx) {return new Gfdb_diff_cmd__tbl__fld();} Gfdb_diff_cmd__tbl__fld() {}
// // *_sdif_ddl_tbl_fld : tbl_uid,fld_idx,fld_name,fld_type,fld_len1, fld_len2, fld_nullable, fld_primary, fld_autonumber
// public void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_wtr wtr) {
// wtr.Itm_bgn("tbl_fld");
// wtr.Set_str ("fld_name" , cur.Name());
// wtr.Set_int ("fld_type" , cur.Type().Tid_ansi());
// wtr.Set_int ("fld_len1" , cur.Type().Len_1());
// wtr.Set_int ("fld_len2" , cur.Type().Len_2());
// wtr.Set_int ("fld_nullable" , cur.Nullable_tid());
// wtr.Set_bool ("fld_primary" , cur.Primary());
// wtr.Set_bool ("fld_autonum" , cur.Autonum());
// wtr.Set_str ("fld_dflt" , Object_.Xto_str_or(cur.Default(), null));
//// wtr.Set_int ("fld_asc" , cur.Sort_tid);
// wtr.Itm_end();
// }
// public void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_rdr rdr) {
// rdr.Itm_bgn("tbl_fld");
// String name = rdr.Get_str("name");
// int type_tid = rdr.Get_int("type_tid");
// int type_len_1 = rdr.Get_int("type_len_1");
// boolean primary = rdr.Get_bool("primary");
// int nullable_tid = rdr.Get_int("nullable");
// String dflt_str = rdr.Get_str("dflt");
// cur = new Dbmeta_fld_itm(name, Dbmeta_fld_tid.New(type_tid, type_len_1));
// cur.Nullable_tid_(nullable_tid);
// if (primary) cur.Primary_y_();
// if (dflt_str != null) cur.Default_(dflt_str);
// rdr.Itm_end();
//// Gfdb_diff_cmd__idx__create idx = ((Gfdb_diff_cmd__idx__create)owner);
//// Dbmeta_tbl_itm tbl = ((Gfdb_diff_ctx)ctx).Tbls__get(idx.cur.Tbl());
//// Dbmeta_fld_tid tid = tbl.Flds().Get_by(name).Type();
// }
//
// public static final Gfdb_diff_cmd__tbl__fld Instance = new Gfdb_diff_cmd__tbl__fld();
// }

@ -15,7 +15,7 @@ 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.dbs.diffs.merges; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
package gplx.dbs.diffs.cmds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import org.junit.*;
import gplx.dbs.*; import gplx.dbs.engines.mems.*;
public class Gfdb_diff_cmd_sql_bldr_tst {

@ -16,7 +16,7 @@ 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.dbs.engines; import gplx.*; import gplx.dbs.*;
import gplx.core.stores.*;
import gplx.core.stores.*; import gplx.dbs.metas.*;
public interface Db_engine {
String Tid();
Db_conn_info Conn_info();
@ -33,12 +33,13 @@ public interface Db_engine {
void Conn_open();
void Conn_term();
Object Exec_as_obj(Db_qry qry);
void Ddl_create_tbl(Db_meta_tbl meta);
void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary);
void Ddl_append_fld(String tbl, Db_meta_fld fld);
void Ddl_create_tbl(Dbmeta_tbl_itm meta);
void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary);
void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld);
void Ddl_delete_tbl(String tbl);
void Env_db_attach(String alias, Io_url db_url);
void Env_db_detach(String alias);
boolean Meta_tbl_exists(String tbl);
boolean Meta_fld_exists(String tbl, String fld);
Dbmeta_tbl_mgr Meta_tbl_load_all();
}

@ -18,16 +18,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.dbs.engines; import gplx.*; import gplx.dbs.*;
import java.sql.*;
import gplx.core.stores.*;
import gplx.dbs.engines.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*;
import gplx.dbs.engines.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.metas.*;
public abstract class Db_engine_sql_base implements Db_engine {
@gplx.Internal protected void Ctor(Db_conn_info conn_info) {this.conn_info = conn_info;}
public abstract String Tid();
public Db_conn_info Conn_info() {return conn_info;} protected Db_conn_info conn_info;
public abstract Db_engine New_clone(Db_conn_info conn_info);
public Db_rdr New_rdr__rls_manual(Object rdr_obj, String sql) {return New_rdr(null, rdr_obj, sql);}
public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {return New_rdr(stmt, rdr_obj, sql);}
@gplx.Virtual public Db_rdr New_rdr_clone() {return new Db_rdr__basic();}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_cmd(this, qry);}
public abstract String Tid();
public Db_conn_info Conn_info() {return conn_info;} protected Db_conn_info conn_info;
public abstract Db_engine New_clone(Db_conn_info conn_info);
public Db_rdr New_rdr__rls_manual(Object rdr_obj, String sql) {return New_rdr(null, rdr_obj, sql);}
public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {return New_rdr(stmt, rdr_obj, sql);}
@gplx.Virtual public Db_rdr New_rdr_clone() {return new Db_rdr__basic();}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_cmd(this, qry);}
@gplx.Virtual public void Txn_bgn(String name) {Exec_as_obj(Db_qry_sql.xtn_("BEGIN TRANSACTION;"));}
@gplx.Virtual public String Txn_end() {Exec_as_obj(Db_qry_sql.xtn_("COMMIT TRANSACTION;")); return "";}
@gplx.Virtual public void Txn_cxl() {Exec_as_obj(Db_qry_sql.xtn_("ROLLBACK TRANSACTION;"));}
@ -56,16 +56,16 @@ public abstract class Db_engine_sql_base implements Db_engine {
}
catch (Exception e) {throw Err_.new_exc(e, "db", "db.engine:rdr failed", "url", conn_info.Xto_api(), "sql", sql);}
}
public void Ddl_create_tbl(Db_meta_tbl tbl) {Exec_as_int(tbl.To_sql_create());}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary) {
public void Ddl_create_tbl(Dbmeta_tbl_itm tbl) {Exec_as_int(tbl.To_sql_create());}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {
int len = ary.length;
for (int i = 0; i < len; ++i) {
Db_meta_idx idx = ary[i];
Dbmeta_idx_itm idx = ary[i];
usr_dlg.Plog_many("", "", "creating database index (please wait); db=~{0} idx=~{1}", conn_info.Database(), idx.Name());
Exec_as_int(idx.To_sql_create());
}
}
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {
Gfo_usr_dlg_.Instance.Plog_many("", "", "adding column to table: db=~{0} tbl=~{1} fld=~{2}", conn_info.Database(), tbl, fld.Name());
try {
Exec_as_int(Db_sqlbldr__sqlite.Instance.Bld_alter_tbl_add(tbl, fld));
@ -75,12 +75,13 @@ public abstract class Db_engine_sql_base implements Db_engine {
Gfo_usr_dlg_.Instance.Warn_many("", "", "column not added to table: db=~{0} tbl=~{1} fld=~{2} err=~{3}", conn_info.Database(), tbl, fld.Name(), Err_.Message_gplx_full(e));
}
}
public void Ddl_delete_tbl(String tbl) {Exec_as_int(Db_sqlbldr__sqlite.Instance.Bld_drop_tbl(tbl));}
@gplx.Virtual public void Env_db_attach(String alias, Io_url db_url) {}
@gplx.Virtual public void Env_db_detach(String alias) {}
public void Ddl_delete_tbl(String tbl) {Exec_as_int(Db_sqlbldr__sqlite.Instance.Bld_drop_tbl(tbl));}
@gplx.Virtual public void Env_db_attach(String alias, Io_url db_url) {}
@gplx.Virtual public void Env_db_detach(String alias) {}
@gplx.Virtual public boolean Meta_tbl_exists(String tbl) {return false;}
@gplx.Virtual public boolean Meta_fld_exists(String tbl, String fld) {return false;}
@gplx.Virtual public DataRdr New_rdr(ResultSet rdr, String sql) {return gplx.core.stores.Db_data_rdr_.new_(rdr, sql);}
public abstract Dbmeta_tbl_mgr Meta_tbl_load_all();
@gplx.Virtual public DataRdr New_rdr(ResultSet rdr, String sql) {return gplx.core.stores.Db_data_rdr_.new_(rdr, sql);}
@gplx.Virtual public Sql_qry_wtr SqlWtr() {return Sql_qry_wtr_.new_ansi();}
private Db_rdr New_rdr(Db_stmt stmt, Object rdr, String sql) {
Db_rdr__basic rv = (Db_rdr__basic)New_rdr_clone();

@ -16,7 +16,7 @@ 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.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*;
import gplx.core.stores.*; import gplx.dbs.metas.*;
public class Db_engine__mem implements Db_engine {
private final Hash_adp tbl_hash = Hash_adp_.new_();
Db_engine__mem(Db_conn_info conn_info) {this.conn_info = conn_info;}
@ -38,20 +38,21 @@ public class Db_engine__mem implements Db_engine {
public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {throw Err_.new_unimplemented();}
public DataRdr New_rdr(java.sql.ResultSet rdr, String sql) {throw Err_.new_unimplemented();}
public Object New_stmt_prep_as_obj(String sql) {throw Err_.new_unimplemented();}
public void Ddl_create_tbl(Db_meta_tbl meta) {
public void Ddl_create_tbl(Dbmeta_tbl_itm meta) {
Mem_tbl mem_tbl = new Mem_tbl(meta);
tbl_hash.Add_if_dupe_use_nth(meta.Name(), mem_tbl);
meta_tbl_mgr.Add(meta);
}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary) {} // TODO: implement unique index
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {} // TODO: implement unique index
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {}
public void Ddl_delete_tbl(String tbl) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public boolean Meta_tbl_exists(String tbl) {return tbl_hash.Has(tbl);}
public boolean Meta_fld_exists(String tbl, String fld) {
Mem_tbl mem_tbl = (Mem_tbl)tbl_hash.Get_by(tbl); if (mem_tbl == null) return false;
return mem_tbl.Meta().Flds_has(fld);
return mem_tbl.Meta().Flds().Has(fld);
}
// public boolean Meta_fld_exists(String name) {return tbl_hash.Has(name);}
public Dbmeta_tbl_mgr Meta_tbl_load_all() {return meta_tbl_mgr;} private final Dbmeta_tbl_mgr meta_tbl_mgr = new Dbmeta_tbl_mgr();
public static final Db_engine__mem Instance = new Db_engine__mem(); Db_engine__mem() {}
}

@ -128,7 +128,7 @@ public class Db_stmt__mem implements Db_stmt {
}
public Object Exec_select_val() {throw Err_.new_unimplemented();}
private void Add(String k, boolean where, Object v) {
if (k == Db_meta_fld.Key_null) return; // key is explicitly null; ignore; allows schema_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return; // key is explicitly null; ignore; allows schema_2+ type definitions
val_list.Add_if_dupe_use_1st(k, v); // NOTE: only add if new; WHERE with IN will call Add many times; fld_ttl IN ('A.png', 'B.png');
if (where) {
List_adp list = (List_adp)crt_hash.Get_by(k);

@ -17,17 +17,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.primitives.*; import gplx.core.criterias.*; import gplx.dbs.qrys.*;
import gplx.dbs.metas.*;
public class Mem_tbl {
private final List_adp rows = List_adp_.new_(); private final List_adp where_rows = List_adp_.new_();
private final Hash_adp autonum_hash = Hash_adp_.new_();
public Mem_tbl(Db_meta_tbl meta) {this.meta = meta;}
public Db_meta_tbl Meta() {return meta;} private final Db_meta_tbl meta;
public Mem_tbl(Dbmeta_tbl_itm meta) {this.meta = meta;}
public Dbmeta_tbl_itm Meta() {return meta;} private final Dbmeta_tbl_itm meta;
public int Insert(Db_stmt__mem stmt) {
Mem_row itm = new Mem_row();
Db_meta_fld[] flds = meta.Flds();
int len = flds.length;
Dbmeta_fld_mgr flds = meta.Flds();
int len = flds.Len();
for (int i = 0; i < len; ++i) {
Db_meta_fld fld = flds[i];
Dbmeta_fld_itm fld = flds.Get_at(i);
String fld_name = fld.Name();
Object val = fld.Autonum() ? Autonum_calc(fld_name) : stmt.Args_get_by(fld_name);
itm.Set_by(fld_name, val);

@ -16,7 +16,7 @@ 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.dbs.engines.mysql; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; import gplx.dbs.metas.*;
import java.sql.*;
public class Mysql_engine extends Db_engine_sql_base {
@Override public String Tid() {return Mysql_conn_info.Tid_const;}
@ -27,6 +27,7 @@ public class Mysql_engine extends Db_engine_sql_base {
return rv;
}
@Override public DataRdr New_rdr(ResultSet rdr, String commandText) {return Mysql_rdr.new_(rdr, commandText);}
@Override public Dbmeta_tbl_mgr Meta_tbl_load_all() {throw Err_.new_unimplemented();}
@gplx.Internal @Override protected Connection Conn_new() {
Mysql_conn_info conn_info_as_mysql = (Mysql_conn_info)conn_info;
return Conn_make_by_url("jdbc:mysql://localhost/" + conn_info_as_mysql.Database() + "?characterEncoding=UTF8", conn_info_as_mysql.Uid(), conn_info_as_mysql.Pwd());

@ -16,7 +16,7 @@ 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.dbs.engines.nulls; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*;
import gplx.core.stores.*; import gplx.dbs.metas.*;
public class Noop_engine implements Db_engine {
public String Tid() {return Noop_conn_info.Tid_const;}
public Db_conn_info Conn_info() {return Db_conn_info_.Null;}
@ -33,13 +33,14 @@ public class Noop_engine implements Db_engine {
public void Txn_cxl() {}
public void Txn_sav() {}
public Object Exec_as_obj(Db_qry cmd) {return cmd.Exec_is_rdr() ? (Object)DataRdr_.Null : -1;}
public void Ddl_create_tbl(Db_meta_tbl meta) {}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary) {}
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {}
public void Ddl_create_tbl(Dbmeta_tbl_itm meta) {}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {}
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {}
public void Ddl_delete_tbl(String tbl) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public boolean Meta_tbl_exists(String tbl) {return false;}
public boolean Meta_fld_exists(String tbl, String fld) {return false;}
public Dbmeta_tbl_mgr Meta_tbl_load_all() {return meta_tbl_mgr;} private final Dbmeta_tbl_mgr meta_tbl_mgr = new Dbmeta_tbl_mgr();
public static final Noop_engine Instance = new Noop_engine(); Noop_engine() {}
}

@ -16,7 +16,7 @@ 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.dbs.engines.postgres; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; import gplx.dbs.metas.*;
import java.sql.*;
public class Postgres_engine extends Db_engine_sql_base {
@Override public String Tid() {return Postgres_conn_info.Tid_const;}
@ -27,6 +27,7 @@ public class Postgres_engine extends Db_engine_sql_base {
return rv;
}
@Override public DataRdr New_rdr(ResultSet rdr, String commandText) {return Db_data_rdr_.new_(rdr, commandText);}
@Override public Dbmeta_tbl_mgr Meta_tbl_load_all() {throw Err_.new_unimplemented();}
@gplx.Internal @Override protected Connection Conn_new() {
Postgres_conn_info conn_info_as_postgres = (Postgres_conn_info)conn_info;
return Conn_make_by_url("jdbc:" + conn_info_as_postgres.Tid() + "://localhost/" + conn_info_as_postgres.Database(), conn_info_as_postgres.Uid(), conn_info_as_postgres.Pwd());

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import java.sql.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.engines.sqlite.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.engines.sqlite.*; import gplx.dbs.metas.*;
import gplx.dbs.qrys.*;
public class Sqlite_engine extends Db_engine_sql_base {
private final Sqlite_txn_mgr txn_mgr; private final Sqlite_schema_mgr schema_mgr;
@ -41,7 +41,9 @@ public class Sqlite_engine extends Db_engine_sql_base {
@Override public void Txn_sav() {txn_mgr.Txn_sav();}
@Override public boolean Meta_tbl_exists(String tbl) {return schema_mgr.Tbl_exists(tbl);}
@Override public boolean Meta_fld_exists(String tbl, String fld) {return schema_mgr.Fld_exists(tbl, fld);}
static boolean loaded = false;
@Override public Dbmeta_tbl_mgr Meta_tbl_load_all() {return schema_mgr.Tbl_load_all();}
private static boolean loaded = false;
protected void Meta_tbl_gather_hook() {throw Err_.new_unimplemented();}
@gplx.Internal @Override protected Connection Conn_new() {
if (!loaded) {
try {

@ -54,10 +54,10 @@ public class Sqlite_engine_ {
Db_qry qry = Db_qry_sql.ddl_("PRAGMA page_size = " + Int_.To_str(val) + ";");
p.Exec_qry(qry);
}
public static void Idx_create(Gfo_usr_dlg usr_dlg, Db_conn conn, String tbl, Db_meta_idx[] idx_ary) {
public static void Idx_create(Gfo_usr_dlg usr_dlg, Db_conn conn, String tbl, Dbmeta_idx_itm[] idx_ary) {
int len = idx_ary.length;
for (int i = 0; i < len; ++i) {
Db_meta_idx idx = idx_ary[i];
Dbmeta_idx_itm idx = idx_ary[i];
String idx_sql = idx.To_sql_create();
usr_dlg.Plog_many("", "", "creating index: ~{0} ~{1}", tbl, idx_sql);
conn.Exec_qry(Db_qry_sql.ddl_(idx.To_sql_create()));

@ -20,22 +20,28 @@ import gplx.dbs.qrys.*;
import gplx.dbs.metas.*; import gplx.dbs.metas.parsers.*;
public class Sqlite_schema_mgr {
private final Db_engine engine; private boolean init = true;
private final Dbmeta_idx_mgr idx_mgr = new Dbmeta_idx_mgr();
private final Dbmeta_tbl_mgr tbl_mgr = new Dbmeta_tbl_mgr();
public Sqlite_schema_mgr(Db_engine engine) {this.engine = engine;}
public Meta_tbl_mgr Tbl_mgr() {return tbl_mgr;} private final Meta_tbl_mgr tbl_mgr = new Meta_tbl_mgr();
public Meta_idx_mgr Idx_mgr() {return idx_mgr;} private final Meta_idx_mgr idx_mgr = new Meta_idx_mgr();
public boolean Tbl_exists(String name) {
if (init) Init(engine);
return tbl_mgr.Has(name);
}
public boolean Fld_exists(String tbl, String fld) {
if (init) Init(engine);
Meta_tbl_itm tbl_itm = tbl_mgr.Get_by(tbl);
return (tbl_itm == null) ? false : tbl_itm.Flds().Has(fld);
Dbmeta_tbl_itm tbl_itm = tbl_mgr.Get_by(tbl);
return tbl_itm == null ? false : tbl_itm.Flds().Has(fld);
}
public Dbmeta_tbl_mgr Tbl_load_all() {
Init(engine);
return tbl_mgr;
}
private void Init(Db_engine engine) {
init = false;
Gfo_usr_dlg_.Instance.Log_many("", "", "db.schema.load.bgn: conn=~{0}", engine.Conn_info().Xto_api());
Meta_parser__tbl tbl_parser = new Meta_parser__tbl();
tbl_mgr.Clear(); idx_mgr.Clear();
Dbmeta_parser__tbl tbl_parser = new Dbmeta_parser__tbl();
Dbmeta_parser__idx idx_parser = new Dbmeta_parser__idx();
Db_qry__select_in_tbl qry = Db_qry__select_in_tbl.new_("sqlite_master", String_.Ary_empty, String_.Ary("type", "name", "sql"), Db_qry__select_in_tbl.Order_by_null);
Db_rdr rdr = engine.New_stmt_prep(qry).Exec_select__rls_auto();
try {
@ -43,17 +49,14 @@ public class Sqlite_schema_mgr {
String type_str = rdr.Read_str("type");
String name = rdr.Read_str("name");
String sql = rdr.Read_str("sql");
int type_int = Meta_itm_tid.Xto_int(type_str);
int type_int = Dbmeta_itm_tid.Xto_int(type_str);
switch (type_int) {
case Meta_itm_tid.Tid_table:
case Dbmeta_itm_tid.Tid_table:
if (String_.Eq(name, "sqlite_sequence")) continue; // ignore b/c of non-orthodox syntax; EX: "CREATE TABLE sqlite_sequence(name, seq)";
// Meta_tbl_itm tbl_itm = new Meta_tbl_itm(tbl_name, tbl_sql);
Meta_tbl_itm tbl_itm = tbl_parser.Parse(Bry_.new_u8(sql));
tbl_mgr.Add(tbl_itm);
tbl_mgr.Add(tbl_parser.Parse(Bry_.new_u8(sql)));
break;
case Meta_itm_tid.Tid_index:
Meta_idx_itm idx_itm = new Meta_idx_itm(name, sql);
idx_mgr.Add(idx_itm);
case Dbmeta_itm_tid.Tid_index:
idx_mgr.Add(idx_parser.Parse(Bry_.new_u8(sql)));
break;
default:
Gfo_usr_dlg_.Instance.Log_many("", "", "db.schema.unknown type: conn=~{0} type=~{1} name=~{2} sql=~{3}", engine.Conn_info().Xto_api(), type_str, name, sql);

@ -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.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Sqlite_tid {
public static final int Tid_int = 1, Tid_text = 2, Tid_none = 3, Tid_real = 4, Tid_numeric = 5;
}

@ -16,7 +16,7 @@ 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.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*;
import gplx.core.stores.*; import gplx.dbs.metas.*;
import gplx.dbs.qrys.*; import gplx.dbs.sqls.*;
public class TdbEngine implements Db_engine {
public String Tid() {return Tdb_conn_info.Tid_const;}
@ -58,14 +58,15 @@ public class TdbEngine implements Db_engine {
public void FlushTbl(TdbTable tbl) {
saveMgr.SaveFile(db, tbl.File());
}
public void Ddl_create_tbl(Db_meta_tbl meta) {throw Err_.new_unimplemented();}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary) {throw Err_.new_unimplemented();}
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {throw Err_.new_unimplemented();}
public void Ddl_delete_tbl(String tbl) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public boolean Meta_tbl_exists(String name) {return false;}
public boolean Meta_fld_exists(String tbl, String fld) {return false;}
public void Ddl_create_tbl(Dbmeta_tbl_itm meta) {throw Err_.new_unimplemented();}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {throw Err_.new_unimplemented();}
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {throw Err_.new_unimplemented();}
public void Ddl_delete_tbl(String tbl) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public boolean Meta_tbl_exists(String name) {return false;}
public boolean Meta_fld_exists(String tbl, String fld) {return false;}
public Dbmeta_tbl_mgr Meta_tbl_load_all() {return meta_tbl_mgr;} private final Dbmeta_tbl_mgr meta_tbl_mgr = new Dbmeta_tbl_mgr();
Hash_adp wkrs = Hash_adp_.new_(); TdbDbLoadMgr loadMgr = TdbDbLoadMgr.new_(); TdbDbSaveMgr saveMgr = TdbDbSaveMgr.new_();
public static final TdbEngine Instance = new TdbEngine();

@ -0,0 +1,28 @@
/*
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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Dbmeta_fld_mgr {
private final Ordered_hash hash = Ordered_hash_.New();
public int Len() {return hash.Count();}
public void Clear() {hash.Clear();}
public void Add(Dbmeta_fld_itm itm) {hash.Add(itm.Name(), itm);}
public boolean Has(String name) {return hash.Has(name);}
public Dbmeta_fld_itm Get_at(int idx) {return (Dbmeta_fld_itm)hash.Get_at(idx);}
public Dbmeta_fld_itm Get_by(String name) {return (Dbmeta_fld_itm)hash.Get_by(name);}
public Dbmeta_fld_itm[] To_ary() {return hash.Count() == 0 ? Dbmeta_fld_itm.Ary_empty : (Dbmeta_fld_itm[])hash.To_ary(Dbmeta_fld_itm.class);}
}

@ -0,0 +1,70 @@
/*
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.dbs.metas; import gplx.*; import gplx.dbs.*;
import gplx.dbs.engines.sqlite.*;
public class Dbmeta_fld_tid {
public Dbmeta_fld_tid(int tid_ansi, int tid_sqlite, byte[] name, int len_1, int len_2) {
this.tid_ansi = tid_ansi; this.tid_sqlite = tid_sqlite; this.name = name; this.len_1 = len_1; this.len_2 = len_2;
}
public int Tid_ansi() {return tid_ansi;} private final int tid_ansi;
public int Tid_sqlite() {return tid_sqlite;} private final int tid_sqlite;
public byte[] Name() {return name;} private final byte[] name;
public int Len_1() {return len_1;} private final int len_1;
public int Len_2() {return len_2;} private final int len_2;
public boolean Eq(Dbmeta_fld_tid comp) {
return tid_ansi == comp.tid_ansi
&& tid_sqlite == comp.tid_sqlite
&& Bry_.Eq(name, comp.name)
&& len_1 == comp.len_1
&& len_2 == comp.len_2;
}
public static final int Tid__bool = 0, Tid__byte = 1, Tid__short = 2, Tid__int = 3, Tid__long = 4, Tid__float = 5, Tid__double = 6, Tid__str = 7, Tid__text = 8, Tid__bry = 9, Tid__decimal = 10, Tid__date = 11;
public static final Dbmeta_fld_tid
Itm__byte = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__byte , Sqlite_tid.Tid_int , Bry_.new_a7("tinyint") , -1, -1)
, Itm__short = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__short , Sqlite_tid.Tid_int , Bry_.new_a7("smallint") , -1, -1)
, Itm__int = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__int , Sqlite_tid.Tid_int , Bry_.new_a7("integer") , -1, -1)
, Itm__long = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__long , Sqlite_tid.Tid_int , Bry_.new_a7("bigint") , -1, -1)
, Itm__text = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__text , Sqlite_tid.Tid_text , Bry_.new_a7("text") , -1, -1)
, Itm__bry = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__bry , Sqlite_tid.Tid_none , Bry_.new_a7("blob") , -1, -1)
, Itm__float = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__float , Sqlite_tid.Tid_real , Bry_.new_a7("float") , -1, -1)
, Itm__double = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__double , Sqlite_tid.Tid_real , Bry_.new_a7("double") , -1, -1)
, Itm__numeric = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__decimal , Sqlite_tid.Tid_numeric , Bry_.new_a7("numeric") , -1, -1)
, Itm__bool = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__bool , Sqlite_tid.Tid_numeric , Bry_.new_a7("bit") , -1, -1) // "bit" is not SQLITE
, Itm__date = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__date , Sqlite_tid.Tid_numeric , Bry_.new_a7("date") , -1, -1)
;
public static Dbmeta_fld_tid Itm__str (int len) {return new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__str , Sqlite_tid.Tid_text , Bry_.new_a7("varchar") , len, -1);}
public static Dbmeta_fld_tid Itm__decimal (int len_1, int len_2) {return new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__decimal , Sqlite_tid.Tid_numeric , Bry_.new_a7("decimal") , len_1, len_2);}
public static Dbmeta_fld_tid New(int tid, int len1) {
switch (tid) {
case Dbmeta_fld_tid.Tid__bool: return Itm__bool;
case Dbmeta_fld_tid.Tid__byte: return Itm__byte;
case Dbmeta_fld_tid.Tid__short: return Itm__short;
case Dbmeta_fld_tid.Tid__int: return Itm__int;
case Dbmeta_fld_tid.Tid__long: return Itm__long;
case Dbmeta_fld_tid.Tid__float: return Itm__float;
case Dbmeta_fld_tid.Tid__double: return Itm__double;
case Dbmeta_fld_tid.Tid__str: return Itm__str(len1);
case Dbmeta_fld_tid.Tid__text: return Itm__text;
case Dbmeta_fld_tid.Tid__bry: return Itm__bry;
case Dbmeta_fld_tid.Tid__date: return Itm__date;
case Dbmeta_fld_tid.Tid__decimal: // return Itm__decimal(len1);
default: throw Err_.new_unhandled(tid);
}
}
}

@ -0,0 +1,39 @@
/*
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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Dbmeta_idx_fld {
public Dbmeta_idx_fld(int order, String name, int sort_tid) {this.Name = name; this.Order = order; this.Sort_tid = sort_tid;}
public int Order;
public String Name;
public int Sort_tid;
public boolean Eq(Dbmeta_idx_fld comp) {
return String_.Eq(Name, comp.Name)
&& Order == comp.Order
&& Sort_tid == comp.Sort_tid;
}
public static final Dbmeta_idx_fld[] Ary_empty = new Dbmeta_idx_fld[0];
public static final int Sort_tid__none = 0, Sort_tid__asc = 1, Sort_tid__desc = 2;
public static boolean Ary_eq(Dbmeta_idx_fld[] lhs_ary, Dbmeta_idx_fld[] rhs_ary) {
int lhs_len = lhs_ary.length, rhs_len = rhs_ary.length;
if (lhs_len != rhs_len) return false;
for (int i = 0; i < lhs_len; ++i)
if (!lhs_ary[i].Eq(rhs_ary[i])) return false;
return true;
}
}

@ -0,0 +1,28 @@
/*
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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Dbmeta_idx_mgr {
private final Ordered_hash hash = Ordered_hash_.New();
public int Len() {return hash.Count();}
public boolean Has(String name) {return hash.Has(name);}
public Dbmeta_idx_itm Get_at(int idx) {return (Dbmeta_idx_itm)hash.Get_at(idx);}
public Dbmeta_idx_itm Get_by(String name) {return (Dbmeta_idx_itm)hash.Get_by(name);}
public void Add(Dbmeta_idx_itm itm) {hash.Add(itm.Name(), itm);}
public void Clear() {hash.Clear();}
public Dbmeta_idx_itm[] To_ary() {return (Dbmeta_idx_itm[])hash.To_ary(Dbmeta_idx_itm.class);}
}

@ -16,7 +16,7 @@ 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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Meta_itm_tid {
public class Dbmeta_itm_tid {
public static final int Tid_unknown = 0, Tid_table = 1, Tid_index = 2;
public static final String Key_table = "table", Key_index = "index";
public static int Xto_int(String s) {

@ -16,11 +16,12 @@ 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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Meta_tbl_mgr {
public class Dbmeta_tbl_mgr {
private final Ordered_hash hash = Ordered_hash_.New();
public int Len() {return hash.Count();}
public void Add(Meta_tbl_itm itm) {hash.Add(itm.Name(), itm);}
public boolean Has(String name) {return hash.Has(name);}
public Meta_tbl_itm Get_at(int i) {return (Meta_tbl_itm)hash.Get_at(i);}
public Meta_tbl_itm Get_by(String name) {return (Meta_tbl_itm)hash.Get_by(name);}
public int Len() {return hash.Count();}
public boolean Has(String name) {return hash.Has(name);}
public Dbmeta_tbl_itm Get_at(int i) {return (Dbmeta_tbl_itm)hash.Get_at(i);}
public Dbmeta_tbl_itm Get_by(String name) {return (Dbmeta_tbl_itm)hash.Get_by(name);}
public void Add(Dbmeta_tbl_itm itm) {hash.Add_if_dupe_use_nth(itm.Name(), itm);}
public void Clear() {hash.Clear();}
}

@ -1,31 +0,0 @@
/*
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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Meta_fld_itm {
public Meta_fld_itm(String name, Meta_type_itm type) {
this.name = name; this.type = type;
}
public String Name() {return name;} private final String name;
public Meta_type_itm Type() {return type;} private final Meta_type_itm type;
public int Nullable_tid() {return nullable_tid;} public void Nullable_tid_(int v) {nullable_tid = v;} private int nullable_tid;
public boolean Autonumber() {return autonumber;} public void Autonumber_y_() {autonumber = true;} private boolean autonumber;
public boolean Primary_key() {return primary_key;} public void Primary_key_y_() {primary_key = true;} private boolean primary_key;
public Object Default_val() {return default_val;} private Object default_val;
public void Default_val_(Object v) {this.default_val = v;}
public static final int Nullable_unknown = 0, Nullable_null = 1, Nullable_not_null = 2;
}

@ -1,28 +0,0 @@
/*
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.dbs.metas; import gplx.*; import gplx.dbs.*;
public class Meta_type_itm {
public Meta_type_itm(int tid_ansi, int tid_sqlite, byte[] name, int len_1, int len_2) {
this.tid_ansi = tid_ansi; this.tid_sqlite = tid_sqlite; this.name = name; this.len_1 = len_1; this.len_2 = len_2;
}
public int Tid_ansi() {return tid_ansi;} private final int tid_ansi;
public int Tid_sqlite() {return tid_sqlite;} private final int tid_sqlite;
public byte[] Name() {return name;} private final byte[] name;
public int Len_1() {return len_1;} private final int len_1;
public int Len_2() {return len_2;} private final int len_2;
}

@ -0,0 +1,119 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*; import gplx.core.btries.*;
abstract class Dbmeta_fld_wkr__base {
private byte[] hook;
private final Btrie_slim_mgr words_trie = Btrie_slim_mgr.ci_a7();
private int words_len;
@gplx.Virtual public int Tid() {return Tid_other;}
public void Ctor(byte[] hook, byte[]... words_ary) {
this.hook = hook;
this.words_len = words_ary.length;
for (byte i = 0; i < words_len; ++i)
words_trie.Add_bry_byte(words_ary[i], i);
}
public void Reg(Btrie_slim_mgr trie) {
trie.Add_obj(hook, this);
}
@gplx.Virtual public void Match(Bry_rdr rdr, Dbmeta_fld_itm fld) {
int words_len = words_trie.Count();
for (int i = 0; i < words_len; ++i) {
rdr.Skip_ws();
rdr.Chk(words_trie);
}
When_match(fld);
}
protected abstract void When_match(Dbmeta_fld_itm fld);
public static final int Tid_end_comma = 1, Tid_end_paren = 2, Tid_other = 3;
}
class Dbmeta_fld_wkr__end_comma extends Dbmeta_fld_wkr__base {
public Dbmeta_fld_wkr__end_comma() {this.Ctor(Hook);}
@Override public int Tid() {return Tid_end_comma;}
@Override protected void When_match(Dbmeta_fld_itm fld) {}
private static final byte[] Hook = Bry_.new_a7(",");
public static final Dbmeta_fld_wkr__end_comma Instance = new Dbmeta_fld_wkr__end_comma();
}
class Dbmeta_fld_wkr__end_paren extends Dbmeta_fld_wkr__base {
public Dbmeta_fld_wkr__end_paren() {this.Ctor(Hook);}
@Override public int Tid() {return Tid_end_paren;}
@Override protected void When_match(Dbmeta_fld_itm fld) {}
private static final byte[] Hook = Bry_.new_a7(")");
public static final Dbmeta_fld_wkr__end_paren Instance = new Dbmeta_fld_wkr__end_paren();
}
class Dbmeta_fld_wkr__nullable_null extends Dbmeta_fld_wkr__base {
public Dbmeta_fld_wkr__nullable_null() {this.Ctor(Hook);}
@Override protected void When_match(Dbmeta_fld_itm fld) {
fld.Nullable_tid_(Dbmeta_fld_itm.Nullable_null);
}
private static final byte[] Hook = Bry_.new_a7("null");
public static final Dbmeta_fld_wkr__nullable_null Instance = new Dbmeta_fld_wkr__nullable_null();
}
class Dbmeta_fld_wkr__nullable_not extends Dbmeta_fld_wkr__base {
public Dbmeta_fld_wkr__nullable_not() {this.Ctor(Hook, Bry_null);}
@Override protected void When_match(Dbmeta_fld_itm fld) {
fld.Nullable_tid_(Dbmeta_fld_itm.Nullable_not_null);
}
private static final byte[] Hook = Bry_.new_a7("not"), Bry_null = Bry_.new_a7("null");
public static final Dbmeta_fld_wkr__nullable_not Instance = new Dbmeta_fld_wkr__nullable_not();
}
class Dbmeta_fld_wkr__primary_key extends Dbmeta_fld_wkr__base {
public Dbmeta_fld_wkr__primary_key() {this.Ctor(Hook, Bry_key);}
@Override protected void When_match(Dbmeta_fld_itm fld) {
fld.Primary_y_();
}
private static final byte[] Hook = Bry_.new_a7("primary"), Bry_key = Bry_.new_a7("key");
public static final Dbmeta_fld_wkr__primary_key Instance = new Dbmeta_fld_wkr__primary_key();
}
class Dbmeta_fld_wkr__autonumber extends Dbmeta_fld_wkr__base {
public Dbmeta_fld_wkr__autonumber() {this.Ctor(Hook);}
@Override protected void When_match(Dbmeta_fld_itm fld) {
fld.Autonum_y_();
}
private static final byte[] Hook = Bry_.new_a7("autoincrement");
public static final Dbmeta_fld_wkr__autonumber Instance = new Dbmeta_fld_wkr__autonumber();
}
class Dbmeta_fld_wkr__default extends Dbmeta_fld_wkr__base {
public Dbmeta_fld_wkr__default() {this.Ctor(Hook);}
@Override public void Match(Bry_rdr rdr, Dbmeta_fld_itm fld) {
Object default_val = null;
rdr.Skip_ws();
byte[] src = rdr.Src();
byte b = src[rdr.Pos()];
switch (b) {
case Byte_ascii.Quote:
case Byte_ascii.Apos:
int bgn_pos = rdr.Pos() + 1;
int end_pos = Bry_find_.Find_fwd(src, b, bgn_pos); if (end_pos == Bry_find_.Not_found) rdr.Err_wkr().Fail("unclosed quote");
default_val = Bry_.Mid(src, bgn_pos, end_pos);
rdr.Move_to(end_pos + 1);
break;
case Byte_ascii.Dash:
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
default_val = rdr.Read_int_to_non_num();
break;
default:
rdr.Err_wkr().Fail("invalid field_default"); break;
}
fld.Default_(default_val);
}
@Override protected void When_match(Dbmeta_fld_itm fld) {}
private static final byte[] Hook = Bry_.new_a7("default");
public static final Dbmeta_fld_wkr__default Instance = new Dbmeta_fld_wkr__default();
}

@ -0,0 +1,112 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*; import gplx.core.btries.*;
import gplx.dbs.engines.sqlite.*;
public class Dbmeta_parser__fld {
public Dbmeta_fld_itm Parse_fld(Sql_bry_rdr rdr) { // starts after "(" or ","; EX: "(fld1 int", ", fld2 int"; ends at ")"
byte[] name = rdr.Read_sql_identifier();
Dbmeta_fld_tid type = this.Parse_type(rdr);
Dbmeta_fld_itm fld = new Dbmeta_fld_itm(String_.new_u8(name), type);
byte[] src = rdr.Src(); int src_len = rdr.Src_end();
while (true) {
rdr.Skip_ws();
if (rdr.Pos() == src_len) return fld; // eos
switch (src[rdr.Pos()]) {
case Byte_ascii.Comma: return fld;
case Byte_ascii.Paren_end: return fld;
}
Dbmeta_fld_wkr__base type_wkr = (Dbmeta_fld_wkr__base)rdr.Chk_trie_as_obj(fld_trie);
switch (type_wkr.Tid()) {
case Dbmeta_fld_wkr__base.Tid_end_comma:
case Dbmeta_fld_wkr__base.Tid_end_paren: return fld;
default:
rdr.Move_to(fld_trie.Match_pos());
type_wkr.Match(rdr, fld);
break;
}
}
}
@gplx.Internal protected Dbmeta_fld_tid Parse_type(Bry_rdr rdr) {
rdr.Skip_ws();
Dbmeta_parser__fld_itm type_itm = (Dbmeta_parser__fld_itm)rdr.Chk_trie_as_obj(type_trie);
rdr.Move_by(type_itm.Word().length);
int paren_itms_count = type_itm.Paren_itms_count();
int len_1 = Int_.Min_value, len_2 = Int_.Min_value;
if (paren_itms_count > 0) {
rdr.Skip_ws().Chk(Byte_ascii.Paren_bgn);
len_1 = rdr.Skip_ws().Read_int_to_non_num(); if (len_1 == Int_.Min_value) rdr.Err_wkr().Fail("invalid fld len_1");
if (paren_itms_count == 2) {
rdr.Skip_ws().Chk(Byte_ascii.Comma);
len_2 = rdr.Skip_ws().Read_int_to_non_num(); if (len_2 == Int_.Min_value) rdr.Err_wkr().Fail("invalid fld len_2");
}
rdr.Skip_ws().Chk(Byte_ascii.Paren_end);
}
return new Dbmeta_fld_tid(type_itm.Tid_ansi(), type_itm.Tid_sqlite(), type_itm.Word(), len_1, len_2);
}
private static final Btrie_slim_mgr fld_trie = fld_trie_init
( Dbmeta_fld_wkr__nullable_null.Instance
, Dbmeta_fld_wkr__nullable_not.Instance
, Dbmeta_fld_wkr__autonumber.Instance
, Dbmeta_fld_wkr__primary_key.Instance
, Dbmeta_fld_wkr__default.Instance
);
private static Btrie_slim_mgr fld_trie_init(Dbmeta_fld_wkr__base... wkrs) {
Btrie_slim_mgr rv = Btrie_slim_mgr.ci_a7();
for (Dbmeta_fld_wkr__base wkr : wkrs)
wkr.Reg(rv);
return rv;
}
private static final Btrie_slim_mgr type_trie = type_trie_init();
private static Btrie_slim_mgr type_trie_init() {
Btrie_slim_mgr rv = Btrie_slim_mgr.ci_a7();
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__byte , Sqlite_tid.Tid_int , 0, "tinyint", "int2");
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__short , Sqlite_tid.Tid_int , 0, "smallint");
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__int , Sqlite_tid.Tid_int , 0, "int", "integer", "mediumint");
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__long , Sqlite_tid.Tid_int , 0, "bigint", "int8"); // "UNSIGNED BIG INT"
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__str , Sqlite_tid.Tid_text , 1, "character", "varchar", "nchar"); // "varying character", "native character"
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__text , Sqlite_tid.Tid_text , 0, "text", "clob");
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__bry , Sqlite_tid.Tid_none , 0, "blob");
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__float , Sqlite_tid.Tid_real , 0, "float");
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__double , Sqlite_tid.Tid_real , 0, "real", "double"); // "double precision"
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__decimal , Sqlite_tid.Tid_numeric , 0, "numeric");
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__decimal , Sqlite_tid.Tid_numeric , 2, "decimal");
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__decimal , Sqlite_tid.Tid_numeric , 2, "decimal");
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__bool , Sqlite_tid.Tid_numeric , 0, "boolean", "bit"); // "bit" is not SQLITE
Dbmeta_parser__fld_itm.reg_many(rv, Dbmeta_fld_tid.Tid__date , Sqlite_tid.Tid_numeric , 0, "date", "datetime");
return rv;
}
}
class Dbmeta_parser__fld_itm {
public Dbmeta_parser__fld_itm(int tid_ansi, int tid_sqlite, byte[] word, int paren_itms_count) {
this.tid_ansi = tid_ansi; this.tid_sqlite = tid_sqlite;
this.word = word; this.paren_itms_count = paren_itms_count;
}
public int Tid_ansi() {return tid_ansi;} private final int tid_ansi;
public int Tid_sqlite() {return tid_sqlite;} private final int tid_sqlite;
public byte[] Word() {return word;} private final byte[] word;
public int Paren_itms_count() {return paren_itms_count;} private final int paren_itms_count;
public static void reg_many(Btrie_slim_mgr trie, int tid_ansi, int tid_sqlite, int paren_itms_count, String... names_str) {
int len = names_str.length;
for (int i = 0; i < len; ++i) {
byte[] name_bry = Bry_.new_a7(names_str[i]);
Dbmeta_parser__fld_itm itm = new Dbmeta_parser__fld_itm(tid_ansi, tid_sqlite, name_bry, paren_itms_count);
trie.Add_obj(name_bry, itm);
}
}
}

@ -0,0 +1,71 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import org.junit.*;
public class Dbmeta_parser__fld_tst {
@Before public void init() {fxt.Clear();} private Dbmeta_parser__fld_fxt fxt = new Dbmeta_parser__fld_fxt();
@Test public void Parse_type() {
fxt.Test_parse_type("int" , fxt.Make_type(Dbmeta_fld_tid.Tid__int));
fxt.Test_parse_type("varchar(255)" , fxt.Make_type(Dbmeta_fld_tid.Tid__str, 255));
fxt.Test_parse_type("decimal(12,10)" , fxt.Make_type(Dbmeta_fld_tid.Tid__decimal, 12, 10));
fxt.Test_parse_type(" int" , fxt.Make_type(Dbmeta_fld_tid.Tid__int));
fxt.Test_parse_type(" decimal ( 12 , 10 )" , fxt.Make_type(Dbmeta_fld_tid.Tid__decimal, 12, 10));
}
@Test public void Parse_fld() {
fxt.Test_parse_fld("name_1 int" , fxt.Make_fld("name_1", Dbmeta_fld_tid.Tid__int, Dbmeta_fld_itm.Nullable_unknown));
fxt.Test_parse_fld("name_1 int null" , fxt.Make_fld("name_1", Dbmeta_fld_tid.Tid__int, Dbmeta_fld_itm.Nullable_null));
fxt.Test_parse_fld("name_1 int not null" , fxt.Make_fld("name_1", Dbmeta_fld_tid.Tid__int, Dbmeta_fld_itm.Nullable_not_null));
fxt.Test_parse_fld("name_1 int not null autoincrement" , fxt.Make_fld("name_1", Dbmeta_fld_tid.Tid__int, Dbmeta_fld_itm.Nullable_not_null, Bool_.N, Bool_.Y));
fxt.Test_parse_fld("name_1 int not null primary key" , fxt.Make_fld("name_1", Dbmeta_fld_tid.Tid__int, Dbmeta_fld_itm.Nullable_not_null, Bool_.Y, Bool_.N));
fxt.Test_parse_fld("name_1 int not null default -1" , fxt.Make_fld("name_1", Dbmeta_fld_tid.Tid__int, Dbmeta_fld_itm.Nullable_not_null, Bool_.Y, Bool_.N, -1));
fxt.Test_parse_fld("name_1 int not null default 'abc'" , fxt.Make_fld("name_1", Dbmeta_fld_tid.Tid__int, Dbmeta_fld_itm.Nullable_not_null, Bool_.Y, Bool_.N, "abc"));
}
}
class Dbmeta_parser__fld_fxt {
private final Dbmeta_parser__fld fld_parser = new Dbmeta_parser__fld();
private final Sql_bry_rdr rdr = new Sql_bry_rdr();
public void Clear() {}
public Dbmeta_fld_tid Make_type(int tid_ansi) {return new Dbmeta_fld_tid(tid_ansi, -1, null, Int_.Min_value, Int_.Min_value);}
public Dbmeta_fld_tid Make_type(int tid_ansi, int len_1) {return new Dbmeta_fld_tid(tid_ansi, -1, null, len_1, Int_.Min_value);}
public Dbmeta_fld_tid Make_type(int tid_ansi, int len_1, int len_2) {return new Dbmeta_fld_tid(tid_ansi, -1, null, len_1, len_2);}
public Dbmeta_fld_itm Make_fld(String name, int tid_ansi, int nullable) {return Make_fld(name, tid_ansi, nullable, false, false, null);}
public Dbmeta_fld_itm Make_fld(String name, int tid_ansi, int nullable, boolean autonumber, boolean primary_key) {return Make_fld(name, tid_ansi, nullable, false, false, null);}
public Dbmeta_fld_itm Make_fld(String name, int tid_ansi, int nullable, boolean autonumber, boolean primary_key, Object default_val) {
Dbmeta_fld_itm rv = new Dbmeta_fld_itm(name, Make_type(tid_ansi));
rv.Nullable_tid_(nullable);
if (autonumber) rv.Autonum_y_();
if (primary_key) rv.Primary_y_();
rv.Default_(default_val);
return rv;
}
public void Test_parse_type(String src, Dbmeta_fld_tid expd_type) {
rdr.Init_by_src(Bry_.new_u8(src));
Dbmeta_fld_tid actl_type = fld_parser.Parse_type(rdr);
Tfds.Eq(expd_type.Tid_ansi() , actl_type.Tid_ansi());
Tfds.Eq(expd_type.Len_1() , actl_type.Len_1());
Tfds.Eq(expd_type.Len_2() , actl_type.Len_2());
}
public void Test_parse_fld(String src, Dbmeta_fld_itm expd_fld) {
rdr.Init_by_src(Bry_.new_u8(src));
Dbmeta_fld_itm actl_fld = fld_parser.Parse_fld(rdr);
Tfds.Eq(expd_fld.Name() , actl_fld.Name());
Tfds.Eq(expd_fld.Type().Tid_ansi() , actl_fld.Type().Tid_ansi());
Tfds.Eq(expd_fld.Nullable_tid() , actl_fld.Nullable_tid());
Tfds.Eq(Object_.Xto_str_strict_or_empty(expd_fld.Default()), Object_.Xto_str_strict_or_empty(actl_fld.Default()));
}
}

@ -0,0 +1,59 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*; import gplx.core.btries.*;
public class Dbmeta_parser__idx {
private final Sql_bry_rdr rdr = new Sql_bry_rdr();
private final List_adp tmp_list = List_adp_.new_();
public Dbmeta_idx_itm Parse(byte[] src) {
rdr.Init_by_page(Bry_.Empty, src, src.length);
rdr.Skip_ws().Chk_trie_val(trie, Tid__create);
boolean unique = false;
byte tid = rdr.Skip_ws().Chk_or(trie, Byte_.Max_value_127);
switch (tid) {
case Tid__index: break;
case Tid__unique: rdr.Skip_ws().Chk_trie_val(trie, Tid__index); unique = true; break;
default: throw Err_.new_("db", "index parse failed; 'CREATE' should be followed by 'INDEX' or 'UNIQUE'", "src", src);
}
byte[] idx_name = rdr.Read_sql_identifier();
rdr.Skip_ws().Chk_trie_val(trie, Tid__on);
byte[] tbl_name = rdr.Read_sql_identifier();
rdr.Skip_ws().Chk(Byte_ascii.Paren_bgn);
int order = -1;
while (true) {
byte[] fld_bry = rdr.Read_sql_identifier(); if (fld_bry == null) throw Err_.new_("db", "index parse failed; index field is not an identifier", "src", src);
// TODO: check for ASC / DESC
Dbmeta_idx_fld fld_itm = new Dbmeta_idx_fld(++order, String_.new_u8(fld_bry), Dbmeta_idx_fld.Sort_tid__none);
tmp_list.Add(fld_itm);
byte sym = rdr.Skip_ws().Read_byte();
if (sym == Byte_ascii.Paren_end) break;
}
return new Dbmeta_idx_itm(unique, String_.new_u8(tbl_name), String_.new_u8(idx_name), (Dbmeta_idx_fld[])tmp_list.To_ary_and_clear(Dbmeta_idx_fld.class));
}
private static final byte Tid__create = 0, Tid__unique = 1, Tid__index = 2, Tid__on = 3;
private static final byte[]
Bry__create = Bry_.new_a7("create")
, Bry__unique = Bry_.new_a7("unique")
, Bry__index = Bry_.new_a7("index")
, Bry__on = Bry_.new_a7("on");
private static final Btrie_slim_mgr trie = Btrie_slim_mgr.ci_a7()
.Add_bry_byte(Bry__create , Tid__create)
.Add_bry_byte(Bry__unique , Tid__unique)
.Add_bry_byte(Bry__index , Tid__index)
.Add_bry_byte(Bry__on , Tid__on);
}

@ -0,0 +1,37 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import org.junit.*;
public class Dbmeta_parser__idx_tst {
@Before public void init() {fxt.Clear();} private final Dbmeta_parser__idx_fxt fxt = new Dbmeta_parser__idx_fxt();
@Test public void Unique() {fxt.Test_parse("CREATE UNIQUE INDEX idx_1 ON tbl_1 (fld_1, fld_2, fld_3)" , fxt.Make_idx(Bool_.Y, "idx_1", "tbl_1", "fld_1", "fld_2", "fld_3"));}
@Test public void Normal() {fxt.Test_parse("CREATE INDEX idx_1 ON tbl_1 (fld_1, fld_2, fld_3)" , fxt.Make_idx(Bool_.N, "idx_1", "tbl_1", "fld_1", "fld_2", "fld_3"));}
@Test public void Fld_1() {fxt.Test_parse("CREATE INDEX idx_1 ON tbl_1 (fld_1)" , fxt.Make_idx(Bool_.N, "idx_1", "tbl_1", "fld_1"));}
}
class Dbmeta_parser__idx_fxt {
private final Dbmeta_parser__idx parser = new Dbmeta_parser__idx();
public void Clear() {}
public Dbmeta_idx_itm Make_idx(boolean unique, String idx_name, String tbl_name, String... fld_names) {return new Dbmeta_idx_itm(unique, tbl_name, idx_name, Dbmeta_idx_itm.To_fld_ary(fld_names));}
public void Test_parse(String src, Dbmeta_idx_itm expd) {
Dbmeta_idx_itm actl = parser.Parse(Bry_.new_u8(src));
Tfds.Eq_bool(expd.Unique(), actl.Unique());
Tfds.Eq_str(expd.Name(), actl.Name());
Tfds.Eq_str(expd.Tbl(), actl.Tbl());
Tfds.Eq_bool(Bool_.Y, Dbmeta_idx_fld.Ary_eq(expd.Flds, actl.Flds));
}
}

@ -0,0 +1,51 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*; import gplx.core.btries.*;
public class Dbmeta_parser__tbl {
private final Sql_bry_rdr rdr = new Sql_bry_rdr();
private final Dbmeta_parser__fld fld_parser = new Dbmeta_parser__fld();
public Dbmeta_tbl_itm Parse(byte[] src) {
rdr.Init_by_page(Bry_.Empty, src, src.length);
rdr.Skip_ws().Chk_trie_val(trie, Tid__create);
rdr.Skip_ws().Chk_trie_val(trie, Tid__table);
byte[] tbl_name = rdr.Read_sql_identifier();
rdr.Skip_ws().Chk(Byte_ascii.Paren_bgn);
Dbmeta_tbl_itm rv = Dbmeta_tbl_itm.New(String_.new_u8(tbl_name));
boolean loop = true;
while (loop) {
Dbmeta_fld_itm fld = fld_parser.Parse_fld(rdr); if (fld == null) rdr.Err_wkr().Fail("unknown field", "src", src);
rv.Flds().Add(fld);
int pos = rdr.Pos();
byte b = pos == rdr.Src_end() ? Byte_ascii.Null : src[pos];
switch (b) {
case Byte_ascii.Comma: rdr.Move_by_one(); break;
case Byte_ascii.Paren_end: rdr.Move_by_one(); loop = false; break;
default: rdr.Err_wkr().Fail("premature end of flds"); break;
}
}
return rv;
}
private static final byte Tid__create = 0, Tid__table = 1;
private static final byte[]
Bry__create = Bry_.new_a7("create")
, Bry__table = Bry_.new_a7("table");
private static final Btrie_slim_mgr trie = Btrie_slim_mgr.ci_a7()
.Add_bry_byte(Bry__create , Tid__create)
.Add_bry_byte(Bry__table , Tid__table);
}

@ -16,9 +16,9 @@ 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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import org.junit.*;
public class Meta_parser__tbl_tst {
@Before public void init() {fxt.Clear();} private Meta_parser__tbl_fxt fxt = new Meta_parser__tbl_fxt();
import org.junit.*; import gplx.dbs.engines.sqlite.*;
public class Dbmeta_parser__tbl_tst {
@Before public void init() {fxt.Clear();} private Dbmeta_parser__tbl_fxt fxt = new Dbmeta_parser__tbl_fxt();
@Test public void Test_parse() {
fxt.Test_parse("CREATE TABLE tbl_1 (fld_1 int, fld_2 int)", fxt.Make_tbl("tbl_1", "fld_1", "fld_2"));
}
@ -39,23 +39,22 @@ public class Meta_parser__tbl_tst {
), fxt.Make_tbl("page", "page_id", "page_namespace", "page_title", "page_is_redirect", "page_touched", "page_len", "page_random_int", "page_text_db_id", "page_html_db_id", "page_redirect_id"));
}
}
class Meta_parser__tbl_fxt {
private final Meta_parser__tbl tbl_parser = new Meta_parser__tbl();
class Dbmeta_parser__tbl_fxt {
private final Dbmeta_parser__tbl tbl_parser = new Dbmeta_parser__tbl();
public void Clear() {}
public Meta_tbl_itm Make_tbl(String tbl_name, String... fld_names) {
Meta_tbl_itm rv = new Meta_tbl_itm(tbl_name, "NONE");
public Dbmeta_tbl_itm Make_tbl(String tbl_name, String... fld_names) {
int len = fld_names.length;
for (int i = 0; i < len; ++i) {
rv.Flds().Add(new Meta_fld_itm(fld_names[i], new Meta_type_itm(Db_meta_fld.Tid_int, Sqlite_tid.Tid_int, Bry_.new_a7("int"), Int_.Min_value, Int_.Min_value)));
}
return rv;
Dbmeta_fld_itm[] flds = new Dbmeta_fld_itm[len];
for (int i = 0; i < len; ++i)
flds[i] = new Dbmeta_fld_itm(fld_names[i], new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__int, Sqlite_tid.Tid_int, Bry_.new_a7("int"), Int_.Min_value, Int_.Min_value));
return Dbmeta_tbl_itm.New(tbl_name, flds);
}
public void Test_parse(String src, Meta_tbl_itm expd_tbl) {
Meta_tbl_itm actl_tbl = tbl_parser.Parse(Bry_.new_u8(src));
public void Test_parse(String src, Dbmeta_tbl_itm expd_tbl) {
Dbmeta_tbl_itm actl_tbl = tbl_parser.Parse(Bry_.new_u8(src));
Tfds.Eq(expd_tbl.Name(), actl_tbl.Name());
Tfds.Eq_ary_str(To_str_ary(expd_tbl.Flds()), To_str_ary(actl_tbl.Flds()));
}
private static String[] To_str_ary(Meta_fld_mgr fld_mgr) {
private static String[] To_str_ary(Dbmeta_fld_mgr fld_mgr) {
int len = fld_mgr.Len();
String[] rv = new String[len];
for (int i = 0; i < len; ++i) {

@ -1,117 +0,0 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*; import gplx.core.btries.*;
abstract class Meta_fld_wkr__base {
private byte[] hook;
private byte[][] words_ary; private int words_len;
@gplx.Virtual public int Tid() {return Tid_other;}
public void Ctor(byte[] hook, byte[]... words_ary) {
this.hook = hook;
this.words_ary = words_ary;
this.words_len = words_ary.length;
}
public void Reg(Btrie_slim_mgr trie) {
trie.Add_obj(hook, this);
}
@gplx.Virtual public void Match(Bry_rdr_old rdr, Meta_fld_itm fld) {
for (int i = 0; i < words_len; ++i) {
rdr.Skip_ws();
byte[] word = words_ary[i];
rdr.Chk_bry_or_fail(word);
}
When_match(fld);
}
protected abstract void When_match(Meta_fld_itm fld);
public static final int Tid_end_comma = 1, Tid_end_paren = 2, Tid_other = 3;
}
class Meta_fld_wkr__end_comma extends Meta_fld_wkr__base {
public Meta_fld_wkr__end_comma() {this.Ctor(Hook);}
@Override public int Tid() {return Tid_end_comma;}
@Override protected void When_match(Meta_fld_itm fld) {}
private static final byte[] Hook = Bry_.new_a7(",");
public static final Meta_fld_wkr__end_comma Instance = new Meta_fld_wkr__end_comma();
}
class Meta_fld_wkr__end_paren extends Meta_fld_wkr__base {
public Meta_fld_wkr__end_paren() {this.Ctor(Hook);}
@Override public int Tid() {return Tid_end_paren;}
@Override protected void When_match(Meta_fld_itm fld) {}
private static final byte[] Hook = Bry_.new_a7(")");
public static final Meta_fld_wkr__end_paren Instance = new Meta_fld_wkr__end_paren();
}
class Meta_fld_wkr__nullable_null extends Meta_fld_wkr__base {
public Meta_fld_wkr__nullable_null() {this.Ctor(Hook);}
@Override protected void When_match(Meta_fld_itm fld) {
fld.Nullable_tid_(Meta_fld_itm.Nullable_null);
}
private static final byte[] Hook = Bry_.new_a7("null");
public static final Meta_fld_wkr__nullable_null Instance = new Meta_fld_wkr__nullable_null();
}
class Meta_fld_wkr__nullable_not extends Meta_fld_wkr__base {
public Meta_fld_wkr__nullable_not() {this.Ctor(Hook, Bry_null);}
@Override protected void When_match(Meta_fld_itm fld) {
fld.Nullable_tid_(Meta_fld_itm.Nullable_not_null);
}
private static final byte[] Hook = Bry_.new_a7("not"), Bry_null = Bry_.new_a7("null");
public static final Meta_fld_wkr__nullable_not Instance = new Meta_fld_wkr__nullable_not();
}
class Meta_fld_wkr__primary_key extends Meta_fld_wkr__base {
public Meta_fld_wkr__primary_key() {this.Ctor(Hook, Bry_key);}
@Override protected void When_match(Meta_fld_itm fld) {
fld.Primary_key_y_();
}
private static final byte[] Hook = Bry_.new_a7("primary"), Bry_key = Bry_.new_a7("key");
public static final Meta_fld_wkr__primary_key Instance = new Meta_fld_wkr__primary_key();
}
class Meta_fld_wkr__autonumber extends Meta_fld_wkr__base {
public Meta_fld_wkr__autonumber() {this.Ctor(Hook);}
@Override protected void When_match(Meta_fld_itm fld) {
fld.Autonumber_y_();
}
private static final byte[] Hook = Bry_.new_a7("autoincrement");
public static final Meta_fld_wkr__autonumber Instance = new Meta_fld_wkr__autonumber();
}
class Meta_fld_wkr__default extends Meta_fld_wkr__base {
public Meta_fld_wkr__default() {this.Ctor(Hook);}
@Override public void Match(Bry_rdr_old rdr, Meta_fld_itm fld) {
Object default_val = null;
rdr.Skip_ws();
byte[] src = rdr.Src();
byte b = src[rdr.Pos()];
switch (b) {
case Byte_ascii.Quote:
case Byte_ascii.Apos:
int bgn_pos = rdr.Pos() + 1;
int end_pos = Bry_find_.Find_fwd(src, b, bgn_pos); if (end_pos == Bry_find_.Not_found) throw Err_.new_wo_type("unclosed quote", "snip", rdr.Mid_by_len_safe(40));
default_val = Bry_.Mid(src, bgn_pos, end_pos);
rdr.Pos_(end_pos + 1);
break;
case Byte_ascii.Dash:
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
default_val = rdr.Read_int_to_non_num();
break;
default:
throw Err_.new_wo_type("invalid field_default", "snip", rdr.Mid_by_len_safe(40));
}
fld.Default_val_(default_val);
}
@Override protected void When_match(Meta_fld_itm fld) {}
private static final byte[] Hook = Bry_.new_a7("default");
public static final Meta_fld_wkr__default Instance = new Meta_fld_wkr__default();
}

@ -1,118 +0,0 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*; import gplx.core.btries.*;
public class Meta_parser__fld {
public Meta_type_itm Parse_type(Bry_rdr_old rdr) {
rdr.Skip_ws();
Object type_obj = type_trie.Match_bgn(rdr.Src(), rdr.Pos(), rdr.Src_len());
if (type_obj == null) throw Err_.new_wo_type("invalid fld type", "snip", rdr.Mid_by_len_safe(40));
Meta_parser__fld_itm type_itm = (Meta_parser__fld_itm)type_obj;
rdr.Pos_add(type_itm.Word().length);
int paren_itms_count = type_itm.Paren_itms_count();
int len_1 = Int_.Min_value, len_2 = Int_.Min_value;
if (paren_itms_count > 0) {
rdr.Skip_ws().Chk_byte_or_fail(Byte_ascii.Paren_bgn);
len_1 = rdr.Skip_ws().Read_int_to_non_num(); if (len_1 == Int_.Min_value) throw Err_.new_wo_type("invalid fld len_1", "snip", rdr.Mid_by_len_safe(40));
if (paren_itms_count == 2) {
rdr.Skip_ws().Chk_byte_or_fail(Byte_ascii.Comma);
len_2 = rdr.Skip_ws().Read_int_to_non_num(); if (len_2 == Int_.Min_value) throw Err_.new_wo_type("invalid fld len_2", "snip", rdr.Mid_by_len_safe(40));
}
rdr.Skip_ws().Chk_byte_or_fail(Byte_ascii.Paren_end);
}
return new Meta_type_itm(type_itm.Tid_ansi(), type_itm.Tid_sqlite(), type_itm.Word(), len_1, len_2);
}
public Meta_fld_itm Parse_fld(Sql_bry_rdr rdr) { // starts after "(" or ","; EX: "(fld1 int", ", fld2 int"; ends at ")"
byte[] name = rdr.Read_sql_identifier();
Meta_type_itm type = this.Parse_type(rdr);
Meta_fld_itm fld = new Meta_fld_itm(String_.new_u8(name), type);
byte[] src = rdr.Src(); int src_len = rdr.Src_len();
while (true) {
rdr.Skip_ws();
if (rdr.Pos() == src_len) return fld; // eos
switch (src[rdr.Pos()]) {
case Byte_ascii.Comma: return fld;
case Byte_ascii.Paren_end: return fld;
}
Object type_obj = fld_trie.Match_bgn(src, rdr.Pos(), src_len); if (type_obj == null) throw Err_.new_wo_type("invalid", "snip", rdr.Mid_by_len_safe(40));
Meta_fld_wkr__base type_wkr = (Meta_fld_wkr__base)type_obj;
switch (type_wkr.Tid()) {
case Meta_fld_wkr__base.Tid_end_comma:
case Meta_fld_wkr__base.Tid_end_paren: return fld;
default:
rdr.Pos_(fld_trie.Match_pos());
type_wkr.Match(rdr, fld);
break;
}
}
// return fld; // NOTE: will happen for tests; EX: "fld_1 int" vs "fld_1 int,"
}
private static final Btrie_slim_mgr fld_trie = fld_trie_init
( Meta_fld_wkr__nullable_null.Instance
, Meta_fld_wkr__nullable_not.Instance
, Meta_fld_wkr__autonumber.Instance
, Meta_fld_wkr__primary_key.Instance
, Meta_fld_wkr__default.Instance
);
private static Btrie_slim_mgr fld_trie_init(Meta_fld_wkr__base... wkrs) {
Btrie_slim_mgr rv = Btrie_slim_mgr.ci_a7();
for (Meta_fld_wkr__base wkr : wkrs)
wkr.Reg(rv);
return rv;
}
private static final Btrie_slim_mgr type_trie = type_trie_init();
private static Btrie_slim_mgr type_trie_init() {
Btrie_slim_mgr rv = Btrie_slim_mgr.ci_a7();
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_byte , Sqlite_tid.Tid_int , 0, "tinyint", "int2");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_short , Sqlite_tid.Tid_int , 0, "smallint");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_int , Sqlite_tid.Tid_int , 0, "int", "integer", "mediumint");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_long , Sqlite_tid.Tid_int , 0, "bigint", "int8"); // "UNSIGNED BIG INT"
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_str , Sqlite_tid.Tid_text , 1, "character", "varchar", "nchar"); // "varying character", "native character"
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_text , Sqlite_tid.Tid_text , 0, "text", "clob");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_bry , Sqlite_tid.Tid_none , 0, "blob");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_float , Sqlite_tid.Tid_real , 0, "float");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_double , Sqlite_tid.Tid_real , 0, "real", "double"); // "double precision"
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_decimal , Sqlite_tid.Tid_numeric , 0, "numeric");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_decimal , Sqlite_tid.Tid_numeric , 2, "decimal");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_decimal , Sqlite_tid.Tid_numeric , 2, "decimal");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_bool , Sqlite_tid.Tid_numeric , 0, "boolean", "bit"); // "bit" is not SQLITE
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_date , Sqlite_tid.Tid_numeric , 0, "date", "datetime");
return rv;
}
}
class Meta_parser__fld_itm {
public Meta_parser__fld_itm(int tid_ansi, int tid_sqlite, byte[] word, int paren_itms_count) {
this.tid_ansi = tid_ansi; this.tid_sqlite = tid_sqlite;
this.word = word; this.paren_itms_count = paren_itms_count;
}
public int Tid_ansi() {return tid_ansi;} private final int tid_ansi;
public int Tid_sqlite() {return tid_sqlite;} private final int tid_sqlite;
public byte[] Word() {return word;} private final byte[] word;
public int Paren_itms_count() {return paren_itms_count;} private final int paren_itms_count;
public static void reg_many(Btrie_slim_mgr trie, int tid_ansi, int tid_sqlite, int paren_itms_count, String... names_str) {
int len = names_str.length;
for (int i = 0; i < len; ++i) {
byte[] name_bry = Bry_.new_a7(names_str[i]);
Meta_parser__fld_itm itm = new Meta_parser__fld_itm(tid_ansi, tid_sqlite, name_bry, paren_itms_count);
trie.Add_obj(name_bry, itm);
}
}
}
class Sqlite_tid {
public static final int Tid_int = 1, Tid_text = 2, Tid_none = 3, Tid_real = 4, Tid_numeric = 5;
}

@ -1,71 +0,0 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import org.junit.*;
public class Meta_parser__fld_tst {
@Before public void init() {fxt.Clear();} private Meta_parser__fld_fxt fxt = new Meta_parser__fld_fxt();
@Test public void Parse_type() {
fxt.Test_parse_type("int" , fxt.Make_type(Db_meta_fld.Tid_int));
fxt.Test_parse_type("varchar(255)" , fxt.Make_type(Db_meta_fld.Tid_str, 255));
fxt.Test_parse_type("decimal(12,10)" , fxt.Make_type(Db_meta_fld.Tid_decimal, 12, 10));
fxt.Test_parse_type(" int" , fxt.Make_type(Db_meta_fld.Tid_int));
fxt.Test_parse_type(" decimal ( 12 , 10 )" , fxt.Make_type(Db_meta_fld.Tid_decimal, 12, 10));
}
@Test public void Parse_fld() {
fxt.Test_parse_fld("name_1 int" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_unknown));
fxt.Test_parse_fld("name_1 int null" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_null));
fxt.Test_parse_fld("name_1 int not null" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null));
fxt.Test_parse_fld("name_1 int not null autoincrement" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null, Bool_.N, Bool_.Y));
fxt.Test_parse_fld("name_1 int not null primary key" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null, Bool_.Y, Bool_.N));
fxt.Test_parse_fld("name_1 int not null default -1" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null, Bool_.Y, Bool_.N, -1));
fxt.Test_parse_fld("name_1 int not null default 'abc'" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null, Bool_.Y, Bool_.N, "abc"));
}
}
class Meta_parser__fld_fxt {
private final Meta_parser__fld fld_parser = new Meta_parser__fld();
private final Sql_bry_rdr rdr = new Sql_bry_rdr();
public void Clear() {}
public Meta_type_itm Make_type(int tid_ansi) {return new Meta_type_itm(tid_ansi, -1, null, Int_.Min_value, Int_.Min_value);}
public Meta_type_itm Make_type(int tid_ansi, int len_1) {return new Meta_type_itm(tid_ansi, -1, null, len_1, Int_.Min_value);}
public Meta_type_itm Make_type(int tid_ansi, int len_1, int len_2) {return new Meta_type_itm(tid_ansi, -1, null, len_1, len_2);}
public Meta_fld_itm Make_fld(String name, int tid_ansi, int nullable) {return Make_fld(name, tid_ansi, nullable, false, false, null);}
public Meta_fld_itm Make_fld(String name, int tid_ansi, int nullable, boolean autonumber, boolean primary_key) {return Make_fld(name, tid_ansi, nullable, false, false, null);}
public Meta_fld_itm Make_fld(String name, int tid_ansi, int nullable, boolean autonumber, boolean primary_key, Object default_val) {
Meta_fld_itm rv = new Meta_fld_itm(name, Make_type(tid_ansi));
rv.Nullable_tid_(nullable);
if (autonumber) rv.Autonumber_y_();
if (primary_key) rv.Primary_key_y_();
rv.Default_val_(default_val);
return rv;
}
public void Test_parse_type(String src, Meta_type_itm expd_type) {
rdr.Init(Bry_.new_u8(src));
Meta_type_itm actl_type = fld_parser.Parse_type(rdr);
Tfds.Eq(expd_type.Tid_ansi() , actl_type.Tid_ansi());
Tfds.Eq(expd_type.Len_1() , actl_type.Len_1());
Tfds.Eq(expd_type.Len_2() , actl_type.Len_2());
}
public void Test_parse_fld(String src, Meta_fld_itm expd_fld) {
rdr.Init(Bry_.new_u8(src));
Meta_fld_itm actl_fld = fld_parser.Parse_fld(rdr);
Tfds.Eq(expd_fld.Name() , actl_fld.Name());
Tfds.Eq(expd_fld.Type().Tid_ansi() , actl_fld.Type().Tid_ansi());
Tfds.Eq(expd_fld.Nullable_tid() , actl_fld.Nullable_tid());
Tfds.Eq(Object_.Xto_str_strict_or_empty(expd_fld.Default_val()), Object_.Xto_str_strict_or_empty(actl_fld.Default_val()));
}
}

@ -1,57 +0,0 @@
/*
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.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*; import gplx.core.btries.*;
public class Meta_parser__tbl {
private final Sql_bry_rdr rdr = new Sql_bry_rdr();
private final Meta_parser__fld fld_parser = new Meta_parser__fld();
private Meta_tbl_itm tbl;
public Meta_tbl_itm Parse(byte[] src) {
src = Bry_.Lcase__all(src);
rdr.Init(src);
tbl = null;
Parse_hdr();
Parse_flds();
return tbl;
}
private void Parse_hdr() {
rdr.Skip_ws().Chk_bry_or_fail(Tkn_create);
rdr.Skip_ws().Chk_bry_or_fail(Tkn_table);
byte[] tbl_name = rdr.Read_sql_identifier();
this.tbl = new Meta_tbl_itm(String_.new_u8(tbl_name), String_.new_u8(rdr.Src()));
rdr.Skip_ws().Chk_byte_or_fail(Byte_ascii.Paren_bgn);
}
private void Parse_flds() {
byte[] src = rdr.Src();
while (true) {
Meta_fld_itm fld = fld_parser.Parse_fld(rdr); if (fld == null) throw Err_.new_wo_type("unknown field", "src", rdr.Src());
tbl.Flds().Add(fld);
int pos = rdr.Pos();
byte b = pos == rdr.Src_len() ? Byte_ascii.Null : src[pos];
switch (b) {
case Byte_ascii.Comma: rdr.Pos_add_one(); break;
case Byte_ascii.Paren_end: rdr.Pos_add_one(); return;
default: throw Err_.new_wo_type("premature end of flds", "src", rdr.Mid_by_len_safe(40));
}
}
}
private static final byte[]
Tkn_create = Bry_.new_a7("create")
, Tkn_table = Bry_.new_a7("table")
;
}

@ -17,14 +17,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*;
public class Sql_bry_rdr extends Bry_rdr_old { public byte[] Read_sql_identifier() {
public class Sql_bry_rdr extends Bry_rdr { public byte[] Read_sql_identifier() {
this.Skip_ws();
int bgn = pos, end = -1;
if (pos == src_len) return null;
if (pos == src_end) return null;
if (src[pos] == Byte_ascii.Brack_bgn) { // EX: [name with space]
bgn = ++pos; // set bgn after [
end = this.Find_fwd(Byte_ascii.Brack_end);
pos = end + 1; // set pos after ]
end = this.Find_fwd_lr(Byte_ascii.Brack_end);
}
else {
this.Skip_alpha_num_under(); // ASSUME: identifier is ASCII and alpha / num / underscore
@ -33,8 +32,8 @@ public class Sql_bry_rdr extends Bry_rdr_old { public byte[] Read_sql_identifie
}
return Bry_.Mid(src, bgn, end);
}
@Override public Bry_rdr_old Skip_ws() {
byte b_0 = pos < src_len ? src[pos] : Byte_ascii.Null;
@Override public Bry_rdr Skip_ws() {
byte b_0 = pos < src_end ? src[pos] : Byte_ascii.Null;
byte bgn_1 = Byte_ascii.Null;
byte[] end_bry = null;
switch (b_0) {
@ -46,12 +45,12 @@ public class Sql_bry_rdr extends Bry_rdr_old { public byte[] Read_sql_identifie
default:
return this;
}
byte b_1 = pos + 1 < src_len ? src[pos + 1] : Byte_ascii.Null;
byte b_1 = pos + 1 < src_end ? src[pos + 1] : Byte_ascii.Null;
if (b_1 != bgn_1) return this;
int end_pos = Bry_find_.Find_fwd(src, end_bry, pos + 2, src_len);
int end_pos = Bry_find_.Find_fwd(src, end_bry, pos + 2, src_end);
if (end_pos == Bry_find_.Not_found) return this;
pos = end_pos + end_bry.length;
return this.Skip_ws();
return super.Skip_ws();
}
private static final byte[] Comm_end_line = Byte_ascii.Nl_bry, Comm_end_multi = Bry_.new_a7("*/");
}

@ -41,12 +41,12 @@ class Sql_bry_rdr_fxt {
private final Sql_bry_rdr rdr = new Sql_bry_rdr();
public void Clear() {}
public void Test_skip_ws(String src, int expd_pos) {
rdr.Init(Bry_.new_u8(src));
rdr.Init_by_src(Bry_.new_u8(src));
rdr.Skip_ws();
Tfds.Eq(expd_pos, rdr.Pos());
}
public void Test_read_sql_identifier(String src, String expd) {
rdr.Init(Bry_.new_u8(src));
rdr.Init_by_src(Bry_.new_u8(src));
Tfds.Eq(expd, String_.new_u8(rdr.Read_sql_identifier()));
}
}

@ -37,7 +37,7 @@ public class Db_qry_insert implements Db_qry_arg_owner {
public Db_qry_arg_owner Arg_(String k, byte[] v) {return Arg_obj_type_(k, String_.new_u8(v), Db_val_type.Tid_varchar);}
public Db_qry_arg_owner Arg_obj_(String k, Object v) {return Arg_obj_type_(k, v, Db_val_type.Tid_null);}
public Db_qry_arg_owner Arg_obj_type_(String key, Object val, byte val_tid) {
if (key == Db_meta_fld.Key_null) return this;
if (key == Dbmeta_fld_itm.Key_null) return this;
Db_arg arg = new Db_arg(key, val).Val_tid_(val_tid);
args.Add(arg.Key(), arg);
return this;

@ -37,7 +37,7 @@ public class Db_qry_update implements Db_qry_arg_owner {
public Db_qry_arg_owner Arg_(String k, byte[] v) {return Arg_obj_type_(k, String_.new_u8(v), Db_val_type.Tid_varchar);}
public Db_qry_arg_owner Arg_obj_(String k, Object v) {return Arg_obj_type_(k, v, Db_val_type.Tid_null);}
public Db_qry_arg_owner Arg_obj_type_(String key, Object val, byte val_tid) {
if (key == Db_meta_fld.Key_null) return this;
if (key == Dbmeta_fld_itm.Key_null) return this;
Db_arg arg = new Db_arg(key, val).Val_tid_(val_tid);
args.Add(arg.Key(), arg);
return this;

@ -41,7 +41,7 @@ public class Db_stmt_cmd implements Db_stmt {
public Db_stmt Val_byte(String k, byte v) {return Add_byte(Bool_.N, k, v);}
public Db_stmt Val_byte(byte v) {return Add_byte(Bool_.N, Key_na, v);}
private Db_stmt Add_byte(boolean where, String k, byte v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setByte(++val_idx, v);} catch (Exception e) {this.Rls(); throw Err_.new_exc(e, "db", "failed to add value", "type", "byte", "val", v, "sql", sql);}
return this;
}
@ -50,7 +50,7 @@ public class Db_stmt_cmd implements Db_stmt {
public Db_stmt Val_int(String k, int v) {return Add_int(Bool_.N, k, v);}
public Db_stmt Val_int(int v) {return Add_int(Bool_.N, Key_na, v);}
private Db_stmt Add_int(boolean where, String k, int v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setInt(++val_idx, v);} catch (Exception e) {this.Rls(); throw Err_.new_exc(e, "db", "failed to add value", "type", "int", "val", v, "sql", sql);}
return this;
}
@ -58,7 +58,7 @@ public class Db_stmt_cmd implements Db_stmt {
public Db_stmt Val_long(String k, long v) {return Add_long(Bool_.N, k, v);}
public Db_stmt Val_long(long v) {return Add_long(Bool_.N, Key_na, v);}
private Db_stmt Add_long(boolean where, String k, long v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setLong(++val_idx, v);} catch (Exception e) {this.Rls(); throw Err_.new_exc(e, "db", "failed to add value", "type", "long", "val", v, "sql", sql);}
return this;
}
@ -66,7 +66,7 @@ public class Db_stmt_cmd implements Db_stmt {
public Db_stmt Val_float(String k, float v) {return Add_float(Bool_.N, k, v);}
public Db_stmt Val_float(float v) {return Add_float(Bool_.N, Key_na, v);}
private Db_stmt Add_float(boolean where, String k, float v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setFloat(++val_idx, v);} catch (Exception e) {this.Rls(); throw Err_.new_exc(e, "db", "failed to add value", "type", "float", "val", v, "sql", sql);}
return this;
}
@ -74,7 +74,7 @@ public class Db_stmt_cmd implements Db_stmt {
public Db_stmt Val_double(String k, double v) {return Add_double(Bool_.N, k, v);}
public Db_stmt Val_double(double v) {return Add_double(Bool_.N, Key_na, v);}
private Db_stmt Add_double(boolean where, String k, double v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setDouble(++val_idx, v);} catch (Exception e) {this.Rls(); throw Err_.new_exc(e, "db", "failed to add value", "type", "double", "val", v, "sql", sql);}
return this;
}
@ -82,7 +82,7 @@ public class Db_stmt_cmd implements Db_stmt {
public Db_stmt Val_decimal(String k, Decimal_adp v) {return Add_decimal(Bool_.N, k, v);}
public Db_stmt Val_decimal(Decimal_adp v) {return Add_decimal(Bool_.N, Key_na, v);}
private Db_stmt Add_decimal(boolean where, String k, Decimal_adp v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setBigDecimal(++val_idx, v.Under_as_native());} catch (Exception e) {this.Rls(); throw Err_.new_exc(e, "db", "failed to add value", "type", "decimal", "val", v, "sql", sql);}
return this;
}
@ -90,7 +90,7 @@ public class Db_stmt_cmd implements Db_stmt {
public Db_stmt Val_bry(String k, byte[] v) {return Add_bry(Bool_.N, k, v);}
public Db_stmt Val_bry(byte[] v) {return Add_bry(Bool_.N, Key_na, v);}
private Db_stmt Add_bry(boolean where, String k, byte[] v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setBytes(++val_idx, v);} catch (Exception e) {this.Rls(); throw Err_.new_exc(e, "db", "failed to add value", "type", "byte[]", v.length, sql);}
return this;
}
@ -102,7 +102,7 @@ public class Db_stmt_cmd implements Db_stmt {
public Db_stmt Val_str(String k, String v) {return Add_str(Bool_.N, k, v);}
public Db_stmt Val_str(String v) {return Add_str(Bool_.N, Key_na, v);}
private Db_stmt Add_str(boolean where, String k, String v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setString(++val_idx, v);} catch (Exception e) {this.Rls(); throw Err_.new_exc(e, "db", "failed to add value", "type", "String", "val", v, "sql", sql);}
return this;
}

@ -125,7 +125,7 @@ public class Db_stmt_sql implements Db_stmt {// used for formatting SQL statemen
}
public void Rls() {this.Clear();}
public void Add(String k, String v) {
if (k == Db_meta_fld.Key_null) return; // key is explicitly null; ignore; allows version_2+ type definitions
if (k == Dbmeta_fld_itm.Key_null) return; // key is explicitly null; ignore; allows version_2+ type definitions
args.Add(v);
}
public String Xto_sql() {

@ -16,11 +16,12 @@ 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.dbs.sqls; import gplx.*; import gplx.dbs.*;
import gplx.dbs.metas.*;
interface Db_sqlbldr {}
public class Db_sqlbldr__sqlite implements Db_sqlbldr {
private Bry_bfr tmp_bfr = Bry_bfr.reset_(1024);
public Db_sqlbldr__sqlite Bfr_(Bry_bfr bfr) {this.tmp_bfr = bfr; return this;}
public String Bld_create_idx(Db_meta_idx idx) {
public String Bld_create_idx(Dbmeta_idx_itm idx) {
tmp_bfr.Add_str_a7("CREATE ");
if (idx.Unique())
tmp_bfr.Add_str_a7("UNIQUE ");
@ -30,22 +31,22 @@ public class Db_sqlbldr__sqlite implements Db_sqlbldr {
tmp_bfr.Add_str_a7(" ON ");
tmp_bfr.Add_str_a7(idx.Tbl());
tmp_bfr.Add_str_a7(" (");
String[] flds = idx.Flds();
Dbmeta_idx_fld[] flds = idx.Flds;
int flds_len = flds.length;
for (int i = 0; i < flds_len; ++i) {
String fld = flds[i];
Dbmeta_idx_fld fld = flds[i];
if (i != 0) tmp_bfr.Add_str_a7(", ");
tmp_bfr.Add_str_a7(fld);
tmp_bfr.Add_str_a7(fld.Name);
}
tmp_bfr.Add_str_a7(");");
return tmp_bfr.To_str_and_clear();
}
public String Bld_create_tbl(Db_meta_tbl tbl) {
public String Bld_create_tbl(Dbmeta_tbl_itm tbl) {
tmp_bfr.Add_str_a7("CREATE TABLE IF NOT EXISTS ").Add_str_a7(tbl.Name()).Add_byte_nl();
Db_meta_fld[] flds = tbl.Flds();
int flds_len = flds.length;
for (int i = 0; i < flds_len; ++i) {
Db_meta_fld fld = flds[i];
Dbmeta_fld_mgr flds = tbl.Flds();
int len = flds.Len();
for (int i = 0; i < len; ++i) {
Dbmeta_fld_itm fld = flds.Get_at(i);
tmp_bfr.Add_byte(i == 0 ? Byte_ascii.Paren_bgn : Byte_ascii.Comma).Add_byte_space();
Bld_fld(tmp_bfr, fld);
tmp_bfr.Add_byte_nl();
@ -53,7 +54,7 @@ public class Db_sqlbldr__sqlite implements Db_sqlbldr {
tmp_bfr.Add_str_a7(");");
return tmp_bfr.To_str_and_clear();
}
public String Bld_alter_tbl_add(String tbl, Db_meta_fld fld) {
public String Bld_alter_tbl_add(String tbl, Dbmeta_fld_itm fld) {
tmp_bfr.Add_str_a7("ALTER TABLE ").Add_str_a7(tbl).Add_str_a7(" ADD ");
Bld_fld(tmp_bfr, fld);
tmp_bfr.Add_byte_semic();
@ -62,15 +63,19 @@ public class Db_sqlbldr__sqlite implements Db_sqlbldr {
public String Bld_drop_tbl(String tbl) {
return String_.Format("DROP TABLE IF EXISTS {0};", tbl);
}
private void Bld_fld(Bry_bfr tmp_bfr, Db_meta_fld fld) {
private void Bld_fld(Bry_bfr tmp_bfr, Dbmeta_fld_itm fld) {
tmp_bfr.Add_str_a7(fld.Name()).Add_byte_space();
Tid_to_sql(tmp_bfr, fld.Tid(), fld.Len()); tmp_bfr.Add_byte_space();
tmp_bfr.Add_str_a7(fld.Nullable() ? "NULL " : "NOT NULL ");
if (fld.Default() != Db_meta_fld.Default_value_null) {
Tid_to_sql(tmp_bfr, fld.Type().Tid_ansi(), fld.Type().Len_1()); tmp_bfr.Add_byte_space();
switch (fld.Nullable_tid()) {
case Dbmeta_fld_itm.Nullable_unknown:
case Dbmeta_fld_itm.Nullable_not_null: tmp_bfr.Add_str_a7("NOT NULL "); break;
case Dbmeta_fld_itm.Nullable_null: tmp_bfr.Add_str_a7("NULL "); break;
}
if (fld.Default() != Dbmeta_fld_itm.Default_value_null) {
tmp_bfr.Add_str_a7("DEFAULT ");
boolean quote = Bool_.N;
switch (fld.Tid()) {
case Db_meta_fld.Tid_str: case Db_meta_fld.Tid_text: quote = Bool_.Y; break;
switch (fld.Type().Tid_ansi()) {
case Dbmeta_fld_tid.Tid__str: case Dbmeta_fld_tid.Tid__text: quote = Bool_.Y; break;
}
if (quote) tmp_bfr.Add_byte_apos();
tmp_bfr.Add_str_u8(Object_.Xto_str_strict_or_null(fld.Default()));
@ -83,17 +88,17 @@ public class Db_sqlbldr__sqlite implements Db_sqlbldr {
}
public static void Tid_to_sql(Bry_bfr tmp_bfr, int tid, int len) {// REF: https://www.sqlite.org/datatype3.html
switch (tid) {
case Db_meta_fld.Tid_bool: tmp_bfr.Add_str_a7("boolean"); break;
case Db_meta_fld.Tid_byte: tmp_bfr.Add_str_a7("tinyint"); break;
case Db_meta_fld.Tid_short: tmp_bfr.Add_str_a7("smallint"); break;
case Db_meta_fld.Tid_int: tmp_bfr.Add_str_a7("integer"); break; // NOTE: must be integer, not int, else "int PRIMARY KEY AUTONUMBER" will fail; DATE:2015-02-12
case Db_meta_fld.Tid_long: tmp_bfr.Add_str_a7("bigint"); break;
case Db_meta_fld.Tid_float: tmp_bfr.Add_str_a7("float"); break;
case Db_meta_fld.Tid_double: tmp_bfr.Add_str_a7("double"); break;
case Db_meta_fld.Tid_str: tmp_bfr.Add_str_a7("varchar(").Add_int_variable(len).Add_byte(Byte_ascii.Paren_end); break;
case Db_meta_fld.Tid_text: tmp_bfr.Add_str_a7("text"); break;
case Db_meta_fld.Tid_bry: tmp_bfr.Add_str_a7("blob"); break;
default: throw Err_.new_unhandled(tid);
case Dbmeta_fld_tid.Tid__bool: tmp_bfr.Add_str_a7("boolean"); break;
case Dbmeta_fld_tid.Tid__byte: tmp_bfr.Add_str_a7("tinyint"); break;
case Dbmeta_fld_tid.Tid__short: tmp_bfr.Add_str_a7("smallint"); break;
case Dbmeta_fld_tid.Tid__int: tmp_bfr.Add_str_a7("integer"); break; // NOTE: must be integer, not int, else "int PRIMARY KEY AUTONUMBER" will fail; DATE:2015-02-12
case Dbmeta_fld_tid.Tid__long: tmp_bfr.Add_str_a7("bigint"); break;
case Dbmeta_fld_tid.Tid__float: tmp_bfr.Add_str_a7("float"); break;
case Dbmeta_fld_tid.Tid__double: tmp_bfr.Add_str_a7("double"); break;
case Dbmeta_fld_tid.Tid__str: tmp_bfr.Add_str_a7("varchar(").Add_int_variable(len).Add_byte(Byte_ascii.Paren_end); break;
case Dbmeta_fld_tid.Tid__text: tmp_bfr.Add_str_a7("text"); break;
case Dbmeta_fld_tid.Tid__bry: tmp_bfr.Add_str_a7("blob"); break;
default: throw Err_.new_unhandled(tid);
}
}
public static final Db_sqlbldr__sqlite Instance = new Db_sqlbldr__sqlite();

@ -20,12 +20,12 @@ import org.junit.*;
public class Db_sqlbldr_tst {
@Before public void setup() {} private final Db_sqlbldr_fxt fxt = new Db_sqlbldr_fxt();
@Test public void Idx_unique() {
fxt.Test_create_idx(Db_meta_idx.new_unique_by_tbl("tbl_name", "idx_name", "fld_1", "fld_2")
fxt.Test_create_idx(Dbmeta_idx_itm.new_unique_by_tbl("tbl_name", "idx_name", "fld_1", "fld_2")
, "CREATE UNIQUE INDEX IF NOT EXISTS tbl_name__idx_name ON tbl_name (fld_1, fld_2);"
);
}
@Test public void Tbl_basic() {
Db_meta_fld_list flds = Db_meta_fld_list.new_();
Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
flds.Add_int_pkey("fld_int_pkey");
flds.Add_bool("fld_bool");
flds.Add_short("fld_short");
@ -36,7 +36,7 @@ public class Db_sqlbldr_tst {
flds.Add_str("fld_str", 123);
flds.Add_text("fld_text");
flds.Add_bry("fld_bry");
fxt.Test_create_tbl(Db_meta_tbl.new_("tbl_name", flds.To_fld_ary())
fxt.Test_create_tbl(Dbmeta_tbl_itm.New("tbl_name", flds.To_fld_ary())
, String_.Concat_lines_nl_skip_last
( "CREATE TABLE IF NOT EXISTS tbl_name"
, "( fld_int_pkey integer NOT NULL PRIMARY KEY"
@ -53,7 +53,7 @@ public class Db_sqlbldr_tst {
));
}
@Test public void Tbl_alter_tbl_add() {
Db_meta_fld_list flds = Db_meta_fld_list.new_();
Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
flds.Add_int_dflt("fld_int", -1);
flds.Add_str_dflt("fld_str", 255, "a");
fxt.Test_alter_tbl_add("tbl_name", flds.Get_by("fld_int"), "ALTER TABLE tbl_name ADD fld_int integer NOT NULL DEFAULT -1;");
@ -62,7 +62,7 @@ public class Db_sqlbldr_tst {
}
class Db_sqlbldr_fxt {
private Db_sqlbldr__sqlite sqlbldr = Db_sqlbldr__sqlite.Instance;
public void Test_create_idx(Db_meta_idx idx, String expd) {Tfds.Eq(expd, sqlbldr.Bld_create_idx(idx));}
public void Test_create_tbl(Db_meta_tbl tbl, String expd) {Tfds.Eq_str_lines(expd, sqlbldr.Bld_create_tbl(tbl));}
public void Test_alter_tbl_add(String tbl, Db_meta_fld fld, String expd) {Tfds.Eq_str_lines(expd, sqlbldr.Bld_alter_tbl_add(tbl, fld));}
public void Test_create_idx(Dbmeta_idx_itm idx, String expd) {Tfds.Eq(expd, sqlbldr.Bld_create_idx(idx));}
public void Test_create_tbl(Dbmeta_tbl_itm tbl, String expd) {Tfds.Eq_str_lines(expd, sqlbldr.Bld_create_tbl(tbl));}
public void Test_alter_tbl_add(String tbl, Dbmeta_fld_itm fld, String expd) {Tfds.Eq_str_lines(expd, sqlbldr.Bld_alter_tbl_add(tbl, fld));}
}

@ -26,29 +26,29 @@ class Db_diff_bldr {
// Io_url trg_url = Io_url_.new_fil_(trg_str);
// Db_conn src_conn = Db_conn_bldr.Instance.Get_or_new(src_url).Conn();
// Db_conn trg_conn = Db_conn_bldr.Instance.Get_or_new(trg_url).Conn();
Meta_tbl_mgr src_tbls = new Meta_tbl_mgr();
Meta_tbl_mgr trg_tbls = new Meta_tbl_mgr();
Dbmeta_tbl_mgr src_tbls = new Dbmeta_tbl_mgr();
Dbmeta_tbl_mgr trg_tbls = new Dbmeta_tbl_mgr();
return Compare_tbls(src_tbls, trg_tbls);
}
public String Compare_tbls(Meta_tbl_mgr src_tbls, Meta_tbl_mgr trg_tbls) {
public String Compare_tbls(Dbmeta_tbl_mgr src_tbls, Dbmeta_tbl_mgr trg_tbls) {
int src_len = src_tbls.Len();
for (int i = 0; i < src_len; ++i) {
Meta_tbl_itm src_tbl = src_tbls.Get_at(i);
Meta_tbl_itm trg_tbl = trg_tbls.Get_by(src_tbl.Name());
Dbmeta_tbl_itm src_tbl = src_tbls.Get_at(i);
Dbmeta_tbl_itm trg_tbl = trg_tbls.Get_by(src_tbl.Name());
if (trg_tbl == null) Tbl_delete(src_tbl);
}
int trg_len = trg_tbls.Len();
for (int i = 0; i < trg_len; ++i) {
Meta_tbl_itm trg_tbl = src_tbls.Get_at(i);
Meta_tbl_itm src_tbl = trg_tbls.Get_by(trg_tbl.Name());
Dbmeta_tbl_itm trg_tbl = src_tbls.Get_at(i);
Dbmeta_tbl_itm src_tbl = trg_tbls.Get_by(trg_tbl.Name());
if (src_tbl == null) Tbl_create(trg_tbl);
}
return bfr.To_str_and_clear();
}
private void Tbl_delete(Meta_tbl_itm tbl) {
private void Tbl_delete(Dbmeta_tbl_itm tbl) {
bfr.Add_str_a7("DROP TABLE ").Add_str_u8(tbl.Name()).Add_byte_nl();
}
private void Tbl_create(Meta_tbl_itm tbl) {
private void Tbl_create(Dbmeta_tbl_itm tbl) {
// sql_bldr.Bld_create_tbl(tbl);
}
}

@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.dbs.cfgs; import gplx.*; import gplx.dbs.*;
import gplx.core.primitives.*;
public class Db_cfg_tbl implements Rls_able {
private final String tbl_name; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String tbl_name; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
private final String fld_grp, fld_key, fld_val;
private Db_stmt stmt_insert, stmt_update, stmt_select;
public Db_conn Conn() {return conn;} private final Db_conn conn;
@ -34,10 +34,10 @@ public class Db_cfg_tbl implements Rls_able {
stmt_update = Db_stmt_.Rls(stmt_update);
stmt_select = Db_stmt_.Rls(stmt_select);
}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds, Db_meta_idx.new_unique_by_tbl(tbl_name, "main", fld_grp, fld_key, fld_val)));}
public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds, Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "main", fld_grp, fld_key, fld_val)));}
public void Delete_val(String grp, String key) {conn.Stmt_delete(tbl_name, fld_grp, fld_key).Crt_str(fld_grp, grp).Crt_str(fld_key, key).Exec_delete();}
public void Delete_grp(String grp) {conn.Stmt_delete(tbl_name, fld_grp).Crt_str(fld_grp, grp).Exec_delete();}
public void Delete_all() {conn.Stmt_delete(tbl_name, Db_meta_fld.Ary_empty).Exec_delete();}
public void Delete_all() {conn.Stmt_delete(tbl_name, Dbmeta_fld_itm.Str_ary_empty).Exec_delete();}
public void Insert_yn (String grp, String key, boolean val) {Insert_str(grp, key, val ? "y" : "n");}
public void Insert_byte (String grp, String key, byte val) {Insert_str(grp, key, Byte_.To_str(val));}
public void Insert_int (String grp, String key, int val) {Insert_str(grp, key, Int_.To_str(val));}

@ -1,34 +0,0 @@
/*
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.dbs.diffs; import gplx.*; import gplx.dbs.*;
public class Gfdb_diff_tbl {
public Gfdb_diff_tbl(String name, Db_meta_fld[] keys, Db_meta_fld[] vals, Db_rdr rdr) {
this.name = name; this.keys = keys; this.vals = vals; this.rdr = rdr;
int keys_len = keys.length; int vals_len = vals.length;
this.flds = new Db_meta_fld[keys_len + vals_len];
for (int i = 0; i < keys_len; ++i)
flds[i] = keys[i];
for (int i = 0; i < vals_len; ++i)
flds[i + keys_len] = vals[i];
}
public String Name() {return name;} private final String name;
public Db_meta_fld[] Flds() {return flds;} private final Db_meta_fld[] flds;
public Db_meta_fld[] Keys() {return keys;} private final Db_meta_fld[] keys;
public Db_meta_fld[] Vals() {return vals;} private final Db_meta_fld[] vals;
public Db_rdr Rdr() {return rdr;} private final Db_rdr rdr;
}

@ -1,56 +0,0 @@
/*
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.dbs.diffs; import gplx.*; import gplx.dbs.*;
public class Gfdb_rdr_utl_ {
public static int Compare(Db_meta_fld[] flds, int len, Db_rdr lhs_rdr, Db_rdr rhs_rdr) {
int comp = CompareAble_.Same;
for (int i = 0; i < len; ++i) {
Db_meta_fld fld = flds[i];
String fld_name = fld.Name();
switch (fld.Tid()) {
case Db_meta_fld.Tid_bool: comp = Bool_.Compare (lhs_rdr.Read_bool_by_byte(fld_name), rhs_rdr.Read_bool_by_byte(fld_name)); break;
case Db_meta_fld.Tid_int: comp = Int_.Compare (lhs_rdr.Read_int(fld_name) , rhs_rdr.Read_int(fld_name)); break;
case Db_meta_fld.Tid_long: comp = Long_.Compare (lhs_rdr.Read_long(fld_name) , rhs_rdr.Read_long(fld_name)); break;
case Db_meta_fld.Tid_float: comp = Float_.Compare (lhs_rdr.Read_float(fld_name) , rhs_rdr.Read_float(fld_name)); break;
case Db_meta_fld.Tid_double: comp = Double_.Compare (lhs_rdr.Read_double(fld_name) , rhs_rdr.Read_double(fld_name)); break;
case Db_meta_fld.Tid_str: comp = String_.Compare (lhs_rdr.Read_str(fld_name) , rhs_rdr.Read_str(fld_name)); break;
case Db_meta_fld.Tid_bry: comp = Bry_.Compare (lhs_rdr.Read_bry(fld_name) , rhs_rdr.Read_bry(fld_name)); break;
default: throw Err_.new_unhandled(fld.Tid());
}
if (comp != CompareAble_.Same) return comp;
}
return CompareAble_.Same;
}
public static void Stmt_args(Db_stmt stmt, Db_meta_fld[] flds, int len, Db_rdr rdr) {
for (int i = 0; i < len; ++i) {
Db_meta_fld fld = flds[i];
String fld_name = fld.Name();
switch (fld.Tid()) {
case Db_meta_fld.Tid_bool: stmt.Val_bool_as_byte (fld_name, rdr.Read_bool_by_byte(fld_name)); break;
case Db_meta_fld.Tid_byte: stmt.Val_byte (fld_name, rdr.Read_byte(fld_name)); break;
case Db_meta_fld.Tid_int: stmt.Val_int (fld_name, rdr.Read_int(fld_name)); break;
case Db_meta_fld.Tid_long: stmt.Val_long (fld_name, rdr.Read_long(fld_name)); break;
case Db_meta_fld.Tid_float: stmt.Val_float (fld_name, rdr.Read_float(fld_name)); break;
case Db_meta_fld.Tid_double: stmt.Val_double (fld_name, rdr.Read_double(fld_name)); break;
case Db_meta_fld.Tid_str: stmt.Val_str (fld_name, rdr.Read_str(fld_name)); break;
case Db_meta_fld.Tid_bry: stmt.Val_bry (fld_name, rdr.Read_bry(fld_name)); break;
default: throw Err_.new_unhandled(fld.Tid());
}
}
}
}

@ -1,123 +0,0 @@
/*
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.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import org.junit.*;
import gplx.dbs.*; import gplx.dbs.engines.mems.*;
public class Gfdb_diff_bldr_tst {
private final Gfdb_diff_bldr_fxt fxt = new Gfdb_diff_bldr_fxt();
@Test public void Same() {
fxt.Init__tbl__lhs(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Init__tbl__rhs(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Test__bld();
}
@Test public void Update() {
fxt.Init__tbl__lhs(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Init__tbl__rhs(Object_.Ary(1, "A1") , Object_.Ary(2, "B1"));
fxt.Test__bld("U|1|A1", "U|2|B1");
}
@Test public void Insert() {
fxt.Init__tbl__lhs(Object_.Ary(1, "A"));
fxt.Init__tbl__rhs(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Test__bld("I|2|B");
}
@Test public void Delete() {
fxt.Init__tbl__lhs(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Init__tbl__rhs(Object_.Ary(1, "A"));
fxt.Test__bld("D|2");
}
@Test public void Basic() {
fxt.Init__tbl__lhs
( Object_.Ary(1, "A")
, Object_.Ary(2, "B")
, Object_.Ary(3, "C")
);
fxt.Init__tbl__rhs
( Object_.Ary(1, "A")
, Object_.Ary(2, "B1")
, Object_.Ary(4, "D")
);
fxt.Test__bld("U|2|B1", "D|3", "I|4|D");
}
}
class Gfdb_diff_bldr_fxt {
private final Gfdb_diff_bldr bldr = new Gfdb_diff_bldr();
private final Gfdb_diff_wkr__test wkr = new Gfdb_diff_wkr__test();
private final Db_meta_fld[] key_flds, val_flds;
private Gfdb_diff_tbl lhs_tbl, rhs_tbl;
public Gfdb_diff_bldr_fxt() {
Db_meta_fld_list fld_list = new Db_meta_fld_list();
fld_list.Add_int("id");
key_flds = fld_list.To_fld_ary();
fld_list.Clear();
fld_list.Add_str("val", 255);
val_flds = fld_list.To_fld_ary();
bldr.Init(wkr);
}
public void Init__tbl__lhs(Object[]... rows) {this.lhs_tbl = Make__tbl(key_flds, val_flds, rows);}
public void Init__tbl__rhs(Object[]... rows) {this.rhs_tbl = Make__tbl(key_flds, val_flds, rows);}
public void Test__bld(String... expd) {
bldr.Compare(lhs_tbl, rhs_tbl);
Tfds.Eq_ary_str(expd, wkr.To_str_ary());
}
private static Gfdb_diff_tbl Make__tbl(Db_meta_fld[] keys, Db_meta_fld[] vals, Object[][] rows) {
int keys_len = keys.length; int vals_len = vals.length;
int cols_len = keys_len + vals_len;
String[] cols = new String[cols_len];
for (int i = 0; i < keys_len; ++i)
cols[i] = keys[i].Name();
for (int i = 0; i < vals_len; ++i)
cols[i + keys_len] = vals[i].Name();
int rows_len = rows.length;
Mem_row[] mem_rows = new Mem_row[rows_len];
for (int i = 0; i < rows_len; ++i) {
Object[] row = rows[i];
Mem_row mem_row = new Mem_row();
mem_rows[i] = mem_row;
for (int j = 0; j < cols_len; ++j) {
Object cell = row[j];
mem_row.Add(cols[j], cell);
}
}
Db_rdr rdr = new Db_rdr__mem(cols, mem_rows);
return new Gfdb_diff_tbl("tbl1", keys, vals, rdr);
}
}
class Gfdb_diff_wkr__test implements Gfdb_diff_wkr {
private final List_adp list = List_adp_.new_();
private final Bry_bfr bfr = Bry_bfr.new_();
private Db_rdr lhs_rdr, rhs_rdr;
public void Init_tbls(Gfdb_diff_tbl lhs_tbl, Gfdb_diff_tbl rhs_tbl) {
this.lhs_rdr = lhs_tbl.Rdr(); this.rhs_rdr = rhs_tbl.Rdr();
}
public void Term_tbls() {}
public void Handle_same() {
String lhs_val = lhs_rdr.Read_str("val");
String rhs_val = rhs_rdr.Read_str("val");
if (!String_.Eq(lhs_val, rhs_val))
list.Add(bfr.Add_str_a7("U").Add_byte_pipe().Add_obj(lhs_rdr.Read_obj("id")).Add_byte_pipe().Add_str_a7(rhs_val).To_str_and_clear());
}
public void Handle_lhs_missing() {
String rhs_val = rhs_rdr.Read_str("val");
list.Add(bfr.Add_str_a7("I").Add_byte_pipe().Add_obj(rhs_rdr.Read_obj("id")).Add_byte_pipe().Add_str_a7(rhs_val).To_str_and_clear());
}
public void Handle_rhs_missing() {
list.Add(bfr.Add_str_a7("D").Add_byte_pipe().Add_obj(lhs_rdr.Read_obj("id")).To_str_and_clear());
}
public String[] To_str_ary() {return list.To_str_ary_and_clear();}
}

@ -1,66 +0,0 @@
/*
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.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
class Gfdb_diff_rdr_comparer {
private Db_rdr lhs_rdr, rhs_rdr;
private boolean lhs_rdr_move, rhs_rdr_move;
private boolean lhs_rdr_done, rhs_rdr_done;
private Db_meta_fld[] key_flds; private int key_flds_len;
public void Init(Gfdb_diff_tbl lhs_tbl, Gfdb_diff_tbl rhs_tbl) {
this.lhs_rdr = lhs_tbl.Rdr(); this.rhs_rdr = rhs_tbl.Rdr();
this.lhs_rdr_move = rhs_rdr_move = Bool_.Y;
this.lhs_rdr_done = rhs_rdr_done = Bool_.N;
this.key_flds = rhs_tbl.Keys(); key_flds_len = key_flds.length;
}
public int Compare() {
if (lhs_rdr_move) {
lhs_rdr_move = lhs_rdr.Move_next();
if (!lhs_rdr_move) lhs_rdr_done = true;
}
if (rhs_rdr_move) {
rhs_rdr_move = rhs_rdr.Move_next();
if (!rhs_rdr_move) rhs_rdr_done = true;
}
if (lhs_rdr_done && rhs_rdr_done) return Gfdb_diff_rdr_comparer.Rslt__done;
else if (lhs_rdr_done) {rhs_rdr_move = true; return Gfdb_diff_rdr_comparer.Rslt__lhs_missing;}
else if (rhs_rdr_done) {lhs_rdr_move = true; return Gfdb_diff_rdr_comparer.Rslt__rhs_missing;}
else {
int comp = Gfdb_rdr_utl_.Compare(key_flds, key_flds_len, lhs_rdr, rhs_rdr);
switch (comp) {
case CompareAble_.Same: // lhs == rhs; move both
lhs_rdr_move = rhs_rdr_move = true;
return Gfdb_diff_rdr_comparer.Rslt__same;
case CompareAble_.Less: // lhs < rhs; EX: lhs == 2; rhs == 3
lhs_rdr_move = true;
rhs_rdr_move = false;
return Gfdb_diff_rdr_comparer.Rslt__rhs_missing;
case CompareAble_.More: // lhs > rhs; EX: lhs == 4; rhs == 3
lhs_rdr_move = false;
rhs_rdr_move = true;
return Gfdb_diff_rdr_comparer.Rslt__lhs_missing;
default: throw Err_.new_unhandled(comp);
}
}
}
public static final int
Rslt__same = 0
, Rslt__lhs_missing = 1
, Rslt__rhs_missing = 2
, Rslt__done = 3
;
}

@ -1,123 +0,0 @@
/*
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.dbs.diffs.merges; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import gplx.core.brys.fmtrs.*;
interface Gfdb_diff_cmd {
void Merge_undo();
void Merge_exec();
}
class Gfdb_diff_cmd__insert {
// else if I
// // txn_bgn
// // audit
// INSERT INTO db_temp.page (diff_type, diff, *)
// SELECT 'D', d.page_id, *
// FROM db_diff.page d
// JOIN db_main.page m ON d.page_id = m.page_id
// WHERE d.diff_type = 0
// AND d.diff_idx BETWEEN lo and hi
//
// // update
// INSERT INTO db_main.page
// SELECT d.page_title
// FROM db_diff.page d
// JOIN db_main.page m
// // txn_end
private Db_conn conn;
private String exec_sql;
public void Init(Db_conn main_conn, Db_conn diff_conn, Db_conn temp_conn, Gfdb_diff_tbl tbl) {
this.conn = temp_conn;
this.exec_sql = "";
// this.exec_sql = String_.Format(String_.Concat_lines_nl_skip_last
// ( "INSERT INTO db_curr.{tbl}"
// ), Gfdb_diff_cmd_ctx.Alias__curr);
}
public void Merge_exec() {
conn.Exec_sql(exec_sql);
}
}
class Gfdb_diff_cmd_sql_bldr {
private final Bry_fmtr fmtr = Bry_fmtr.new_();
private final Bry_bfr tmp_bfr = Bry_bfr.new_();
public void Bld_insert(Bry_bfr bfr, String tbl_name, String[] keys, String[] vals, int rng_bgn, int rng_end) {
fmtr.Fmt_(Insert__fmt).Keys_(Insert__keys);
fmtr.Bld_bfr_many(bfr, tbl_name, Bld_flds(tmp_bfr, ", ", "d.", keys, vals), Bld_join(keys), rng_bgn, rng_end);
}
public void Bld_update(Bry_bfr bfr, String tbl_name, String[] keys, String[] vals, int rng_bgn, int rng_end) {
fmtr.Fmt_(Update__fmt).Keys_(Update__keys);
fmtr.Bld_bfr_many(bfr, tbl_name, Bld_flds(tmp_bfr, ", ", "d.", keys, vals), Bld_join(keys), rng_bgn, rng_end);
}
public void Bld_delete(Bry_bfr bfr, String tbl_name, String[] keys, int rng_bgn, int rng_end) {
fmtr.Fmt_(Delete__fmt).Keys_(Delete__keys);
fmtr.Bld_bfr_many(bfr, tbl_name, Bld_flds(tmp_bfr, " || '|' || ", "", keys, String_.Ary_empty), Bld_flds(tmp_bfr, " || '|' || ", "k.", keys, String_.Ary_empty), Bld_join(keys), rng_bgn, rng_end);
}
private static String Bld_flds(Bry_bfr tmp_bfr, String dlm, String alias, String[] keys, String[] vals) {
int keys_len = keys.length;
for (int i = 0; i < keys_len; ++i) {
String key = keys[i];
if (i != 0) tmp_bfr.Add_str_a7(dlm);
tmp_bfr.Add_str_a7(alias).Add_str_a7(key);
}
int flds_len = vals.length;
for (int i = 0; i < flds_len; ++i) {
String val = vals[i];
tmp_bfr.Add_str_a7(dlm);
tmp_bfr.Add_str_a7(alias).Add_str_a7(val);
}
return tmp_bfr.To_str_and_clear();
}
private String Bld_join(String[] keys) {
int len = keys.length;
for (int i = 0; i < len; ++i) {
String key = keys[i];
tmp_bfr.Add_str_a7(i == 0 ? " ON " : " AND ");
tmp_bfr.Add_str_a7("k.").Add_str_a7(key).Add_str_a7(" = ");
tmp_bfr.Add_str_a7("d.").Add_str_a7(key);
}
return tmp_bfr.To_str_and_clear();
}
private static final String[] Insert__keys = String_.Ary("tbl", "flds", "join", "rng_bgn", "rng_end");
private static final String Insert__fmt = String_.Concat_lines_nl_skip_last
( "INSERT INTO db_curr.~{tbl}"
, "SELECT ~{flds}"
, "FROM db_temp.~{tbl}_pkey k"
, " JOIN db_diff.~{tbl} d~{join}"
, "WHERE k.diff_type = 1"
, "AND k.diff_uid BETWEEN ~{rng_bgn} AND ~{rng_end};"
);
private static final String[] Update__keys = String_.Ary("tbl", "flds", "join", "rng_bgn", "rng_end");
private static final String Update__fmt = String_.Concat_lines_nl_skip_last
( "REPLACE INTO db_curr.~{tbl}"
, "SELECT ~{flds}"
, "FROM db_temp.~{tbl}_pkey k"
, " JOIN db_diff.~{tbl} d~{join}"
, "WHERE k.diff_type = 2"
, "AND k.diff_uid BETWEEN ~{rng_bgn} AND ~{rng_end};"
);
private static final String[] Delete__keys = String_.Ary("tbl", "pkey_where", "pkey_select", "join", "rng_bgn", "rng_end");
private static final String Delete__fmt = String_.Concat_lines_nl_skip_last
( "DELETE db_curr.~{tbl}"
, "WHERE ~{pkey_where} IN"
, "( SELECT ~{pkey_select}"
, " FROM db_temp.~{tbl}_pkey k"
, " JOIN db_diff.~{tbl} d~{join}"
, " WHERE k.diff_type = 0"
, " AND k.diff_uid BETWEEN ~{rng_bgn} AND ~{rng_end}"
, ");"
);
}

@ -20,7 +20,7 @@ import gplx.dbs.metas.updates.*;
public class Schema_db_mgr {
public Schema_loader_mgr Loader() {return loader;} public void Loader_(Schema_loader_mgr v) {loader = v;} private Schema_loader_mgr loader;
public Schema_update_mgr Updater() {return updater;} private final Schema_update_mgr updater = new Schema_update_mgr();
public Meta_tbl_mgr Tbl_mgr() {return tbl_mgr;} private final Meta_tbl_mgr tbl_mgr = new Meta_tbl_mgr();
public Dbmeta_tbl_mgr Tbl_mgr() {return tbl_mgr;} private final Dbmeta_tbl_mgr tbl_mgr = new Dbmeta_tbl_mgr();
public void Init(Db_conn conn) {
loader.Load(this, conn);
updater.Update(this, conn);

@ -27,21 +27,20 @@ class Schema_loader_mgr__null implements Schema_loader_mgr {
class Schema_loader_mgr__sqlite implements Schema_loader_mgr {
public void Load(Schema_db_mgr db_mgr, Db_conn conn) {
Gfo_usr_dlg_.Instance.Log_many("", "", "db.schema.load.bgn: conn=~{0}", conn.Conn_info().Xto_api());
Meta_tbl_mgr tbl_mgr = db_mgr.Tbl_mgr();
Dbmeta_tbl_mgr tbl_mgr = db_mgr.Tbl_mgr();
Db_qry__select_in_tbl qry = Db_qry__select_in_tbl.new_("sqlite_master", String_.Ary_empty, String_.Ary("type", "name", "sql"), Db_qry__select_in_tbl.Order_by_null);
Db_rdr rdr = conn.Stmt_new(qry).Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
String type_str = rdr.Read_str("type");
String name = rdr.Read_str("name");
String sql = rdr.Read_str("sql");
int type_int = Meta_itm_tid.Xto_int(type_str);
int type_int = Dbmeta_itm_tid.Xto_int(type_str);
switch (type_int) {
case Meta_itm_tid.Tid_table:
Meta_tbl_itm tbl_itm = new Meta_tbl_itm(name, sql);
case Dbmeta_itm_tid.Tid_table:
Dbmeta_tbl_itm tbl_itm = Dbmeta_tbl_itm.New(name);
tbl_mgr.Add(tbl_itm);
break;
case Meta_itm_tid.Tid_index: break; // noop for now
case Dbmeta_itm_tid.Tid_index: break; // noop for now
default: throw Err_.new_unhandled(type_str);
}
}

@ -23,7 +23,7 @@ public class Schema_update_mgr_tst {
fxt.Test_exec_y(new Schema_update_cmd__mock());
}
@Test public void Delete() {
fxt.Init_itm(Meta_itm_tid.Tid_table, Schema_update_cmd__mock.Tbl_name);
fxt.Init_itm(Dbmeta_itm_tid.Tid_table, Schema_update_cmd__mock.Tbl_name);
fxt.Test_exec_n(new Schema_update_cmd__mock());
}
}
@ -34,7 +34,7 @@ class Schema_update_mgr_fxt {
db_mgr = new Schema_db_mgr();
}
public void Init_itm(int tid, String name) {
db_mgr.Tbl_mgr().Add(new Meta_tbl_itm(name, "sql"));
db_mgr.Tbl_mgr().Add(Dbmeta_tbl_itm.New(name));
}
public void Test_exec_y(Schema_update_cmd cmd) {Test_exec(cmd, Bool_.Y);}
public void Test_exec_n(Schema_update_cmd cmd) {Test_exec(cmd, Bool_.N);}

@ -20,7 +20,7 @@ import gplx.core.primitives.*; import gplx.core.envs.*;
import gplx.dbs.*; import gplx.core.ios.*;
import gplx.dbs.engines.sqlite.*;
public class Fsd_bin_tbl implements Rls_able {
private final String tbl_name = "fsdb_bin"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String tbl_name = "fsdb_bin"; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
private final String fld_owner_id, fld_owner_tid, fld_part_id, fld_data_url, fld_data;
private Db_conn conn; private Db_stmt stmt_insert, stmt_select; private Bry_bfr tmp_bfr;
private final Bool_obj_ref saved_in_parts = Bool_obj_ref.n_();
@ -37,7 +37,7 @@ public class Fsd_bin_tbl implements Rls_able {
stmt_insert = Db_stmt_.Rls(stmt_insert);
stmt_select = Db_stmt_.Rls(stmt_select);
}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds));}
public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds));}
public void Insert_bgn() {conn.Txn_bgn("fsdb_bin__insert"); stmt_insert = conn.Stmt_insert(tbl_name, flds);}
public void Insert_commit() {conn.Txn_sav();}
public void Insert_end() {conn.Txn_end(); stmt_insert = Db_stmt_.Rls(stmt_insert);}

@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
import gplx.dbs.*;
public class Fsd_dir_tbl implements Rls_able {
private final String tbl_name = "fsdb_dir"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String tbl_name = "fsdb_dir"; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
private final String fld_id, fld_owner_id, fld_name;
private final Db_conn conn; private Db_stmt stmt_insert, stmt_update, stmt_select_by_name;
public Fsd_dir_tbl(Db_conn conn, boolean schema_is_1) {
@ -35,8 +35,8 @@ public class Fsd_dir_tbl implements Rls_able {
}
public void Create_tbl() {
conn.Ddl_create_tbl
( Db_meta_tbl.new_(tbl_name, flds
, Db_meta_idx.new_normal_by_tbl(tbl_name, "name", fld_name, fld_owner_id, fld_id)));
( Dbmeta_tbl_itm.New(tbl_name, flds
, Dbmeta_idx_itm.new_normal_by_tbl(tbl_name, "name", fld_name, fld_owner_id, fld_id)));
}
public void Insert(int id, byte[] name, int owner_id) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);

@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
import gplx.dbs.*; import gplx.dbs.qrys.*; import gplx.dbs.engines.sqlite.*;
public class Fsd_fil_tbl implements Rls_able {
private final String tbl_name = "fsdb_fil"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String tbl_name = "fsdb_fil"; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
private final String fld_id, fld_owner_id, fld_name, fld_xtn_id, fld_ext_id, fld_size, fld_modified, fld_hash, fld_bin_db_id;
private final String idx_owner;
private Db_conn conn; private Db_stmt stmt_insert, stmt_update, stmt_select_by_name; private int mnt_id;
@ -33,7 +33,7 @@ public class Fsd_fil_tbl implements Rls_able {
this.fld_size = flds.Add_long ("fil_size");
this.fld_modified = flds.Add_str ("fil_modified", 14); // stored as yyyyMMddHHmmss
this.fld_hash = flds.Add_str ("fil_hash", 40);
this.idx_owner = Db_meta_idx.Bld_idx_name(tbl_name, "owner");
this.idx_owner = Dbmeta_idx_itm.Bld_idx_name(tbl_name, "owner");
conn.Rls_reg(this);
}
public void Rls() {
@ -42,8 +42,8 @@ public class Fsd_fil_tbl implements Rls_able {
stmt_select_by_name = Db_stmt_.Rls(stmt_select_by_name);
}
public void Create_tbl() {
conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds
, Db_meta_idx.new_unique_by_name(tbl_name, idx_owner, fld_owner_id, fld_name, fld_id)
conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds
, Dbmeta_idx_itm.new_unique_by_name(tbl_name, idx_owner, fld_owner_id, fld_name, fld_id)
));
}
public void Insert(int id, int owner_id, byte[] name, int xtn_id, int ext_id, long size, int bin_db_id) {
@ -89,7 +89,7 @@ public class Fsd_fil_tbl implements Rls_able {
finally {rdr.Rls();}
}
public void Select_all(Bry_bfr key_bfr, gplx.core.caches.Gfo_cache_mgr_bry cache) {
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Db_meta_fld.Ary_empty).Exec_select__rls_auto();
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Dbmeta_fld_itm.Str_ary_empty).Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
Fsd_fil_itm fil = new_(mnt_id, rdr);

@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
import gplx.dbs.*; import gplx.fsdb.meta.*; import gplx.xowa.files.*;
public class Fsd_thm_tbl implements Rls_able {
private final String tbl_name; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String tbl_name; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
private final String fld_id, fld_owner_id, fld_w, fld_h, fld_time, fld_page, fld_bin_db_id, fld_size, fld_modified, fld_hash;
private final Db_conn conn; private Db_stmt stmt_insert, stmt_select_by_fil_exact, stmt_select_by_fil_near; private int mnt_id; private boolean schema_thm_page;
public Fsd_thm_tbl(Db_conn conn, boolean schema_is_1, int mnt_id, boolean schema_thm_page) {
@ -34,7 +34,7 @@ public class Fsd_thm_tbl implements Rls_able {
}
else {
this.fld_time = flds.Add_int ("thm_thumbtime");
this.fld_page = Db_meta_fld.Key_null;
this.fld_page = Dbmeta_fld_itm.Key_null;
}
this.fld_bin_db_id = flds.Add_int ("thm_bin_db_id");
this.fld_size = flds.Add_long ("thm_size");
@ -48,8 +48,8 @@ public class Fsd_thm_tbl implements Rls_able {
stmt_select_by_fil_near = Db_stmt_.Rls(stmt_select_by_fil_near);
}
public void Create_tbl() {
conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds
, Db_meta_idx.new_unique_by_tbl(tbl_name, "owner", fld_owner_id, fld_id, fld_w, fld_time, fld_page)
conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds
, Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "owner", fld_owner_id, fld_id, fld_w, fld_time, fld_page)
));
}
public void Insert(int id, int thm_owner_id, int width, int height, double thumbtime, int page, int bin_db_id, long size) {

@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.fsdb.meta; import gplx.*; import gplx.fsdb.*;
import gplx.dbs.*; import gplx.dbs.qrys.*;
public class Fsm_atr_tbl {
private final String tbl_name; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String tbl_name; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
private final String fld_uid, fld_url;
private final Db_conn conn;
public Fsm_atr_tbl(Db_conn conn, boolean schema_is_1) {
@ -29,9 +29,9 @@ public class Fsm_atr_tbl {
this.fld_uid = flds.Add_int_pkey (fld_prefix + "uid");
this.fld_url = flds.Add_str (fld_prefix + "url", 255);
}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds));}
public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds));}
public Fsm_atr_fil Select_1st_or_fail(Fsm_mnt_itm mnt_itm, Fsdb_db_mgr core_mgr, int mnt_id, boolean schema_thm_page) {
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Db_meta_fld.Ary_empty).Exec_select__rls_auto();
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Dbmeta_fld_itm.Str_ary_empty).Exec_select__rls_auto();
boolean schema_is_1 = core_mgr.File__schema_is_1();
try {
if (rdr.Move_next()) {

@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.fsdb.meta; import gplx.*; import gplx.fsdb.*;
import gplx.dbs.*; import gplx.dbs.qrys.*;
public class Fsm_bin_tbl {
private final String tbl_name; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String tbl_name; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
private final String fld_uid, fld_url, fld_bin_len, fld_bin_max;
private final Db_conn conn; private int mnt_id;
public Fsm_bin_tbl(Db_conn conn, boolean schema_is_1, int mnt_id) {
@ -33,17 +33,17 @@ public class Fsm_bin_tbl {
fld_bin_max = flds.Add_long("bin_max");
}
else {
fld_bin_len = Db_meta_fld.Key_null;
fld_bin_max = Db_meta_fld.Key_null;
fld_bin_len = Dbmeta_fld_itm.Key_null;
fld_bin_max = Dbmeta_fld_itm.Key_null;
}
}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds));}
public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds));}
public void Insert(int id, String url_rel) {
conn.Stmt_insert(tbl_name, flds).Crt_int(fld_uid, id).Val_str(fld_url, url_rel).Val_long(fld_bin_len, 0).Val_long(fld_bin_max, 0).Exec_insert();
}
public Fsm_bin_fil[] Select_all(Fsdb_db_mgr db_conn_mgr) {
List_adp rv = List_adp_.new_();
Db_rdr rdr = conn.Stmt_select_order(tbl_name, flds, Db_meta_fld.Ary_empty, fld_uid).Clear().Exec_select__rls_auto();
Db_rdr rdr = conn.Stmt_select_order(tbl_name, flds, Dbmeta_fld_itm.Str_ary_empty, fld_uid).Clear().Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
int bin_id = rdr.Read_int(fld_uid);

@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.fsdb.meta; import gplx.*; import gplx.fsdb.*;
import gplx.dbs.*;
public class Fsm_mnt_tbl implements Rls_able {
private final String tbl_name = "fsdb_mnt"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String tbl_name = "fsdb_mnt"; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
private final String fld_id, fld_name, fld_url;
private final Db_conn conn;
public Fsm_mnt_tbl(Db_conn conn, boolean schema_is_1) {
@ -29,7 +29,7 @@ public class Fsm_mnt_tbl implements Rls_able {
conn.Rls_reg(this);
}
public void Create_tbl() {
Db_meta_tbl meta = Db_meta_tbl.new_(tbl_name, flds);
Dbmeta_tbl_itm meta = Dbmeta_tbl_itm.New(tbl_name, flds);
conn.Ddl_create_tbl(meta);
this.Insert(Fsm_mnt_mgr.Mnt_idx_main, Mnt_name_main, Mnt_name_main);
this.Insert(Fsm_mnt_mgr.Mnt_idx_user, Mnt_name_user, Mnt_name_user);
@ -45,7 +45,7 @@ public class Fsm_mnt_tbl implements Rls_able {
}
public Fsm_mnt_itm[] Select_all() {
List_adp list = List_adp_.new_();
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Db_meta_fld.Ary_empty).Clear().Exec_select__rls_auto();
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Dbmeta_fld_itm.Str_ary_empty).Clear().Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
Fsm_mnt_itm itm = new Fsm_mnt_itm(rdr.Read_int(fld_id), rdr.Read_str(fld_name), rdr.Read_str(fld_url));

@ -85,6 +85,10 @@ public class Gfh_tag implements Mwh_atr_wkr {
byte[] rv_val = rv.Val();
return style_wkr.Parse(rv_val, 0, rv_val.length, key);
}
public boolean Atrs__has(byte[] key) {
if (atrs_null) Atrs__make();
return atrs_hash.Get_by(key) != null;
}
public byte[] Atrs__get_as_bry(byte[] key) {
if (atrs_null) Atrs__make();
Gfh_atr rv = (Gfh_atr)atrs_hash.Get_by(key);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save