diff --git a/100_core/src/gplx/Bry_bfr.java b/100_core/src/gplx/Bry_bfr.java index 3aa9a4665..2574254bc 100644 --- a/100_core/src/gplx/Bry_bfr.java +++ b/100_core/src/gplx/Bry_bfr.java @@ -195,6 +195,8 @@ public class Bry_bfr { this.Add_byte(b); return this; } + public Bry_bfr Add_byte_variable(byte v) {return Add_int_variable(v);} + public Bry_bfr Add_short_variable(short v) {return Add_int_variable(v);} public Bry_bfr Add_u8_int(int val) { if (bfr_len + 4 > bfr_max) Resize((bfr_max + 4) * 2); int utf8_len = gplx.core.intls.Utf16_.Encode_int(val, bfr, bfr_len); @@ -204,6 +206,10 @@ public class Bry_bfr { public Bry_bfr Add_bool(boolean v) {return Add(v ? Bool_.True_bry : Bool_.False_bry);} public Bry_bfr Add_int_bool(boolean v) {return Add_int_fixed(v ? 1 : 0, 1);} public Bry_bfr Add_int_variable(int val) { + if (val < 0) { + this.Add(Int_.To_bry(val)); + return this; + } int log10 = Int_.Log10(val); int slots = val > -1 ? log10 + 1 : log10 * -1 + 2; return Add_int(val, log10, slots); @@ -305,6 +311,12 @@ public class Bry_bfr { } catch (Exception e) {throw Err_.new_exc(e, "core", "invalid UTF-8 sequence", "s", str);} } + public Bry_bfr Add_str_u8_many(String... ary) { + int len = ary.length; + for (int i = 0; i < len; ++i) + Add_str_u8(ary[i]); + return this; + } public Bry_bfr Add_str_a7_null(String s) {return Add_str_a7(s == null ? String_.Null_mark : s);} public Bry_bfr Add_str_a7_w_nl(String s) {Add_str_a7(s); return Add_byte_nl();} public Bry_bfr Add_str_a7(String str) { diff --git a/100_core/src/gplx/DateAdp.java b/100_core/src/gplx/DateAdp.java index 0734de797..15480df0a 100644 --- a/100_core/src/gplx/DateAdp.java +++ b/100_core/src/gplx/DateAdp.java @@ -23,11 +23,6 @@ import java.text.SimpleDateFormat; public class DateAdp implements CompareAble, GfoInvkAble { public int compareTo(Object obj) {DateAdp comp = (DateAdp)obj; return under.compareTo(comp.under);} @Override public String toString() {return XtoStr_gplx_long();} - public String XtoStr_gplx() {return XtoStr_fmt("yyyyMMdd_HHmmss.fff");} - public String XtoStr_gplx_long() {return XtoStr_fmt("yyyy-MM-dd HH:mm:ss.fff");} - public String XtoStr_fmt_HHmmss() {return XtoStr_fmt("HH:mm:ss");} - public String XtoStr_fmt_HHmm() {return XtoStr_fmt("HH:mm");} - public String XtoStr_fmt_yyyy_MM_dd() {return XtoStr_fmt("yyyy-MM-dd");} public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_XtoStr_fmt)) return XtoStr_fmt("yyyy-MM-dd HH:mm:ss"); else if (ctx.Match(k, Invk_AddDays)) { @@ -63,6 +58,11 @@ public class DateAdp implements CompareAble, GfoInvkAble { rv[DateAdp_.SegIdx_frac] = this.Frac(); return rv; } + public String XtoStr_gplx() {return XtoStr_fmt("yyyyMMdd_HHmmss.fff");} + public String XtoStr_gplx_long() {return XtoStr_fmt("yyyy-MM-dd HH:mm:ss.fff");} + public String XtoStr_fmt_HHmmss() {return XtoStr_fmt("HH:mm:ss");} + public String XtoStr_fmt_HHmm() {return XtoStr_fmt("HH:mm");} + public String XtoStr_fmt_yyyy_MM_dd() {return XtoStr_fmt("yyyy-MM-dd");} public String XtoStr_fmt_yyyyMMdd_HHmmss() {return XtoStr_fmt("yyyyMMdd_HHmmss");} public String XtoStr_fmt_yyyyMMdd_HHmmss_fff() {return XtoStr_fmt("yyyyMMdd_HHmmss.fff");} public String XtoStr_fmt_yyyyMMdd_HHmm() {return XtoStr_fmt("yyyyMMdd_HHmm");} diff --git a/100_core/src/gplx/DateAdp_.java b/100_core/src/gplx/DateAdp_.java index d8da51109..27991d477 100644 --- a/100_core/src/gplx/DateAdp_.java +++ b/100_core/src/gplx/DateAdp_.java @@ -113,8 +113,10 @@ public class DateAdp_ implements GfoInvkAble { return new DateAdp(c); } public static final int SegIdx_year = 0, SegIdx_month = 1, SegIdx_day = 2, SegIdx_hour = 3, SegIdx_minute = 4, SegIdx_second = 5, SegIdx_frac = 6, SegIdx_dayOfWeek = 7, SegIdx_weekOfYear = 8, SegIdx_dayOfYear = 9, SegIdx__max = 10; - public static final String Fmt_iso8561_date_time = "yyyy-MM-dd HH:mm:ss"; public static String Xto_str_fmt_or(DateAdp v, String fmt, String or) { return v == null ? or : v.XtoStr_fmt(fmt); } + public static final String + Fmt_iso8561_date_time = "yyyy-MM-dd HH:mm:ss" + , Fmt__yyyyMMdd = "yyyyMMdd"; } diff --git a/100_core/src/gplx/Err_.java b/100_core/src/gplx/Err_.java index e6acf1ff8..1510c580d 100644 --- a/100_core/src/gplx/Err_.java +++ b/100_core/src/gplx/Err_.java @@ -28,6 +28,7 @@ public class Err_ { return rv; } public static Err new_unhandled(Object val) {return new Err(Bool_.Y, Trace_null, Type__gplx, "val is not in switch/if", "val", val);} + public static Err new_unhandled_default(Object val) {return new Err(Bool_.Y, Trace_null, Type__gplx, "val is not in switch", "val", val);} public static Err new_unsupported() {return new Err(Bool_.Y, Trace_null, Type__gplx, "method not supported");} public static Err new_unimplemented() {return new Err(Bool_.Y, Trace_null, Type__gplx, "method not implemented");} public static Err new_unimplemented_w_msg(String msg, Object... args) {return new Err(Bool_.Y, Trace_null, Type__gplx, msg, args);} diff --git a/100_core/src/gplx/Object_.java b/100_core/src/gplx/Object_.java index 955172876..f9356e721 100644 --- a/100_core/src/gplx/Object_.java +++ b/100_core/src/gplx/Object_.java @@ -56,5 +56,6 @@ public class Object_ { else if (Type_adp_.Eq(c, Double_.Cls_ref_type)) return Double_.To_str_loose(Double_.cast(v)); else return v.toString(); } + public static final Object Null = null; public static final byte[] Bry__null = Bry_.new_a7("null"); } \ No newline at end of file diff --git a/100_core/src/gplx/Short_.java b/100_core/src/gplx/Short_.java index 660d2ea3b..7b87f4740 100644 --- a/100_core/src/gplx/Short_.java +++ b/100_core/src/gplx/Short_.java @@ -19,4 +19,5 @@ package gplx; public class Short_ { public static final Class Cls_ref_type = Short.class; public static short cast(Object obj) {try {return (Short)obj;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, short.class, obj);}} + public static short By_int(int v) {return (short)v;} } diff --git a/100_core/src/gplx/core/brys/fmtrs/Bry_fmt.java b/100_core/src/gplx/core/brys/fmtrs/Bry_fmt.java index f120fed9f..1c8aa362d 100644 --- a/100_core/src/gplx/core/brys/fmtrs/Bry_fmt.java +++ b/100_core/src/gplx/core/brys/fmtrs/Bry_fmt.java @@ -29,7 +29,16 @@ public class Bry_fmt { public Bry_fmt Fmt_(String v) {dirty = true; src = Bry_.new_u8(v); return this;} public Bry_fmt Args_(Bfr_fmt_arg... v) {dirty = true; args = v; return this;} public Bry_fmt Keys_(byte[]... v) {dirty = true; keys = v; return this;} - public void Bld_bfr_many(Bry_bfr bfr, Object... vals) { + public String Bld_many_to_str_auto_bfr(Object... vals) { + Bry_bfr bfr = Bry_bfr_.Get(); + try {return Bld_many_to_str(bfr, vals);} + finally {bfr.Mkr_rls();} + } + public String Bld_many_to_str(Bry_bfr bfr, Object... vals) { + Bld_many(bfr, vals); + return bfr.To_str_and_clear(); + } + public void Bld_many(Bry_bfr bfr, Object... vals) { if (dirty) Compile(); int vals_len = vals.length; for (int i = 0; i < itms_len; ++i) { diff --git a/100_core/src/gplx/core/brys/fmtrs/Bry_fmt_tst.java b/100_core/src/gplx/core/brys/fmtrs/Bry_fmt_tst.java index 0cd0bbae9..27c316fb4 100644 --- a/100_core/src/gplx/core/brys/fmtrs/Bry_fmt_tst.java +++ b/100_core/src/gplx/core/brys/fmtrs/Bry_fmt_tst.java @@ -46,7 +46,7 @@ class Bry_fmt_fxt { public Bry_fmt_fxt Args(String key, Bfr_arg arg) {fmt.Args_(new Bfr_fmt_arg(Bry_.new_u8(key), arg)); return this;} public Bry_fmt_fxt Keys(String... keys) {fmt.Keys_(Bry_.Ary(keys)); return this;} public void Test(String expd) { - fmt.Bld_bfr_many(bfr, vals); + fmt.Bld_many(bfr, vals); Tfds.Eq(expd, bfr.To_str_and_clear()); } } diff --git a/100_core/src/gplx/core/criterias/Criteria_between.java b/100_core/src/gplx/core/criterias/Criteria_between.java index 91a36439b..a2b831d1a 100644 --- a/100_core/src/gplx/core/criterias/Criteria_between.java +++ b/100_core/src/gplx/core/criterias/Criteria_between.java @@ -17,24 +17,24 @@ along with this program. If not, see . */ package gplx.core.criterias; import gplx.*; import gplx.core.*; public class Criteria_between implements Criteria { - public Criteria_between(boolean negate, Comparable lhs, Comparable rhs) {this.negate = negate; this.lhs = lhs; this.rhs = rhs;} - public byte Tid() {return Criteria_.Tid_between;} - public boolean Negated() {return negate;} private final boolean negate; + public Criteria_between(boolean neg, Comparable lo, Comparable hi) {this.neg = neg; this.lo = lo; this.hi = hi;} + public byte Tid() {return Criteria_.Tid_between;} + public boolean Neg() {return neg;} private final boolean neg; + public Comparable Lo() {return lo;} private Comparable lo; + public Comparable Hi() {return hi;} private Comparable hi; public void Val_from_args(Hash_adp args) {throw Err_.new_unimplemented();} public void Val_as_obj_(Object v) { Object[] ary = (Object[])v; - lhs = (Comparable)ary[0]; - rhs = (Comparable)ary[1]; + lo = (Comparable)ary[0]; + hi = (Comparable)ary[1]; } - public Comparable Lhs() {return lhs;} private Comparable lhs; - public Comparable Rhs() {return rhs;} private Comparable rhs; - public String To_str() {return String_.Concat_any("BETWEEN ", lhs, " AND ", rhs);} - public boolean Matches(Object compObj) { - Comparable comp = CompareAble_.as_(compObj); - int lhsResult = CompareAble_.CompareComparables(lhs, comp); - int rhsResult = CompareAble_.CompareComparables(rhs, comp); - boolean rv = (lhsResult * rhsResult) != 1; - return negate ? !rv : rv; + public boolean Matches(Object comp_obj) { + Comparable comp = CompareAble_.as_(comp_obj); + int lo_rslt = CompareAble_.CompareComparables(lo, comp); + int hi_rslt = CompareAble_.CompareComparables(hi, comp); + boolean rv = (lo_rslt * hi_rslt) != 1; + return neg ? !rv : rv; } - public static Criteria_between as_(Object obj) {return obj instanceof Criteria_between ? (Criteria_between)obj : null;} + + public String To_str() {return String_.Concat_any("BETWEEN ", lo, " AND ", hi);} } diff --git a/100_core/src/gplx/core/criterias/Criteria_comp.java b/100_core/src/gplx/core/criterias/Criteria_comp.java index 241e7d97e..a1f03e242 100644 --- a/100_core/src/gplx/core/criterias/Criteria_comp.java +++ b/100_core/src/gplx/core/criterias/Criteria_comp.java @@ -17,21 +17,19 @@ along with this program. If not, see . */ package gplx.core.criterias; import gplx.*; import gplx.core.*; public class Criteria_comp implements Criteria { - private final int comp_mode; @gplx.Internal protected Criteria_comp(int comp_mode, Comparable val) {this.comp_mode = comp_mode; this.val = val;} public byte Tid() {return Criteria_.Tid_comp;} public Comparable Val() {return val;} private Comparable val; public void Val_from_args(Hash_adp args) {throw Err_.new_unimplemented();} public void Val_as_obj_(Object v) {val = (Comparable)v;} - public boolean Matches(Object compObj) { - Comparable comp = CompareAble_.as_(compObj); - return CompareAble_.Is(comp_mode, comp, val); + public int Comp_mode() {return comp_mode;} private final int comp_mode; + public boolean Matches(Object comp_obj) { + return CompareAble_.Is(comp_mode, CompareAble_.as_(comp_obj), val); } - public String To_str() {return String_.Concat_any(XtoSymbol(), " ", val);} - public String XtoSymbol() { + + public String To_str() { String comp_sym = comp_mode < CompareAble_.Same ? "<" : ">"; String eq_sym = comp_mode % 2 == CompareAble_.Same ? "=" : ""; - return comp_sym + eq_sym; + return String_.Concat_any(comp_sym, eq_sym, " ", val); } - public static Criteria_comp as_(Object obj) {return obj instanceof Criteria_comp ? (Criteria_comp)obj : null;} } diff --git a/100_core/src/gplx/core/criterias/Criteria_eq.java b/100_core/src/gplx/core/criterias/Criteria_eq.java index fb52e148f..8d75d3e06 100644 --- a/100_core/src/gplx/core/criterias/Criteria_eq.java +++ b/100_core/src/gplx/core/criterias/Criteria_eq.java @@ -17,9 +17,9 @@ along with this program. If not, see . */ package gplx.core.criterias; import gplx.*; import gplx.core.*; public class Criteria_eq implements Criteria { - @gplx.Internal protected Criteria_eq(boolean negated, Object val) {this.negated = negated; this.val = val;} + @gplx.Internal protected Criteria_eq(boolean neg, Object val) {this.neg = neg; this.val = val;} public byte Tid() {return Criteria_.Tid_eq;} - public boolean Negated() {return negated;} private final boolean negated; + public boolean Neg() {return neg;} private final boolean neg; public Object Val() {return val;} private Object val; public void Val_as_obj_(Object v) {this.val = v;} public void Val_from_args(Hash_adp args) {throw Err_.new_unimplemented();} @@ -27,7 +27,7 @@ public class Criteria_eq implements Criteria { Class val_type = Type_adp_.ClassOf_obj(val); if (!Type_adp_.Eq_typeSafe(comp, val_type)) throw Err_.new_type_mismatch(val_type, comp); boolean rv = Object_.Eq(val, comp); - return negated ? !rv : rv; + return neg ? !rv : rv; } public String To_str() {return String_.Concat_any("= ", val);} public static Criteria_eq as_(Object obj) {return obj instanceof Criteria_eq ? (Criteria_eq)obj : null;} diff --git a/100_core/src/gplx/core/criterias/Criteria_fld.java b/100_core/src/gplx/core/criterias/Criteria_fld.java index 9d3b303b8..298f77444 100644 --- a/100_core/src/gplx/core/criterias/Criteria_fld.java +++ b/100_core/src/gplx/core/criterias/Criteria_fld.java @@ -17,8 +17,9 @@ along with this program. If not, see . */ package gplx.core.criterias; import gplx.*; import gplx.core.*; public class Criteria_fld implements Criteria { - Criteria_fld(String key, Criteria crt) {this.key = key; this.crt = crt;} + Criteria_fld(String pre, String key, Criteria crt) {this.pre = pre; this.key = key; this.crt = crt;} public byte Tid() {return Criteria_.Tid_wrapper;} + public String Pre() {return pre;} private final String pre; public String Key() {return key;} private final String key; public Criteria Crt() {return crt;} private final Criteria crt; public void Val_as_obj_(Object v) {throw Err_.new_unimplemented();} @@ -34,9 +35,11 @@ public class Criteria_fld implements Criteria { return crt.Matches(comp); } public String To_str() {return String_.Concat(key, " ", crt.To_str());} - public static final String Key_null = null; + + public static final String Key_null = null, Pre_null = null; public static Criteria_fld as_(Object obj) {return obj instanceof Criteria_fld ? (Criteria_fld)obj : null;} - public static Criteria_fld new_(String key, Criteria crt) {return new Criteria_fld(key, crt);} + public static Criteria_fld new_(String pre, String key, Criteria crt) {return new Criteria_fld(pre, key, crt);} + public static Criteria_fld new_(String key, Criteria crt) {return new Criteria_fld(Pre_null, key, crt);} public static Object Fill_val(String key, byte tid, List_adp list) { int len = list.Count(); switch (tid) { diff --git a/100_core/src/gplx/core/criterias/Criteria_in.java b/100_core/src/gplx/core/criterias/Criteria_in.java index b34f7efee..55c70c5e8 100644 --- a/100_core/src/gplx/core/criterias/Criteria_in.java +++ b/100_core/src/gplx/core/criterias/Criteria_in.java @@ -17,30 +17,32 @@ along with this program. If not, see . */ package gplx.core.criterias; import gplx.*; import gplx.core.*; public class Criteria_in implements Criteria { - public Criteria_in(boolean negated, Object[] ary) {this.negated = negated; Val_as_obj_ary_(ary);} + public Criteria_in(boolean neg, Object[] ary) {this.neg = neg; Ary_(ary);} public byte Tid() {return Criteria_.Tid_in;} - public boolean Negated() {return negated;} private final boolean negated; - public Object[] Val_as_obj_ary() {return ary;} private Object[] ary; private Class ary_type; private int ary_len; - private void Val_as_obj_ary_(Object[] v) { + public boolean Neg() {return neg;} private final boolean neg; + public Object[] Ary() {return ary;} private Object[] ary; + public int Ary_len() {return ary_len;} private int ary_len; + public Class Itm_type() {return itm_type;} private Class itm_type; + private void Ary_(Object[] v) { this.ary = v; - ary_len = Array_.Len(ary); - ary_type = ary_len == 0 ? Object.class : Type_adp_.ClassOf_obj(ary[0]); + this.ary_len = ary.length; + this.itm_type = ary_len == 0 ? Object.class : Type_adp_.ClassOf_obj(ary[0]); } - public void Val_as_obj_(Object v) {Val_as_obj_ary_((Object[])v);} + public void Val_as_obj_(Object v) {Ary_((Object[])v);} public void Val_from_args(Hash_adp args) {throw Err_.new_unimplemented();} public boolean Matches(Object comp) { if (ary_len == 0) return false; // empty array never matches - if (!Type_adp_.Eq_typeSafe(comp, ary_type)) throw Err_.new_type_mismatch(ary_type, comp); + if (!Type_adp_.Eq_typeSafe(comp, itm_type)) throw Err_.new_type_mismatch(itm_type, comp); boolean rv = false; - for (int i = 0; i < ary_len; i++) { + for (int i = 0; i < ary_len; ++i) { Object val = ary[i]; if (Object_.Eq(val, comp)) { rv = true; break; } } - return negated ? !rv : rv; + return neg ? !rv : rv; } + public String To_str() {return String_.Concat_any("IN ", String_.Concat_any(ary));} - public static Criteria_in as_(Object obj) {return obj instanceof Criteria_in ? (Criteria_in)obj : null;} } diff --git a/100_core/src/gplx/core/criterias/Criteria_ioMatch.java b/100_core/src/gplx/core/criterias/Criteria_ioMatch.java index 5190dd5dc..b5ba51d98 100644 --- a/100_core/src/gplx/core/criterias/Criteria_ioMatch.java +++ b/100_core/src/gplx/core/criterias/Criteria_ioMatch.java @@ -20,7 +20,7 @@ import gplx.core.texts.*; public class Criteria_ioMatch implements Criteria { // EX: url IOMATCH '*.xml|*.txt' public Criteria_ioMatch(boolean match, RegxPatn_cls_ioMatch pattern) {this.match = match; this.pattern = pattern;} public byte Tid() {return Criteria_.Tid_iomatch;} - public boolean Negated() {return !match;} private final boolean match; + public boolean Neg() {return !match;} private final boolean match; public void Val_from_args(Hash_adp args) {throw Err_.new_unimplemented();} public void Val_as_obj_(Object v) {this.pattern = (RegxPatn_cls_ioMatch)v;} public RegxPatn_cls_ioMatch Pattern() {return pattern;} private RegxPatn_cls_ioMatch pattern; diff --git a/100_core/src/gplx/core/criterias/Criteria_like.java b/100_core/src/gplx/core/criterias/Criteria_like.java index e54febc1e..c3377f54c 100644 --- a/100_core/src/gplx/core/criterias/Criteria_like.java +++ b/100_core/src/gplx/core/criterias/Criteria_like.java @@ -18,19 +18,17 @@ along with this program. If not, see . package gplx.core.criterias; import gplx.*; import gplx.core.*; import gplx.core.texts.*; /*RegxPatn_cls_like*/ public class Criteria_like implements Criteria { - @gplx.Internal protected Criteria_like(boolean negated, RegxPatn_cls_like pattern) { - this.negated = negated; this.pattern = pattern; - } + @gplx.Internal protected Criteria_like(boolean neg, RegxPatn_cls_like pattern) {this.neg = neg; this.pattern = pattern;} public byte Tid() {return Criteria_.Tid_like;} - public boolean Negated() {return negated;} private final boolean negated; + public boolean Neg() {return neg;} private final boolean neg; public RegxPatn_cls_like Pattern() {return pattern;} private RegxPatn_cls_like pattern; public void Val_from_args(Hash_adp args) {throw Err_.new_unimplemented();} public void Val_as_obj_(Object v) {this.pattern = (RegxPatn_cls_like)v;} public boolean Matches(Object compObj) { String comp = String_.as_(compObj); if (comp == null) throw Err_.new_type_mismatch(String.class, compObj); boolean rv = pattern.Matches(comp); - return negated ? !rv : rv; + return neg ? !rv : rv; } + public String To_str() {return String_.Concat_any("LIKE ", pattern);} - public static Criteria_like as_(Object obj) {return obj instanceof Criteria_like ? (Criteria_like)obj : null;} } \ No newline at end of file diff --git a/100_core/src/gplx/core/stores/DataRdr.java b/100_core/src/gplx/core/stores/DataRdr.java index cd1beb2bf..a7664bef3 100644 --- a/100_core/src/gplx/core/stores/DataRdr.java +++ b/100_core/src/gplx/core/stores/DataRdr.java @@ -39,7 +39,7 @@ public interface DataRdr extends SrlMgr, Rls_able { double ReadDouble(String key); double ReadDoubleOr(String key, double or); float ReadFloat(String key); float ReadFloatOr(String key, float or); byte ReadByte(String key); byte ReadByteOr(String key, byte or); - Decimal_adp ReadDecimal(String key); Decimal_adp ReadDecimalOr(String key, Decimal_adp or); + Decimal_adp ReadDecimal(String key); Decimal_adp ReadDecimalOr(String key, Decimal_adp or); DateAdp ReadDate(String key); DateAdp ReadDateOr(String key, DateAdp or); gplx.core.ios.Io_stream_rdr ReadRdr(String key); diff --git a/100_core/src/gplx/core/stores/DataRdr_.java b/100_core/src/gplx/core/stores/DataRdr_.java index f3a37a55f..5ce373df4 100644 --- a/100_core/src/gplx/core/stores/DataRdr_.java +++ b/100_core/src/gplx/core/stores/DataRdr_.java @@ -21,6 +21,12 @@ public class DataRdr_ { public static final DataRdr Null = new DataRdr_null(); public static DataRdr as_(Object obj) {return obj instanceof DataRdr ? (DataRdr)obj : null;} public static DataRdr cast(Object obj) {try {return (DataRdr)obj;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, DataRdr.class, obj);}} + + public static Object Read_1st_row_and_1st_fld(DataRdr rdr) { + try {return rdr.MoveNextPeer() ? rdr.ReadAt(0) : null;} + finally {rdr.Rls();} + } + } class DataRdr_null implements DataRdr { public String NameOfNode() {return To_str();} public String To_str() {return "<< NULL READER >>";} @@ -34,8 +40,8 @@ class DataRdr_null implements DataRdr { public KeyVal KeyValAt(int i) {return KeyVal_.new_(this.KeyAt(i), this.ReadAt(i));} public Object Read(String name) {return null;} public String ReadStr(String key) {return String_.Empty;} public String ReadStrOr(String key, String or) {return or;} - public byte[] ReadBryByStr(String key) {return Bry_.Empty;} public byte[] ReadBryByStrOr(String key, byte[] or) {return or;} - public byte[] ReadBry(String key) {return Bry_.Empty;} public byte[] ReadBryOr(String key, byte[] or) {return or;} + public byte[] ReadBryByStr(String key) {return Bry_.Empty;} public byte[] ReadBryByStrOr(String key, byte[] or) {return or;} + public byte[] ReadBry(String key) {return Bry_.Empty;} public byte[] ReadBryOr(String key, byte[] or) {return or;} public char ReadChar(String key) {return Char_.Null;} public char ReadCharOr(String key, char or) {return or;} public int ReadInt(String key) {return Int_.Min_value;} public int ReadIntOr(String key, int or) {return or;} public boolean ReadBool(String key) {return false;} public boolean ReadBoolOr(String key, boolean or) {return or;} diff --git a/140_dbs/src/gplx/core/stores/DbMaprMgr_tst.java b/140_dbs/src/gplx/core/stores/DbMaprMgr_tst.java index 56d1aabd1..6f14d8755 100644 --- a/140_dbs/src/gplx/core/stores/DbMaprMgr_tst.java +++ b/140_dbs/src/gplx/core/stores/DbMaprMgr_tst.java @@ -64,15 +64,15 @@ public class DbMaprMgr_tst { disc = MockDisc.new_().Id_(1).Name_("disc"); wtr.StoreRoot(disc, "mock_discs"); - Db_qry_fxt.tst_Select(conn, "mock_discs", DbTstRow.vals_only_(1, "disc")); + Db_qry_fxt.tst_Select(conn, "mock_discs", Db_mock_row.vals_only_(1, "disc")); } @Test public void Save_subs() { disc = MockDisc.new_().Id_(1).Name_("disc"); title = MockTitle.new_().Id_(2).Name_("title").Disc_(disc); wtr.StoreRoot(disc, "mock_discs"); - Db_qry_fxt.tst_Select(conn, "mock_discs", DbTstRow.vals_only_(1, "disc")); - Db_qry_fxt.tst_Select(conn, "mock_titles", DbTstRow.vals_only_(1, 2, "title")); + Db_qry_fxt.tst_Select(conn, "mock_discs", Db_mock_row.vals_only_(1, "disc")); + Db_qry_fxt.tst_Select(conn, "mock_titles", Db_mock_row.vals_only_(1, 2, "title")); } @Test public void Save_deep() { disc = MockDisc.new_().Id_(1).Name_("disc"); @@ -82,12 +82,12 @@ public class DbMaprMgr_tst { subtitle = MockStream.new_().Id_(5).Name_("subtitle").Title_(title.Subtitles()); wtr.StoreRoot(disc, "mock_discs"); - Db_qry_fxt.tst_Select(conn, "mock_discs", DbTstRow.vals_only_(1, "disc")); - Db_qry_fxt.tst_Select(conn, "mock_titles", DbTstRow.vals_only_(1, 2, "title")); - Db_qry_fxt.tst_Select(conn, "mock_chapters", DbTstRow.vals_only_(1, 2, 3, "chap")); + Db_qry_fxt.tst_Select(conn, "mock_discs", Db_mock_row.vals_only_(1, "disc")); + Db_qry_fxt.tst_Select(conn, "mock_titles", Db_mock_row.vals_only_(1, 2, "title")); + Db_qry_fxt.tst_Select(conn, "mock_chapters", Db_mock_row.vals_only_(1, 2, 3, "chap")); Db_qry_fxt.tst_Select(conn, "mock_streams" - , DbTstRow.vals_only_(1, 2, null, 4, "audio") - , DbTstRow.vals_only_(1, 2, null, 5, "subtitle") + , Db_mock_row.vals_only_(1, 2, null, 4, "audio") + , Db_mock_row.vals_only_(1, 2, null, 5, "subtitle") ); } @Test public void Load_root() { @@ -133,7 +133,7 @@ public class DbMaprMgr_tst { Tfds.Eq("subtitle1", ((MockStream)t.Subtitles().Get_at(0)).Name()); } DbMaprRdr rdr_() { - DbMaprRdr rv = DbMaprRdr.new_(Db_conn_info_.Test, Db_crt_.eq_("disc_id", 1)); + DbMaprRdr rv = DbMaprRdr.new_(Db_conn_info_.Test, Db_crt_.New_eq("disc_id", 1)); rv.EnvVars().Add(DbMaprWtr.Key_Mgr, mgr); return rv; } diff --git a/140_dbs/src/gplx/core/stores/DbMaprRdr.java b/140_dbs/src/gplx/core/stores/DbMaprRdr.java index 5091d5688..a5fb79998 100644 --- a/140_dbs/src/gplx/core/stores/DbMaprRdr.java +++ b/140_dbs/src/gplx/core/stores/DbMaprRdr.java @@ -51,7 +51,7 @@ public class DbMaprRdr extends DataRdr_base implements SrlMgr { List_adp list = GetIdxFlds(mgr, mapr); for (Object kvObj : list) { KeyVal kv = (KeyVal)kvObj; - cur = Db_crt_.eq_(kv.Key(), kv.Val()); + cur = Db_crt_.New_eq(kv.Key(), kv.Val()); rv = (rv == null) ? cur : Criteria_.And(rv, cur); } return rv; @@ -80,7 +80,7 @@ public class DbMaprRdr extends DataRdr_base implements SrlMgr { if (tblByRootCrt == null) { DataRdr dbRdr = null; try { - dbRdr = Db_qry_.select_().From_(mapr.TableName()).Where_(rootCrt).Exec_qry_as_rdr(conn); + dbRdr = conn.Exec_qry_as_old_rdr(Db_qry_.select_().From_(mapr.TableName()).Where_(rootCrt)); tblByRootCrt = GfoNde_.rdr_(dbRdr); } finally {dbRdr.Rls();} diff --git a/140_dbs/src/gplx/core/stores/DbMaprWtr.java b/140_dbs/src/gplx/core/stores/DbMaprWtr.java index 7e0d10483..fe366335b 100644 --- a/140_dbs/src/gplx/core/stores/DbMaprWtr.java +++ b/140_dbs/src/gplx/core/stores/DbMaprWtr.java @@ -69,9 +69,9 @@ public class DbMaprWtr extends DataWtr_base implements DataWtr { void WriteDataVal(String fld, Object val) { if (insertCmd == null) insertCmd = Db_qry_.insert_(curTableName); if (Type_adp_.Eq_typeSafe(val, String.class)) - insertCmd.Arg_obj_type_(fld, val, Db_val_type.Tid_varchar); + insertCmd.Val_obj_type(fld, val, Db_val_type.Tid_varchar); else - insertCmd.Arg_obj_(fld, val); + insertCmd.Val_obj(fld, val); } @Override public void WriteNodeEnd() { if (insertCmd != null) insertCmd.Exec_qry(conn); // occurs for nodes and leaves; for nodes, insertCmd will be null (committed by last leaf) @@ -100,7 +100,7 @@ class DbMaprWtrUtl { Criteria rv = null; for (DbMaprArg arg : objRootIdxFlds) { Object argVal = GfoInvkAble_.InvkCmd((GfoInvkAble)root, arg.ObjProp()); - Criteria cur = Db_crt_.eq_(arg.DbFld(), argVal); + Criteria cur = Db_crt_.New_eq(arg.DbFld(), argVal); rv = (rv == null) ? cur : Criteria_.And(rv, cur); } return rv; diff --git a/140_dbs/src/gplx/dbs/Db_conn.java b/140_dbs/src/gplx/dbs/Db_conn.java index fc1c69e8c..1d8a0273c 100644 --- a/140_dbs/src/gplx/dbs/Db_conn.java +++ b/140_dbs/src/gplx/dbs/Db_conn.java @@ -16,10 +16,14 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs; import gplx.*; -import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.engines.*; import gplx.dbs.qrys.*; +import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.engines.*; import gplx.dbs.qrys.*; import gplx.dbs.sys.*; 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(Db_engine engine) { + this.engine = engine; + sys_mgr = new Db_sys_mgr(this); + } + public Db_engine Engine() {return 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(String name) {engine.Txn_bgn(name);} @@ -28,8 +32,8 @@ public class Db_conn { public void Txn_sav() {engine.Txn_sav();} 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, 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_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, 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, Dbmeta_fld_list flds, String... where) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, flds.To_str_ary(), null));} @@ -40,6 +44,7 @@ public class Db_conn { 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 Db_sys_mgr Sys_mgr() {return sys_mgr;} private final Db_sys_mgr sys_mgr; 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;");} @@ -61,6 +66,7 @@ public class Db_conn { engine.Conn_term(); Db_conn_pool.Instance.Del(engine.Conn_info()); } + public void Exec_delete_all(String tbl) {Stmt_delete(tbl).Exec_delete();} public int Exec_sql(String sql) {return this.Exec_qry(Db_qry_sql.dml_(sql));} public Db_rdr Exec_sql_as_rdr_v2(String sql) {return this.Stmt_new(Db_qry_sql.dml_(sql)).Exec_select__rls_auto();} public int Exec_sql_plog_ntx(String msg, String sql) {return Exec_sql_plog(Bool_.N, msg, sql);} @@ -74,7 +80,7 @@ public class Db_conn { return rv; } public int Exec_qry(Db_qry qry) {return Int_.cast(engine.Exec_as_obj(qry));} - public DataRdr Exec_qry_as_rdr(Db_qry qry) {return DataRdr_.cast(engine.Exec_as_obj(qry));} public int Exec_sql_args(String sql, Object... args) {return this.Exec_qry(Db_qry_sql.dml_(String_.Format(sql, args)));} - public DataRdr Exec_sql_as_rdr(String sql) {return this.Exec_qry_as_rdr(Db_qry_sql.rdr_(sql));} + public DataRdr Exec_sql_as_old_rdr(String sql) {return DataRdr_.cast(engine.Exec_as_obj(Db_qry_sql.rdr_(sql)));} + public DataRdr Exec_qry_as_old_rdr(Db_qry qry) {return DataRdr_.cast(engine.Exec_as_obj(qry));} } diff --git a/140_dbs/src/gplx/dbs/Db_conn_.java b/140_dbs/src/gplx/dbs/Db_conn_.java index 05d91ad1e..ebf1bd4bd 100644 --- a/140_dbs/src/gplx/dbs/Db_conn_.java +++ b/140_dbs/src/gplx/dbs/Db_conn_.java @@ -20,10 +20,10 @@ import gplx.core.stores.*; import gplx.dbs.qrys.*; public class Db_conn_ { public static final Db_conn Noop = Db_conn_pool.Instance.Get_or_new(Db_conn_info_.Null); - public static int Select_fld0_as_int_or(Db_conn p, String sql, int or) { + public static int Select_fld0_as_int_or(Db_conn conn, String sql, int or) { DataRdr rdr = DataRdr_.Null; try { - rdr = p.Exec_qry_as_rdr(Db_qry_sql.rdr_(sql)); + rdr = conn.Exec_qry_as_old_rdr(Db_qry_sql.rdr_(sql)); int rv = or; if (rdr.MoveNextPeer()) { Object rv_obj = rdr.ReadAt(0); diff --git a/140_dbs/src/gplx/dbs/Db_conn_bldr.java b/140_dbs/src/gplx/dbs/Db_conn_bldr.java index de6f927c1..a0dbb133c 100644 --- a/140_dbs/src/gplx/dbs/Db_conn_bldr.java +++ b/140_dbs/src/gplx/dbs/Db_conn_bldr.java @@ -21,6 +21,11 @@ public class Db_conn_bldr { public void Reg_default_sqlite() {wkr = Db_conn_bldr_wkr__sqlite.Instance; wkr.Clear_for_tests();} public void Reg_default_mem() {wkr = Db_conn_bldr_wkr__mem.Instance; wkr.Clear_for_tests();} public boolean Exists(Io_url url) {return wkr.Exists(url);} +// public Db_conn Parse(String s) { +// Db_conn_info conn_info = Db_conn_info_.parse(s); +// Db_conn conn = Db_conn_pool.Instance.Get_or_new(conn_info); +// return conn; +// } public Db_conn Get(Io_url url) {return wkr.Get(url);} public Db_conn New(Io_url url) {return wkr.New(url);} public Db_conn_bldr_data Get_or_new(Io_url url) { diff --git a/140_dbs/src/gplx/dbs/Db_conn_info_.java b/140_dbs/src/gplx/dbs/Db_conn_info_.java index dcf12775a..ed7201676 100644 --- a/140_dbs/src/gplx/dbs/Db_conn_info_.java +++ b/140_dbs/src/gplx/dbs/Db_conn_info_.java @@ -52,5 +52,32 @@ class Db_conn_info_pool { } catch(Exception exc) {throw Err_.new_parse_exc(exc, Db_conn_info.class, raw);} } + public Db_conn_info Parse_or_sqlite_or_fail(String raw) {// assume each pair has format of: name=val; + GfoMsg msg = GfoMsg_.new_parse_("db_url"); + String[] kvps = String_.Split(raw, ";"); + String cs_tid = null; + int kvps_len = kvps.length; + for (int i = 0; i < kvps_len; ++i) { + String kvp_str = kvps[i]; + if (String_.Len(kvp_str) == 0) continue; // ignore empty; EX: "data source=/db.sqlite;;" + String[] kvp = String_.Split(kvp_str, "="); + String key = kvp[0], val = kvp[1]; + if (String_.Eq(key, "gplx_key")) + cs_tid = val; // NOTE: do not add to GfoMsg; will not be part of ApiStr + else + msg.Add(key, val); + } + if (cs_tid == null) { // gplx_key not found; try url as sqlite; EX: "/db.sqlite" + Io_url sqlite_url = null; + try {sqlite_url = Io_url_.new_any_(raw);} + catch (Exception exc) {throw Err_.new_exc(exc, "dbs", "invalid connection String", "raw", raw);} + msg.Clear(); + cs_tid = Sqlite_conn_info.Tid_const; + msg.Add(Sqlite_conn_info.Cs__data_source, sqlite_url.Raw()); + msg.Add(Sqlite_conn_info.Cs__version , Sqlite_conn_info.Cs__version__3); + } + Db_conn_info prototype = (Db_conn_info)regy.Get_by(cs_tid); + return prototype.New_self(raw, msg); + } public static final Db_conn_info_pool Instance = new Db_conn_info_pool(); } diff --git a/140_dbs/src/gplx/dbs/Db_crt_.java b/140_dbs/src/gplx/dbs/Db_crt_.java index eb9d1fc36..05d9ece5a 100644 --- a/140_dbs/src/gplx/dbs/Db_crt_.java +++ b/140_dbs/src/gplx/dbs/Db_crt_.java @@ -19,22 +19,22 @@ package gplx.dbs; import gplx.*; import gplx.core.criterias.*; public class Db_crt_ { public static final Criteria Wildcard = Criteria_.All; - public static Criteria_fld eq_(String key, Object val) {return Criteria_fld.new_(key, Criteria_.eq_(val));} - public static Criteria_fld eqn_(String key, Object val) {return Criteria_fld.new_(key, Criteria_.eqn_(val));} - public static Criteria_fld lt_(String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.lt_(val));} - public static Criteria_fld lte_(String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.lte_(val));} - public static Criteria_fld mt_(String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.mt_(val));} - public static Criteria_fld mte_(String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.mte_(val));} - public static Criteria_fld between_(String key, Comparable lhs, Comparable rhs) {return Criteria_fld.new_(key, Criteria_.between_(lhs, rhs));} - public static Criteria_fld in_(String key, Object... vals) {return Criteria_fld.new_(key, Criteria_.in_(vals));} - public static Criteria_fld like_(String key, String pattern) {return Criteria_fld.new_(key, Criteria_.like_(pattern));} - public static Criteria_fld liken_(String key, String pattern) {return Criteria_fld.new_(key, Criteria_.liken_(pattern));} - public static Criteria_fld eq_(String key) {return Criteria_fld.new_(key, Criteria_.eq_(null));} + public static Criteria_fld New_eq (String key, Object val) {return Criteria_fld.new_(key, Criteria_.eq_(val));} + public static Criteria_fld New_eq (String pre, String key, Object val) {return Criteria_fld.new_(pre, key, Criteria_.eq_(val));} + public static Criteria_fld New_eq_not (String key, Object val) {return Criteria_fld.new_(key, Criteria_.eqn_(val));} + public static Criteria_fld New_lt (String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.lt_(val));} + public static Criteria_fld New_lte (String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.lte_(val));} + public static Criteria_fld New_mt (String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.mt_(val));} + public static Criteria_fld New_mte (String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.mte_(val));} + public static Criteria_fld New_between (String key, Comparable lo, Comparable hi) {return Criteria_fld.new_(key, Criteria_.between_(lo, hi));} + public static Criteria_fld New_in (String key, Object... vals) {return Criteria_fld.new_(key, Criteria_.in_(vals));} + public static Criteria_fld New_like (String key, String pattern) {return Criteria_fld.new_(key, Criteria_.like_(pattern));} + public static Criteria eq_many_(String... ary) { Criteria rv = null; int len = ary.length; for (int i = 0; i < len; i++) { - Criteria crt = Db_crt_.eq_(ary[i], null); + Criteria crt = Db_crt_.New_eq(ary[i], null); rv = (i == 0)? crt : Criteria_.And(rv, crt); } return rv; @@ -45,7 +45,7 @@ public class Db_crt_ { int crt_idx = 0; for (int i = 0; i < len; i++) { String itm = ary[i]; if (itm == Dbmeta_fld_itm.Key_null) continue; - Criteria crt = Db_crt_.eq_(itm, null); + Criteria crt = Db_crt_.New_eq(itm, null); rv = (crt_idx == 0) ? crt : Criteria_.And(rv, crt); ++crt_idx; } @@ -55,7 +55,7 @@ public class Db_crt_ { Criteria rv = null; for (int i = 0; i < array.length; i++) { KeyVal pair = array[i]; - Criteria crt = Db_crt_.eq_(pair.Key(), pair.Val()); + Criteria crt = Db_crt_.New_eq(pair.Key(), pair.Val()); rv = (i == 0)? crt : Criteria_.And(rv, crt); } return rv; diff --git a/140_dbs/src/gplx/dbs/Db_crt_tst.java b/140_dbs/src/gplx/dbs/Db_crt_tst.java index c662345fd..97ff9c062 100644 --- a/140_dbs/src/gplx/dbs/Db_crt_tst.java +++ b/140_dbs/src/gplx/dbs/Db_crt_tst.java @@ -22,25 +22,25 @@ public class Db_crt_tst { row = GfoNde_.vals_(GfoFldList_.new_().Add("id", IntClassXtn.Instance).Add("name", StringClassXtn.Instance), Object_.Ary(1, "me")); } @Test public void EqualTest() { - crt = Db_crt_.eq_("id", 1); + crt = Db_crt_.New_eq("id", 1); tst_Match(true, row, crt); } @Test public void EqualFalseTest() { - crt = Db_crt_.eq_("id", 2); + crt = Db_crt_.New_eq("id", 2); tst_Match(false, row, crt); } @Test public void AndCompositeTest() { - crt = Criteria_.And(Db_crt_.eq_("id", 1), Db_crt_.eq_("name", "me")); + crt = Criteria_.And(Db_crt_.New_eq("id", 1), Db_crt_.New_eq("name", "me")); tst_Match(true, row, crt); - crt = Criteria_.And(Db_crt_.eq_("id", 1), Db_crt_.eq_("name", "you")); + crt = Criteria_.And(Db_crt_.New_eq("id", 1), Db_crt_.New_eq("name", "you")); tst_Match(false, row, crt); } @Test public void OrCompositeTest() { - crt = Criteria_.Or(Db_crt_.eq_("id", 1), Db_crt_.eq_("name", "you")); + crt = Criteria_.Or(Db_crt_.New_eq("id", 1), Db_crt_.New_eq("name", "you")); tst_Match(true, row, crt); - crt = Criteria_.Or(Db_crt_.eq_("id", 2), Db_crt_.eq_("name", "you")); + crt = Criteria_.Or(Db_crt_.New_eq("id", 2), Db_crt_.New_eq("name", "you")); tst_Match(false, row, crt); } diff --git a/140_dbs/src/gplx/dbs/DbTstDat.java b/140_dbs/src/gplx/dbs/Db_mock_cell.java similarity index 62% rename from 140_dbs/src/gplx/dbs/DbTstDat.java rename to 140_dbs/src/gplx/dbs/Db_mock_cell.java index afe7852b6..005b4690a 100644 --- a/140_dbs/src/gplx/dbs/DbTstDat.java +++ b/140_dbs/src/gplx/dbs/Db_mock_cell.java @@ -16,9 +16,9 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs; import gplx.*; -public class DbTstDat { - public int Idx() {return idx;} public DbTstDat Idx_(int val) {idx = val; return this;} int idx = -1; - public String Fld() {return fld;} public DbTstDat Fld_(String v) {fld = v; return this;} private String fld = null; - public Object Val() {return val;} public DbTstDat Val_(Object v) {val = v; return this;} Object val = null; - public static DbTstDat new_() {return new DbTstDat();} DbTstDat() {} +public class Db_mock_cell { + public int Idx() {return idx;} public Db_mock_cell Idx_(int val) {idx = val; return this;} int idx = -1; + public String Fld() {return fld;} public Db_mock_cell Fld_(String v) {fld = v; return this;} private String fld = null; + public Object Val() {return val;} public Db_mock_cell Val_(Object v) {val = v; return this;} Object val = null; + public static Db_mock_cell new_() {return new Db_mock_cell();} Db_mock_cell() {} } diff --git a/140_dbs/src/gplx/dbs/DbTstRow.java b/140_dbs/src/gplx/dbs/Db_mock_row.java similarity index 63% rename from 140_dbs/src/gplx/dbs/DbTstRow.java rename to 140_dbs/src/gplx/dbs/Db_mock_row.java index f10015b58..5caea903e 100644 --- a/140_dbs/src/gplx/dbs/DbTstRow.java +++ b/140_dbs/src/gplx/dbs/Db_mock_row.java @@ -16,16 +16,16 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs; import gplx.*; -public class DbTstRow { - public int Idx() {return idx;} public DbTstRow Idx_(int val) {idx = val; return this;} int idx = -1; - public DbTstDat[] Dat() {return dat;} DbTstDat[] dat = null; - public static DbTstRow vals_only_(Object... ary) { - DbTstRow rv = new DbTstRow(); +public class Db_mock_row { + public int Idx() {return idx;} public Db_mock_row Idx_(int val) {idx = val; return this;} int idx = -1; + public Db_mock_cell[] Dat() {return dat;} Db_mock_cell[] dat = null; + public static Db_mock_row vals_only_(Object... ary) { + Db_mock_row rv = new Db_mock_row(); int len = Array_.Len(ary); - rv.dat = new DbTstDat[len]; + rv.dat = new Db_mock_cell[len]; for (int i = 0; i < len; i++) - rv.dat[i] = DbTstDat.new_().Val_(ary[i]); + rv.dat[i] = Db_mock_cell.new_().Val_(ary[i]); return rv; } - public static DbTstRow new_() {return new DbTstRow();} DbTstRow() {} + public static Db_mock_row new_() {return new Db_mock_row();} Db_mock_row() {} } diff --git a/140_dbs/src/gplx/dbs/Db_qry.java b/140_dbs/src/gplx/dbs/Db_qry.java index 0b5e3150c..dfd04050d 100644 --- a/140_dbs/src/gplx/dbs/Db_qry.java +++ b/140_dbs/src/gplx/dbs/Db_qry.java @@ -20,5 +20,11 @@ public interface Db_qry { int Tid(); boolean Exec_is_rdr(); String Base_table(); - String Xto_sql(); + String To_sql__exec(gplx.dbs.sqls.Sql_qry_wtr wtr); +} +class Db_qry__noop implements Db_qry { + public int Tid() {return Db_qry_.Tid_noop;} + public boolean Exec_is_rdr() {return false;} + public String Base_table() {return "";} + public String To_sql__exec(gplx.dbs.sqls.Sql_qry_wtr wtr) {return "";} } diff --git a/140_dbs/src/gplx/dbs/Db_qry_.java b/140_dbs/src/gplx/dbs/Db_qry_.java index 412300406..4b8ea65d7 100644 --- a/140_dbs/src/gplx/dbs/Db_qry_.java +++ b/140_dbs/src/gplx/dbs/Db_qry_.java @@ -16,36 +16,48 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs; import gplx.*; -import gplx.core.criterias.*; import gplx.dbs.qrys.*; +import gplx.core.criterias.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.itms.*; public class Db_qry_ { public static Db_qry__select_cmd select_cols_(String tbl, Criteria crt, String... cols){return select_().From_(tbl).Where_(crt).Cols_(cols);} public static Db_qry__select_cmd select_val_(String tbl, String col, Criteria crt) {return select_().From_(tbl).Where_(crt).Cols_(col);} public static Db_qry__select_cmd select_tbl_(String tbl) {return select_().From_(tbl);} - public static Db_qry__select_cmd select_() {return Db_qry__select_cmd.new_();} + public static Db_qry__select_cmd select_() {return new Db_qry__select_cmd();} + public static Db_qry__select_cmd select_(String tbl, String... cols) {return new Db_qry__select_cmd().From_(tbl).Cols_(cols);} public static Db_qry_delete delete_(String tbl, Criteria crt) {return Db_qry_delete.new_(tbl, crt);} public static Db_qry_delete delete_tbl_(String tbl) {return Db_qry_delete.new_(tbl);} public static Db_qry_insert insert_(String tbl) {return new Db_qry_insert(tbl);} public static Db_qry_insert insert_common_(String tbl, KeyVal... pairs) { Db_qry_insert cmd = new Db_qry_insert(tbl); for (KeyVal pair : pairs) - cmd.Arg_obj_(pair.Key(), pair.Val()); + cmd.Val_obj(pair.Key(), pair.Val()); return cmd; } + public static Sql_join_itm New_join__join(String trg_fld, String src_tbl, String src_fld) {return new Sql_join_itm(trg_fld, src_tbl, src_fld);} + public static Sql_join_itm New_join__same(String tbl, String fld) {return new Sql_join_itm(fld, tbl, fld);} + public static Db_qry_update update_(String tbl, Criteria crt) { - Db_qry_update update = Db_qry_update.new_(); + Db_qry_update update = new Db_qry_update(); update.From_(tbl); update.Where_(crt); return update; } public static Db_qry_update update_common_(String tbl, Criteria crt, KeyVal... pairs) { - Db_qry_update cmd = Db_qry_update.new_(); + Db_qry_update cmd = new Db_qry_update(); cmd.From_(tbl); cmd.Where_(crt); for (KeyVal pair : pairs) - cmd.Arg_obj_(pair.Key(), pair.Val()); + cmd.Val_obj(pair.Key(), pair.Val()); return cmd; } - public static final Object WhereAll = null; + public static gplx.core.gfo_ndes.GfoNde Exec_as_nde(Db_conn conn, Db_qry qry) {return gplx.core.gfo_ndes.GfoNde_.rdr_(conn.Exec_qry_as_old_rdr(qry));} + public static Object Exec_as_obj(Db_conn conn, Db_qry__select_cmd qry) { + gplx.core.stores.DataRdr rdr = conn.Exec_qry_as_old_rdr(qry); + try { + return rdr.MoveNextPeer() ? rdr.Read(qry.Cols().Flds.Get_at(0).Fld) : null; // NOTE: need to access from flds for tdb + } finally {rdr.Rls();} + } + public static Db_qry as_(Object obj) {return obj instanceof Db_qry ? (Db_qry)obj : null;} - public static final int Tid_insert = 0, Tid_delete = 1, Tid_update = 2, Tid_select = 3, Tid_sql = 4, Tid_select_in_tbl = 5, Tid_flush = 6; + public static final Db_qry Noop = new Db_qry__noop(); + public static final int Tid_insert = 0, Tid_delete = 1, Tid_update = 2, Tid_select = 3, Tid_sql = 4, Tid_select_in_tbl = 5, Tid_flush = 6, Tid_noop = 7; } diff --git a/140_dbs/src/gplx/dbs/Db_qry_fxt.java b/140_dbs/src/gplx/dbs/Db_qry_fxt.java index 9c5bd8dbc..fe4e68899 100644 --- a/140_dbs/src/gplx/dbs/Db_qry_fxt.java +++ b/140_dbs/src/gplx/dbs/Db_qry_fxt.java @@ -22,12 +22,12 @@ public class Db_qry_fxt { Db_qry_insert qry = Db_qry_.insert_(tblName); for (int i = 0; i < kvList.Count(); i++) { KeyVal kv = kvList.GetAt(i); - qry.Arg_obj_(kv.Key(), kv.Val()); + qry.Val_obj(kv.Key(), kv.Val()); } qry.Exec_qry(conn); } public static GfoNde SelectAll(Db_conn conn, String tblName) { - return Db_qry_.select_tbl_(tblName).ExecRdr_nde(conn); + return Db_qry_.Exec_as_nde(conn, Db_qry_.select_tbl_(tblName)); } public static int SelectAll_count(Db_conn conn, String tblName) { GfoNde nde = Db_qry_fxt.SelectAll(conn, tblName); @@ -37,16 +37,16 @@ public class Db_qry_fxt { for (String s : ary) Db_qry_.delete_tbl_(s).Exec_qry(conn); } - public static void tst_Select(Db_conn conn, String tblName, DbTstRow... expdAry) { + public static void tst_Select(Db_conn conn, String tblName, Db_mock_row... expdAry) { GfoNde nde = Db_qry_fxt.SelectAll(conn, tblName); int len = Array_.Len(expdAry); for (int i = 0; i < len; i++) { - DbTstRow expdRow = expdAry[i]; + Db_mock_row expdRow = expdAry[i]; int actlIdx = (expdRow.Idx() == -1) ? i : expdRow.Idx(); GfoNde actlNde = nde.Subs().FetchAt_asGfoNde(actlIdx); int fldLen = Array_.Len(expdRow.Dat()); for (int j = 0; j < fldLen; j++) { - DbTstDat expdDat = expdRow.Dat()[j]; + Db_mock_cell expdDat = expdRow.Dat()[j]; Object actlVal = expdDat.Fld() == null ? actlNde.ReadAt(j) : actlNde.Read(expdDat.Fld()); Tfds.Eq(expdDat.Val(), actlVal); } diff --git a/140_dbs/src/gplx/dbs/Db_rdr.java b/140_dbs/src/gplx/dbs/Db_rdr.java index 69c451ca2..bcb146a0f 100644 --- a/140_dbs/src/gplx/dbs/Db_rdr.java +++ b/140_dbs/src/gplx/dbs/Db_rdr.java @@ -30,5 +30,6 @@ public interface Db_rdr { DateAdp Read_date_by_str(String k); boolean Read_bool_by_byte(String k); Object Read_obj(String k); + Object Read_at(int i); void Rls(); } diff --git a/140_dbs/src/gplx/dbs/Db_rdr_.java b/140_dbs/src/gplx/dbs/Db_rdr_.java index 106541c31..426d71af8 100644 --- a/140_dbs/src/gplx/dbs/Db_rdr_.java +++ b/140_dbs/src/gplx/dbs/Db_rdr_.java @@ -33,5 +33,6 @@ class Db_rdr__empty implements Db_rdr { public double Read_double(String k) {return Double_.NaN;} public boolean Read_bool_by_byte(String k) {return false;} public Object Read_obj(String k) {return null;} + public Object Read_at(int i) {return null;} public void Rls() {} } diff --git a/140_dbs/src/gplx/dbs/Db_rdr__basic.java b/140_dbs/src/gplx/dbs/Db_rdr__basic.java index 7824c3515..7487121b0 100644 --- a/140_dbs/src/gplx/dbs/Db_rdr__basic.java +++ b/140_dbs/src/gplx/dbs/Db_rdr__basic.java @@ -38,6 +38,7 @@ public class Db_rdr__basic implements Db_rdr { @gplx.Virtual public byte Read_byte(String k) {try {return Byte_.cast(rdr.getObject(k));} catch (Exception e) {throw Err_.new_exc(e, "db", "read failed", "key", k, "type", Byte_.Cls_val_name);}} @gplx.Virtual public boolean Read_bool_by_byte(String k) {try {return Byte_.cast(rdr.getObject(k)) == 1;} catch (Exception e) {throw Err_.new_exc(e, "db", "read failed", "key", k, "type", Bool_.Cls_val_name);}} @gplx.Virtual public Object Read_obj(String k) {try {return rdr.getObject(k);} catch (Exception e) {throw Err_.new_exc(e, "db", "read failed", "key", k, "type", Object_.Cls_val_name);}} + @gplx.Virtual public Object Read_at(int i) {try {return rdr.getObject(i);} catch (Exception e) {throw Err_.new_exc(e, "db", "read failed", "idx", i, "type", Object_.Cls_val_name);}} @gplx.Virtual public void Rls() { try {rdr.close();} catch (Exception e) {throw Err_.new_exc(e, "db", "close failed");} diff --git a/140_dbs/src/gplx/dbs/Db_stmt.java b/140_dbs/src/gplx/dbs/Db_stmt.java index 54caf5794..3cd872548 100644 --- a/140_dbs/src/gplx/dbs/Db_stmt.java +++ b/140_dbs/src/gplx/dbs/Db_stmt.java @@ -50,6 +50,10 @@ public interface Db_stmt extends Rls_able { Db_stmt Val_bry_as_str(String k, byte[] v); Db_stmt Val_bry_as_str(byte[] v); Db_stmt Val_rdr_(gplx.core.ios.Io_stream_rdr rdr, long rdr_len); + Db_stmt Crt_date(String k, DateAdp v); + Db_stmt Val_date(String k, DateAdp v); + Db_stmt Crt_text(String k, String v); + Db_stmt Val_text(String k, String v); boolean Exec_insert(); int Exec_update(); int Exec_delete(); diff --git a/140_dbs/src/gplx/dbs/Db_stmt_.java b/140_dbs/src/gplx/dbs/Db_stmt_.java index c24344c20..ba6f18fda 100644 --- a/140_dbs/src/gplx/dbs/Db_stmt_.java +++ b/140_dbs/src/gplx/dbs/Db_stmt_.java @@ -24,7 +24,7 @@ public class Db_stmt_ { return conn.Stmt_new(qry); } public static Db_stmt new_update_(Db_conn conn, String tbl, String[] where, String... flds) { - Db_qry qry = Db_qry_update.new_(tbl, where, flds); + Db_qry qry = Db_qry_update.New(tbl, where, flds); return conn.Stmt_new(qry); } public static Db_stmt new_delete_(Db_conn conn, String tbl, String... where) { @@ -36,7 +36,7 @@ public class Db_stmt_ { return conn.Stmt_new(qry); } public static Db_stmt new_select_in_(Db_conn conn, String tbl, String in_fld, Object[] in_vals, String... flds) { - Db_qry__select_cmd qry = Db_qry_.select_cols_(tbl, Db_crt_.in_(in_fld, in_vals), flds).OrderBy_asc_(in_fld); + Db_qry__select_cmd qry = Db_qry_.select_cols_(tbl, Db_crt_.New_in(in_fld, in_vals), flds).Order_asc_(in_fld); return conn.Stmt_new(qry); } public static Db_stmt new_select_all_(Db_conn conn, String tbl) { diff --git a/140_dbs/src/gplx/dbs/Dbmeta_fld_list.java b/140_dbs/src/gplx/dbs/Dbmeta_fld_list.java index 4437edbbd..ed3c8dd6c 100644 --- a/140_dbs/src/gplx/dbs/Dbmeta_fld_list.java +++ b/140_dbs/src/gplx/dbs/Dbmeta_fld_list.java @@ -66,6 +66,7 @@ public class Dbmeta_fld_list { 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_date(String name) {return Add(Dbmeta_fld_itm.new_str(name, 32));} 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) diff --git a/140_dbs/src/gplx/dbs/Dbmeta_idx_itm.java b/140_dbs/src/gplx/dbs/Dbmeta_idx_itm.java index 221cae4d2..aa066abc4 100644 --- a/140_dbs/src/gplx/dbs/Dbmeta_idx_itm.java +++ b/140_dbs/src/gplx/dbs/Dbmeta_idx_itm.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs; import gplx.*; -import gplx.dbs.sqls.*; import gplx.dbs.metas.*; +import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*; 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; @@ -25,7 +25,7 @@ public class Dbmeta_idx_itm { 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 String To_sql_create(Sql_qry_wtr sql_wtr) {return sql_wtr.Schema_wtr().Bld_create_idx(this);} public boolean Eq(Dbmeta_idx_itm comp) { return String_.Eq(name, comp.name) && unique == comp.unique diff --git a/140_dbs/src/gplx/dbs/Dbmeta_tbl_itm.java b/140_dbs/src/gplx/dbs/Dbmeta_tbl_itm.java index 7c45bbbb5..5f8c82d44 100644 --- a/140_dbs/src/gplx/dbs/Dbmeta_tbl_itm.java +++ b/140_dbs/src/gplx/dbs/Dbmeta_tbl_itm.java @@ -16,12 +16,12 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs; import gplx.*; -import gplx.dbs.metas.*; import gplx.dbs.sqls.*; +import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*; 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 String To_sql_create(Sql_qry_wtr sql_wtr) {return sql_wtr.Schema_wtr().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);} diff --git a/140_dbs/src/gplx/dbs/diffs/Gdif_core.java b/140_dbs/src/gplx/dbs/diffs/Gdif_core.java new file mode 100644 index 000000000..069c8fdbd --- /dev/null +++ b/140_dbs/src/gplx/dbs/diffs/Gdif_core.java @@ -0,0 +1,46 @@ +/* +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 . +*/ +package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*; +import gplx.dbs.diffs.itms.*; +import gplx.dbs.diffs.builds.*; +public class Gdif_core { + private final Db_conn conn; + private final Gdif_job_tbl job_tbl; + private final Gdif_cmd_tbl cmd_tbl; + private final Gdif_txn_tbl txn_tbl; + public Gdif_core(Db_conn conn) { + this.conn = conn; + this.db = new Gdif_db(conn); + this.job_tbl = db.Job_tbl(); + this.cmd_tbl = db.Cmd_tbl(); + this.txn_tbl = db.Txn_tbl(); + } + public Gdif_db Db() {return db;} private final Gdif_db db; + public Gdif_job_itm New_job(String name, String made_by) { + int job_id = conn.Sys_mgr().Autonum_next(job_tbl.Tbl_name(), job_tbl.Fld_job_id()); + return job_tbl.Insert(job_id, name, made_by, DateAdp_.Now().XtoUtc(), ""); + } + public Gdif_cmd_itm New_cmd(Gdif_bldr_ctx ctx, int tid) { + ctx.Cur_cmd_count++; + return cmd_tbl.Insert(ctx.Cur_job.Id, ctx.Cur_cmd_count, tid, ""); + } + public Gdif_txn_itm New_txn(Gdif_bldr_ctx ctx, int cmd_id, int owner_txn) { + ctx.Cur_txn_count++; + return txn_tbl.Insert(ctx.Cur_job.Id, ctx.Cur_txn_count, cmd_id, owner_txn); + } +} diff --git a/140_dbs/src/gplx/dbs/diffs/Gdif_db.java b/140_dbs/src/gplx/dbs/diffs/Gdif_db.java new file mode 100644 index 000000000..c66ef705b --- /dev/null +++ b/140_dbs/src/gplx/dbs/diffs/Gdif_db.java @@ -0,0 +1,31 @@ +/* +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 . +*/ +package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*; +import gplx.dbs.diffs.itms.*; +public class Gdif_db { + public Gdif_db(Db_conn conn) { + this.conn = conn; + this.job_tbl = new Gdif_job_tbl(conn); + this.cmd_tbl = new Gdif_cmd_tbl(conn); + this.txn_tbl = new Gdif_txn_tbl(conn); + } + public Db_conn Conn() {return conn;} private final Db_conn conn; + public Gdif_job_tbl Job_tbl() {return job_tbl;} private final Gdif_job_tbl job_tbl; + public Gdif_cmd_tbl Cmd_tbl() {return cmd_tbl;} private final Gdif_cmd_tbl cmd_tbl; + public Gdif_txn_tbl Txn_tbl() {return txn_tbl;} private final Gdif_txn_tbl txn_tbl; +} diff --git a/140_dbs/src/gplx/dbs/diffs/Gfdb_diff_db_.java b/140_dbs/src/gplx/dbs/diffs/Gdif_db_.java similarity index 91% rename from 140_dbs/src/gplx/dbs/diffs/Gfdb_diff_db_.java rename to 140_dbs/src/gplx/dbs/diffs/Gdif_db_.java index b767d05ae..78a2b5c6d 100644 --- a/140_dbs/src/gplx/dbs/diffs/Gfdb_diff_db_.java +++ b/140_dbs/src/gplx/dbs/diffs/Gdif_db_.java @@ -16,13 +16,13 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*; -public class Gfdb_diff_db_ { +public class Gdif_db_ { public static final String Fld__dif_txn = "dif_txn" // 0+ where 0+ is defined in a tbl , Fld__dif_uid = "dif_uid" // 0+ , Fld__dif_type = "dif_type" // I,U,D,M , Fld__dif_db_trg = "dif_db_trg" // -1 for single-db tables; 0+ for multiple-db tables - , Fld__dif_db_src = "dff_db_src" // -1 for I,U,D; 0+ for M + , Fld__dif_db_src = "dif_db_src" // -1 for I,U,D; 0+ for M ; public static final byte Tid__insert = 0 diff --git a/140_dbs/src/gplx/dbs/diffs/Gfdb_diff_cmd.java b/140_dbs/src/gplx/dbs/diffs/Gfdb_diff_cmd.java index 4bb1318a2..5458d40d4 100644 --- a/140_dbs/src/gplx/dbs/diffs/Gfdb_diff_cmd.java +++ b/140_dbs/src/gplx/dbs/diffs/Gfdb_diff_cmd.java @@ -23,11 +23,11 @@ class Gfdb_diff_cmd { 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) { + public Gfdb_diff_job New_job(Gdif_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); + 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); @@ -53,6 +53,6 @@ class Gfdb_diff_cmd { } } 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; + public Gfdb_diff_job(Gdif_db db) {this.db = db;} + public Gdif_db Db() {return db;} private Gdif_db db; } diff --git a/140_dbs/src/gplx/dbs/diffs/builds/Gdif_bldr_ctx.java b/140_dbs/src/gplx/dbs/diffs/builds/Gdif_bldr_ctx.java new file mode 100644 index 000000000..52b7c55a7 --- /dev/null +++ b/140_dbs/src/gplx/dbs/diffs/builds/Gdif_bldr_ctx.java @@ -0,0 +1,38 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; +import gplx.dbs.diffs.itms.*; +public class Gdif_bldr_ctx { + public Gdif_bldr_ctx() {} + public Gdif_core Core; + public Gdif_job_itm Cur_job; + public Gdif_cmd_itm Cur_cmd; + public Gdif_txn_itm Cur_txn; + public int Cur_cmd_count; + public int Cur_txn_count; + public Gdif_bldr_ctx Init(Gdif_core core, Gdif_job_itm cur_job) { + this.Core = core; this.Cur_job = cur_job; + return this; + } + public void Clear() { + Cur_cmd_count = 0; Cur_txn_count = 0; + Cur_job = null; + Cur_cmd = null; + Cur_txn = null; + } +} diff --git a/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_bldr.java b/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_bldr.java index 19d73f45f..97e8f8115 100644 --- a/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_bldr.java +++ b/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_bldr.java @@ -21,10 +21,10 @@ 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(int txn, Gfdb_diff_tbl tbl, Db_conn old_conn, Db_conn new_conn) { + public void Compare(Gdif_bldr_ctx ctx, 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(txn, tbl, old_rdr, new_rdr); + diff_wkr.Init_rdrs(ctx, tbl, old_rdr, new_rdr); boolean loop = true; while (loop) { int rslt = rdr_comparer.Compare(); diff --git a/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_bldr_tst.java b/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_bldr_tst.java index 83b294c62..aebb9d38f 100644 --- a/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_bldr_tst.java +++ b/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_bldr_tst.java @@ -62,6 +62,7 @@ class Gfdb_diff_bldr_fxt { 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"; + private final Gdif_bldr_ctx ctx = new Gdif_bldr_ctx(); public Gfdb_diff_bldr_fxt() { old_conn = Db_conn_utl.Conn__new("old_db"); new_conn = Db_conn_utl.Conn__new("new_db"); @@ -70,13 +71,14 @@ class Gfdb_diff_bldr_fxt { bldr.Init(wkr); } public void Clear() { + ctx.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(-1, tbl, old_conn, new_conn); + bldr.Compare(ctx, tbl, old_conn, new_conn); Tfds.Eq_ary_str(expd, wkr.To_str_ary()); } } @@ -84,7 +86,7 @@ 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(int txn, Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr) { + public void Init_rdrs(Gdif_bldr_ctx ctx, 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() {} diff --git a/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_wkr.java b/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_wkr.java index 944263b4a..910331189 100644 --- a/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_wkr.java +++ b/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_wkr.java @@ -17,7 +17,7 @@ along with this program. If not, see . */ package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; public interface Gfdb_diff_wkr { - void Init_rdrs(int txn, Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr); + void Init_rdrs(Gdif_bldr_ctx ctx, Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr); void Term_tbls(); void Handle_same(); void Handle_old_missing(); diff --git a/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_wkr__db.java b/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_wkr__db.java index 889302d15..8a6fd5ec6 100644 --- a/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_wkr__db.java +++ b/140_dbs/src/gplx/dbs/diffs/builds/Gfdb_diff_wkr__db.java @@ -16,37 +16,47 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; -import gplx.dbs.metas.*; +import gplx.dbs.metas.*; import gplx.dbs.diffs.itms.*; 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_rdr old_rdr, new_rdr; - private Db_conn dif_conn; private Db_stmt stmt; - private int txn, uid, prog_interval, prog_count; - public void Init_conn(Gfdb_diff_db diff_db, int prog_interval) {this.dif_conn = diff_db.Conn(); this.prog_interval = prog_interval;} - public void Init_rdrs(int txn, 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; + private Gdif_bldr_ctx ctx; + private Db_conn dif_conn; private Db_stmt stmt; + private int uid, prog_interval, prog_count; + private boolean cmd_create; + public void Init_conn(Gdif_db dif_db, int prog_interval) {this.dif_conn = dif_db.Conn(); this.prog_interval = prog_interval;} + public void Init_rdrs(Gdif_bldr_ctx ctx, Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr) { + this.ctx = ctx; 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.txn = txn; this.uid = -1; this.prog_count = 0; + this.uid = 0; this.prog_count = 0; String dif_tbl = tbl.Name; Dbmeta_fld_itm[] dif_flds = Gfdb_diff_wkr__db_.New_dif_flds(tbl.Flds); if (!dif_conn.Meta_tbl_exists(dif_tbl)) dif_conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(dif_tbl, dif_flds)); this.stmt = dif_conn.Stmt_insert(dif_tbl, Gfdb_diff_wkr__db_.To_str_ary(dif_flds)); dif_conn.Txn_bgn("dif_db_tbl_" + dif_tbl); + cmd_create = true; } - public void Term_tbls() {dif_conn.Txn_end();} - public void Handle_old_missing() {Insert(Gfdb_diff_db_.Tid__insert, ++uid, new_rdr, tbl.Flds);} - public void Handle_new_missing() {Insert(Gfdb_diff_db_.Tid__delete, ++uid, old_rdr, tbl.Flds);} + public void Term_tbls() { + dif_conn.Txn_end(); + } + public void Handle_old_missing() {Insert(Gdif_db_.Tid__insert, ++uid, new_rdr, tbl.Flds);} + public void Handle_new_missing() {Insert(Gdif_db_.Tid__delete, ++uid, old_rdr, tbl.Flds);} public void Handle_same() { if (Gfdb_rdr_utl_.Compare(val_flds, val_flds_len, old_rdr, new_rdr) != CompareAble_.Same) - Insert(Gfdb_diff_db_.Tid__update, ++uid, new_rdr, tbl.Flds); + Insert(Gdif_db_.Tid__update, ++uid, new_rdr, tbl.Flds); } private void Insert(byte dif_type, int uid, Db_rdr rdr, Dbmeta_fld_itm[] flds) { + if (cmd_create) { + cmd_create = false; + ctx.Cur_cmd = ctx.Core.New_cmd(ctx, Gdif_cmd_itm.Tid__data); + ctx.Cur_txn = ctx.Core.New_txn(ctx, ctx.Cur_cmd.Cmd_id, Gdif_txn_itm.Owner_txn__null); + } stmt.Clear(); - stmt.Val_int (Gfdb_diff_db_.Fld__dif_txn , txn) - .Val_int (Gfdb_diff_db_.Fld__dif_uid , uid) - .Val_int (Gfdb_diff_db_.Fld__dif_type , dif_type) - .Val_int (Gfdb_diff_db_.Fld__dif_db_src , -1) - .Val_int (Gfdb_diff_db_.Fld__dif_db_trg , -1); + stmt.Val_int (Gdif_db_.Fld__dif_txn , ctx.Cur_txn.Txn_id) + .Val_int (Gdif_db_.Fld__dif_uid , uid) + .Val_int (Gdif_db_.Fld__dif_type , dif_type) + .Val_int (Gdif_db_.Fld__dif_db_src , -1) + .Val_int (Gdif_db_.Fld__dif_db_trg , -1); Gfdb_rdr_utl_.Stmt_args(stmt, flds, flds.length, rdr); stmt.Exec_insert(); if ((++prog_count % prog_interval) == 0) dif_conn.Txn_sav(); @@ -57,11 +67,11 @@ class Gfdb_diff_wkr__db_ { int len = cur_flds.length; int sys_flds = 5; Dbmeta_fld_itm[] rv = new Dbmeta_fld_itm[len + sys_flds]; - rv[0] = Dbmeta_fld_itm.new_int (Gfdb_diff_db_.Fld__dif_txn); - rv[1] = Dbmeta_fld_itm.new_int (Gfdb_diff_db_.Fld__dif_uid); - rv[2] = Dbmeta_fld_itm.new_byte (Gfdb_diff_db_.Fld__dif_type); - rv[3] = Dbmeta_fld_itm.new_int (Gfdb_diff_db_.Fld__dif_db_trg); - rv[4] = Dbmeta_fld_itm.new_int (Gfdb_diff_db_.Fld__dif_db_src); + rv[0] = Dbmeta_fld_itm.new_int (Gdif_db_.Fld__dif_txn); + rv[1] = Dbmeta_fld_itm.new_int (Gdif_db_.Fld__dif_uid); + rv[2] = Dbmeta_fld_itm.new_byte (Gdif_db_.Fld__dif_type); + rv[3] = Dbmeta_fld_itm.new_int (Gdif_db_.Fld__dif_db_trg); + rv[4] = Dbmeta_fld_itm.new_int (Gdif_db_.Fld__dif_db_src); for (int i = 0; i < len; ++i) { Dbmeta_fld_itm cur_fld = cur_flds[i]; Dbmeta_fld_itm dif_fld = new Dbmeta_fld_itm(cur_fld.Name(), cur_fld.Type()); diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_from.java b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_cmd_itm.java similarity index 65% rename from 140_dbs/src/gplx/dbs/sqls/Sql_from.java rename to 140_dbs/src/gplx/dbs/diffs/itms/Gdif_cmd_itm.java index 88c734efb..35840a727 100644 --- a/140_dbs/src/gplx/dbs/sqls/Sql_from.java +++ b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_cmd_itm.java @@ -15,13 +15,15 @@ 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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -public class Sql_from { - public List_adp Tbls() {return tbls;} List_adp tbls = List_adp_.new_(); - public Sql_tbl_src BaseTable() {return (Sql_tbl_src)tbls.Get_at(0);} - public static Sql_from new_(Sql_tbl_src baseTable) { - Sql_from rv = new Sql_from(); - rv.tbls.Add(baseTable); - return rv; - } Sql_from() {} +package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; +public class Gdif_cmd_itm { + public Gdif_cmd_itm(int grp_id, int cmd_id, int tid) { + this.Grp_id = grp_id; this.Cmd_id = cmd_id; this.Tid = tid; + } + public final int Grp_id; + public final int Cmd_id; + public final int Tid; + public String Data; + + public static final int Tid__data = 1; } diff --git a/140_dbs/src/gplx/dbs/diffs/itms/Gdif_cmd_tbl.java b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_cmd_tbl.java new file mode 100644 index 000000000..e824e6a47 --- /dev/null +++ b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_cmd_tbl.java @@ -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 . +*/ +package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; +public class Gdif_cmd_tbl implements Rls_able { + private String tbl_name = "gdif_cmd"; + private String fld_grp_id, fld_cmd_id, fld_tid, fld_data; + private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_(); + private final Db_conn conn; private Db_stmt stmt_insert; + public Gdif_cmd_tbl(Db_conn conn) { + this.conn = conn; + fld_grp_id = flds.Add_int("grp_id"); fld_cmd_id = flds.Add_int("cmd_id"); fld_tid = flds.Add_int("tid"); fld_data = flds.Add_text("data"); + conn.Rls_reg(this); + } + 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_id, fld_cmd_id)));} + public Gdif_cmd_itm Insert(int grp_id, int cmd_id, int tid, String data) { + if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds); + stmt_insert.Clear() + .Val_int(fld_grp_id , grp_id) + .Val_int(fld_cmd_id , cmd_id) + .Val_int(fld_tid , tid) + .Val_str(fld_data , data) + .Exec_insert(); + return new Gdif_cmd_itm(grp_id, cmd_id, tid); + } + public void Rls() { + stmt_insert = Db_stmt_.Rls(stmt_insert); + } +} diff --git a/140_dbs/src/gplx/dbs/diffs/itms/Gdif_job_itm.java b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_job_itm.java new file mode 100644 index 000000000..1850ad092 --- /dev/null +++ b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_job_itm.java @@ -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 . +*/ +package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; +public class Gdif_job_itm { + public Gdif_job_itm(int id, String name, String made_by, DateAdp made_on) { + this.Id = id; this.Name = name; this.Made_by = made_by; this.Made_on = made_on; + } + public final int Id; + public final String Name; + public final String Made_by; + public final DateAdp Made_on; + public String Data; +} diff --git a/140_dbs/src/gplx/dbs/diffs/itms/Gdif_job_tbl.java b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_job_tbl.java new file mode 100644 index 000000000..137638b2d --- /dev/null +++ b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_job_tbl.java @@ -0,0 +1,46 @@ +/* +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 . +*/ +package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; +public class Gdif_job_tbl implements Rls_able { + private String tbl_name = "gdif_job"; + private String fld_job_id, fld_name, fld_made_by, fld_made_on, fld_data; + private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_(); + private final Db_conn conn; private Db_stmt stmt_insert; + public Gdif_job_tbl(Db_conn conn) { + this.conn = conn; + fld_job_id = flds.Add_int_pkey("job_id"); fld_name = flds.Add_str("name", 255); fld_made_by = flds.Add_str("made_by", 255); fld_made_on = flds.Add_date("made_on"); fld_data = flds.Add_text("data"); + conn.Rls_reg(this); + } + public String Tbl_name() {return tbl_name;} + public String Fld_job_id() {return fld_job_id;} + public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds));} + public Gdif_job_itm Insert(int id, String name, String made_by, DateAdp made_on, String data) { + if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds); + stmt_insert.Clear() + .Val_int(fld_job_id , id) + .Val_str(fld_name , name) + .Val_str(fld_made_by , made_by) + .Val_date(fld_made_on , made_on) + .Val_str(fld_data , data) + .Exec_insert(); + return new Gdif_job_itm(id, name, made_by, made_on); + } + public void Rls() { + stmt_insert = Db_stmt_.Rls(stmt_insert); + } +} diff --git a/140_dbs/src/gplx/dbs/diffs/itms/Gdif_txn_itm.java b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_txn_itm.java new file mode 100644 index 000000000..ad5476c14 --- /dev/null +++ b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_txn_itm.java @@ -0,0 +1,29 @@ +/* +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 . +*/ +package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; +public class Gdif_txn_itm { + public Gdif_txn_itm(int job_id, int txn_id, int cmd_id, int owner_txn) { + this.Job_id = job_id; this.Txn_id = txn_id; this.Cmd_id = cmd_id; this.Owner_txn = owner_txn; + } + public final int Job_id; + public final int Txn_id; + public final int Cmd_id; + public final int Owner_txn; + + public static final int Owner_txn__null = 0; +} diff --git a/140_dbs/src/gplx/dbs/diffs/tbls/Gdif_txn_tbl.java b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_txn_tbl.java similarity index 58% rename from 140_dbs/src/gplx/dbs/diffs/tbls/Gdif_txn_tbl.java rename to 140_dbs/src/gplx/dbs/diffs/itms/Gdif_txn_tbl.java index f8549dc9d..e19fffb98 100644 --- a/140_dbs/src/gplx/dbs/diffs/tbls/Gdif_txn_tbl.java +++ b/140_dbs/src/gplx/dbs/diffs/itms/Gdif_txn_tbl.java @@ -15,42 +15,27 @@ 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 . */ -package gplx.dbs.diffs.tbls; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; -import gplx.dbs.*; -/* -reg: -id,name,made_by,made_on,meta -0,'Diffs for Simple Wikipedia betwee 2015-11-16 and 2015-12-23',gnosygnu,2015-12-23'dif;simplewiki;20151223;20151116' -cmd: -owner,id,tid,meta -0,0,data_comp_tid,page -0,1,data_comp_tid,cat_core -0,2,data_comp_tid,cat_link -txn: -reg_id,txn_id,cmd_id,owner_txn -0,0,0,-1,page -0,1,-1,-1,cat -0,2,-1,1,mid -0,3,1,2,cat_core -0,4,2,2,cat_link -*/ -class Gdif_txn_tbl implements Rls_able { +package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*; +public class Gdif_txn_tbl implements Rls_able { private String tbl_name = "gdif_txn"; - private String fld_owner, fld_id; + private String fld_job_id, fld_txn_id, fld_cmd_id, fld_owner_txn; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_(); private final Db_conn conn; private Db_stmt stmt_insert; public Gdif_txn_tbl(Db_conn conn) { this.conn = conn; - fld_owner = flds.Add_int("txn_owner"); fld_id = flds.Add_int("txn_id"); + fld_job_id = flds.Add_int("job_id"); fld_txn_id = flds.Add_int("txn_id"); fld_cmd_id = flds.Add_int("cmd_id"); fld_owner_txn = flds.Add_int("owner_txn"); conn.Rls_reg(this); } - public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds.To_fld_ary(), Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "main", fld_owner, fld_id)));} - public void Insert(int txn_owner, int txn_id) { + 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_job_id, fld_txn_id)));} + public Gdif_txn_itm Insert(int job_id, int txn_id, int cmd_id, int owner_txn) { if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds); stmt_insert.Clear() - .Val_int(fld_owner , txn_owner) - .Val_int(fld_id , txn_id) + .Val_int(fld_job_id , job_id) + .Val_int(fld_txn_id , txn_id) + .Val_int(fld_cmd_id , cmd_id) + .Val_int(fld_owner_txn , owner_txn) .Exec_insert(); + return new Gdif_txn_itm(job_id, txn_id, cmd_id, owner_txn); } public void Rls() { stmt_insert = Db_stmt_.Rls(stmt_insert); diff --git a/140_dbs/src/gplx/dbs/engines/Db_engine.java b/140_dbs/src/gplx/dbs/engines/Db_engine.java index 4d3151daf..f48770a4a 100644 --- a/140_dbs/src/gplx/dbs/engines/Db_engine.java +++ b/140_dbs/src/gplx/dbs/engines/Db_engine.java @@ -16,10 +16,11 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.engines; import gplx.*; import gplx.dbs.*; -import gplx.core.stores.*; import gplx.dbs.metas.*; +import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*; public interface Db_engine { String Tid(); Db_conn_info Conn_info(); + Sql_qry_wtr Sql_wtr(); Db_engine New_clone(Db_conn_info url); Db_rdr New_rdr__rls_manual (Object rdr_obj, String sql); // Object o:ResultSet if desktop; Cursor if android Db_rdr New_rdr__rls_auto (Db_stmt stmt, Object rdr_obj, String sql); // Object o:ResultSet if desktop; Cursor if android diff --git a/140_dbs/src/gplx/dbs/engines/Db_engine_sql_base.java b/140_dbs/src/gplx/dbs/engines/Db_engine_sql_base.java index 1313adc4e..4de33ecbc 100644 --- a/140_dbs/src/gplx/dbs/engines/Db_engine_sql_base.java +++ b/140_dbs/src/gplx/dbs/engines/Db_engine_sql_base.java @@ -18,26 +18,27 @@ along with this program. If not, see . 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.metas.*; +import gplx.dbs.engines.*; import gplx.dbs.metas.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*; 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);} - @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;"));} - @gplx.Virtual public void Txn_sav() { + public abstract String Tid(); + public Db_conn_info Conn_info() {return conn_info;} protected Db_conn_info conn_info; + public abstract Sql_qry_wtr Sql_wtr(); + 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();} + @gplx.Virtual 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;"));} + @gplx.Virtual public void Txn_sav() { String txn_name = this.Txn_end(); this.Txn_bgn(txn_name); } public Object Exec_as_obj(Db_qry qry) { if (qry.Tid() == Db_qry_.Tid_flush) return null; // ignore flush (delete-db) statements - String sql = this.SqlWtr().Xto_str(qry, false); // DBG: Tfds.Write(sql); + String sql = this.Sql_wtr().To_sql_str(qry, false); // DBG: Tfds.Write(sql); return qry.Exec_is_rdr() ? (Object)this.Exec_as_rdr(sql) : this.Exec_as_int(sql); } protected int Exec_as_int(String sql) { @@ -56,33 +57,32 @@ 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(Dbmeta_tbl_itm tbl) {Exec_as_int(tbl.To_sql_create());} + public void Ddl_create_tbl(Dbmeta_tbl_itm tbl) {Exec_as_int(tbl.To_sql_create(this.Sql_wtr()));} 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) { 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()); + Exec_as_int(idx.To_sql_create(Sql_wtr())); } } 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)); + Exec_as_int(this.Sql_wtr().Schema_wtr().Bld_alter_tbl_add(tbl, fld)); Gfo_usr_dlg_.Instance.Plog_many("", "", "column added to table: db=~{0} tbl=~{1} fld=~{2}", conn_info.Database(), tbl, fld.Name()); } catch (Exception e) { // catch error if column already added to table 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));} + public void Ddl_delete_tbl(String tbl) {Exec_as_int(this.Sql_wtr().Schema_wtr().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;} 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(); rv.Ctor(stmt, (ResultSet)rdr, sql); diff --git a/140_dbs/src/gplx/dbs/engines/mems/Db_engine__mem.java b/140_dbs/src/gplx/dbs/engines/mems/Db_engine__mem.java index 974aacf20..dfe2a58ba 100644 --- a/140_dbs/src/gplx/dbs/engines/mems/Db_engine__mem.java +++ b/140_dbs/src/gplx/dbs/engines/mems/Db_engine__mem.java @@ -16,12 +16,13 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*; -import gplx.core.stores.*; import gplx.dbs.metas.*; +import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*; 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;} public String Tid() {return Db_conn_info__mem.Tid_const;} public Db_conn_info Conn_info() {return conn_info;} private Db_conn_info conn_info; + public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.Basic; public Db_engine New_clone(Db_conn_info conn_info) {return new Db_engine__mem(conn_info);} public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt__mem(this, qry);} public Mem_tbl Tbls_get(String name) {return (Mem_tbl)tbl_hash.Get_by(name);} diff --git a/140_dbs/src/gplx/dbs/engines/mems/Db_rdr__mem.java b/140_dbs/src/gplx/dbs/engines/mems/Db_rdr__mem.java index a880c7160..45c27c996 100644 --- a/140_dbs/src/gplx/dbs/engines/mems/Db_rdr__mem.java +++ b/140_dbs/src/gplx/dbs/engines/mems/Db_rdr__mem.java @@ -40,5 +40,6 @@ public class Db_rdr__mem implements Db_rdr { public double Read_double(String k) {return Double_.cast(row.Get_by(k));} public boolean Read_bool_by_byte(String k) {return Byte_.cast(row.Get_by(k)) == 1;} public Object Read_obj(String k) {return row.Get_by(k);} + public Object Read_at(int i) {return row.Get_at(i);} public void Rls() {} } diff --git a/140_dbs/src/gplx/dbs/engines/mems/Db_stmt__mem.java b/140_dbs/src/gplx/dbs/engines/mems/Db_stmt__mem.java index 4a370e8b3..88176e0c8 100644 --- a/140_dbs/src/gplx/dbs/engines/mems/Db_stmt__mem.java +++ b/140_dbs/src/gplx/dbs/engines/mems/Db_stmt__mem.java @@ -99,6 +99,18 @@ public class Db_stmt__mem implements Db_stmt { try {Add(k, where, v);} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "String", "val", v);} return this; } + public Db_stmt Crt_date(String k, DateAdp v) {return Add_date(Bool_.Y, k, v);} + public Db_stmt Val_date(String k, DateAdp v) {return Add_date(Bool_.N, k, v);} + private Db_stmt Add_date(boolean where, String k, DateAdp v) { + try {Add(k, where, v);} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "date", "val", v);} + return this; + } + public Db_stmt Crt_text(String k, String v) {return Add_text(Bool_.Y, k, v);} + public Db_stmt Val_text(String k, String v) {return Add_text(Bool_.N, k, v);} + private Db_stmt Add_text(boolean where, String k, String v) { + try {Add(k, where, v);} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "text", "val", v);} + return this; + } public Db_stmt Val_rdr_(gplx.core.ios.Io_stream_rdr v, long rdr_len) { try { Bry_bfr bfr = Bry_bfr.new_(); diff --git a/140_dbs/src/gplx/dbs/engines/mems/Mem_tbl.java b/140_dbs/src/gplx/dbs/engines/mems/Mem_tbl.java index 4a25b6072..42c0f7dae 100644 --- a/140_dbs/src/gplx/dbs/engines/mems/Mem_tbl.java +++ b/140_dbs/src/gplx/dbs/engines/mems/Mem_tbl.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ 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.core.primitives.*; import gplx.core.criterias.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.itms.*; 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_(); @@ -73,8 +73,8 @@ public class Mem_tbl { Db_qry__select_in_tbl qry = Db_qry__select_in_tbl.as_(stmt.Qry()); if (qry == null) { Db_qry__select_cmd qry2 = (Db_qry__select_cmd)stmt.Qry(); - select = qry2.Cols_ary(); - where = qry2.Where(); + select = To_str_ary(qry2.Cols().Flds); + where = qry2.Where_itm().Root; } else { select = qry.Select_flds(); @@ -84,6 +84,13 @@ public class Mem_tbl { Select_rows_where(where_rows, stmt, where); return new Db_rdr__mem(select, (Mem_row[])where_rows.To_ary_and_clear(Mem_row.class)); } + private String[] To_str_ary(Sql_select_fld_list flds) { + int len = flds.Len(); + String[] rv = new String[len]; + for (int i = 0; i < len; ++i) + rv[i] = flds.Get_at(i).Fld; + return rv; + } private void Select_rows_where(List_adp rv, Db_stmt__mem stmt, Criteria crt) { rv.Clear(); int rows_len = rows.Count(); diff --git a/140_dbs/src/gplx/dbs/engines/mysql/Mysql_engine.java b/140_dbs/src/gplx/dbs/engines/mysql/Mysql_engine.java index 8aecfce92..c4c5771a6 100644 --- a/140_dbs/src/gplx/dbs/engines/mysql/Mysql_engine.java +++ b/140_dbs/src/gplx/dbs/engines/mysql/Mysql_engine.java @@ -20,7 +20,7 @@ import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; im import java.sql.*; public class Mysql_engine extends Db_engine_sql_base { @Override public String Tid() {return Mysql_conn_info.Tid_const;} - @Override public Sql_qry_wtr SqlWtr() {return Sql_qry_wtr_.new_escape_backslash();} + @Override public Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.Mysql;} @Override public Db_engine New_clone(Db_conn_info connectInfo) { Mysql_engine rv = new Mysql_engine(); rv.Ctor(connectInfo); diff --git a/140_dbs/src/gplx/dbs/engines/nulls/Noop_engine.java b/140_dbs/src/gplx/dbs/engines/nulls/Noop_engine.java index d88ca085b..d37308c03 100644 --- a/140_dbs/src/gplx/dbs/engines/nulls/Noop_engine.java +++ b/140_dbs/src/gplx/dbs/engines/nulls/Noop_engine.java @@ -16,10 +16,11 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.engines.nulls; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*; -import gplx.core.stores.*; import gplx.dbs.metas.*; +import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*; 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;} + public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.Basic; public void Conn_open() {} public void Conn_term() {} public Db_engine New_clone(Db_conn_info url) {return this;} diff --git a/140_dbs/src/gplx/dbs/engines/postgres/Postgres_engine.java b/140_dbs/src/gplx/dbs/engines/postgres/Postgres_engine.java index 8e706990a..56e683dba 100644 --- a/140_dbs/src/gplx/dbs/engines/postgres/Postgres_engine.java +++ b/140_dbs/src/gplx/dbs/engines/postgres/Postgres_engine.java @@ -20,7 +20,7 @@ import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; im import java.sql.*; public class Postgres_engine extends Db_engine_sql_base { @Override public String Tid() {return Postgres_conn_info.Tid_const;} - @Override public Sql_qry_wtr SqlWtr() {return Sql_qry_wtr_.new_escape_backslash();} + @Override public Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.Mysql;} @Override public Db_engine New_clone(Db_conn_info connectInfo) { Postgres_engine rv = new Postgres_engine(); rv.Ctor(connectInfo); diff --git a/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_conn_info.java b/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_conn_info.java index 727a0157e..7c58762b2 100644 --- a/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_conn_info.java +++ b/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_conn_info.java @@ -30,18 +30,19 @@ public class Sqlite_conn_info extends Db_conn_info__base { public static Db_conn_info load_(Io_url url) { return Db_conn_info_.parse(Bld_raw ( "gplx_key" , Tid_const - , "data source" , url.Xto_api() - , "version" , "3" + , Cs__data_source , url.Xto_api() + , Cs__version , Cs__version__3 )); } public static Db_conn_info make_(Io_url url) { Io_mgr.Instance.CreateDirIfAbsent(url.OwnerDir()); return Db_conn_info_.parse(Bld_raw ( "gplx_key" , Tid_const - , "data source" , url.Xto_api() - , "version" , "3" + , Cs__data_source , url.Xto_api() + , Cs__version , Cs__version__3 )); } public static final Sqlite_conn_info Instance = new Sqlite_conn_info(); Sqlite_conn_info() {} + public static final String Cs__data_source = "data source", Cs__version = "version", Cs__version__3 = "3"; } \ No newline at end of file diff --git a/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine.java b/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine.java index e4cf8ebb0..33215e6b7 100644 --- a/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine.java +++ b/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine.java @@ -17,7 +17,7 @@ along with this program. If not, see . */ 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.dbs.metas.*; +import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.engines.sqlite.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*; 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; @@ -26,13 +26,14 @@ public class Sqlite_engine extends Db_engine_sql_base { this.schema_mgr = new Sqlite_schema_mgr(this); } @Override public String Tid() {return Sqlite_conn_info.Tid_const;} + @Override public gplx.dbs.sqls.Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.Sqlite;} @Override public Db_engine New_clone(Db_conn_info connectInfo) { Sqlite_engine rv = new Sqlite_engine(); rv.Ctor(connectInfo); return rv; } @Override public DataRdr New_rdr(ResultSet rdr, String commandText) {return Sqlite_rdr.new_(rdr, commandText);} - @Override public Db_rdr New_rdr_clone() {return new Db_rdr__sqlite();} + @Override public Db_rdr New_rdr_clone() {return new Db_rdr__sqlite();} @Override public void Env_db_attach(String alias, Io_url db_url) {Exec_as_int(String_.Format("ATTACH '{0}' AS {1};", db_url.Raw(), alias));} @Override public void Env_db_detach(String alias) {Exec_as_int(String_.Format("DETACH {0};", alias));} @Override public void Txn_bgn(String name) {txn_mgr.Txn_bgn(name);} @@ -42,6 +43,7 @@ public class Sqlite_engine extends Db_engine_sql_base { @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);} @Override public Dbmeta_tbl_mgr Meta_tbl_load_all() {return schema_mgr.Tbl_load_all();} + @Override public Db_stmt New_stmt_prep(Db_qry qry) {return new Sqlite_stmt(this, qry);} private static boolean loaded = false; protected void Meta_tbl_gather_hook() {throw Err_.new_unimplemented();} @gplx.Internal @Override protected Connection Conn_new() { @@ -130,3 +132,9 @@ class Sqlite_rdr extends Db_data_rdr { @Override public float ReadFloat(String return rv; } Sqlite_rdr() {} } +class Sqlite_stmt extends gplx.dbs.qrys.Db_stmt_cmd { public Sqlite_stmt(Db_engine engine, Db_qry qry) {super(engine, qry);} + @Override protected Db_stmt Add_date(boolean where, String k, DateAdp v) { + if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions + return super.Add_str(where, k, v.XtoStr_fmt_iso_8561()); + } +} diff --git a/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine_.java b/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine_.java index 04f909af7..f99fdae95 100644 --- a/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine_.java +++ b/140_dbs/src/gplx/dbs/engines/sqlite/Sqlite_engine_.java @@ -58,9 +58,9 @@ public class Sqlite_engine_ { int len = idx_ary.length; for (int i = 0; i < len; ++i) { Dbmeta_idx_itm idx = idx_ary[i]; - String idx_sql = idx.To_sql_create(); + String idx_sql = idx.To_sql_create(conn.Engine().Sql_wtr()); usr_dlg.Plog_many("", "", "creating index: ~{0} ~{1}", tbl, idx_sql); - conn.Exec_qry(Db_qry_sql.ddl_(idx.To_sql_create())); + conn.Exec_qry(Db_qry_sql.ddl_(idx.To_sql_create(conn.Engine().Sql_wtr()))); usr_dlg.Log_many("", "", "index created: ~{0} ~{1}", tbl, idx_sql); } } diff --git a/140_dbs/src/gplx/dbs/engines/tdbs/TdbDelete.java b/140_dbs/src/gplx/dbs/engines/tdbs/TdbDelete.java index 7369b452e..9dbd2db5e 100644 --- a/140_dbs/src/gplx/dbs/engines/tdbs/TdbDelete.java +++ b/140_dbs/src/gplx/dbs/engines/tdbs/TdbDelete.java @@ -23,7 +23,7 @@ class TdbDeleteWkr implements Db_qryWkr { TdbTable tbl = engine.FetchTbl(cmd.Base_table()); List_adp deleted = List_adp_.new_(); int rv = 0; - if (cmd.Where() == Db_qry_.WhereAll) { + if (cmd.Where() == Db_qry_delete.Where__null) { rv = tbl.Rows().Count(); tbl.Rows().Clear(); } diff --git a/140_dbs/src/gplx/dbs/engines/tdbs/TdbEngine.java b/140_dbs/src/gplx/dbs/engines/tdbs/TdbEngine.java index bcde62667..48bd52351 100644 --- a/140_dbs/src/gplx/dbs/engines/tdbs/TdbEngine.java +++ b/140_dbs/src/gplx/dbs/engines/tdbs/TdbEngine.java @@ -21,6 +21,7 @@ import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; public class TdbEngine implements Db_engine { public String Tid() {return Tdb_conn_info.Tid_const;} public Db_conn_info Conn_info() {return conn_info;} private Db_conn_info conn_info; + public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.Basic; public TdbDatabase Db() {return db;} TdbDatabase db; public void Conn_open() { Tdb_conn_info tdb_url = (Tdb_conn_info)conn_info; @@ -42,7 +43,7 @@ public class TdbEngine implements Db_engine { Db_qryWkr wkr = (Db_qryWkr)wkrs.Get_by_or_fail(qry.Tid()); return wkr.Exec(this, qry); } - public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_sql().Parse(qry, Sql_qry_wtr_.Instance.Xto_str(qry, true));} + public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_sql().Parse(qry, Sql_qry_wtr_.Basic.To_sql_str(qry, true));} public Object New_stmt_prep_as_obj(String sql) {throw Err_.new_unimplemented();} public Db_rdr New_rdr__rls_manual(Object rdr_obj, String sql) {return Db_rdr_.Empty;} public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {return Db_rdr_.Empty;} diff --git a/140_dbs/src/gplx/dbs/engines/tdbs/TdbFlush_tst.java b/140_dbs/src/gplx/dbs/engines/tdbs/TdbFlush_tst.java index 97e0d9f93..3c48f6190 100644 --- a/140_dbs/src/gplx/dbs/engines/tdbs/TdbFlush_tst.java +++ b/140_dbs/src/gplx/dbs/engines/tdbs/TdbFlush_tst.java @@ -94,7 +94,7 @@ class TdbEngineFxt { } public void run_InsertRow(TdbEngine engine, String tblName, int idVal) { Db_qry_insert cmd = new Db_qry_insert(tblName); - cmd.Arg_("id", idVal); + cmd.Val_int("id", idVal); engine.Exec_as_obj(cmd); } diff --git a/140_dbs/src/gplx/dbs/engines/tdbs/TdbInsert.java b/140_dbs/src/gplx/dbs/engines/tdbs/TdbInsert.java index 26287e4ac..ce474d276 100644 --- a/140_dbs/src/gplx/dbs/engines/tdbs/TdbInsert.java +++ b/140_dbs/src/gplx/dbs/engines/tdbs/TdbInsert.java @@ -17,7 +17,7 @@ along with this program. If not, see . */ package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*; import gplx.core.gfo_ndes.*; import gplx.core.stores.*; -import gplx.core.lists.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; +import gplx.core.lists.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.itms.*; class TdbInsertWkr implements Db_qryWkr { public Object Exec(Db_engine engineObj, Db_qry cmdObj) { TdbEngine engine = TdbEngine.cast(engineObj); Db_qry_insert cmd = (Db_qry_insert)cmdObj; @@ -31,11 +31,11 @@ class TdbInsertWkr implements Db_qryWkr { int InsertRowsBySelect(TdbEngine engine, TdbTable tbl, Db_qry_insert insert) { int count = 0; DataRdr rdr = (DataRdr)TdbSelectWkr.Instance.Exec(engine, insert.Select()); - Sql_select_fld_list insertFlds = insert.Cols(); int insertFldsCount = insertFlds.Count(); + Sql_select_fld_list insertFlds = insert.Cols(); int insertFldsCount = insertFlds.Len(); GfoFldList selectFldsForNewRow = null; - try {selectFldsForNewRow = insertFlds.XtoGfoFldLst(tbl);} + try {selectFldsForNewRow = TdbSelectWkr.To_GfoFldLst(tbl, insertFlds);} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to generate flds for new row");} - if (insertFldsCount > selectFldsForNewRow.Count()) throw Err_.new_wo_type("insert flds cannot exceed selectFlds", "insertFlds", insertFlds.To_str(), "selectFlds", selectFldsForNewRow.To_str()); + if (insertFldsCount > selectFldsForNewRow.Count()) throw Err_.new_wo_type("insert flds cannot exceed selectFlds", "insertFlds", To_str(insertFlds), "selectFlds", selectFldsForNewRow.To_str()); while (rdr.MoveNextPeer()) { count++; GfoNde row = GfoNde_.vals_(selectFldsForNewRow, new Object[insertFldsCount]); @@ -51,10 +51,18 @@ class TdbInsertWkr implements Db_qryWkr { for (int i = 0; i < insert.Args().Count(); i++) { KeyVal kv = insert.Args().Get_at(i); Db_arg arg = (Db_arg)kv.Val(); - row.Write(kv.Key(), arg.Val()); + row.Write(kv.Key(), arg.Val); } tbl.Rows().Add(row); return 1; } + private String To_str(Sql_select_fld_list flds) { + Bry_bfr bfr = Bry_bfr.new_(); + for (int i = 0; i < flds.Len(); i++) { + Sql_select_fld fld = flds.Get_at(i); + bfr.Add_str_u8(String_.Format("{0},{1}|", fld.Fld, fld.Alias)); + } + return bfr.To_str(); + } public static TdbInsertWkr new_() {TdbInsertWkr rv = new TdbInsertWkr(); return rv;} } diff --git a/140_dbs/src/gplx/dbs/engines/tdbs/TdbSelect.java b/140_dbs/src/gplx/dbs/engines/tdbs/TdbSelect.java index 75635a9c8..aa1bab260 100644 --- a/140_dbs/src/gplx/dbs/engines/tdbs/TdbSelect.java +++ b/140_dbs/src/gplx/dbs/engines/tdbs/TdbSelect.java @@ -16,19 +16,19 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*; -import gplx.core.criterias.*; import gplx.core.gfo_ndes.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; +import gplx.core.criterias.*; import gplx.core.gfo_ndes.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.itms.*; import gplx.core.lists.*; /*ComparerAble*/ import gplx.core.stores.*; /*GfoNdeRdr*/ class TdbSelectWkr implements Db_qryWkr { public Object Exec(Db_engine engineObj, Db_qry cmdObj) { TdbEngine engine = TdbEngine.cast(engineObj); Db_qry__select_cmd cmd = (Db_qry__select_cmd)cmdObj; - if (cmd.From().Tbls().Count() > 1) throw Err_.new_("gplx.tdbs", "joins not supported for tdbs", "sql", cmd.Xto_sql()); + if (cmd.From().Tbls.Count() > 1) throw Err_.new_("gplx.tdbs", "joins not supported for tdbs", "sql", cmd.To_sql__exec(engineObj.Sql_wtr())); - TdbTable tbl = engine.FetchTbl(cmd.From().BaseTable().TblName()); - GfoNdeList rv = (cmd.Where() == Db_qry_.WhereAll && cmd.Limit() == Db_qry__select_cmd.Limit_disabled) ? rv = tbl.Rows() : FilterRecords(tbl, cmd.Where(), cmd.Limit()); + TdbTable tbl = engine.FetchTbl(cmd.From().Base_tbl.Name); + GfoNdeList rv = (cmd.Where_itm() == Sql_where_itm.Where__null && cmd.Limit() == Db_qry__select_cmd.Limit__disabled) ? rv = tbl.Rows() : FilterRecords(tbl, cmd.Where_itm().Root, cmd.Limit()); if (cmd.GroupBy() != null) rv = TdbGroupByWkr.GroupByExec(cmd, rv, tbl); - if (cmd.OrderBy() != null) { // don't use null pattern here; if null ORDER BY, then don't call .Sort on GfoNdeList - ComparerAble comparer = Sql_order_by_sorter.new_((Sql_order_by_itm[])cmd.OrderBy().Flds().To_ary(Sql_order_by_itm.class)); + if (cmd.Order() != null) { // don't use null pattern here; if null ORDER BY, then don't call .Sort on GfoNdeList + ComparerAble comparer = Sql_order_fld_sorter.new_(cmd.Order().Flds); rv.Sort_by(comparer); } return GfoNdeRdr_.peers_(rv, false); @@ -44,6 +44,19 @@ class TdbSelectWkr implements Db_qryWkr { } return rv; } + public static GfoFldList To_GfoFldLst(TdbTable tbl, Sql_select_fld_list flds) { + GfoFldList rv = GfoFldList_.new_(); + int len = flds.Len(); + for (int i = 0; i < len; ++i) { + Sql_select_fld selectFld = flds.Get_at(i); + GfoFld fld = tbl.Flds().FetchOrNull(selectFld.Fld); + if (fld == null) throw Err_.new_wo_type("fld not found in tbl", "fldName", selectFld.Fld, "tblName", tbl.Name(), "tblFlds", tbl.Flds().To_str()); + if (rv.Has(selectFld.Alias)) throw Err_.new_wo_type("alias is not unique", "fldName", selectFld.Fld, "flds", rv.To_str()); + selectFld.GroupBy_type(fld.Type()); + rv.Add(selectFld.Alias, selectFld.Val_type()); + } + return rv; + } public static final TdbSelectWkr Instance = new TdbSelectWkr(); TdbSelectWkr() {} } class TdbGroupByWkr { @@ -51,15 +64,16 @@ class TdbGroupByWkr { GfoNdeList rv = GfoNdeList_.new_(); Ordered_hash groupByHash = Ordered_hash_.New(); List_adp groupByFlds = select.GroupBy().Flds(); - GfoFldList selectFldsForNewRow = select.Cols().Flds().XtoGfoFldLst(tbl); - Sql_select_fld_list selectFlds = select.Cols().Flds(); + GfoFldList selectFldsForNewRow = TdbSelectWkr.To_GfoFldLst(tbl, select.Cols().Flds); + Sql_select_fld_list selectFlds = select.Cols().Flds; for (int rowIdx = 0; rowIdx < selectRows.Count(); rowIdx++) { GfoNde selectRow = selectRows.FetchAt_asGfoNde(rowIdx); GfoNde groupByRow = FindOrNew(selectFldsForNewRow, groupByFlds, selectRow, groupByHash, rv); - for (int i = 0; i < selectFlds.Count(); i++) { - Sql_select_fld_base selectFld = selectFlds.Get_at(i); - Object val = groupByRow.Read(selectFld.Alias()); // groupByRow is keyed by Alias; EX: Count(Id) AS CountOf - groupByRow.WriteAt(i, selectFld.GroupBy_eval(val, selectRow.Read(selectFld.Fld()), selectFld.ValType())); + int len = selectFlds.Len(); + for (int i = 0; i < len; ++i) { + Sql_select_fld selectFld = selectFlds.Get_at(i); + Object val = groupByRow.Read(selectFld.Alias); // groupByRow is keyed by Alias; EX: Count(Id) AS CountOf + groupByRow.WriteAt(i, selectFld.GroupBy_eval(val, selectRow.Read(selectFld.Fld), selectFld.Val_type())); } } return rv; diff --git a/140_dbs/src/gplx/dbs/engines/tdbs/TdbUpdate.java b/140_dbs/src/gplx/dbs/engines/tdbs/TdbUpdate.java index 15780a4a2..cb8353661 100644 --- a/140_dbs/src/gplx/dbs/engines/tdbs/TdbUpdate.java +++ b/140_dbs/src/gplx/dbs/engines/tdbs/TdbUpdate.java @@ -39,7 +39,7 @@ class TdbUpdateWkr implements Db_qryWkr { for (int i = 0; i < cmd.Args().Count(); i++) { KeyVal p = (KeyVal)cmd.Args().Get_at(i); Db_arg prm = (Db_arg)p.Val(); - row.Write(p.Key(), prm.Val()); + row.Write(p.Key(), prm.Val); } } public static TdbUpdateWkr new_() {TdbUpdateWkr rv = new TdbUpdateWkr(); return rv;} diff --git a/140_dbs/src/gplx/dbs/qrys/Db_arg.java b/140_dbs/src/gplx/dbs/qrys/Db_arg.java index 26877ae39..5e80a9efd 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_arg.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_arg.java @@ -17,8 +17,8 @@ along with this program. If not, see . */ package gplx.dbs.qrys; import gplx.*; import gplx.dbs.*; public class Db_arg { - public Db_arg(String key, Object val) {this.key = key; this.val = val;} - public String Key() {return key;} private String key; - public Object Val() {return val;} public void Val_(Object v) {this.val = v;} private Object val; - public byte Val_tid() {return val_tid;} public Db_arg Val_tid_(byte v) {val_tid = v; return this;} private byte val_tid = Db_val_type.Tid_null; + public Db_arg(String key, Object val, byte val_tid) {this.Key = key; this.Val = val; this.Val_tid = val_tid;} + public final String Key; + public final Object Val; + public final byte Val_tid; } diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry_arg_owner.java b/140_dbs/src/gplx/dbs/qrys/Db_arg_owner.java similarity index 53% rename from 140_dbs/src/gplx/dbs/qrys/Db_qry_arg_owner.java rename to 140_dbs/src/gplx/dbs/qrys/Db_arg_owner.java index 0e32abbf3..7d136cd45 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry_arg_owner.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_arg_owner.java @@ -16,18 +16,18 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.qrys; import gplx.*; import gplx.dbs.*; -public interface Db_qry_arg_owner extends Db_qry { - Db_qry_arg_owner From_(String tbl); - Db_qry_arg_owner Key_arg_(String k, int v); - Db_qry_arg_owner Key_arg_(String k, String v); - Db_qry_arg_owner Arg_(String k, int v); - Db_qry_arg_owner Arg_(String k, long v); - Db_qry_arg_owner Arg_(String k, String v); - Db_qry_arg_owner Arg_(String k, byte[] v); - Db_qry_arg_owner Arg_(String k, DateAdp v); - Db_qry_arg_owner Arg_(String k, Decimal_adp v); - Db_qry_arg_owner Arg_byte_(String k, byte v); - Db_qry_arg_owner Arg_bry_(String k, byte[] v); - Db_qry_arg_owner Arg_obj_(String key, Object val); - Db_qry_arg_owner Arg_obj_type_(String key, Object val, byte val_tid); +public interface Db_arg_owner extends Db_qry { + Db_arg_owner From_(String tbl); + Db_arg_owner Crt_int(String k, int v); + Db_arg_owner Crt_str(String k, String v); + Db_arg_owner Val_byte(String k, byte v); + Db_arg_owner Val_int(String k, int v); + Db_arg_owner Val_long(String k, long v); + Db_arg_owner Val_decimal(String k, Decimal_adp v); + Db_arg_owner Val_str(String k, String v); + Db_arg_owner Val_date(String k, DateAdp v); + Db_arg_owner Val_blob(String k, byte[] v); + Db_arg_owner Val_str_by_bry(String k, byte[] v); + Db_arg_owner Val_obj(String key, Object val); + Db_arg_owner Val_obj_type(String key, Object val, byte val_tid); } diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry__select_cmd.java b/140_dbs/src/gplx/dbs/qrys/Db_qry__select_cmd.java index b9a6f29fb..9d145381c 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry__select_cmd.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry__select_cmd.java @@ -16,116 +16,101 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.qrys; import gplx.*; import gplx.dbs.*; -import gplx.core.criterias.*; import gplx.dbs.sqls.*; import gplx.core.gfo_ndes.*; import gplx.core.stores.*; +import gplx.core.criterias.*; +import gplx.dbs.sqls.*; import gplx.dbs.sqls.itms.*; public class Db_qry__select_cmd implements Db_qry { - public int Tid() {return Db_qry_.Tid_select;} - public boolean Exec_is_rdr() {return true;} - public String Base_table() {return from.BaseTable().TblName();} - public String Xto_sql() {return Sql_qry_wtr_.Instance.Xto_str(this, false);} - public String Xto_sql_prepare() {return Sql_qry_wtr_.Instance.Xto_str(this, true);} - public DataRdr Exec_qry_as_rdr(Db_conn conn) {return conn.Exec_qry_as_rdr(this);} - public GfoNde ExecRdr_nde(Db_conn conn) { - DataRdr rdr = DataRdr_.Null; - try {return GfoNde_.rdr_(Exec_qry_as_rdr(conn));} finally {rdr.Rls();} + public int Tid() {return Db_qry_.Tid_select;} + public boolean Exec_is_rdr() {return Bool_.Y;} + public String Base_table() {return from.Base_tbl.Name;} + public Sql_from_itm From() {return from;} private Sql_from_itm from; + public Db_qry__select_cmd From_(String tbl) {return From_(tbl, Sql_tbl_itm.Alias__null);} + public Db_qry__select_cmd From_(String name, String alias) {return From_(Sql_tbl_itm.Db__null, name, alias);} + public Db_qry__select_cmd From_(String db, String tbl, String alias) { + if (from != null) throw Err_.new_("sql_qry", "super table already defined", "from", from.Base_tbl.Name); + from = new Sql_from_itm(new Sql_tbl_itm(Sql_tbl_itm.Tid__from, db, tbl, alias, Sql_join_itm.Ary__empty)); + return this; } - public Object ExecRdr_val(Db_conn conn) { - DataRdr rdr = Exec_qry_as_rdr(conn); - try { - Object rv = null; - if (rdr.MoveNextPeer()) { - rv = rdr.Read(cols.Flds().Get_at(0).Fld()); // NOTE: need to access from flds for tdb - } - return rv; - } finally {rdr.Rls();} + public Db_qry__select_cmd Join_(String name, String alias, Sql_join_itm... join_flds) {return Join_(Sql_tbl_itm.Db__null, name, alias, join_flds);} + public Db_qry__select_cmd Join_(String db, String name, String alias, Sql_join_itm... join_flds) { + if (from == null) throw Err_.new_("sql_qry", "super table is not defined"); + from.Tbls.Add(new Sql_tbl_itm(Sql_tbl_itm.Tid__inner, db, name, alias, join_flds)); + return this; } - public static Object Rdr_to_val(DataRdr rdr) { - try { - Object rv = null; - if (rdr.MoveNextPeer()) { - rv = rdr.ReadAt(0); - } - return rv; - } finally {rdr.Rls();} + public Sql_select_itm Cols() {return cols;} private Sql_select_itm cols = Sql_select_itm.All; + public Db_qry__select_cmd Distinct_() {cols.Distinct = true; return this;} + public Db_qry__select_cmd Cols_all_() {cols = Sql_select_itm.All; return this;} + public Db_qry__select_cmd Cols_(String... ary) {return Cols_w_tbl_(Sql_select_fld.Tbl_null, ary);} + public Db_qry__select_cmd Cols_w_tbl_(String tbl, String... ary) { + if (cols == Sql_select_itm.All) cols = new Sql_select_itm(); + for (String itm : ary) + cols.Flds.Add(Sql_select_fld.New_fld(tbl, itm, itm)); + return this; } - - public Sql_from From() {return from;} Sql_from from; - public Db_qry__select_cmd From_(String tblName) {return From_(tblName, null);} - public Db_qry__select_cmd From_(String tblName, String alias) { - if (from != null) throw Err_.new_wo_type("super table already defined", "from", from.Tbls().Count()); - from = Sql_from.new_(Sql_tbl_src.new_().JoinType_(Sql_join_itmType.From).TblName_(tblName).Alias_(alias)); + public Db_qry__select_cmd Cols_w_alias_(String expr, String alias) { + if (cols == Sql_select_itm.All) cols = new Sql_select_itm(); + cols.Flds.Add(Sql_select_fld.New_fld(Sql_select_fld.Tbl_null, expr, alias)); return this; } - public Db_qry__select_cmd Join_(String name, String alias, Sql_join_itm... ary) { - if (from == null) throw Err_.new_wo_type("super table is not defined"); - Sql_tbl_src tbl = Sql_tbl_src.new_().JoinType_(Sql_join_itmType.Inner).TblName_(name).Alias_(alias); - for (Sql_join_itm itm : ary) - tbl.JoinLinks().Add(itm); - from.Tbls().Add(tbl); + public Sql_where_itm Where_itm() {return where_itm;} private Sql_where_itm where_itm = Sql_where_itm.All; + public Db_qry__select_cmd Where_(Criteria root) { + if (where_itm == Sql_where_itm.All) where_itm = new Sql_where_itm(); + where_itm.Root = root; return this; } - - public Sql_select Cols() {return cols;} Sql_select cols = Sql_select.All; - public String[] Cols_ary() {return cols.Flds().To_str_ary();} - public Db_qry__select_cmd Cols_all_() {return this;} - public Db_qry__select_cmd Cols_alias_(String expr, String alias) { - if (cols == Sql_select.All) cols = Sql_select.new_(); - cols.Add(expr, alias); + public Db_qry__select_cmd Where_and(Criteria crt) { + if (where_itm == Sql_where_itm.All) throw Err_.new_("sql_qry", "where is not defined"); + where_itm.Root = Criteria_.And(where_itm.Root, crt); return this; } - public Db_qry__select_cmd Cols_(String... ary) { - if (cols == Sql_select.All) cols = Sql_select.new_(); - for (String itm : ary) - cols.Add(itm); + public Sql_order_itm Order() {return order;} private Sql_order_itm order = null; + public Db_qry__select_cmd Order_asc_(String fld) {return Order_(fld, Bool_.Y);} + public Db_qry__select_cmd Order_(String fld, boolean asc) {return Order_(Sql_order_fld.Tbl__null, fld, asc);} + public Db_qry__select_cmd Order_(String tbl, String fld, boolean asc) { + Sql_order_fld item = new Sql_order_fld(tbl, fld, asc ? Sql_order_fld.Sort__nil : Sql_order_fld.Sort__dsc); + order = new Sql_order_itm(new Sql_order_fld[] {item}); + return this; + } + public Db_qry__select_cmd Order_asc_many_(String... flds) { + int flds_len = flds.length; + Sql_order_fld[] ary = new Sql_order_fld[flds_len]; + for (int i = 0; i < flds_len; ++i) + ary[i] = new Sql_order_fld(Sql_order_fld.Tbl__null, flds[i], Sql_order_fld.Sort__nil); + order = new Sql_order_itm(ary); + return this; + } + public int Limit() {return limit;} public Db_qry__select_cmd Limit_(int v) {this.limit = v; return this;} private int limit = Limit__disabled; public static final int Limit__disabled = Int_.Min_value; + public int Offset() {return offset;} public Db_qry__select_cmd Offset_(int v) {this.offset = v; return this;} private int offset = Offset__disabled; public static final int Offset__disabled = Int_.Min_value; + public String Indexed_by() {return indexed_by;} public Db_qry__select_cmd Indexed_by_(String v) {indexed_by = v; return this;} private String indexed_by; + + public Sql_group_itm GroupBy() {return groupBy;} private Sql_group_itm groupBy = null; + public Db_qry__select_cmd GroupBy_(String... flds) { + if (groupBy != null) throw Err_.new_("sql_qry", "group by already defined", "group", groupBy); + groupBy = Sql_group_itm.new_(flds); return this; } public Db_qry__select_cmd Cols_groupBy_max(String fld) {return Cols_groupBy_max(fld, fld);} public Db_qry__select_cmd Cols_groupBy_max(String fld, String alias) { - if (cols == Sql_select.All) cols = Sql_select.new_(); - cols.Add(Sql_select_fld_.new_max(Sql_select_fld_base.Tbl_null, fld, alias)); + if (cols == Sql_select_itm.All) cols = new Sql_select_itm(); + cols.Flds.Add(Sql_select_fld.New_max(Sql_select_fld.Tbl_null, fld, alias)); return this; } public Db_qry__select_cmd Cols_groupBy_min(String fld, String alias) { - if (cols == Sql_select.All) cols = Sql_select.new_(); - cols.Add(Sql_select_fld_.new_min(Sql_select_fld_base.Tbl_null, fld, alias)); + if (cols == Sql_select_itm.All) cols = new Sql_select_itm(); + cols.Flds.Add(Sql_select_fld.New_min(Sql_select_fld.Tbl_null, fld, alias)); return this; } public Db_qry__select_cmd Cols_groupBy_count(String fld, String alias) { - if (cols == Sql_select.All) cols = Sql_select.new_(); - cols.Add(Sql_select_fld_.new_count(Sql_select_fld_base.Tbl_null, fld, alias)); + if (cols == Sql_select_itm.All) cols = new Sql_select_itm(); + cols.Flds.Add(Sql_select_fld.New_count(Sql_select_fld.Tbl_null, fld, alias)); return this; } public Db_qry__select_cmd Cols_groupBy_sum(String fld) {return Cols_groupBy_sum(fld, fld);} public Db_qry__select_cmd Cols_groupBy_sum(String fld, String alias) { - if (cols == Sql_select.All) cols = Sql_select.new_(); - cols.Add(Sql_select_fld_.new_sum(Sql_select_fld_base.Tbl_null, fld, alias)); - return this; - } - - public Criteria Where() {return where;} public Db_qry__select_cmd Where_(Criteria crt) {where = crt; return this;} Criteria where; - public Sql_order_by OrderBy() {return orderBy;} Sql_order_by orderBy = null; - public Db_qry__select_cmd OrderBy_(String fieldName, boolean ascending) { - Sql_order_by_itm item = Sql_order_by_itm.new_(fieldName, ascending); - orderBy = Sql_order_by.new_(item); - return this; - } - public Db_qry__select_cmd OrderBy_asc_(String fieldName) {return OrderBy_(fieldName, true);} - public Db_qry__select_cmd OrderBy_many_(String... fldNames) { - Sql_order_by_itm[] ary = new Sql_order_by_itm[fldNames.length]; - for (int i = 0; i < fldNames.length; i++) - ary[i] = Sql_order_by_itm.new_(fldNames[i], true); - orderBy = Sql_order_by.new_(ary); - return this; - } - public Sql_group_by GroupBy() {return groupBy;} Sql_group_by groupBy = null; - public Db_qry__select_cmd GroupBy_(String... flds) { - if (groupBy != null) throw Err_.new_wo_type("group by already defined", "group", groupBy); - groupBy = Sql_group_by.new_(flds); + if (cols == Sql_select_itm.All) cols = new Sql_select_itm(); + cols.Flds.Add(Sql_select_fld.New_sum(Sql_select_fld.Tbl_null, fld, alias)); return this; } - public String Indexed_by() {return indexed_by;} public Db_qry__select_cmd Indexed_by_(String v) {indexed_by = v; return this;} private String indexed_by; - public Db_qry__select_cmd Distinct_() {cols.Distinct_set(true); return this;} - public int Limit() {return limit;} int limit = -1; public static final int Limit_disabled = -1; - public Db_qry__select_cmd Limit_(int v) {this.limit = v; return this;} - - public static Db_qry__select_cmd new_() {return new Db_qry__select_cmd();} Db_qry__select_cmd() {} + + public String To_sql__exec(gplx.dbs.sqls.Sql_qry_wtr wtr) {return wtr.To_sql_str(this, Bool_.N);} + public String To_sql__prep(gplx.dbs.sqls.Sql_qry_wtr wtr) {return wtr.To_sql_str(this, Bool_.Y);} } diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry__select_in_tbl.java b/140_dbs/src/gplx/dbs/qrys/Db_qry__select_in_tbl.java index 886ee78e8..d62c6839e 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry__select_in_tbl.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry__select_in_tbl.java @@ -40,8 +40,7 @@ public class Db_qry__select_in_tbl implements Db_qry { public String Having_sql() {return having_sql;} private final String having_sql; public String Order_by_sql() {return order_by_sql;} public Db_qry__select_in_tbl Order_by_sql_(String v) {order_by_sql = v; return this;} private String order_by_sql; public String Limit_sql() {return limit_sql;} private final String limit_sql; - public String XtoSql() {return Xto_sql();} - public String Xto_sql() { + public String To_sql__exec(gplx.dbs.sqls.Sql_qry_wtr wtr) { synchronized (this) { String_bldr sb = String_bldr_.new_(); sb.Add("SELECT "); diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry_delete.java b/140_dbs/src/gplx/dbs/qrys/Db_qry_delete.java index 1cba042c5..1bb68223f 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry_delete.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry_delete.java @@ -19,13 +19,14 @@ package gplx.dbs.qrys; import gplx.*; import gplx.dbs.*; import gplx.core.criterias.*; import gplx.dbs.sqls.*; public class Db_qry_delete implements Db_qry { Db_qry_delete(String base_table, Criteria where) {this.base_table = base_table; this.where = where;} - public int Tid() {return Db_qry_.Tid_delete;} - public boolean Exec_is_rdr() {return false;} - public String Base_table() {return base_table;} private final String base_table; - public String Xto_sql() {return Sql_qry_wtr_.Instance.Xto_str(this, false);} - public Criteria Where() {return where;} private final Criteria where; - public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);} + public int Tid() {return Db_qry_.Tid_delete;} + public boolean Exec_is_rdr() {return Bool_.N;} + public String Base_table() {return base_table;} private final String base_table; + public String To_sql__exec(Sql_qry_wtr wtr) {return wtr.To_sql_str(this, false);} + public Criteria Where() {return where;} private final Criteria where; + public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);} public static Db_qry_delete new_all_(String tbl) {return new Db_qry_delete(tbl, Criteria_.All);} public static Db_qry_delete new_(String tbl, String... where) {return new Db_qry_delete(tbl, Db_crt_.eq_many_(where));} public static Db_qry_delete new_(String tbl, Criteria where) {return new Db_qry_delete(tbl, where);} + public static final Criteria Where__null = null; } diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry_dml_tst.java b/140_dbs/src/gplx/dbs/qrys/Db_qry_dml_tst.java index daa8e6755..3b69387cf 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry_dml_tst.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry_dml_tst.java @@ -20,25 +20,25 @@ import org.junit.*; import gplx.core.criterias.*; public class Db_qry_dml_tst { @Test public void Delete_basic() { - tst_XtoSql(Db_qry_delete.new_("tbl0", Db_crt_.eq_("fld0", "val0")) - , "DELETE FROM tbl0 WHERE fld0='val0'"); + tst_XtoSql(Db_qry_delete.new_("tbl0", Db_crt_.New_eq("fld0", "val0")) + , "DELETE FROM tbl0 WHERE fld0 = 'val0'"); } @Test public void Insert_basic() { - tst_XtoSql(new Db_qry_insert("tbl0").Arg_("id", 0).Arg_("name", "me").Arg_("time", DateAdp_.parse_gplx("2007-12-23")) + tst_XtoSql(new Db_qry_insert("tbl0").Val_int("id", 0).Val_str("name", "me").Val_date("time", DateAdp_.parse_gplx("2007-12-23")) , "INSERT INTO tbl0 (id, name, time) VALUES (0, 'me', '2007-12-23 00:00:00.000')"); } @Test public void Update_basic() { - Db_qry_update qry = Db_qry_update.new_(); + Db_qry_update qry = new Db_qry_update(); qry.From_("tbl0"); - qry.Where_(Db_crt_.eq_("id", 0)).Arg_("name", "me"); - tst_XtoSql(qry, "UPDATE tbl0 SET name='me' WHERE id=0"); + qry.Where_(Db_crt_.New_eq("id", 0)).Val_str("name", "me"); + tst_XtoSql(qry, "UPDATE tbl0 SET name='me' WHERE id = 0"); } @Test public void Update_all() { - Db_qry_update qry = Db_qry_update.new_(); + Db_qry_update qry = new Db_qry_update(); qry.From_("tbl0"); - qry.Arg_("id", 1).Arg_("name", "me").Arg_("startTime", DateAdp_.parse_gplx("2007-12-23")); - qry.Where_(Criteria_.And(Db_crt_.eq_("id", 0), Db_crt_.mt_("startTime", DateAdp_.parse_gplx("2005-01-01")))); - tst_XtoSql(qry, "UPDATE tbl0 SET id=1, name='me', startTime='2007-12-23 00:00:00.000' WHERE (id=0 AND startTime>'2005-01-01 00:00:00.000')"); + qry.Val_int("id", 1).Val_str("name", "me").Val_date("startTime", DateAdp_.parse_gplx("2007-12-23")); + qry.Where_(Criteria_.And(Db_crt_.New_eq("id", 0), Db_crt_.New_mt("startTime", DateAdp_.parse_gplx("2005-01-01")))); + tst_XtoSql(qry, "UPDATE tbl0 SET id=1, name='me', startTime='2007-12-23 00:00:00.000' WHERE (id = 0 AND startTime > '2005-01-01 00:00:00.000')"); } - void tst_XtoSql(Db_qry qry, String expd) {Tfds.Eq(expd, qry.Xto_sql());} + void tst_XtoSql(Db_qry qry, String expd) {Tfds.Eq(expd, qry.To_sql__exec(gplx.dbs.sqls.Sql_qry_wtr_.Basic));} } diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry_flush.java b/140_dbs/src/gplx/dbs/qrys/Db_qry_flush.java index 2f3f2ad88..d15b49d0d 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry_flush.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry_flush.java @@ -21,7 +21,7 @@ public class Db_qry_flush implements Db_qry { public int Tid() {return Db_qry_.Tid_flush;} public boolean Exec_is_rdr() {return false;} public String Base_table() {return tableNames[0];} - public String Xto_sql() {return Sql_qry_wtr_.Instance.Xto_str(this, false);} + public String To_sql__exec(Sql_qry_wtr wtr) {return wtr.To_sql_str(this, false);} public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);} public String[] TableNames() {return tableNames;} private String[] tableNames; diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry_insert.java b/140_dbs/src/gplx/dbs/qrys/Db_qry_insert.java index 36006507c..72b791d6c 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry_insert.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry_insert.java @@ -16,40 +16,39 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.qrys; import gplx.*; import gplx.dbs.*; -import gplx.dbs.sqls.*; -public class Db_qry_insert implements Db_qry_arg_owner { +import gplx.dbs.sqls.*; import gplx.dbs.sqls.itms.*; +public class Db_qry_insert implements Db_arg_owner { public Db_qry_insert(String base_table) {this.base_table = base_table;} public int Tid() {return Db_qry_.Tid_insert;} public boolean Exec_is_rdr() {return false;} - public String Xto_sql() {return Sql_qry_wtr_.Instance.Xto_str(this, false);} + public String To_sql__exec(Sql_qry_wtr wtr) {return wtr.To_sql_str(this, false);} public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);} public String Base_table() {return base_table;} private String base_table; public String[] Cols_for_insert() {return cols_for_insert;} private String[] cols_for_insert; - public Db_qry_arg_owner From_(String tbl) {base_table = tbl; return this;} + public Db_arg_owner From_(String tbl) {base_table = tbl; return this;} public KeyValHash Args() {return args;} private final KeyValHash args = KeyValHash.new_(); - public Db_qry_arg_owner Arg_(String k, Decimal_adp v) {return Arg_obj_type_(k, v.Under(), Db_val_type.Tid_decimal);} - public Db_qry_arg_owner Arg_(String k, DateAdp v) {return Arg_obj_type_(k, v, Db_val_type.Tid_date);} - public Db_qry_arg_owner Arg_byte_(String k, byte v) {return Arg_obj_type_(k, v, Db_val_type.Tid_byte);} - public Db_qry_arg_owner Arg_(String k, int v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int32);} - public Db_qry_arg_owner Arg_(String k, long v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int64);} - public Db_qry_arg_owner Arg_(String k, String v) {return Arg_obj_type_(k, v, Db_val_type.Tid_varchar);} - public Db_qry_arg_owner Arg_bry_(String k, byte[] v) {return Arg_obj_type_(k, v, Db_val_type.Tid_bry);} - 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) { + public Db_arg_owner Val_byte(String k, byte v) {return Val_obj_type(k, v, Db_val_type.Tid_byte);} + public Db_arg_owner Val_int(String k, int v) {return Val_obj_type(k, v, Db_val_type.Tid_int32);} + public Db_arg_owner Val_long(String k, long v) {return Val_obj_type(k, v, Db_val_type.Tid_int64);} + public Db_arg_owner Val_decimal(String k, Decimal_adp v) {return Val_obj_type(k, v.Under(), Db_val_type.Tid_decimal);} + public Db_arg_owner Val_str(String k, String v) {return Val_obj_type(k, v, Db_val_type.Tid_varchar);} + public Db_arg_owner Val_str_by_bry(String k, byte[] v) {return Val_obj_type(k, String_.new_u8(v), Db_val_type.Tid_varchar);} + public Db_arg_owner Val_date(String k, DateAdp v) {return Val_obj_type(k, v, Db_val_type.Tid_date);} + public Db_arg_owner Val_blob(String k, byte[] v) {return Val_obj_type(k, v, Db_val_type.Tid_bry);} + public Db_arg_owner Val_obj(String k, Object v) {return Val_obj_type(k, v, Db_val_type.Tid_null);} + public Db_arg_owner Val_obj_type(String key, Object val, byte val_tid) { 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); + args.Add(key, new Db_arg(key, val, val_tid)); return this; } - public Db_qry_arg_owner Key_arg_(String k, int v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int32);} - public Db_qry_arg_owner Key_arg_(String k, String v) {return Arg_obj_type_(k, v, Db_val_type.Tid_varchar);} + public Db_arg_owner Crt_int(String k, int v) {return Val_obj_type(k, v, Db_val_type.Tid_int32);} + public Db_arg_owner Crt_str(String k, String v) {return Val_obj_type(k, v, Db_val_type.Tid_varchar);} public Db_qry__select_cmd Select() {return select;} Db_qry__select_cmd select; public Db_qry_insert Select_(Db_qry__select_cmd qry) {this.select = qry; return this;} public Db_qry_insert Cols_(String... ary) { - if (cols == null) cols = Sql_select_fld_list.new_(); + if (cols == null) cols = new Sql_select_fld_list(); for (String fld : ary) - cols.Add(Sql_select_fld_.new_fld(Sql_select_fld_base.Tbl_null, fld, fld)); + cols.Add(Sql_select_fld.New_fld(Sql_select_fld.Tbl_null, fld, fld)); return this; } public Sql_select_fld_list Cols() {return cols;} private Sql_select_fld_list cols; @@ -61,7 +60,7 @@ public class Db_qry_insert implements Db_qry_arg_owner { rv.cols_for_insert = keys; int len = keys.length; for (int i = 0; i < len; ++i) - rv.Arg_obj_(keys[i], null); + rv.Val_obj(keys[i], null); return rv; } } diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry_select_tst.java b/140_dbs/src/gplx/dbs/qrys/Db_qry_select_tst.java index 904892ec7..e65ef39a9 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry_select_tst.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry_select_tst.java @@ -19,7 +19,7 @@ package gplx.dbs.qrys; import gplx.*; import gplx.dbs.*; import org.junit.*; import gplx.dbs.sqls.*; public class Db_qry_select_tst { @Before public void setup() { - cmd = Db_qry__select_cmd.new_(); + cmd = new Db_qry__select_cmd(); } Db_qry__select_cmd cmd; String expd; @Test public void Basic() { cmd.Cols_("fld0", "fld1").From_("tbl0"); @@ -40,25 +40,25 @@ public class Db_qry_select_tst { tst_XtoStr(cmd, expd); } @Test public void Where() { - cmd.From_("tbl0").Where_(Db_crt_.eq_("fld0", 0)); - expd = "SELECT * FROM tbl0 WHERE fld0=0"; + cmd.From_("tbl0").Where_(Db_crt_.New_eq("fld0", 0)); + expd = "SELECT * FROM tbl0 WHERE fld0 = 0"; tst_XtoStr(cmd, expd); } @Test public void Join() { - cmd.From_("tbl0").Join_("tbl1", "t1", Sql_join_itm.new_("fld1", "tbl0", "fld0")); - expd = "SELECT * FROM tbl0 INNER JOIN tbl1 t1 ON tbl0.fld0=t1.fld1"; + cmd.From_("tbl0").Join_("tbl1", "t1", Db_qry_.New_join__join("fld1", "tbl0", "fld0")); + expd = "SELECT * FROM tbl0 INNER JOIN tbl1 t1 ON tbl0.fld0 = t1.fld1"; tst_XtoStr(cmd, expd); } @Test public void OrderBy() { - cmd.From_("tbl0").OrderBy_("fld0", true); + cmd.From_("tbl0").Order_("fld0", true); expd = "SELECT * FROM tbl0 ORDER BY fld0"; tst_XtoStr(cmd, expd); } @Test public void OrderByMany() { - cmd.From_("tbl0").OrderBy_many_("fld0", "fld1"); + cmd.From_("tbl0").Order_asc_many_("fld0", "fld1"); expd = "SELECT * FROM tbl0 ORDER BY fld0, fld1"; tst_XtoStr(cmd, expd); @@ -85,5 +85,5 @@ public class Db_qry_select_tst { // expd = "SELECT fld0, fld1 FROM tbl0 GROUP BY fld0, fld1 HAVING Count(fld0) > 1"; // Tfds.Eq(cmd.To_str(), expd); // } - void tst_XtoStr(Db_qry qry, String expd) {Tfds.Eq(expd, cmd.Xto_sql());} + void tst_XtoStr(Db_qry qry, String expd) {Tfds.Eq(expd, cmd.To_sql__exec(Sql_qry_wtr_.Basic));} } diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry_sql.java b/140_dbs/src/gplx/dbs/qrys/Db_qry_sql.java index 7fc65f7ea..8c992035c 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry_sql.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry_sql.java @@ -21,7 +21,7 @@ public class Db_qry_sql implements Db_qry { public int Tid() {return Db_qry_.Tid_sql;} public boolean Exec_is_rdr() {return isReader;} private boolean isReader; public String Base_table() {throw Err_.new_unimplemented();} - public String Xto_sql() {return sql;} private String sql; + public String To_sql__exec(Sql_qry_wtr wtr) {return sql;} private String sql; public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);} public static Db_qry_sql dml_(String sql) {return sql_(sql);} public static Db_qry_sql ddl_(String sql) {return sql_(sql);} diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry_sql_tst.java b/140_dbs/src/gplx/dbs/qrys/Db_qry_sql_tst.java index c81f80c4e..6260d38e9 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry_sql_tst.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry_sql_tst.java @@ -28,16 +28,16 @@ public class Db_qry_sql_tst { } @Test public void Update() { fxt.Test_qry - ( Db_qry_update.new_("tbl", String_.Ary("k1", "k2"), "k3", "k4") + ( Db_qry_update.New("tbl", String_.Ary("k1", "k2"), "k3", "k4") , Object_.Ary("v3", "v4", "v1", "v2") - , "UPDATE tbl SET k3='v3', k4='v4' WHERE (k1='v1' AND k2='v2')" + , "UPDATE tbl SET k3='v3', k4='v4' WHERE (k1 = 'v1' AND k2 = 'v2')" ); } @Test public void Delete() { fxt.Test_qry ( Db_qry_delete.new_("tbl", String_.Ary("k1", "k2")) , Object_.Ary("v1", "v2") - , "DELETE FROM tbl WHERE (k1='v1' AND k2='v2')" + , "DELETE FROM tbl WHERE (k1 = 'v1' AND k2 = 'v2')" ); } } diff --git a/140_dbs/src/gplx/dbs/qrys/Db_qry_update.java b/140_dbs/src/gplx/dbs/qrys/Db_qry_update.java index 8aedb1ed1..5ce9eb5d1 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_qry_update.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_qry_update.java @@ -17,45 +17,43 @@ along with this program. If not, see . */ package gplx.dbs.qrys; import gplx.*; import gplx.dbs.*; import gplx.core.criterias.*; import gplx.dbs.sqls.*; -public class Db_qry_update implements Db_qry_arg_owner { +public class Db_qry_update implements Db_arg_owner { public int Tid() {return Db_qry_.Tid_update;} public boolean Exec_is_rdr() {return false;} - public String Xto_sql() {return Sql_qry_wtr_.Instance.Xto_str(this, false);} + public String To_sql__exec(Sql_qry_wtr wtr) {return wtr.To_sql_str(this, false);} public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);} public String Base_table() {return base_table;} private String base_table; public String[] Cols_for_update() {return cols_for_update;} private String[] cols_for_update; public Criteria Where() {return where;} public Db_qry_update Where_(Criteria crt) {where = crt; return this;} private Criteria where; - public Db_qry_arg_owner From_(String tbl) {base_table = tbl; return this;} + public Db_arg_owner From_(String tbl) {base_table = tbl; return this;} public KeyValHash Args() {return args;} private final KeyValHash args = KeyValHash.new_(); - public Db_qry_arg_owner Arg_(String k, Decimal_adp v) {return Arg_obj_type_(k, v.Under(), Db_val_type.Tid_decimal);} - public Db_qry_arg_owner Arg_(String k, DateAdp v) {return Arg_obj_type_(k, v, Db_val_type.Tid_date);} - public Db_qry_arg_owner Arg_byte_(String k, byte v) {return Arg_obj_type_(k, v, Db_val_type.Tid_byte);} - public Db_qry_arg_owner Arg_(String k, int v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int32);} - public Db_qry_arg_owner Arg_(String k, long v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int64);} - public Db_qry_arg_owner Arg_(String k, String v) {return Arg_obj_type_(k, v, Db_val_type.Tid_varchar);} - public Db_qry_arg_owner Arg_bry_(String k, byte[] v) {return Arg_obj_type_(k, v, Db_val_type.Tid_bry);} - 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) { + public Db_arg_owner Val_byte(String k, byte v) {return Val_obj_type(k, v, Db_val_type.Tid_byte);} + public Db_arg_owner Val_int(String k, int v) {return Val_obj_type(k, v, Db_val_type.Tid_int32);} + public Db_arg_owner Val_long(String k, long v) {return Val_obj_type(k, v, Db_val_type.Tid_int64);} + public Db_arg_owner Val_decimal(String k, Decimal_adp v) {return Val_obj_type(k, v.Under(), Db_val_type.Tid_decimal);} + public Db_arg_owner Val_str(String k, String v) {return Val_obj_type(k, v, Db_val_type.Tid_varchar);} + public Db_arg_owner Val_str_by_bry(String k, byte[] v) {return Val_obj_type(k, String_.new_u8(v), Db_val_type.Tid_varchar);} + public Db_arg_owner Val_date(String k, DateAdp v) {return Val_obj_type(k, v, Db_val_type.Tid_date);} + public Db_arg_owner Val_blob(String k, byte[] v) {return Val_obj_type(k, v, Db_val_type.Tid_bry);} + public Db_arg_owner Val_obj(String k, Object v) {return Val_obj_type(k, v, Db_val_type.Tid_null);} + public Db_arg_owner Val_obj_type(String key, Object val, byte val_tid) { 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); + args.Add(key, new Db_arg(key, val, val_tid)); return this; } - public Db_qry_arg_owner Key_arg_(String k, int v) {return Key_arg_obj_(k, v);} - public Db_qry_arg_owner Key_arg_(String k, String v) {return Key_arg_obj_(k, v);} - private Db_qry_arg_owner Key_arg_obj_(String k, Object v) { - Criteria crt = Db_crt_.eq_(k, v); + public Db_arg_owner Crt_int(String k, int v) {return Key_obj_(k, v);} + public Db_arg_owner Crt_str(String k, String v) {return Key_obj_(k, v);} + private Db_arg_owner Key_obj_(String k, Object v) { + Criteria crt = Db_crt_.New_eq(k, v); where = where == null ? crt : Criteria_.And(where, crt); return this; } - public static Db_qry_update new_() {return new Db_qry_update();} Db_qry_update() {} - public static Db_qry_update new_(String tbl, String[] where, String... update) { + public static Db_qry_update New(String tbl, String[] where, String... update) { Db_qry_update rv = Db_qry_.update_(tbl, Db_crt_.eq_many_(where)); rv.cols_for_update = update; int len = update.length; for (int i = 0; i < len; i++) - rv.Arg_obj_(update[i], null); + rv.Val_obj(update[i], null); return rv; } } diff --git a/140_dbs/src/gplx/dbs/qrys/Db_stmt_cmd.java b/140_dbs/src/gplx/dbs/qrys/Db_stmt_cmd.java index 1e1fc3482..1602d8073 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_stmt_cmd.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_stmt_cmd.java @@ -26,7 +26,7 @@ public class Db_stmt_cmd implements Db_stmt { public Db_stmt_cmd(Db_engine engine, Db_qry qry) {Ctor_stmt(engine, qry);} public void Ctor_stmt(Db_engine engine, Db_qry qry) { this.engine = engine; - sql = qry.Tid() == Db_qry_.Tid_select_in_tbl ? ((Db_qry__select_in_tbl)qry).Xto_sql() : Sql_qry_wtr_.Instance.Xto_str(qry, true); + sql = qry.Tid() == Db_qry_.Tid_select_in_tbl ? ((Db_qry__select_in_tbl)qry).To_sql__exec(engine.Sql_wtr()) : engine.Sql_wtr().To_sql_str(qry, true); Reset_stmt(); } public Db_stmt Reset_stmt() { @@ -101,11 +101,25 @@ public class Db_stmt_cmd implements Db_stmt { public Db_stmt Crt_str(String k, String v) {return Add_str(Bool_.Y, k, v);} 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) { + @gplx.Virtual protected Db_stmt Add_str(boolean where, String k, String v) { 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; } + public Db_stmt Crt_date(String k, DateAdp v) {return Add_date(Bool_.Y, k, v);} + public Db_stmt Val_date(String k, DateAdp v) {return Add_date(Bool_.N, k, v);} + @gplx.Virtual protected Db_stmt Add_date(boolean where, String k, DateAdp v) { + if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions + try {stmt.setTimestamp(++val_idx, new java.sql.Timestamp(v.UnderDateTime().getTime().getTime()));} catch (Exception e) {this.Rls(); throw Err_.new_exc(e, "db", "failed to add value", "type", "date", "val", v, "sql", sql);} + return this; + } + public Db_stmt Crt_text(String k, String v) {return Add_text(Bool_.Y, k, v);} + public Db_stmt Val_text(String k, String v) {return Add_text(Bool_.N, k, v);} + private Db_stmt Add_text(boolean where, String k, String v) { + 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", "text", "val", v, "sql", sql);} + return this; + } public Db_stmt Val_rdr_(gplx.core.ios.Io_stream_rdr v, long rdr_len) { try {stmt.setBinaryStream(++val_idx, (java.io.InputStream)v.Under(), (int)rdr_len);} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "rdr", "val", v);} return this; @@ -144,7 +158,7 @@ public class Db_stmt_cmd implements Db_stmt { try {return engine.New_rdr__rls_manual(stmt.executeQuery(), sql);} catch (Exception e) {throw Err_.new_exc(e, "db", "select failed", "sql", sql);} } public Object Exec_select_val() { - try {Object rv = Db_qry__select_cmd.Rdr_to_val(engine.New_rdr(stmt.executeQuery(), sql)); return rv;} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql);} + try {Object rv = DataRdr_.Read_1st_row_and_1st_fld(engine.New_rdr(stmt.executeQuery(), sql)); return rv;} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql);} } public Db_stmt Clear() { val_idx = 0; diff --git a/140_dbs/src/gplx/dbs/qrys/Db_stmt_sql.java b/140_dbs/src/gplx/dbs/qrys/Db_stmt_sql.java index 3c6b55ecd..c549e15ca 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_stmt_sql.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_stmt_sql.java @@ -91,6 +91,18 @@ public class Db_stmt_sql implements Db_stmt {// used for formatting SQL statemen try {Add(k, Val_str_wrap(v));} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "String", "val", v);} return this; } + public Db_stmt Crt_date(String k, DateAdp v) {return Add_date(Bool_.Y, k, v);} + public Db_stmt Val_date(String k, DateAdp v) {return Add_date(Bool_.N, k, v);} + private Db_stmt Add_date(boolean where, String k, DateAdp v) { + try {Add(k, Val_str_wrap(v.XtoStr_fmt_iso_8561()));} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "date", "val", v);} + return this; + } + public Db_stmt Crt_text(String k, String v) {return Add_text(Bool_.Y, k, v);} + public Db_stmt Val_text(String k, String v) {return Add_text(Bool_.N, k, v);} + private Db_stmt Add_text(boolean where, String k, String v) { + try {Add(k, Val_str_wrap(v));} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "text", "val", v);} + return this; + } public Db_stmt Val_rdr_(gplx.core.ios.Io_stream_rdr v, long rdr_len) { try { Bry_bfr bfr = Bry_bfr.new_(); @@ -112,12 +124,12 @@ public class Db_stmt_sql implements Db_stmt {// used for formatting SQL statemen try {int rv = conn.Exec_qry(Db_qry_sql.dml_(this.Xto_sql())); return rv;} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);} } public DataRdr Exec_select() { - try {DataRdr rv = conn.Exec_qry_as_rdr(Db_qry_sql.rdr_(this.Xto_sql())); return rv;} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);} + try {DataRdr rv = conn.Exec_qry_as_old_rdr(Db_qry_sql.rdr_(this.Xto_sql())); return rv;} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);} } public Db_rdr Exec_select__rls_auto() {return Db_rdr_.Empty;} public Db_rdr Exec_select__rls_manual() {return Db_rdr_.Empty;} public Object Exec_select_val() { - try {Object rv = Db_qry__select_cmd.Rdr_to_val(this.Exec_select()); return rv;} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);} + try {Object rv = DataRdr_.Read_1st_row_and_1st_fld(this.Exec_select()); return rv;} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);} } public Db_stmt Clear() { args.Clear(); diff --git a/140_dbs/src/gplx/dbs/qrys/Db_val_type.java b/140_dbs/src/gplx/dbs/qrys/Db_val_type.java index 6ae591103..0cd81c2f2 100644 --- a/140_dbs/src/gplx/dbs/qrys/Db_val_type.java +++ b/140_dbs/src/gplx/dbs/qrys/Db_val_type.java @@ -31,5 +31,6 @@ public class Db_val_type { , Tid_varchar = 10 , Tid_nvarchar = 11 , Tid_rdr = 12 + , Tid_text = 13 ; } diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_join_itm.java b/140_dbs/src/gplx/dbs/sqls/Sql_join_itm.java deleted file mode 100644 index 48a858f99..000000000 --- a/140_dbs/src/gplx/dbs/sqls/Sql_join_itm.java +++ /dev/null @@ -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 . -*/ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -import gplx.core.strings.*; -public class Sql_join_itm { - public String SrcTbl() {return srcTbl;} public Sql_join_itm SrcTbl_(String v) {srcTbl = v; return this;} private String srcTbl; - public String SrcFld() {return srcFld;} public Sql_join_itm SrcFld_(String v) {srcFld = v; return this;} private String srcFld; - public String TrgFld() {return trgFld;} public Sql_join_itm TrgFld_(String v) {trgFld = v; return this;} private String trgFld; - public String TrgFldOrSrcFld() {return trgFld == null ? srcFld : trgFld;} - public static Sql_join_itm new_(String trgFld, String srcTbl, String srcFld) { - Sql_join_itm rv = new Sql_join_itm(); - rv.trgFld = trgFld; rv.srcTbl = srcTbl; rv.srcFld = srcFld; - return rv; - } Sql_join_itm() {} - public static Sql_join_itm same_(String tbl, String fld) { - Sql_join_itm rv = new Sql_join_itm(); - rv.trgFld = fld; rv.srcTbl = tbl; rv.srcFld = fld; - return rv; - } -} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_join_itmType.java b/140_dbs/src/gplx/dbs/sqls/Sql_join_itmType.java deleted file mode 100644 index cddf092f8..000000000 --- a/140_dbs/src/gplx/dbs/sqls/Sql_join_itmType.java +++ /dev/null @@ -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 . -*/ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -public class Sql_join_itmType { - public int Val() {return val;} int val; - public String Name() {return name;} private String name; - Sql_join_itmType(int v, String name) {this.val = v; this.name = name;} - public static final Sql_join_itmType - From = new Sql_join_itmType(0, "FROM") - , Inner = new Sql_join_itmType(1, "INNER JOIN") - , Left = new Sql_join_itmType(2, "LEFT JOIN") - , Right = new Sql_join_itmType(3, "RIGHT JOIN") - , Outer = new Sql_join_itmType(4, "OUTER JOIN") - , Cross = new Sql_join_itmType(5, "CROSS JOIN") - ; -} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr.java b/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr.java index 37c6d268e..f916281ad 100644 --- a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr.java +++ b/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr.java @@ -16,7 +16,8 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -import gplx.core.criterias.*; +import gplx.dbs.sqls.wtrs.*; public interface Sql_qry_wtr { - String Xto_str(Db_qry qry, boolean prepare); + String To_sql_str(Db_qry qry, boolean mode_is_prep); + Sql_schema_wtr Schema_wtr(); } diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_.java b/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_.java index 5ed331cfa..362582ea0 100644 --- a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_.java +++ b/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_.java @@ -16,9 +16,12 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; +import gplx.dbs.sqls.wtrs.*; public class Sql_qry_wtr_ { - public static Sql_qry_wtr new_ansi() {return new Sql_qry_wtr_ansi();} - public static Sql_qry_wtr new_escape_backslash() {return new Sql_qry_wtr_ansi_escape_backslash();} - public static final Sql_qry_wtr Instance = new Sql_qry_wtr_ansi(); - public static String Gen_placeholder_parameters(Db_qry qry) {return Sql_qry_wtr_.Instance.Xto_str(qry, true);} // replace arguments with ?; EX: UPDATE a SET b = ? WHERE c = ?; + public static final Sql_qry_wtr + Basic = new Sql_core_wtr() + , Mysql = new Sql_core_wtr__mysql() + , Sqlite = new Sql_core_wtr__sqlite() + ; + public static String Gen_placeholder_parameters(Db_qry qry) {return Sql_qry_wtr_.Sqlite.To_sql_str(qry, true);} // replace arguments with ?; EX: UPDATE a SET b = ? WHERE c = ?; } diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_ansi.java b/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_ansi.java deleted file mode 100644 index 6e213761f..000000000 --- a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_ansi.java +++ /dev/null @@ -1,300 +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 . -*/ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -import gplx.core.strings.*; import gplx.core.criterias.*; -import gplx.dbs.qrys.*; -public class Sql_qry_wtr_ansi implements Sql_qry_wtr { - private final String_bldr sb = String_bldr_.new_(); - public boolean prepare = false; - public String Xto_str(Db_qry cmd, boolean prepare) { - synchronized (sb) { - this.prepare = prepare; - switch (cmd.Tid()) { - case Db_qry_.Tid_insert: return Bld_qry_insert((Db_qry_insert)cmd); - case Db_qry_.Tid_delete: return Bld_qry_delete((Db_qry_delete)cmd); - case Db_qry_.Tid_update: return Bld_qry_update((Db_qry_update)cmd); - case Db_qry_.Tid_select_in_tbl: - case Db_qry_.Tid_select: return Bld_qry_select((Db_qry__select_cmd)cmd); - case Db_qry_.Tid_sql: return ((Db_qry_sql)cmd).Xto_sql(); - default: throw Err_.new_unhandled(cmd.Tid()); - } - } - } - private String Bld_qry_delete(Db_qry_delete cmd) { - sb.Add_many("DELETE FROM ", cmd.Base_table()); - Bld_where(sb, cmd.Where()); - return sb.To_str_and_clear(); - } - private String Bld_qry_insert(Db_qry_insert cmd) { - if (cmd.Select() != null) { - sb.Add_many("INSERT INTO ", cmd.Base_table(), " ("); - for (int i = 0; i < cmd.Cols().Count(); i++) { - Sql_select_fld_base fld = cmd.Cols().Get_at(i); - sb.Add(fld.Alias()); - sb.Add(i == cmd.Cols().Count() - 1 ? ") " : ", "); - } - sb.Add(Bld_qry_select(cmd.Select())); - return sb.To_str_and_clear(); - } - int arg_count = cmd.Args().Count(); if (arg_count == 0) throw Err_.new_wo_type("Db_qry_insert has no columns", "base_table", cmd.Base_table()); - int last = arg_count - 1; - sb.Add_many("INSERT INTO ", cmd.Base_table(), " ("); - for (int i = 0; i < arg_count; i++) { - KeyVal pair = cmd.Args().Get_at(i); - this.Xto_sql_col(sb, pair.Key_as_obj()); - sb.Add(i == last ? ")" : ", "); - } - sb.Add(" VALUES ("); - for (int i = 0; i < arg_count; i++) { - KeyVal pair = cmd.Args().Get_at(i); - Db_arg arg = (Db_arg)pair.Val(); - this.Bld_val(sb, arg); - sb.Add(i == last ? ")" : ", "); - } - return sb.To_str_and_clear(); - } - private String Bld_qry_update(Db_qry_update cmd) { - int arg_count = cmd.Args().Count(); if (arg_count == 0) throw Err_.new_wo_type("Db_qry_update has no columns", "base_table", cmd.Base_table()); - sb.Add_many("UPDATE ", cmd.Base_table(), " SET "); - for (int i = 0; i < arg_count; i++) { - KeyVal pair = cmd.Args().Get_at(i); - if (i > 0) sb.Add(", "); - this.Xto_sql_col(sb, pair.Key_as_obj()); - sb.Add("="); - this.Bld_val(sb, (Db_arg)pair.Val()); - } - Bld_where(sb, cmd.Where()); - return sb.To_str_and_clear(); - } - private String Bld_qry_select(Db_qry__select_cmd cmd) { - sb.Add("SELECT "); - if (cmd.Cols().Distinct()) sb.Add("DISTINCT "); - Sql_select_fld_list flds = cmd.Cols().Flds(); - if (flds.Count() == 0) sb.Add("*"); - for (int i = 0; i < flds.Count(); i++) { - Sql_select_fld_base fld = (Sql_select_fld_base)flds.Get_at(i); - if (i > 0) sb.Add(", "); - this.Xto_sql_col(sb, fld.XtoSql()); - } - Bld_clause_from(sb, cmd.From()); - Bld_indexed_by(sb, cmd.Indexed_by()); - Bld_where(sb, cmd.Where()); - Bld_select_group_by(sb, cmd.GroupBy()); - Bld_select_order_by(sb, cmd.OrderBy()); - Bld_select_limit(sb, cmd.Limit()); - return sb.To_str_and_clear(); - } - private void Bld_select_group_by(String_bldr sb, Sql_group_by groupBy) { - if (groupBy == null) return; - sb.Add(" GROUP BY "); - for (int i = 0; i < groupBy.Flds().Count(); i++) { - String item = (String)groupBy.Flds().Get_at(i); - if (i > 0) sb.Add(", "); - sb.Add(item); - } - } - private void Bld_select_order_by(String_bldr sb, Sql_order_by orderBy) { - if (orderBy == null) return; - sb.Add(" ORDER BY "); - for (int i = 0; i < orderBy.Flds().Count(); i++) { - Sql_order_by_itm item = (Sql_order_by_itm)orderBy.Flds().Get_at(i); - if (i > 0) sb.Add(", "); - sb.Add(item.XtoSql()); - } - } - private void Bld_select_limit(String_bldr sb, int limit) { - if (limit == Db_qry__select_cmd.Limit_disabled) return; - sb.Add(" LIMIT ").Add(limit); - } - private void Bld_clause_from(String_bldr sb, Sql_from from) { - for (Object tblObj : from.Tbls()) { - Sql_tbl_src tbl = (Sql_tbl_src)tblObj; - sb.Add_many - ( " ", String_.Upper(tbl.JoinType().Name()), " ", tbl.TblName(), String_.FormatOrEmptyStrIfNull(" {0}", tbl.Alias()) - ); - String tblAliasForJoin = tbl.Alias() == null ? tbl.TblName() : tbl.Alias(); - for (int i = 0; i < tbl.JoinLinks().Count(); i++) { - Sql_join_itm joinLink = (Sql_join_itm)tbl.JoinLinks().Get_at(i); - String conjunction = i == 0 ? " ON " : " AND "; - sb.Add_many(conjunction, joinLink.SrcTbl(), ".", joinLink.SrcFld(), "=", tblAliasForJoin, ".", joinLink.TrgFldOrSrcFld()); - } - } - } - private void Bld_indexed_by(String_bldr sb, String idx_name) { - if (idx_name == null) return; - sb.Add(" INDEXED BY ").Add(idx_name); - } - private void Xto_sql_col(String_bldr sb, Object obj) { - if (obj == null) throw Err_.new_null(); - sb.Add_obj(obj); // FIXME: options for bracketing; ex: [name] - } - public void Bld_val(String_bldr sb, Db_arg arg) { - if (prepare) { - sb.Add("?"); - return; - } - Object val = arg.Val(); - if (val == null) { - sb.Add("NULL"); - return; - } - Class val_type = val.getClass(); - if (val_type == Bool_.Cls_ref_type) - sb.Add_obj(Bool_.To_int(Bool_.cast(val))); // NOTE: save boolean to 0 or 1, b/c (a) db may not support bit datatype (sqllite) and (b) avoid i18n issues with "true"/"false" - else if - ( val_type == Byte_.Cls_ref_type || val_type == Short_.Cls_ref_type - || val_type == Int_.Cls_ref_type || val_type == Long_.Cls_ref_type - || val_type == Float_.Cls_ref_type || val_type == Double_.Cls_ref_type - ) - sb.Add(Object_.Xto_str_strict_or_null(val)); - else if (val_type == DateAdp.class) - Bld_val_date(sb, arg, (DateAdp)val); - else if (val_type == Decimal_adp.class) { - Decimal_adp valDecimal = (Decimal_adp)val; - sb.Add(valDecimal.To_str()); - } - else { - String valString = Object_.Xto_str_strict_or_null(val); - Bld_val_str(sb, arg, valString); - } - } - @gplx.Virtual public void Bld_val_str(String_bldr sb, Db_arg arg, String s) { - sb.Add_many("'", String_.Replace(s, "'", "''"), "'"); // stupid escaping of ' - } - @gplx.Virtual public void Bld_val_date(String_bldr sb, Db_arg arg, DateAdp s) { - sb.Add_many("'", s.XtoStr_gplx_long(), "'"); - } - public void Bld_where(String_bldr sb, Criteria crt) { - if (crt == null) return; - if (crt.Tid() == Criteria_.Tid_wrapper) { - Criteria_fld crt_fld = (Criteria_fld)crt; - Criteria crt_inner = crt_fld.Crt(); - switch (crt_inner.Tid()) { - case Criteria_.Tid_const: - case Criteria_.Tid_not: - case Criteria_.Tid_and: - case Criteria_.Tid_or: crt = crt_inner; break; - default: break; - } - } - if (crt.Tid() == Criteria_.Tid_const) return; - sb.Add(" WHERE "); - this.Bld_where_val(sb, crt); - } - public void Bld_where_val(String_bldr sb, Criteria crt) { - if (crt == null) return; // handle empty crt; EX: SELECT * FROM tbl; - Criteria_bool_base crt_bool = Criteria_bool_base.as_(crt); - if (crt_bool != null) { - sb.Add("("); - Bld_where_val(sb, crt_bool.Lhs()); - sb.Add_many(" ", crt_bool.Op_literal(), " "); - Bld_where_val(sb, crt_bool.Rhs()); - sb.Add(")"); - return; - } - if (crt.Tid() == Criteria_.Tid_db_obj_ary) { - Append_db_obj_ary(sb, (Db_obj_ary_crt)crt); - } - else { - Criteria_fld leaf = Criteria_fld.as_(crt); if (leaf == null) throw Err_.new_invalid_op(crt.To_str()); - sb.Add(leaf.Key()); - Bld_where_crt(sb, leaf.Crt()); - } - } - private void Bld_where_crt(String_bldr sb, Criteria crt) { - switch (crt.Tid()) { - case Criteria_.Tid_eq: Bld_where_eq(sb, Criteria_eq.as_(crt)); break; - case Criteria_.Tid_comp: Bld_where_comp(sb, Criteria_comp.as_(crt)); break; - case Criteria_.Tid_between: Bld_where_between(sb, Criteria_between.as_(crt)); break; - case Criteria_.Tid_in: Bld_where_in(sb, Criteria_in.as_(crt)); break; - case Criteria_.Tid_like: Bld_where_like(sb, Criteria_like.as_(crt)); break; - case Criteria_.Tid_iomatch: Bld_where_iomatch(sb, Criteria_ioMatch.as_(crt)); break; - default: throw Err_.new_unhandled(crt); - } - } - private void Bld_where_eq(String_bldr sb, Criteria_eq crt) { - sb.Add(crt.Negated() ? "!=" : "="); - this.Bld_val(sb, Wrap(crt.Val())); - } - private void Bld_where_comp(String_bldr sb, Criteria_comp crt) { - sb.Add_many(crt.XtoSymbol()); - this.Bld_val(sb, Wrap(crt.Val())); - } - private void Bld_where_between(String_bldr sb, Criteria_between crt) { - sb.Add(crt.Negated() ? " NOT BETWEEN " : " BETWEEN "); - this.Bld_val(sb, Wrap(crt.Lhs())); - sb.Add(" AND "); - this.Bld_val(sb, Wrap(crt.Rhs())); - } - private void Bld_where_like(String_bldr sb, Criteria_like crt) { - sb.Add(crt.Negated() ? " NOT LIKE " : " LIKE "); - this.Bld_val(sb, Wrap(crt.Pattern().Raw())); - sb.Add_fmt(" ESCAPE '{0}'", crt.Pattern().Escape()); - } - private void Bld_where_in(String_bldr sb, Criteria_in crt) { - sb.Add(crt.Negated() ? " NOT IN (" : " IN ("); - Object[] crt_vals = crt.Val_as_obj_ary(); - int len = crt_vals.length; - int last = len - 1; - for (int i = 0; i < len; i++) { - Object val = crt_vals[i]; - this.Bld_val(sb, Wrap(val)); - sb.Add(i == last ? ")" : ", "); - } - } - private void Bld_where_iomatch(String_bldr sb, Criteria_ioMatch crt) { - sb.Add(crt.Negated() ? " NOT IOMATCH " : " IOMATCH "); - this.Bld_val(sb, Wrap(crt.Pattern().Raw())); - } - public void Append_db_obj_ary(String_bldr sb, Db_obj_ary_crt crt) { - Object[][] ary = crt.Vals(); - int ary_len = ary.length; - Db_fld[] flds = crt.Flds(); - for (int i = 0; i < ary_len; i++) { - Object[] itm = (Object[])ary[i]; - int itm_len = itm.length; - if (i != 0) sb.Add(" OR "); - sb.Add("("); - for (int j = 0; j < itm_len; j++) { - if (j != 0) sb.Add(" AND "); - Db_fld fld = flds[j]; - Object val = itm[j]; - boolean quote = false; - switch (fld.Type_tid()) { - case Type_adp_.Tid__str: - case Type_adp_.Tid__char: - case Type_adp_.Tid__date: - quote = true; - break; - } - sb.Add(fld.Name()); - sb.Add("="); - if (quote) sb.Add("'"); - sb.Add(Object_.Xto_str_strict_or_empty(val)); - if (quote) sb.Add("'"); - } - sb.Add(")"); - } - } - private Db_arg Wrap(Object val) {return new Db_arg("unknown", val);} -} -class Sql_qry_wtr_ansi_escape_backslash extends Sql_qry_wtr_ansi { @Override public void Bld_val_str(String_bldr sb, Db_arg arg, String s) { - if (String_.Has(s, "\\")) s = String_.Replace(s, "\\", "\\\\"); - super.Bld_val_str(sb, arg, s); - } -} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_tst.java b/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_tst.java deleted file mode 100644 index 675a4255e..000000000 --- a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_tst.java +++ /dev/null @@ -1,60 +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 . -*/ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -import org.junit.*; import gplx.core.strings.*; import gplx.core.criterias.*; import gplx.dbs.qrys.*; -public class Sql_qry_wtr_tst { - private final Sql_qry_wtr_fxt fxt = new Sql_qry_wtr_fxt(); - @Test public void Val() { - fxt.Test_val(null , "NULL"); - fxt.Test_val(true , "1"); - fxt.Test_val(false , "0"); - fxt.Test_val(1 , "1"); - fxt.Test_val(1.1 , "1.1"); - fxt.Test_val("a" , "'a'"); - fxt.Test_val("a'b" , "'a''b'"); - } - @Test public void Where_basic() { - fxt.Test_where(Db_crt_.eq_("id", 1), "id=1"); - fxt.Test_where(Db_crt_.eqn_("id", 1), "id!=1"); - fxt.Test_where(Db_crt_.mt_("id", 1), "id>1"); - fxt.Test_where(Db_crt_.mte_("id", 1), "id>=1"); - fxt.Test_where(Db_crt_.lt_("id", 1), "id<1"); - fxt.Test_where(Db_crt_.lte_("id", 1), "id<=1"); - fxt.Test_where(Db_crt_.between_("id", 1, 2), "id BETWEEN 1 AND 2"); - fxt.Test_where(Db_crt_.in_("id", 1, 2, 3), "id IN (1, 2, 3)"); - } - @Test public void Where_and() { - fxt.Test_where(Criteria_.And(Db_crt_.eq_("id", 1), Db_crt_.eq_("name", "me")), "(id=1 AND name='me')"); - fxt.Test_where(Criteria_.Or(Db_crt_.eq_("id", 1), Db_crt_.eq_("name", "me")), "(id=1 OR name='me')"); - fxt.Test_where(Criteria_.Or(Db_crt_.eq_("id", 1), Criteria_.And(Db_crt_.eq_("name", "me"), Db_crt_.eq_("id", 1))), "(id=1 OR (name='me' AND id=1))"); - } -} -class Sql_qry_wtr_fxt { - private final Sql_qry_wtr_ansi sql_wtr = (Sql_qry_wtr_ansi)Sql_qry_wtr_.new_ansi(); - public void Test_val(Object val, String expd) { - String_bldr sb = String_bldr_.new_(); - Db_arg arg = new Db_arg("not needed", val); - sql_wtr.Bld_val(sb, arg); - Tfds.Eq(expd, sb.To_str()); - } - public void Test_where(Criteria crt, String expd) { - String_bldr sb = String_bldr_.new_(); - sql_wtr.Bld_where_val(sb, crt); - Tfds.Eq(expd, sb.To_str()); - } -} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_select.java b/140_dbs/src/gplx/dbs/sqls/Sql_select.java deleted file mode 100644 index 2470a397d..000000000 --- a/140_dbs/src/gplx/dbs/sqls/Sql_select.java +++ /dev/null @@ -1,30 +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 . -*/ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -import gplx.core.strings.*; -import gplx.dbs.engines.tdbs.*; -public class Sql_select { - public Sql_select_fld_list Flds() {return flds;} Sql_select_fld_list flds = Sql_select_fld_list.new_(); - public boolean Distinct() {return distinct;} public void Distinct_set(boolean v) {distinct = v;} private boolean distinct; - public void Add(String fldName) {flds.Add(Sql_select_fld_.new_fld(Sql_select_fld_base.Tbl_null, fldName, fldName));} - public void Add(String fldName, String alias) {flds.Add(Sql_select_fld_.new_fld(Sql_select_fld_base.Tbl_null, fldName, alias));} - public void Add(Sql_select_fld_base fld) {flds.Add(fld);} - - public static final Sql_select All = all_(); static Sql_select all_() {Sql_select rv = new_(); rv.Add(Sql_select_fld_wild.Instance); return rv;} - public static Sql_select new_() {return new Sql_select();} Sql_select() {} -} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_select_fld_.java b/140_dbs/src/gplx/dbs/sqls/Sql_select_fld_.java deleted file mode 100644 index 8c34888f8..000000000 --- a/140_dbs/src/gplx/dbs/sqls/Sql_select_fld_.java +++ /dev/null @@ -1,70 +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 . -*/ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -import gplx.core.gfo_ndes.*; import gplx.core.type_xtns.*; -public class Sql_select_fld_ { - public static Sql_select_fld_base new_fld(String tbl, String fld, String alias) {return new Sql_select_fld_fld(tbl, fld, alias);} - public static Sql_select_fld_base new_count(String tbl, String fld, String alias) {return new Sql_select_fld_count(tbl, fld, alias);} - public static Sql_select_fld_base new_sum(String tbl, String fld, String alias) {return new Sql_select_fld_sum(tbl, fld, alias);} - public static Sql_select_fld_base new_min(String tbl, String fld, String alias) {return new Sql_select_fld_minMax(CompareAble_.Less, tbl, fld, alias);} - public static Sql_select_fld_base new_max(String tbl, String fld, String alias) {return new Sql_select_fld_minMax(CompareAble_.More, tbl, fld, alias);} -} -class Sql_select_fld_fld extends Sql_select_fld_base { - public Sql_select_fld_fld(String tbl, String fld, String alias) {this.ctor_(tbl, fld, alias);} - @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) {return curVal;} - @Override public void GroupBy_type(GfoFld fld) {this.ValType_set(fld.Type());} - @Override public String XtoSql() { - String rv = Fld(); - if (Tbl() != Tbl_null) - rv = Tbl() + "." + Fld(); - if (!String_.Eq(Alias(), Fld())) - rv = rv + " AS " + Alias(); - return rv; - } -} -class Sql_select_fld_count extends Sql_select_fld_func_base { - public Sql_select_fld_count(String tbl, String fld, String alias) {this.ctor_(tbl, fld, alias);} - @Override public String XtoSql_functionName() {return "COUNT";} - @Override public void GroupBy_type(GfoFld fld) {this.ValType_set(IntClassXtn.Instance);} - @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) { - if (groupByVal == null) return 1; - return Int_.cast(groupByVal) + 1; - } -} -class Sql_select_fld_sum extends Sql_select_fld_func_base { - public Sql_select_fld_sum(String tbl, String fld, String alias) {this.ctor_(tbl, fld, alias);} - @Override public String XtoSql_functionName() {return "SUM";} - @Override public void GroupBy_type(GfoFld fld) {this.ValType_set(IntClassXtn.Instance);} - @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) { - if (groupByVal == null) return Int_.cast(curVal); - return Int_.cast(groupByVal) + Int_.cast(curVal); - } -} -class Sql_select_fld_minMax extends Sql_select_fld_func_base { - private final int compareType; - public Sql_select_fld_minMax(int compareType, String tbl, String fld, String alias) { - this.compareType = compareType; - this.ctor_(tbl, fld, alias); - } - @Override public String XtoSql_functionName() {return compareType == CompareAble_.Less ? "MIN" : "MAX";} - @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) { - if (groupByVal == null) return curVal; - int compareVal = CompareAble_.Compare_obj(curVal, groupByVal); - return compareVal * compareType > 0 ? curVal : groupByVal; - } -} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_select_fld_base.java b/140_dbs/src/gplx/dbs/sqls/Sql_select_fld_base.java deleted file mode 100644 index 8170be88e..000000000 --- a/140_dbs/src/gplx/dbs/sqls/Sql_select_fld_base.java +++ /dev/null @@ -1,46 +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 . -*/ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -import gplx.core.gfo_ndes.*; import gplx.core.type_xtns.*; -public abstract class Sql_select_fld_base { - public String Tbl() {return tbl;} public void Tbl_set(String val) {tbl = val;} private String tbl; - public String Fld() {return fld;} public void Fld_set(String val) {fld = val;} private String fld; - public String Alias() {return alias;} public void Alias_set(String val) {alias = val;} private String alias; - public ClassXtn ValType() {return valType;} public void ValType_set(ClassXtn val) {valType = val;} ClassXtn valType = ObjectClassXtn.Instance; - public abstract Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type); - @gplx.Virtual public void GroupBy_type(GfoFld fld) {this.ValType_set(fld.Type());} - @gplx.Virtual public boolean Type_fld() {return true;} - public abstract String XtoSql(); - public static final String Tbl_null = null; - @gplx.Internal protected void ctor_(String tbl, String fld, String alias) { - Tbl_set(tbl); Fld_set(fld); Alias_set(alias); - } -} -class Sql_select_fld_wild extends Sql_select_fld_base { - @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) {throw Err_.new_wo_type("group by eval not allowed on *");} - @Override public void GroupBy_type(GfoFld fld) {throw Err_.new_wo_type("group by type not allowed on *");} - @Override public String XtoSql() {return "*";} - public static final Sql_select_fld_wild Instance = new Sql_select_fld_wild(); Sql_select_fld_wild() {this.ctor_(Tbl_null, "*", "*");} -} -abstract class Sql_select_fld_func_base extends Sql_select_fld_base { - public abstract String XtoSql_functionName(); - @Override public boolean Type_fld() {return false;} - @Override public String XtoSql() { - return String_.Format("{0}({1}) AS {2}", XtoSql_functionName(), Fld(), Alias()); - } -} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_select_fld_list.java b/140_dbs/src/gplx/dbs/sqls/Sql_select_fld_list.java deleted file mode 100644 index 9ebb23e95..000000000 --- a/140_dbs/src/gplx/dbs/sqls/Sql_select_fld_list.java +++ /dev/null @@ -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 . -*/ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -import gplx.core.strings.*; import gplx.core.gfo_ndes.*; -import gplx.dbs.engines.tdbs.*; -public class Sql_select_fld_list { - public int Count() {return hash.Count();} - public void Add(Sql_select_fld_base fld) {hash.Add(fld.Alias(), fld);} - public Sql_select_fld_base Get_at(int i) {return (Sql_select_fld_base)hash.Get_at(i);} - public Sql_select_fld_base FetchOrNull(String k) {return (Sql_select_fld_base)hash.Get_by(k);} - public GfoFldList XtoGfoFldLst(TdbTable tbl) { - GfoFldList rv = GfoFldList_.new_(); - for (int i = 0; i < this.Count(); i++) { - Sql_select_fld_base selectFld = this.Get_at(i); - GfoFld fld = tbl.Flds().FetchOrNull(selectFld.Fld()); - if (fld == null) throw Err_.new_wo_type("fld not found in tbl", "fldName", selectFld.Fld(), "tblName", tbl.Name(), "tblFlds", tbl.Flds().To_str()); - if (rv.Has(selectFld.Alias())) throw Err_.new_wo_type("alias is not unique", "fldName", selectFld.Fld(), "flds", rv.To_str()); - selectFld.GroupBy_type(fld); - rv.Add(selectFld.Alias(), selectFld.ValType()); - } - return rv; - } - public String[] To_str_ary() { - int len = this.Count(); - String[] rv = new String[len]; - for (int i = 0; i < len; i++) { - Sql_select_fld_base fld = this.Get_at(i); - rv[i] = fld.Fld(); - } - return rv; - } - public String To_str() { - String_bldr sb = String_bldr_.new_(); - for (int i = 0; i < this.Count(); i++) { - Sql_select_fld_base fld = this.Get_at(i); - sb.Add_fmt("{0},{1}|", fld.Fld(), fld.Alias()); - } - return sb.To_str(); - } - Ordered_hash hash = Ordered_hash_.New(); - public static Sql_select_fld_list new_() {return new Sql_select_fld_list();} Sql_select_fld_list() {} -} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_tbl_src.java b/140_dbs/src/gplx/dbs/sqls/Sql_tbl_src.java deleted file mode 100644 index 43f0530e1..000000000 --- a/140_dbs/src/gplx/dbs/sqls/Sql_tbl_src.java +++ /dev/null @@ -1,29 +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 . -*/ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -import gplx.core.strings.*; -public class Sql_tbl_src { - public Sql_join_itmType JoinType() {return type;} public Sql_tbl_src JoinType_(Sql_join_itmType v) {this.type = v; return this;} Sql_join_itmType type = Sql_join_itmType.Inner; - public List_adp JoinLinks() {return joinLinks;} List_adp joinLinks = List_adp_.new_(); - public String TblName() {return tblName;} public Sql_tbl_src TblName_(String s) {tblName = s; return this;} private String tblName; - public String Alias() {return alias;} public Sql_tbl_src Alias_(String s) {alias = s; return this;} private String alias; - public void XtoSql(String_bldr sb) { - sb.Add_many(tblName, alias == null ? "" : " " + alias); - } - public static Sql_tbl_src new_() {return new Sql_tbl_src();} Sql_tbl_src() {} -} diff --git a/140_dbs/src/gplx/dbs/sqls/Db_obj_ary_crt.java b/140_dbs/src/gplx/dbs/sqls/itms/Db_obj_ary_crt.java similarity index 75% rename from 140_dbs/src/gplx/dbs/sqls/Db_obj_ary_crt.java rename to 140_dbs/src/gplx/dbs/sqls/itms/Db_obj_ary_crt.java index d07dde655..f20de7bdd 100644 --- a/140_dbs/src/gplx/dbs/sqls/Db_obj_ary_crt.java +++ b/140_dbs/src/gplx/dbs/sqls/itms/Db_obj_ary_crt.java @@ -15,22 +15,22 @@ 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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; import gplx.core.criterias.*; public class Db_obj_ary_crt implements gplx.core.criterias.Criteria { public byte Tid() {return Criteria_.Tid_db_obj_ary;} - public Db_fld[] Flds() {return flds;} public Db_obj_ary_crt Flds_(Db_fld[] v) {this.flds = v; return this;} private Db_fld[] flds; + public Db_obj_ary_fld[] Flds() {return flds;} public Db_obj_ary_crt Flds_(Db_obj_ary_fld[] v) {this.flds = v; return this;} private Db_obj_ary_fld[] flds; public Object[][] Vals() {return vals;} public void Vals_(Object[][] v) {this.vals = v;} private Object[][] vals; public void Val_from_args(Hash_adp args) {throw Err_.new_unimplemented();} public void Val_as_obj_(Object v) {throw Err_.new_unimplemented();} public boolean Matches(Object obj) {return false;} public String To_str() {return "";} - public static Db_obj_ary_crt new_(Db_fld... flds) {return new Db_obj_ary_crt().Flds_(flds);} + public static Db_obj_ary_crt new_(Db_obj_ary_fld... flds) {return new Db_obj_ary_crt().Flds_(flds);} public static Db_obj_ary_crt new_by_type(byte type_tid, String... names) { int len = names.length; - Db_fld[] flds = new Db_fld[len]; + Db_obj_ary_fld[] flds = new Db_obj_ary_fld[len]; for (int i = 0; i < len; i++) - flds[i] = new Db_fld(names[i], type_tid); + flds[i] = new Db_obj_ary_fld(names[i], type_tid); return new Db_obj_ary_crt().Flds_(flds); } } diff --git a/140_dbs/src/gplx/dbs/sqls/itms/Db_obj_ary_fld.java b/140_dbs/src/gplx/dbs/sqls/itms/Db_obj_ary_fld.java new file mode 100644 index 000000000..2e83549ca --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/itms/Db_obj_ary_fld.java @@ -0,0 +1,23 @@ +/* +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 . +*/ +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Db_obj_ary_fld { + public Db_obj_ary_fld(String name, int type_tid) {this.name = name; this.type_tid = type_tid;} + public String Name() {return name;} public Db_obj_ary_fld Name_(String v) {name = v; return this;} private String name; + public int Type_tid() {return type_tid;} public Db_obj_ary_fld Type_tid_(int v) {type_tid = v; return this;} private int type_tid; +} diff --git a/140_dbs/src/gplx/dbs/sqls/Db_obj_ary_tst.java b/140_dbs/src/gplx/dbs/sqls/itms/Db_obj_ary_tst.java similarity index 72% rename from 140_dbs/src/gplx/dbs/sqls/Db_obj_ary_tst.java rename to 140_dbs/src/gplx/dbs/sqls/itms/Db_obj_ary_tst.java index 0a6c6e0b1..8cc2734d8 100644 --- a/140_dbs/src/gplx/dbs/sqls/Db_obj_ary_tst.java +++ b/140_dbs/src/gplx/dbs/sqls/itms/Db_obj_ary_tst.java @@ -15,8 +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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; import org.junit.*; import gplx.core.strings.*; import gplx.dbs.sqls.*; +import gplx.dbs.sqls.wtrs.*; public class Db_obj_ary_tst { @Before public void init() {} private Db_obj_ary_fxt fxt = new Db_obj_ary_fxt(); @Test public void Int() { @@ -27,16 +28,17 @@ public class Db_obj_ary_tst { } } class Db_obj_ary_fxt { - private Db_obj_ary_crt crt = new Db_obj_ary_crt(); - public Db_obj_ary_fxt Init_fld(String name, int tid) {flds_list.Add(new Db_fld(name, tid)); return this;} private List_adp flds_list = List_adp_.new_(); + private final Db_obj_ary_crt crt = new Db_obj_ary_crt(); + private final Sql_wtr_ctx ctx = new Sql_wtr_ctx(false); + public Db_obj_ary_fxt Init_fld(String name, int tid) {flds_list.Add(new Db_obj_ary_fld(name, tid)); return this;} private List_adp flds_list = List_adp_.new_(); public Db_obj_ary_fxt Init_vals(Object... ary) {vals_list.Add(ary); return this;} private List_adp vals_list = List_adp_.new_(); public Db_obj_ary_fxt Test_sql(String expd) { - Sql_qry_wtr_ansi cmd_wtr = (Sql_qry_wtr_ansi)Sql_qry_wtr_.Instance; - String_bldr sb = String_bldr_.new_(); - crt.Flds_((Db_fld[])flds_list.To_ary_and_clear(Db_fld.class)); + Sql_core_wtr cmd_wtr = (Sql_core_wtr)Sql_qry_wtr_.Basic; + crt.Flds_((Db_obj_ary_fld[])flds_list.To_ary_and_clear(Db_obj_ary_fld.class)); crt.Vals_((Object[][])vals_list.To_ary_and_clear(Object[].class)); - cmd_wtr.Append_db_obj_ary(sb, crt); - Tfds.Eq(expd, sb.To_str_and_clear()); + Bry_bfr bfr = Bry_bfr.new_(); + cmd_wtr.Where_wtr().Bld_where__db_obj(bfr, ctx, crt); + Tfds.Eq(expd, bfr.To_str_and_clear()); return this; } } diff --git a/400_xowa/src/gplx/xowa/specials/search/quicks/Xoa_search_mgr.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_from_itm.java similarity index 70% rename from 400_xowa/src/gplx/xowa/specials/search/quicks/Xoa_search_mgr.java rename to 140_dbs/src/gplx/dbs/sqls/itms/Sql_from_itm.java index c4f39f229..c55acac0b 100644 --- a/400_xowa/src/gplx/xowa/specials/search/quicks/Xoa_search_mgr.java +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_from_itm.java @@ -15,11 +15,12 @@ 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 . */ -package gplx.xowa.specials.search.quicks; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; -public class Xoa_search_mgr { - public Xoa_search_itm[] Search(byte[] search) { - // page_title LIKE 'Ear%' - // page_title LIKE '%Ear%' - return null; +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_from_itm { + public Sql_from_itm(Sql_tbl_itm base_tbl) { + this.Base_tbl = base_tbl; + Tbls.Add(base_tbl); } + public final List_adp Tbls = List_adp_.new_(); + public final Sql_tbl_itm Base_tbl; } diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_group_by.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_group_itm.java similarity index 77% rename from 140_dbs/src/gplx/dbs/sqls/Sql_group_by.java rename to 140_dbs/src/gplx/dbs/sqls/itms/Sql_group_itm.java index 1c2561079..0c40141d6 100644 --- a/140_dbs/src/gplx/dbs/sqls/Sql_group_by.java +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_group_itm.java @@ -15,14 +15,14 @@ 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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -public class Sql_group_by { +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_group_itm { public List_adp Flds() {return flds;} List_adp flds = List_adp_.new_(); - public static Sql_group_by new_(String... ary) { - Sql_group_by rv = new Sql_group_by(); + public static Sql_group_itm new_(String... ary) { + Sql_group_itm rv = new Sql_group_itm(); for (String itm : ary) rv.flds.Add(itm); return rv; - } Sql_group_by() {} + } Sql_group_itm() {} } \ No newline at end of file diff --git a/140_dbs/src/gplx/dbs/sqls/itms/Sql_join_itm.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_join_itm.java new file mode 100644 index 000000000..df91d228d --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_join_itm.java @@ -0,0 +1,30 @@ +/* +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 . +*/ +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_join_itm { + public Sql_join_itm(String trg_fld, String src_tbl, String src_fld) { + this.Trg_fld = trg_fld; + this.Src_tbl = src_tbl; + this.Src_fld = src_fld; + } + public final String Src_tbl; + public final String Src_fld; + public final String Trg_fld; + + public static final Sql_join_itm[] Ary__empty = new Sql_join_itm[0]; +} diff --git a/140_dbs/src/gplx/dbs/sqls/itms/Sql_order_fld.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_order_fld.java new file mode 100644 index 000000000..0c2cb3123 --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_order_fld.java @@ -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 . +*/ +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_order_fld { + public Sql_order_fld(String tbl, String name, byte sort) {this.Tbl = tbl; this.Name = name; this.Sort = sort;} + public final String Tbl; + public final String Name; + public final byte Sort; + public String To_sql() { + String rv = this.Name; + if (Tbl != null) rv = Tbl + "." + rv; + switch (Sort) { + case Sort__asc: rv += " ASC"; break; + case Sort__dsc: rv += " DESC"; break; + case Sort__nil: break; + } + return rv; + } + + public static final String Tbl__null = String_.Null; + public static final byte Sort__asc = Bool_.Y_byte, Sort__dsc = Bool_.N_byte, Sort__nil = Bool_.__byte; +} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_order_by_sorter.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_order_fld_sorter.java similarity index 69% rename from 140_dbs/src/gplx/dbs/sqls/Sql_order_by_sorter.java rename to 140_dbs/src/gplx/dbs/sqls/itms/Sql_order_fld_sorter.java index 49b73eed1..7efc11930 100644 --- a/140_dbs/src/gplx/dbs/sqls/Sql_order_by_sorter.java +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_order_fld_sorter.java @@ -15,26 +15,26 @@ 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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; import gplx.core.gfo_ndes.*; import gplx.core.lists.*; -public class Sql_order_by_sorter implements ComparerAble { +public class Sql_order_fld_sorter implements ComparerAble { public int compare(Object lhsObj, Object rhsObj) { GfoNde lhs = (GfoNde)lhsObj; GfoNde rhs = (GfoNde)rhsObj; - Sql_order_by_itm item = null; Object lhsData = null, rhsData = null; + Sql_order_fld item = null; Object lhsData = null, rhsData = null; for (int i = 0; i < items.length; i++) { item = items[i]; - lhsData = lhs.Read(item.Name()); rhsData = rhs.Read(item.Name()); + lhsData = lhs.Read(item.Name); rhsData = rhs.Read(item.Name); int compare = CompareAble_.Compare_obj(lhsData, rhsData); if (compare == CompareAble_.Same) continue; - int ascendingVal = item.Ascending() ? 1 : -1; + int ascendingVal = item.Sort == Sql_order_fld.Sort__dsc ? -1 : 1; return compare * ascendingVal; } return CompareAble_.Same; } - Sql_order_by_itm[] items; - public static ComparerAble new_(Sql_order_by_itm[] items) { - Sql_order_by_sorter rv = new Sql_order_by_sorter(); + Sql_order_fld[] items; + public static ComparerAble new_(Sql_order_fld[] items) { + Sql_order_fld_sorter rv = new Sql_order_fld_sorter(); rv.items = items; return rv; } diff --git a/140_dbs/src/gplx/dbs/diffs/Gfdb_diff_db.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_order_itm.java similarity index 76% rename from 140_dbs/src/gplx/dbs/diffs/Gfdb_diff_db.java rename to 140_dbs/src/gplx/dbs/sqls/itms/Sql_order_itm.java index b0641f4b0..c3c213b1a 100644 --- a/140_dbs/src/gplx/dbs/diffs/Gfdb_diff_db.java +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_order_itm.java @@ -15,10 +15,8 @@ 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 . */ -package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*; -public class Gfdb_diff_db { - public Gfdb_diff_db(Db_conn conn) { - this.conn = conn; - } - public Db_conn Conn() {return conn;} private final Db_conn conn; +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_order_itm { + public Sql_order_itm(Sql_order_fld[] flds) {this.Flds = flds;} + public final Sql_order_fld[] Flds; } diff --git a/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_fld.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_fld.java new file mode 100644 index 000000000..a085bfdfd --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_fld.java @@ -0,0 +1,63 @@ +/* +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 . +*/ +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import gplx.core.gfo_ndes.*; import gplx.core.type_xtns.*; +public abstract class Sql_select_fld { + public Sql_select_fld(String tbl, String fld, String alias) { + this.Tbl = tbl; this.Fld = fld; this.Alias = alias; + } + public final String Tbl; + public final String Fld; + public final String Alias; + public abstract String To_sql(); + + public static final String Tbl_null = null; + public static Sql_select_fld New_fld (String tbl, String fld, String alias) {return new Sql_select_fld_col(tbl, fld, alias);} + public static Sql_select_fld New_count (String tbl, String fld, String alias) {return new Sql_select_fld_count(tbl, fld, alias);} + public static Sql_select_fld New_sum (String tbl, String fld, String alias) {return new Sql_select_fld_sum(tbl, fld, alias);} + public static Sql_select_fld New_min (String tbl, String fld, String alias) {return new Sql_select_fld_minMax(CompareAble_.Less, tbl, fld, alias);} + public static Sql_select_fld New_max (String tbl, String fld, String alias) {return new Sql_select_fld_minMax(CompareAble_.More, tbl, fld, alias);} + + // tdb related functions + public ClassXtn Val_type() {return val_type;} public void Val_type_(ClassXtn val) {val_type = val;} private ClassXtn val_type = ObjectClassXtn.Instance; + public abstract Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type); + @gplx.Virtual public void GroupBy_type(ClassXtn type) {this.Val_type_(type);} +} +class Sql_select_fld_wild extends Sql_select_fld { Sql_select_fld_wild() {super(Tbl_null, Fld_wildcard, Fld_wildcard);} + @Override public String To_sql() {return Fld_wildcard;} + + public static final Sql_select_fld_wild Instance = new Sql_select_fld_wild(); + public static final String Fld_wildcard = "*"; + + // tdb-related functions + @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) {throw Err_.new_wo_type("group by eval not allowed on *");} + @Override public void GroupBy_type(ClassXtn type) {throw Err_.new_wo_type("group by type not allowed on *");} +} +class Sql_select_fld_col extends Sql_select_fld { public Sql_select_fld_col(String tbl, String fld, String alias) {super(tbl, fld, alias);} + @Override public String To_sql() { + String rv = Fld; + if (this.Tbl != Tbl_null) + rv = this.Tbl + "." + Fld; + if (!String_.Eq(Alias, Fld)) + rv = rv + " AS " + Alias; + return rv; + } + + // tdb-related functions + @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) {return curVal;} +} diff --git a/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_fld_func.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_fld_func.java new file mode 100644 index 000000000..d9394e102 --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_fld_func.java @@ -0,0 +1,52 @@ +/* +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 . +*/ +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import gplx.core.type_xtns.*; +abstract class Sql_select_fld_func extends Sql_select_fld { public Sql_select_fld_func(String tbl, String fld, String alias) {super(tbl, fld, alias);} + public abstract String XtoSql_functionName(); + @Override public String To_sql() { + return String_.Format("{0}({1}) AS {2}", XtoSql_functionName(), Fld, Alias); + } +} +class Sql_select_fld_count extends Sql_select_fld_func { public Sql_select_fld_count(String tbl, String fld, String alias) {super(tbl, fld, alias);} + @Override public String XtoSql_functionName() {return "COUNT";} + @Override public void GroupBy_type(ClassXtn type) {this.Val_type_(IntClassXtn.Instance);} + @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) { + if (groupByVal == null) return 1; + return Int_.cast(groupByVal) + 1; + } +} +class Sql_select_fld_sum extends Sql_select_fld_func { public Sql_select_fld_sum(String tbl, String fld, String alias) {super(tbl, fld, alias);} + @Override public String XtoSql_functionName() {return "SUM";} + @Override public void GroupBy_type(ClassXtn type) {this.Val_type_(IntClassXtn.Instance);} + @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) { + if (groupByVal == null) return Int_.cast(curVal); + return Int_.cast(groupByVal) + Int_.cast(curVal); + } +} +class Sql_select_fld_minMax extends Sql_select_fld_func { private final int compareType; + public Sql_select_fld_minMax(int compareType, String tbl, String fld, String alias) {super(tbl, fld, alias); + this.compareType = compareType; + } + @Override public String XtoSql_functionName() {return compareType == CompareAble_.Less ? "MIN" : "MAX";} + @Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) { + if (groupByVal == null) return curVal; + int compareVal = CompareAble_.Compare_obj(curVal, groupByVal); + return compareVal * compareType > 0 ? curVal : groupByVal; + } +} diff --git a/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_fld_list.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_fld_list.java new file mode 100644 index 000000000..08b554fea --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_fld_list.java @@ -0,0 +1,24 @@ +/* +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 . +*/ +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_select_fld_list { + private final Ordered_hash hash = Ordered_hash_.New(); + public int Len() {return hash.Count();} + public Sql_select_fld Get_at(int i) {return (Sql_select_fld)hash.Get_at(i);} + public void Add(Sql_select_fld fld) {hash.Add(fld.Alias, fld);} +} diff --git a/140_dbs/src/gplx/dbs/sqls/Db_fld.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_itm.java similarity index 63% rename from 140_dbs/src/gplx/dbs/sqls/Db_fld.java rename to 140_dbs/src/gplx/dbs/sqls/itms/Sql_select_itm.java index 6b739e962..825637152 100644 --- a/140_dbs/src/gplx/dbs/sqls/Db_fld.java +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_select_itm.java @@ -15,9 +15,11 @@ 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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -public class Db_fld { - public Db_fld(String name, int type_tid) {this.name = name; this.type_tid = type_tid;} - public String Name() {return name;} public Db_fld Name_(String v) {name = v; return this;} private String name; - public int Type_tid() {return type_tid;} public Db_fld Type_tid_(int v) {type_tid = v; return this;} private int type_tid; +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_select_itm { + public boolean Distinct = false; + public final Sql_select_fld_list Flds = new Sql_select_fld_list(); + + public static final Sql_select_itm All = all_(); + private static Sql_select_itm all_() {Sql_select_itm rv = new Sql_select_itm(); rv.Flds.Add(Sql_select_fld_wild.Instance); return rv;} } diff --git a/140_dbs/src/gplx/dbs/sqls/itms/Sql_tbl_itm.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_tbl_itm.java new file mode 100644 index 000000000..d6bc10c8e --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_tbl_itm.java @@ -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 . +*/ +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_tbl_itm { + public Sql_tbl_itm(int join_tid, String db, String name, String alias, Sql_join_itm[] join_flds) { + this.Join_tid = join_tid; + this.Db = db; + this.Name = name; + this.Alias = alias; + this.Join_flds = join_flds; + } + public final int Join_tid; + public final String Db; + public final String Name; + public final String Alias; + public final Sql_join_itm[] Join_flds; + + public static final String Alias__null = String_.Null; + public static final String Db__null = String_.Null; + public static final int + Tid__from = 0 // "FROM" + , Tid__inner = 1 // "INNER JOIN" + , Tid__left = 2 // "LEFT JOIN" + , Tid__right = 3 // "RIGHT JOIN" + , Tid__outer = 4 // "OUTER JOIN" + , Tid__cross = 5 // "CROSS JOIN" + ; +} diff --git a/140_dbs/src/gplx/dbs/sqls/itms/Sql_where_itm.java b/140_dbs/src/gplx/dbs/sqls/itms/Sql_where_itm.java new file mode 100644 index 000000000..1fb3f3f07 --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/itms/Sql_where_itm.java @@ -0,0 +1,25 @@ +/* +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 . +*/ +package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import gplx.core.criterias.*; +public class Sql_where_itm { + public Criteria Root = Criteria_.All; + public static final Object Where__null = null; + + public static final Sql_where_itm All = new Sql_where_itm(); +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr.java new file mode 100644 index 000000000..725b14f9e --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr.java @@ -0,0 +1,104 @@ +/* +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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import gplx.core.criterias.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.wtrs.*; import gplx.dbs.sqls.itms.*; +public class Sql_core_wtr implements Sql_qry_wtr { + private final Bry_bfr bfr = Bry_bfr.new_(64); + public byte[] Seq__nl = Byte_ascii.Space_bry; + public byte Seq__quote = Byte_ascii.Apos, Seq__escape = Byte_ascii.Backslash; + public Sql_core_wtr() { + this.val_wtr = Make__val_wtr(); + this.from_wtr = Make__from_wtr(); + this.where_wtr = Make__where_wtr(this, val_wtr); + this.select_wtr = Make__select_wtr(this); + this.schema_wtr = Make__schema_wtr(); + } + public Sql_schema_wtr Schema_wtr() {return schema_wtr;} private final Sql_schema_wtr schema_wtr; + public Sql_val_wtr Val_wtr() {return val_wtr;} private final Sql_val_wtr val_wtr; + public Sql_from_wtr From_wtr() {return from_wtr;} private final Sql_from_wtr from_wtr; + public Sql_where_wtr Where_wtr() {return where_wtr;} private final Sql_where_wtr where_wtr; + public Sql_select_wtr Select_wtr() {return select_wtr;} private final Sql_select_wtr select_wtr; + public String To_sql_str(Db_qry qry, boolean mode_is_prep) { + synchronized (bfr) { + Sql_wtr_ctx ctx = new Sql_wtr_ctx(mode_is_prep); + switch (qry.Tid()) { + case Db_qry_.Tid_insert: return Bld_qry_insert(ctx, (Db_qry_insert)qry); + case Db_qry_.Tid_delete: return Bld_qry_delete(ctx, (Db_qry_delete)qry); + case Db_qry_.Tid_update: return Bld_qry_update(ctx, (Db_qry_update)qry); + case Db_qry_.Tid_select_in_tbl: + case Db_qry_.Tid_select: select_wtr.Bld_qry_select(bfr, ctx, (Db_qry__select_cmd)qry); return bfr.To_str_and_clear(); + case Db_qry_.Tid_sql: return ((Db_qry_sql)qry).To_sql__exec(this); + default: throw Err_.new_unhandled(qry.Tid()); + } + } + } + private String Bld_qry_delete(Sql_wtr_ctx ctx, Db_qry_delete qry) { + bfr.Add_str_u8_many("DELETE FROM ", qry.Base_table()); + where_wtr.Bld_where(bfr, ctx, qry.Where()); + return bfr.To_str_and_clear(); + } + private String Bld_qry_insert(Sql_wtr_ctx ctx, Db_qry_insert qry) { + if (qry.Select() != null) { + bfr.Add_str_u8_many("INSERT INTO ", qry.Base_table(), " ("); + int cols_len = qry.Cols().Len(); + for (int i = 0; i < cols_len; i++) { + Sql_select_fld fld = qry.Cols().Get_at(i); + bfr.Add_str_a7(fld.Alias); + bfr.Add_str_a7(i == cols_len - 1 ? ") " : ", "); + } + select_wtr.Bld_qry_select(bfr, ctx, qry.Select()); + return bfr.To_str_and_clear(); + } + int arg_count = qry.Args().Count(); if (arg_count == 0) throw Err_.new_wo_type("Db_qry_insert has no columns", "base_table", qry.Base_table()); + int last = arg_count - 1; + bfr.Add_str_u8_many("INSERT INTO ", qry.Base_table(), " ("); + for (int i = 0; i < arg_count; i++) { + KeyVal pair = qry.Args().Get_at(i); + this.Bld_col_name(bfr, pair.Key()); + bfr.Add_str_a7(i == last ? ")" : ", "); + } + bfr.Add_str_a7(" VALUES ("); + for (int i = 0; i < arg_count; i++) { + KeyVal pair = qry.Args().Get_at(i); + Db_arg arg = (Db_arg)pair.Val(); + val_wtr.Bld_val(bfr, ctx, arg.Val); + bfr.Add_str_a7(i == last ? ")" : ", "); + } + return bfr.To_str_and_clear(); + } + private String Bld_qry_update(Sql_wtr_ctx ctx, Db_qry_update qry) { + int arg_count = qry.Args().Count(); if (arg_count == 0) throw Err_.new_wo_type("Db_qry_update has no columns", "base_table", qry.Base_table()); + bfr.Add_str_u8_many("UPDATE ", qry.Base_table(), " SET "); + for (int i = 0; i < arg_count; i++) { + KeyVal pair = qry.Args().Get_at(i); + if (i > 0) bfr.Add_str_a7(", "); + this.Bld_col_name(bfr, pair.Key()); + bfr.Add_str_a7("="); + Db_arg arg = (Db_arg)pair.Val(); + val_wtr.Bld_val(bfr, ctx, arg.Val); + } + where_wtr.Bld_where(bfr, ctx, qry.Where()); + return bfr.To_str_and_clear(); + } + public void Bld_col_name(Bry_bfr bfr, String key) {bfr.Add_str_u8(key);} + @gplx.Virtual protected Sql_val_wtr Make__val_wtr () {return new Sql_val_wtr();} + @gplx.Virtual protected Sql_from_wtr Make__from_wtr () {return new Sql_from_wtr();} + @gplx.Virtual protected Sql_select_wtr Make__select_wtr(Sql_core_wtr qry_wtr) {return new Sql_select_wtr(qry_wtr);} + @gplx.Virtual protected Sql_where_wtr Make__where_wtr (Sql_core_wtr qry_wtr, Sql_val_wtr val_wtr) {return new Sql_where_wtr(qry_wtr, val_wtr);} + @gplx.Virtual protected Sql_schema_wtr Make__schema_wtr() {return new Sql_schema_wtr();} +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr__mysql.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr__mysql.java new file mode 100644 index 000000000..2df7f725f --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr__mysql.java @@ -0,0 +1,20 @@ +/* +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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_core_wtr__mysql extends Sql_core_wtr { @Override protected Sql_val_wtr Make__val_wtr() {return new Sql_val_wtr_mysql();} +} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_order_by.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr__sqlite.java similarity index 66% rename from 140_dbs/src/gplx/dbs/sqls/Sql_order_by.java rename to 140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr__sqlite.java index a86c9b764..078630125 100644 --- a/140_dbs/src/gplx/dbs/sqls/Sql_order_by.java +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr__sqlite.java @@ -15,14 +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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -public class Sql_order_by { - public List_adp Flds() {return flds;} List_adp flds = List_adp_.new_(); - - public static Sql_order_by new_(Sql_order_by_itm... ary) { - Sql_order_by rv = new Sql_order_by(); - for (Sql_order_by_itm itm : ary) - rv.flds.Add(itm); - return rv; - } Sql_order_by() {} +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_core_wtr__sqlite extends Sql_core_wtr { @Override protected Sql_val_wtr Make__val_wtr() {return new Sql_val_wtr_sqlite();} + @Override protected Sql_select_wtr Make__select_wtr(Sql_core_wtr qry_wtr) {return new Sql_select_wtr_sqlite(qry_wtr);} } diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr_fxt.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr_fxt.java new file mode 100644 index 000000000..42eceb16b --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_core_wtr_fxt.java @@ -0,0 +1,36 @@ +/* +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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import gplx.core.criterias.*; +class Sql_core_wtr_fxt { + private final Sql_core_wtr__sqlite wtr = new Sql_core_wtr__sqlite(); + private final Sql_wtr_ctx ctx = new Sql_wtr_ctx(false); + private final Bry_bfr bfr = Bry_bfr.new_(); + public Sql_core_wtr_fxt Sql_wtr_(Sql_qry_wtr v) {sql_wtr = v; return this;} private Sql_qry_wtr sql_wtr = Sql_qry_wtr_.Sqlite; + public void Test__val(Object val, String expd) { + wtr.Val_wtr().Bld_val(bfr, ctx, val); + Tfds.Eq_str(expd, bfr.To_str_and_clear()); + } + public void Test__where(Criteria crt, String... expd) { + wtr.Where_wtr().Bld_where_elem(bfr, ctx, crt); + Tfds.Eq_str_lines(String_.Concat_lines_nl_skip_last(expd), bfr.To_str_and_clear()); + } + public void Test__qry(Db_qry qry, String expd) { + Tfds.Eq_str_lines(expd, sql_wtr.To_sql_str(qry, Bool_.N)); + } +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_from_wtr.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_from_wtr.java new file mode 100644 index 000000000..61b948341 --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_from_wtr.java @@ -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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import gplx.dbs.sqls.itms.*; +public class Sql_from_wtr { + public void Bld_clause_from(Bry_bfr bfr, Sql_from_itm from) { + List_adp tbls = from.Tbls; int tbls_len = tbls.Count(); + for (int i = 0; i < tbls_len; ++i) { + Sql_tbl_itm tbl = (Sql_tbl_itm)tbls.Get_at(i); + bfr.Add_byte_space().Add_str_a7(Bld_join(tbl.Join_tid)).Add_byte_space(); + if (tbl.Db != Sql_tbl_itm.Db__null) + bfr.Add_str_u8(tbl.Db).Add_byte_dot(); + bfr.Add_str_u8(tbl.Name); + if (tbl.Alias != Sql_tbl_itm.Alias__null) + bfr.Add_byte_space().Add_str_u8(tbl.Alias); + String tbl_alias = tbl.Alias == null ? tbl.Name : tbl.Alias; + Sql_join_itm[] flds = tbl.Join_flds; int flds_len = flds.length; + for (int j = 0; j < flds_len; ++j) { + Sql_join_itm join_fld = flds[j]; + bfr.Add_str_a7(j == 0 ? " ON " : " AND "); + bfr.Add_str_u8(join_fld.Src_tbl).Add_byte_dot().Add_str_u8(join_fld.Src_fld); + bfr.Add(Bry__join_eq); + bfr.Add_str_u8(tbl_alias).Add_byte_dot().Add_str_u8(join_fld.Trg_fld); + } + } + } + private String Bld_join(int tid) { + switch (tid) { + case Sql_tbl_itm.Tid__from : return "FROM"; + case Sql_tbl_itm.Tid__inner : return "INNER JOIN"; + case Sql_tbl_itm.Tid__left : return "LEFT JOIN"; + case Sql_tbl_itm.Tid__right : return "RIGHT JOIN"; + case Sql_tbl_itm.Tid__outer : return "OUTER JOIN"; + case Sql_tbl_itm.Tid__cross : return "CROSS JOIN"; + default : throw Err_.new_unhandled_default(tid); + } + } + private static final byte[] Bry__join_eq = Bry_.new_a7(" = "); +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_from_wtr_tst.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_from_wtr_tst.java new file mode 100644 index 000000000..4b598e83d --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_from_wtr_tst.java @@ -0,0 +1,33 @@ +/* +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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import org.junit.*; +public class Sql_from_wtr_tst { + private final Sql_core_wtr_fxt fxt = new Sql_core_wtr_fxt(); + @Test public void Abrv() { + fxt.Test__qry(Db_qry_.select_().Cols_all_().From_("tbl", "t"), "SELECT * FROM tbl t"); + } + @Test public void Db() { + fxt.Test__qry(Db_qry_.select_().Cols_all_().From_("db", "tbl", "t"), "SELECT * FROM db.tbl t"); + } + @Test public void Join() { + fxt.Test__qry + ( Db_qry_.select_().Cols_all_().From_("src", "s").Join_("trg", "t", Db_qry_.New_join__join("trg_id", "s", "src_id")) + , "SELECT * FROM src s INNER JOIN trg t ON s.src_id = t.trg_id"); + } +} diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_ansi_tst.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_qry_wtr__ansi__tst.java similarity index 64% rename from 140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_ansi_tst.java rename to 140_dbs/src/gplx/dbs/sqls/wtrs/Sql_qry_wtr__ansi__tst.java index 18e197da9..2a74eec7f 100644 --- a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_ansi_tst.java +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_qry_wtr__ansi__tst.java @@ -15,28 +15,28 @@ 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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; import org.junit.*; import gplx.core.criterias.*; import gplx.dbs.sqls.*; -public class Sql_qry_wtr_ansi_tst { - Sql_qry_wtr sqlWtr = Sql_qry_wtr_.new_ansi(); +public class Sql_qry_wtr__ansi__tst { + Sql_qry_wtr sqlWtr = Sql_qry_wtr_.Basic; @Test public void Insert() { tst_XtoSql - ( Db_qry_.insert_("people").Arg_("id", 1).Arg_("name", "me") + ( Db_qry_.insert_("people").Val_int("id", 1).Val_str("name", "me") , "INSERT INTO people (id, name) VALUES (1, 'me')" ); } @Test public void Delete() { - Criteria crt = Db_crt_.eq_("id", 1); + Criteria crt = Db_crt_.New_eq("id", 1); tst_XtoSql ( Db_qry_.delete_("people", crt) - , "DELETE FROM people WHERE id=1" + , "DELETE FROM people WHERE id = 1" ); } @Test public void Update() { tst_XtoSql - ( Db_qry_.update_("people", Db_crt_.eq_("id", 1)).Arg_("name", "me") - , "UPDATE people SET name='me' WHERE id=1" + ( Db_qry_.update_("people", Db_crt_.New_eq("id", 1)).Val_str("name", "me") + , "UPDATE people SET name='me' WHERE id = 1" ); } @Test public void SelectAll() { @@ -53,14 +53,14 @@ public class Sql_qry_wtr_ansi_tst { } @Test public void SelectOrderBy() { tst_XtoSql - ( Db_qry_.select_().From_("people").OrderBy_("name", false) + ( Db_qry_.select_().From_("people").Order_("name", false) , "SELECT * FROM people ORDER BY name DESC" ); } @Test public void SelectWhere() { tst_XtoSql - ( Db_qry_.select_().From_("people").Where_(Db_crt_.eq_("id", 1)) - , "SELECT * FROM people WHERE id=1" + ( Db_qry_.select_().From_("people").Where_(Db_crt_.New_eq("id", 1)) + , "SELECT * FROM people WHERE id = 1" ); } @Test public void Select_From_Alias() { @@ -71,29 +71,29 @@ public class Sql_qry_wtr_ansi_tst { } @Test public void Select_Join_Alias() { tst_XtoSql - ( Db_qry_.select_().From_("people", "p").Join_("roles", "r", Sql_join_itm.same_("p", "id")) - , "SELECT * FROM people p INNER JOIN roles r ON p.id=r.id" + ( Db_qry_.select_().From_("people", "p").Join_("roles", "r", Db_qry_.New_join__same("p", "id")) + , "SELECT * FROM people p INNER JOIN roles r ON p.id = r.id" ); } @Test public void Prepare() { tst_XtoSql - ( Db_qry_.insert_("people").Arg_("id", 1).Arg_("name", "me") + ( Db_qry_.insert_("people").Val_int("id", 1).Val_str("name", "me") , "INSERT INTO people (id, name) VALUES (?, ?)" , true ); tst_XtoSql - ( Db_qry_.delete_("people", Db_crt_.eq_("id", 1)) - , "DELETE FROM people WHERE id=?" + ( Db_qry_.delete_("people", Db_crt_.New_eq("id", 1)) + , "DELETE FROM people WHERE id = ?" , true ); tst_XtoSql - ( Db_qry_.update_("people", Db_crt_.eq_("id", 1)).Arg_("name", "me") - , "UPDATE people SET name=? WHERE id=?" + ( Db_qry_.update_("people", Db_crt_.New_eq("id", 1)).Val_str("name", "me") + , "UPDATE people SET name=? WHERE id = ?" , true ); } void tst_XtoSql(Db_qry cmd, String expd) {tst_XtoSql(cmd, expd, false);} - void tst_XtoSql(Db_qry cmd, String expd, boolean prepare) {Tfds.Eq(expd, sqlWtr.Xto_str(cmd, prepare));} + void tst_XtoSql(Db_qry cmd, String expd, boolean prepare) {Tfds.Eq(expd, sqlWtr.To_sql_str(cmd, prepare));} } diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_iosql_tst.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_qry_wtr__iosql__tst.java similarity index 67% rename from 140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_iosql_tst.java rename to 140_dbs/src/gplx/dbs/sqls/wtrs/Sql_qry_wtr__iosql__tst.java index e47732399..164125396 100644 --- a/140_dbs/src/gplx/dbs/sqls/Sql_qry_wtr_iosql_tst.java +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_qry_wtr__iosql__tst.java @@ -15,46 +15,47 @@ 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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; import org.junit.*; import gplx.core.strings.*; import gplx.core.criterias.*; /*Criteria_base*/ -import gplx.core.ios.*; import gplx.dbs.sqls.*; -public class Sql_qry_wtr_iosql_tst { +import gplx.core.ios.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*; +public class Sql_qry_wtr__iosql__tst { @Test public void Type() { fld = IoItm_base_.Prop_Type; - tst_Write("type=1", ioCrt_(fld, Criteria_.eq_(IoItmDir.Type_Dir))); - tst_Write("type=2", ioCrt_(fld, Criteria_.eq_(IoItmFil.Type_Fil))); + tst_Write("type = 1", ioCrt_(fld, Criteria_.eq_(IoItmDir.Type_Dir))); + tst_Write("type = 2", ioCrt_(fld, Criteria_.eq_(IoItmFil.Type_Fil))); } @Test public void Ext() { fld = IoItm_base_.Prop_Ext; - tst_Write("ext='.txt'", ioCrt_(fld, Criteria_.eq_(".txt"))); + tst_Write("ext = '.txt'", ioCrt_(fld, Criteria_.eq_(".txt"))); tst_Write("ext IN ('.txt', '.xml', '.html')", ioCrt_(fld, Criteria_.in_(".txt", ".xml", ".html"))); tst_Write("ext NOT IN ('.dll', '.exe')", ioCrt_(fld, Criteria_.inn_(".dll", ".exe"))); } @Test public void Title() { fld = IoItm_base_.Prop_Title; - tst_Write("title='bin'", ioCrt_(fld, Criteria_.eq_("bin"))); + tst_Write("title = 'bin'", ioCrt_(fld, Criteria_.eq_("bin"))); tst_Write("title NOT IN ('bin', 'obj')", ioCrt_(fld, Criteria_.inn_("bin", "obj"))); } @Test public void Url() { fld = IoItm_base_.Prop_Path; - tst_Write("url='C:\\fil.txt'", ioCrt_(fld, Criteria_.eq_("C:\\fil.txt"))); + tst_Write("url = 'C:\\fil.txt'", ioCrt_(fld, Criteria_.eq_("C:\\fil.txt"))); tst_Write("url IOMATCH '*.txt'", ioCrt_(fld, Criteria_ioMatch.parse(true, "*.txt", false))); } @Test public void Binary() { // parentheses around lhs and rhs tst_Write( - "(type=1 OR type=2)" + "(type = 1 OR type = 2)" , Criteria_.Or ( ioCrt_(IoItm_base_.Prop_Type, Criteria_.eq_(IoItmDir.Type_Dir)), ioCrt_(IoItm_base_.Prop_Type, Criteria_.eq_(IoItmFil.Type_Fil)) )); } Criteria ioCrt_(String fld, Criteria crt) {return Criteria_fld.new_(fld, crt);} String fld; + private final Sql_wtr_ctx ctx = new Sql_wtr_ctx(false); void tst_Write(String expd, Criteria crt) { - String_bldr sb = String_bldr_.new_(); - Sql_qry_wtr_ansi whereWtr = (Sql_qry_wtr_ansi)Sql_qry_wtr_.new_ansi(); - whereWtr.Bld_where_val(sb, crt); - Tfds.Eq(expd, sb.To_str()); + Sql_where_wtr where_wtr = ((Sql_core_wtr)Sql_qry_wtr_.Basic).Where_wtr(); + Bry_bfr bfr = Bry_bfr.new_(); + where_wtr.Bld_where_elem(bfr, ctx, crt); + Tfds.Eq(expd, bfr.To_str_and_clear()); } } diff --git a/140_dbs/src/gplx/dbs/sqls/Db_sqlbldr__sqlite.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_schema_wtr.java similarity index 90% rename from 140_dbs/src/gplx/dbs/sqls/Db_sqlbldr__sqlite.java rename to 140_dbs/src/gplx/dbs/sqls/wtrs/Sql_schema_wtr.java index db5bb192d..1194cc935 100644 --- a/140_dbs/src/gplx/dbs/sqls/Db_sqlbldr__sqlite.java +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_schema_wtr.java @@ -15,12 +15,11 @@ 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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; 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 class Sql_schema_wtr { + private Bry_bfr tmp_bfr = Bry_bfr.reset_(255); + public Sql_schema_wtr Bfr_(Bry_bfr bfr) {this.tmp_bfr = bfr; return this;} public String Bld_create_idx(Dbmeta_idx_itm idx) { tmp_bfr.Add_str_a7("CREATE "); if (idx.Unique()) @@ -101,5 +100,5 @@ public class Db_sqlbldr__sqlite implements Db_sqlbldr { default: throw Err_.new_unhandled(tid); } } - public static final Db_sqlbldr__sqlite Instance = new Db_sqlbldr__sqlite(); +// public static final Sql_schema_wtr Instance = new Sql_schema_wtr(); } diff --git a/140_dbs/src/gplx/dbs/sqls/Db_sqlbldr_tst.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_schema_wtr_tst.java similarity index 88% rename from 140_dbs/src/gplx/dbs/sqls/Db_sqlbldr_tst.java rename to 140_dbs/src/gplx/dbs/sqls/wtrs/Sql_schema_wtr_tst.java index f997be91b..67167aa9a 100644 --- a/140_dbs/src/gplx/dbs/sqls/Db_sqlbldr_tst.java +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_schema_wtr_tst.java @@ -15,10 +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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; import org.junit.*; -public class Db_sqlbldr_tst { - @Before public void setup() {} private final Db_sqlbldr_fxt fxt = new Db_sqlbldr_fxt(); +public class Sql_schema_wtr_tst { + @Before public void setup() {} private final Sql_schema_wtr_fxt fxt = new Sql_schema_wtr_fxt(); @Test public void Idx_unique() { 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);" @@ -60,8 +60,8 @@ public class Db_sqlbldr_tst { fxt.Test_alter_tbl_add("tbl_name", flds.Get_by("fld_str"), "ALTER TABLE tbl_name ADD fld_str varchar(255) NOT NULL DEFAULT 'a';"); } } -class Db_sqlbldr_fxt { - private Db_sqlbldr__sqlite sqlbldr = Db_sqlbldr__sqlite.Instance; +class Sql_schema_wtr_fxt { + private Sql_schema_wtr sqlbldr = Sql_qry_wtr_.Sqlite.Schema_wtr(); 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));} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_select_wtr.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_select_wtr.java new file mode 100644 index 000000000..fe7f5d90c --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_select_wtr.java @@ -0,0 +1,80 @@ +/* +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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import gplx.dbs.qrys.*; import gplx.dbs.sqls.itms.*; +public class Sql_select_wtr { + private final Sql_core_wtr qry_wtr; + public Sql_select_wtr(Sql_core_wtr qry_wtr) {this.qry_wtr = qry_wtr;} + public void Bld_qry_select(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry) { + bfr.Add_str_a7("SELECT "); + if (qry.Cols().Distinct) bfr.Add_str_a7("DISTINCT "); + Sql_select_fld_list flds = qry.Cols().Flds; + int flds_len = flds.Len(); + if (flds_len == 0) bfr.Add_str_a7("*"); + for (int i = 0; i < flds_len; i++) { + Sql_select_fld fld = (Sql_select_fld)flds.Get_at(i); + if (i > 0) bfr.Add_str_a7(", "); + qry_wtr.Bld_col_name(bfr, fld.To_sql()); + } + qry_wtr.From_wtr().Bld_clause_from(bfr, qry.From()); + Bld_indexed_by(bfr, ctx, qry, qry.Indexed_by()); + qry_wtr.Where_wtr().Bld_where(bfr, ctx, qry.Where_itm()); + Bld_select_group_by(bfr, ctx, qry, qry.GroupBy()); + Bld_select_order_by(bfr, ctx, qry, qry.Order()); + Bld_select_limit(bfr, ctx, qry, qry.Limit()); + if (qry.Offset() != Db_qry__select_cmd.Offset__disabled) + Bld_offset(bfr, ctx, qry, qry.Offset()); + } + private void Bld_select_group_by(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, Sql_group_itm groupBy) { + if (groupBy == null) return; + bfr.Add_str_a7(" GROUP BY "); + for (int i = 0; i < groupBy.Flds().Count(); i++) { + String item = (String)groupBy.Flds().Get_at(i); + if (i > 0) bfr.Add_str_a7(", "); + bfr.Add_str_a7(item); + } + } + private void Bld_select_order_by(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, Sql_order_itm orderBy) { + if (orderBy == null) return; + bfr.Add_str_a7(" ORDER BY "); + int len = orderBy.Flds.length; + for (int i = 0; i < len; ++i) { + Sql_order_fld item = orderBy.Flds[i]; + if (i > 0) bfr.Add_str_a7(", "); + bfr.Add_str_a7(item.To_sql()); + } + } + protected void Bld_select_limit(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, int limit) { + if (limit == Db_qry__select_cmd.Limit__disabled) return; + bfr.Add_str_a7(" LIMIT ").Add_int_variable(limit); + } + @gplx.Virtual protected void Bld_offset(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, int offset) { + bfr.Add_str_a7(" OFFSET ").Add_int_variable(offset); + } + private void Bld_indexed_by(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, String idx_name) { + if (idx_name == null) return; + // ( "SELECT {0}, {1}, {2}, {3} FROM {4} INDEXED BY {4}__title WHERE {1} = {5} AND {2} BETWEEN '{6}' AND '{7}' ORDER BY {3} DESC LIMIT {8};" + bfr.Add_str_a7(" INDEXED BY ").Add_str_a7(idx_name); + } +} +class Sql_select_wtr_sqlite extends Sql_select_wtr { public Sql_select_wtr_sqlite(Sql_core_wtr qry_wtr) {super(qry_wtr);} + @Override protected void Bld_offset(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, int offset) { + if (qry.Limit() == Db_qry__select_cmd.Limit__disabled) Bld_select_limit(bfr, ctx, qry, -1); // SQLite requires a LIMIT if OFFSET is specified + super.Bld_offset(bfr, ctx, qry, offset); + } +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_select_wtr_tst.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_select_wtr_tst.java new file mode 100644 index 000000000..471411478 --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_select_wtr_tst.java @@ -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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import org.junit.*; +public class Sql_select_wtr_tst { + private final Sql_core_wtr_fxt fxt = new Sql_core_wtr_fxt(); + @Test public void Offset__automatically_add_limit() { + fxt.Test__qry(Db_qry_.select_tbl_("tbl").Offset_(1), "SELECT * FROM tbl LIMIT -1 OFFSET 1"); + } + @Test public void Offset__do_not_overwrite_limit() { + fxt.Test__qry(Db_qry_.select_tbl_("tbl").Limit_(20).Offset_(1), "SELECT * FROM tbl LIMIT 20 OFFSET 1"); + } +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_val_wtr.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_val_wtr.java new file mode 100644 index 000000000..8f0db19b6 --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_val_wtr.java @@ -0,0 +1,91 @@ +/* +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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_val_wtr { +// private final Bry_bfr tmp_bfr = Bry_bfr.new_(32); + public byte Seq__quote = Byte_ascii.Apos, Seq__escape = Byte_ascii.Backslash; + public void Bld_val(Bry_bfr bfr, Sql_wtr_ctx ctx, Object val) { + if (ctx.Mode_is_prep) { + bfr.Add_byte(Byte_ascii.Question); + return; + } + if (val == null) { + bfr.Add_str_a7("NULL"); + return; + } + int tid_type = Type_adp_.To_tid_type(val.getClass()); + switch (tid_type) { + case Type_adp_.Tid__bool: Bld_val__bool (bfr, Bool_.cast(val)); break; + case Type_adp_.Tid__byte: Bld_val__byte (bfr, Byte_.cast(val)); break; + case Type_adp_.Tid__short: Bld_val__short (bfr, Short_.cast(val)); break; + case Type_adp_.Tid__int: Bld_val__int (bfr, Int_.cast(val)); break; + case Type_adp_.Tid__long: Bld_val__long (bfr, Long_.cast(val)); break; + case Type_adp_.Tid__float: Bld_val__float (bfr, Float_.cast(val)); break; + case Type_adp_.Tid__double: Bld_val__double (bfr, Double_.cast(val)); break; + case Type_adp_.Tid__decimal: Bld_val__decimal (bfr, Decimal_adp_.cast(val)); break; + case Type_adp_.Tid__str: Bld_val__str (bfr, String_.cast(val)); break; + case Type_adp_.Tid__date: Bld_val__date (bfr, DateAdp_.cast(val)); break; + case Type_adp_.Tid__obj: Bld_val__str (bfr, Object_.Xto_str_strict_or_null(val)); break; + } + } + @gplx.Virtual public void Bld_val__bool (Bry_bfr bfr, boolean val) {bfr.Add_int_digits(1, val ? 1 : 0);} // NOTE: save boolean to 0 or 1 b/c sqlite doesn't support true / false //{bfr.Add_str_a7(val ? "true" : "false");} + @gplx.Virtual public void Bld_val__byte (Bry_bfr bfr, byte val) {bfr.Add_byte_variable(val);} + @gplx.Virtual public void Bld_val__short (Bry_bfr bfr, short val) {bfr.Add_short_variable(val);} + @gplx.Virtual public void Bld_val__int (Bry_bfr bfr, int val) {bfr.Add_int_variable(val);} + @gplx.Virtual public void Bld_val__long (Bry_bfr bfr, long val) {bfr.Add_long_variable(val);} + @gplx.Virtual public void Bld_val__float (Bry_bfr bfr, float val) {bfr.Add_float(val);} + @gplx.Virtual public void Bld_val__double (Bry_bfr bfr, double val) {bfr.Add_double(val);} + @gplx.Virtual public void Bld_val__date (Bry_bfr bfr, DateAdp val) {bfr.Add_str_u8_many("'", val.XtoStr_gplx_long(), "'");} + @gplx.Virtual public void Bld_val__decimal (Bry_bfr bfr, Decimal_adp val) {bfr.Add_str_u8_many("'", val.To_str(), "'");} + @gplx.Virtual public void Bld_val__str (Bry_bfr bfr, String val) { +// byte[] bry = Bry_.new_u8(val); int len = bry.length; int pos = 0; int prv = -1; boolean dirty = false; +// while (true) { +// if (pos == len) break; +// byte b = bry[pos]; +// if (b == Seq__quote) { +// if (!dirty) {dirty = true; if (prv != -1) {tmp_bfr.Add_mid(bry, prv, pos); prv = -1;}} +// tmp_bfr.Add_byte(Seq__quote).Add_byte(Seq__quote); // double-up +// } +//// else if (b == Seq__escape) { +//// if (!dirty) {dirty = true; if (prv != -1) {tmp_bfr.Add_mid(bry, prv, pos); prv = -1;}} +//// tmp_bfr.Add_byte(Seq__escape).Add_byte(Seq__escape); // double-up +//// } +// else +// if (prv == -1) prv = pos; +// ++pos; +// } +// if (dirty && prv != -1) tmp_bfr.Add_mid(bry, prv, len); + + bfr.Add_byte(Seq__quote); + bfr.Add_str_u8(String_.Replace(val, "'", "''")); +// if (dirty) +// bfr.Add_bfr_and_clear(tmp_bfr); +// else +// bfr.Add(bry); + bfr.Add_byte(Seq__quote); + } +} +class Sql_val_wtr_sqlite extends Sql_val_wtr { @Override public void Bld_val__bool(Bry_bfr bfr, boolean val) { + bfr.Add_int_digits(1, val ? 1 : 0); // NOTE: save boolean to 0 or 1 b/c sqlite doesn't support true / false + } +} +class Sql_val_wtr_mysql extends Sql_val_wtr { @Override public void Bld_val__str(Bry_bfr bfr, String val) { + if (String_.Has(val, "\\")) val = String_.Replace(val, "\\", "\\\\"); + super.Bld_val__str(bfr, val); + } +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_val_wtr_tst.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_val_wtr_tst.java new file mode 100644 index 000000000..91a43740a --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_val_wtr_tst.java @@ -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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import org.junit.*; +public class Sql_val_wtr_tst { + private final Sql_core_wtr_fxt fxt = new Sql_core_wtr_fxt(); + @Test public void Null() {fxt.Test__val(null , "NULL");} + @Test public void Bool__n() {fxt.Test__val(Bool_.N , "0");} + @Test public void Bool__y() {fxt.Test__val(Bool_.Y , "1");} + @Test public void Byte() {fxt.Test__val(Byte_.By_int(2) , "2");} + @Test public void Short() {fxt.Test__val(Short_.By_int(3) , "3");} + @Test public void Int() {fxt.Test__val(4 , "4");} + @Test public void Long() {fxt.Test__val(5 , "5");} + @Test public void Float() {fxt.Test__val(6.1f , "6.1");} + @Test public void Double() {fxt.Test__val(7.1d , "7.1");} + @Test public void Decimal() {fxt.Test__val(Decimal_adp_.float_(8) , "'8'");} + @Test public void Str() {fxt.Test__val("abc" , "'abc'");} + @Test public void Str__apos_mid() {fxt.Test__val("a'b" , "'a''b'");} + @Test public void Str__apos_bgn() {fxt.Test__val("'ab" , "'''ab'");} + @Test public void Str__apos_end() {fxt.Test__val("ab'" , "'ab'''");} + @Test public void Str__apos_many() {fxt.Test__val("a'b'c" , "'a''b''c'");} + @Test public void Str__back() {fxt.Test__val("a\\b" , "'a\\b'");} + @Test public void Date() {fxt.Test__val(DateAdp_.parse_gplx("2016-02-03") , "'2016-02-03 00:00:00.000'");} +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_where_wtr.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_where_wtr.java new file mode 100644 index 000000000..0536e3368 --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_where_wtr.java @@ -0,0 +1,145 @@ +/* +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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import gplx.core.criterias.*; import gplx.dbs.sqls.itms.*; +public class Sql_where_wtr { + private final Sql_core_wtr qry_wtr; + private final Sql_val_wtr val_wtr; + public Sql_where_wtr(Sql_core_wtr qry_wtr, Sql_val_wtr val_wtr) {this.qry_wtr = qry_wtr; this.val_wtr = val_wtr;} + public void Bld_where(Bry_bfr bfr, Sql_wtr_ctx ctx, Sql_where_itm where_itm) { + if (where_itm == Sql_where_itm.Where__null) return; + Bld_where(bfr, ctx, where_itm.Root); + } + public void Bld_where(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria crt) { + if (crt == null) return; + if (crt.Tid() == Criteria_.Tid_wrapper) { + Criteria_fld crt_fld = (Criteria_fld)crt; + Criteria crt_inner = crt_fld.Crt(); + switch (crt_inner.Tid()) { + case Criteria_.Tid_const: + case Criteria_.Tid_not: + case Criteria_.Tid_and: + case Criteria_.Tid_or: crt = crt_inner; break; + default: break; + } + } + if (crt.Tid() == Criteria_.Tid_const) return; + bfr.Add_str_a7(" WHERE "); + Bld_where_elem(bfr, ctx, crt); + } + public void Bld_where_elem(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria crt) { + if (crt == null) return; // handle empty crt; EX: SELECT * FROM tbl; + Criteria_bool_base crt_bool = Criteria_bool_base.as_(crt); + if (crt_bool != null) { + bfr.Add_str_a7("("); + Bld_where_elem(bfr, ctx, crt_bool.Lhs()); + bfr.Add_str_u8_many(" ", crt_bool.Op_literal(), " "); + Bld_where_elem(bfr, ctx, crt_bool.Rhs()); + bfr.Add_str_a7(")"); + return; + } + if (crt.Tid() == Criteria_.Tid_db_obj_ary) { + Bld_where__db_obj(bfr, ctx, (Db_obj_ary_crt)crt); + } + else { + Criteria_fld leaf = Criteria_fld.as_(crt); if (leaf == null) throw Err_.new_invalid_op(crt.To_str()); + String leaf_pre = leaf.Pre(); if (leaf_pre != Criteria_fld.Pre_null) bfr.Add_str_u8(leaf_pre).Add_byte_dot(); + qry_wtr.Bld_col_name(bfr, leaf.Key()); + Criteria leaf_crt = leaf.Crt(); + switch (leaf_crt.Tid()) { + case Criteria_.Tid_eq: Bld_where__eq (bfr, ctx, (Criteria_eq)leaf_crt); break; + case Criteria_.Tid_comp: Bld_where__comp (bfr, ctx, (Criteria_comp)leaf_crt); break; + case Criteria_.Tid_between: Bld_where__between (bfr, ctx, (Criteria_between)leaf_crt); break; + case Criteria_.Tid_in: Bld_where__in (bfr, ctx, (Criteria_in)leaf_crt); break; + case Criteria_.Tid_like: Bld_where__like (bfr, ctx, (Criteria_like)leaf_crt); break; + case Criteria_.Tid_iomatch: Bld_where__iomatch (bfr, ctx, (Criteria_ioMatch)leaf_crt); break; + default: throw Err_.new_unhandled(leaf_crt); + } + } + } + private void Bld_where__eq(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_eq crt) { + bfr.Add_str_a7(crt.Neg() ? " != " : " = "); + val_wtr.Bld_val(bfr, ctx, crt.Val()); + } + private void Bld_where__comp(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_comp crt) { + int comp_tid = crt.Comp_mode(); + bfr.Add_byte_space(); + bfr.Add_byte(comp_tid < CompareAble_.Same ? Byte_ascii.Angle_bgn : Byte_ascii.Angle_end); + if (comp_tid % 2 == CompareAble_.Same) bfr.Add_byte_eq(); + bfr.Add_byte_space(); + val_wtr.Bld_val(bfr, ctx, crt.Val()); + } + private void Bld_where__between(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_between crt) { + bfr.Add_str_a7(crt.Neg() ? " NOT BETWEEN " : " BETWEEN "); + val_wtr.Bld_val(bfr, ctx, crt.Lo()); + bfr.Add_str_a7(" AND "); + val_wtr.Bld_val(bfr, ctx, crt.Hi()); + } + private void Bld_where__like(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_like crt) { + bfr.Add_str_a7(crt.Neg() ? " NOT LIKE " : " LIKE "); + val_wtr.Bld_val(bfr, ctx, crt.Pattern().Raw()); + bfr.Add_str_u8(String_.Format(" ESCAPE '{0}'", crt.Pattern().Escape())); + } + private void Bld_where__in(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_in crt) { + bfr.Add_str_a7(crt.Neg() ? " NOT IN " : " IN "); + Object[] ary = crt.Ary(); + int len = crt.Ary_len(); + for (int i = 0; i < len; ++i) { + if (i == 0) + bfr.Add_byte(Byte_ascii.Paren_bgn); + else + bfr.Add_byte(Byte_ascii.Comma).Add_byte_space(); + val_wtr.Bld_val(bfr, ctx, ary[i]); + } + bfr.Add_byte(Byte_ascii.Paren_end); + } + private void Bld_where__iomatch(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_ioMatch crt) { + bfr.Add_str_a7(crt.Neg() ? " NOT IOMATCH " : " IOMATCH "); + val_wtr.Bld_val(bfr, ctx, crt.Pattern().Raw()); + } + public void Bld_where__db_obj(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_obj_ary_crt crt) { + Object[][] ary = crt.Vals(); + int ary_len = ary.length; + Db_obj_ary_fld[] flds = crt.Flds(); + for (int i = 0; i < ary_len; i++) { + Object[] itm = (Object[])ary[i]; + int itm_len = itm.length; + if (i != 0) bfr.Add_str_a7(" OR "); + bfr.Add_str_a7("("); + for (int j = 0; j < itm_len; j++) { + if (j != 0) bfr.Add_str_a7(" AND "); + Db_obj_ary_fld fld = flds[j]; + Object val = itm[j]; + boolean quote = false; + switch (fld.Type_tid()) { + case Type_adp_.Tid__str: + case Type_adp_.Tid__char: + case Type_adp_.Tid__date: + quote = true; + break; + } + bfr.Add_str_a7(fld.Name()); + bfr.Add_str_a7("="); + if (quote) bfr.Add_str_a7("'"); + bfr.Add_str_a7(Object_.Xto_str_strict_or_empty(val)); + if (quote) bfr.Add_str_a7("'"); + } + bfr.Add_str_a7(")"); + } + } +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_where_wtr_tst.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_where_wtr_tst.java new file mode 100644 index 000000000..83d849278 --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_where_wtr_tst.java @@ -0,0 +1,55 @@ +/* +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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +import org.junit.*; import gplx.core.criterias.*; +public class Sql_where_wtr_tst { + private final Sql_core_wtr_fxt fxt = new Sql_core_wtr_fxt(); + @Test public void Eq() {fxt.Test__where(Db_crt_.New_eq ("fld", 1) , "fld = 1");} + @Test public void Eq_not() {fxt.Test__where(Db_crt_.New_eq_not ("fld", 1) , "fld != 1");} + @Test public void Eq_pre() {fxt.Test__where(Db_crt_.New_eq ("a", "fld", 1) , "a.fld = 1");} + @Test public void Lt() {fxt.Test__where(Db_crt_.New_lt ("fld", 1) , "fld < 1");} + @Test public void Lte() {fxt.Test__where(Db_crt_.New_lte ("fld", 1) , "fld <= 1");} + @Test public void Mt() {fxt.Test__where(Db_crt_.New_mt ("fld", 1) , "fld > 1");} + @Test public void Mte() {fxt.Test__where(Db_crt_.New_mte ("fld", 1) , "fld >= 1");} + @Test public void Between() {fxt.Test__where(Db_crt_.New_between ("fld", 1, 3) , "fld BETWEEN 1 AND 3");} + @Test public void In() {fxt.Test__where(Db_crt_.New_in ("fld", 1, 2, 3) , "fld IN (1, 2, 3)");} + @Test public void Like() {fxt.Test__where(Db_crt_.New_like ("fld", "A%") , "fld LIKE 'A%' ESCAPE '|'");} + @Test public void And__subs__2() { + fxt.Test__where + ( Criteria_.And + ( Db_crt_.New_eq("id", 1) + , Db_crt_.New_eq("name", "me") + ), "(id = 1 AND name = 'me')"); + } + @Test public void Or__subs__2() { + fxt.Test__where + ( Criteria_.Or + ( Db_crt_.New_eq("id", 1) + , Db_crt_.New_eq("name", "me") + ), "(id = 1 OR name = 'me')"); + } + @Test public void Nested() { + fxt.Test__where + ( Criteria_.Or + ( Db_crt_.New_eq("id", 1) + , Criteria_.And + ( Db_crt_.New_eq("name", "me") + , Db_crt_.New_eq("id", 2)) + ), "(id = 1 OR (name = 'me' AND id = 2))"); + } +} diff --git a/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_wtr_ctx.java b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_wtr_ctx.java new file mode 100644 index 000000000..1044174ee --- /dev/null +++ b/140_dbs/src/gplx/dbs/sqls/wtrs/Sql_wtr_ctx.java @@ -0,0 +1,22 @@ +/* +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 . +*/ +package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*; +public class Sql_wtr_ctx { + public Sql_wtr_ctx(boolean mode_is_prep) {this.Mode_is_prep = mode_is_prep;} + public final boolean Mode_is_prep; +} diff --git a/140_dbs/src/gplx/dbs/sys/Db_sys_mgr.java b/140_dbs/src/gplx/dbs/sys/Db_sys_mgr.java new file mode 100644 index 000000000..bb9322728 --- /dev/null +++ b/140_dbs/src/gplx/dbs/sys/Db_sys_mgr.java @@ -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 . +*/ +package gplx.dbs.sys; import gplx.*; import gplx.dbs.*; +import gplx.core.primitives.*; +public class Db_sys_mgr { + private final Db_conn conn; + private final Db_sys_tbl sys_tbl; + private boolean assert_exists = true; + public Db_sys_mgr(Db_conn conn) { + this.conn = conn; + sys_tbl = new Db_sys_tbl(conn); + } + public int Autonum_next(String tbl, String fld) {return Autonum_next(String_.Concat(tbl, ".", fld));} + public int Autonum_next(String key) { + if (assert_exists) Assert_exists(); + int rv = sys_tbl.Assert_int_or(key, 1); + sys_tbl.Update_int(key, rv + 1); + return rv; + } + private void Assert_exists() { + assert_exists = false; + if (!conn.Meta_tbl_exists(sys_tbl.Tbl_name())) sys_tbl.Create_tbl(); + } +} diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/randoms/Xob_rnd_cmd.java b/140_dbs/src/gplx/dbs/sys/Db_sys_mgr_tst.java similarity index 52% rename from 400_xowa/src/gplx/xowa/bldrs/cmds/randoms/Xob_rnd_cmd.java rename to 140_dbs/src/gplx/dbs/sys/Db_sys_mgr_tst.java index dc5349362..d94743a03 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/randoms/Xob_rnd_cmd.java +++ b/140_dbs/src/gplx/dbs/sys/Db_sys_mgr_tst.java @@ -15,17 +15,20 @@ 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 . */ -package gplx.xowa.bldrs.cmds.randoms; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.cmds.*; -public class Xob_rnd_cmd implements Xob_cmd { - // private final Xob_bldr bldr; private final Xowe_wiki wiki; - public Xob_rnd_cmd(Xob_bldr bldr, Xowe_wiki wiki) {}//this.bldr = bldr; this.wiki = wiki;} - public String Cmd_key() {return Xob_cmd_keys.Key_util_random;} - public void Cmd_run() { +package gplx.dbs.sys; import gplx.*; import gplx.dbs.*; +import org.junit.*; +public class Db_sys_mgr_tst { + private final Db_sys_mgr_fxt fxt = new Db_sys_mgr_fxt(); + @Test public void FetchNextId() { + fxt.Test__autonum_next("tbl_1.fld", 1); // default to "1" on first creation + fxt.Test__autonum_next("tbl_1.fld", 2); // read "2" from db } - public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return this;} - - public void Cmd_init(Xob_bldr bldr) {} - public void Cmd_bgn(Xob_bldr bldr) {} - public void Cmd_end() {} - public void Cmd_term() {} +} +class Db_sys_mgr_fxt { + private final Db_sys_mgr sys_mgr; + public Db_sys_mgr_fxt() { + Db_conn conn = Db_conn_pool.Instance.Get_or_new(Db_conn_info_.mem_("test")); + sys_mgr = new Db_sys_mgr(conn); + } + public void Test__autonum_next(String key, int expd) {Tfds.Eq_int(expd, sys_mgr.Autonum_next(key));} } diff --git a/140_dbs/src/gplx/dbs/sys/Db_sys_tbl.java b/140_dbs/src/gplx/dbs/sys/Db_sys_tbl.java new file mode 100644 index 000000000..94b86504f --- /dev/null +++ b/140_dbs/src/gplx/dbs/sys/Db_sys_tbl.java @@ -0,0 +1,68 @@ +/* +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 . +*/ +package gplx.dbs.sys; import gplx.*; import gplx.dbs.*; +class Db_sys_tbl implements Rls_able { + private final String tbl_name = "gfdb_sys"; + private String fld_key, fld_val; + private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_(); + private final Db_conn conn; private Db_stmt stmt_insert, stmt_update, stmt_select; + public Db_sys_tbl(Db_conn conn) { + this.conn = conn; + fld_key = flds.Add_str_pkey("sys_key", 255); fld_val = flds.Add_text("sys_val"); + conn.Rls_reg(this); + } + public String Tbl_name() {return tbl_name;} + public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds));} + public int Assert_int_or(String key, int or) { + String rv = Assert_str_or(key, Int_.To_str(or)); + try {return Int_.parse(rv);} + catch (Exception e) {Err_.Noop(e); return or;} + } + public String Assert_str_or(String key, String or) { + if (stmt_select == null) stmt_select = conn.Stmt_select(tbl_name, flds, fld_key); + Db_rdr rdr = stmt_select.Clear().Crt_str(fld_key, key).Exec_select__rls_manual(); + try { + if (rdr.Move_next()) + return rdr.Read_str(fld_val); + else { + Insert_str(key, or); + return or; + } + } finally {rdr.Rls();} + } + public void Update_int(String key, int val) {Update_str(key, Int_.To_str(val));} + private void Update_str(String key, String val) { + if (stmt_update == null) stmt_update = conn.Stmt_update(tbl_name, String_.Ary(fld_key), fld_val); + stmt_update.Clear() + .Val_str(fld_val , val) + .Crt_str(fld_key , key) + .Exec_update(); + } + private void Insert_str(String key, String val) { + if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds); + stmt_insert.Clear() + .Val_str(fld_key , key) + .Val_str(fld_val , val) + .Exec_insert(); + } + public void Rls() { + stmt_insert = Db_stmt_.Rls(stmt_insert); + stmt_update = Db_stmt_.Rls(stmt_update); + stmt_select = Db_stmt_.Rls(stmt_select); + } +} diff --git a/140_dbs/src/gplx/dbs/utls/PoolIds.java b/140_dbs/src/gplx/dbs/utls/PoolIds.java index 43d2dec7a..58464bb87 100644 --- a/140_dbs/src/gplx/dbs/utls/PoolIds.java +++ b/140_dbs/src/gplx/dbs/utls/PoolIds.java @@ -20,11 +20,11 @@ import gplx.core.stores.*; import gplx.dbs.qrys.*; public class PoolIds { public int FetchNext(Db_conn conn, String url) { - Db_qry__select_cmd cmd = Db_qry_.select_().From_(Tbl_Name).Where_(Db_crt_.eq_(Fld_id_path, url)); + Db_qry__select_cmd cmd = Db_qry_.select_().From_(Tbl_Name).Where_(Db_crt_.New_eq(Fld_id_path, url)); int rv = 0;//boolean isNew = true; DataRdr rdr = DataRdr_.Null; try { - rdr = cmd.Exec_qry_as_rdr(conn); + rdr = conn.Exec_qry_as_old_rdr(cmd); if (rdr.MoveNextPeer()) { rv = rdr.ReadInt(Fld_id_next_id); } @@ -39,9 +39,9 @@ public class PoolIds { return rv; } public void Commit(Db_conn conn, String url, int val) { - int rv = conn.Exec_qry(Db_qry_.update_(Tbl_Name, Db_crt_.eq_(Fld_id_path, url)).Arg_(Fld_id_path, url).Arg_(Fld_id_next_id, val)); + int rv = conn.Exec_qry(Db_qry_.update_(Tbl_Name, Db_crt_.New_eq(Fld_id_path, url)).Val_str(Fld_id_path, url).Val_int(Fld_id_next_id, val)); if (rv == 0) { - rv = conn.Exec_qry(Db_qry_.insert_(Tbl_Name).Arg_(Fld_id_path, url).Arg_(Fld_id_next_id, val)); + rv = conn.Exec_qry(Db_qry_.insert_(Tbl_Name).Val_str(Fld_id_path, url).Val_int(Fld_id_next_id, val)); } if (rv != 1) throw Err_.new_wo_type("failed to update nextId", "url", url, "nextId", val); } diff --git a/140_dbs/tst/gplx/dbs/Db_conn_fxt.java b/140_dbs/tst/gplx/dbs/Db_conn_fxt.java index 96227b489..5f5dc5bfe 100644 --- a/140_dbs/tst/gplx/dbs/Db_conn_fxt.java +++ b/140_dbs/tst/gplx/dbs/Db_conn_fxt.java @@ -25,17 +25,17 @@ public class Db_conn_fxt implements Rls_able { public void tst_ExecDml(int expd, Db_qry qry) { int actl = conn.Exec_qry(qry); if (dmlAffectedAvailable) - Tfds.Eq(expd, actl, "Exec_qry failed: sql={0}", qry.Xto_sql()); + Tfds.Eq(expd, actl, "Exec_qry failed: sql={0}", qry.To_sql__exec(conn.Engine().Sql_wtr())); } public void tst_ExecRdrTbl(int expd, String tblName) {tst_ExecRdr(expd, Db_qry_.select_tbl_(tblName));} public void tst_ExecRdr(int expd, Db_qry qry) { DataRdr rdr = DataRdr_.Null; try { - rdr = conn.Exec_qry_as_rdr(qry); + rdr = conn.Exec_qry_as_old_rdr(qry); tbl = GfoNde_.rdr_(rdr); } catch (Exception e) {Err_.Noop(e); rdr.Rls();} - Tfds.Eq(expd, tbl.Subs().Count(), "Exec_qry_as_rdr failed: sql={0}", qry.Xto_sql()); + Tfds.Eq(expd, tbl.Subs().Count(), "Exec_qry_as_rdr failed: sql={0}", qry.To_sql__exec(conn.Engine().Sql_wtr())); } GfoNde tbl; public GfoNde tst_RowAry(int index, Object... expdValAry) { GfoNde record = tbl.Subs().FetchAt_asGfoNde(index); diff --git a/140_dbs/tst/gplx/dbs/engines/db_CrudOps_tst.java b/140_dbs/tst/gplx/dbs/engines/db_CrudOps_tst.java index 8c5df52f2..3cb8c6fb7 100644 --- a/140_dbs/tst/gplx/dbs/engines/db_CrudOps_tst.java +++ b/140_dbs/tst/gplx/dbs/engines/db_CrudOps_tst.java @@ -51,79 +51,79 @@ class CrudOpsFxt { } public void Insert_hook() { this.Init(); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 1).Arg_("name", "John Doe")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 1).Val_str("name", "John Doe")); fx.tst_ExecRdrTbl(1, "dbs_crud_ops"); fx.tst_RowAry(0, 1, "John Doe"); } public void UpdateOne_hook() { this.Init(); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 1).Arg_("name", "John Doe")); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 2).Arg_("name", "John Doe")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 1).Val_str("name", "John Doe")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 2).Val_str("name", "John Doe")); - fx.tst_ExecDml(1, Db_qry_.update_common_("dbs_crud_ops", Db_crt_.eq_("id", 2), KeyVal_.new_("name", "Jane Smith"))); + fx.tst_ExecDml(1, Db_qry_.update_common_("dbs_crud_ops", Db_crt_.New_eq("id", 2), KeyVal_.new_("name", "Jane Smith"))); fx.tst_ExecRdrTbl(2, "dbs_crud_ops"); fx.tst_RowAry(0, 1, "John Doe"); fx.tst_RowAry(1, 2, "Jane Smith"); } public void UpdateMany_hook() { this.Init(); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 1).Arg_("name", "John Doe")); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 2).Arg_("name", "John Doe")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 1).Val_str("name", "John Doe")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 2).Val_str("name", "John Doe")); - fx.tst_ExecDml(2, Db_qry_.update_common_("dbs_crud_ops", Db_crt_.eq_("name", "John Doe"), KeyVal_.new_("name", "Jane Smith"))); + fx.tst_ExecDml(2, Db_qry_.update_common_("dbs_crud_ops", Db_crt_.New_eq("name", "John Doe"), KeyVal_.new_("name", "Jane Smith"))); fx.tst_ExecRdrTbl(2, "dbs_crud_ops"); fx.tst_RowAry(0, 1, "Jane Smith"); fx.tst_RowAry(1, 2, "Jane Smith"); } public void DeleteOne_hook() { this.Init(); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 1).Arg_("name", "John Doe")); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 2).Arg_("name", "Jane Smith")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 1).Val_str("name", "John Doe")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 2).Val_str("name", "Jane Smith")); - fx.tst_ExecDml(1, Db_qry_.delete_("dbs_crud_ops", Db_crt_.eq_("id", 2))); + fx.tst_ExecDml(1, Db_qry_.delete_("dbs_crud_ops", Db_crt_.New_eq("id", 2))); fx.tst_ExecRdrTbl(1, "dbs_crud_ops"); fx.tst_RowAry(0, 1, "John Doe"); } public void DeleteMany_hook() { this.Init(); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 1).Arg_("name", "John Doe")); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 2).Arg_("name", "Jane Smith")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 1).Val_str("name", "John Doe")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 2).Val_str("name", "Jane Smith")); fx.tst_ExecDml(2, Db_qry_.delete_tbl_("dbs_crud_ops")); fx.tst_ExecRdrTbl(0, "dbs_crud_ops"); } public void SelectLike_hook() { this.Init(); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 1).Arg_("name", "John Doe")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 1).Val_str("name", "John Doe")); - fx.tst_ExecRdr(1, Db_qry_.select_cols_("dbs_crud_ops", Db_crt_.like_("name", "John%"))); + fx.tst_ExecRdr(1, Db_qry_.select_cols_("dbs_crud_ops", Db_crt_.New_like("name", "John%"))); fx.tst_RowAry(0, 1, "John Doe"); } public void SelectLikeForFileName_hook() { this.Init(); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 1).Arg_("name", "file%")); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 1).Arg_("name", "file|%")); - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 1).Arg_("name", "file test")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 1).Val_str("name", "file%")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 1).Val_str("name", "file|%")); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 1).Val_str("name", "file test")); - fx.tst_ExecRdr(1, Db_qry_.select_cols_("dbs_crud_ops", Db_crt_.like_("name", "file|%"))); + fx.tst_ExecRdr(1, Db_qry_.select_cols_("dbs_crud_ops", Db_crt_.New_like("name", "file|%"))); fx.tst_RowAry(0, 1, "file%"); } public void InsertUnicode_hook() { this.Init(); String val = "Ω"; - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 3).Arg_obj_type_("name", val, Db_val_type.Tid_nvarchar)); - Db_qry__select_cmd select = Db_qry_.select_val_("dbs_crud_ops", "name", Db_crt_.eq_("id", 3)); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 3).Val_obj_type("name", val, Db_val_type.Tid_nvarchar)); + Db_qry__select_cmd select = Db_qry_.select_val_("dbs_crud_ops", "name", Db_crt_.New_eq("id", 3)); Tfds.Eq(val, ExecRdr_val(select)); - fx.tst_ExecDml(1, Db_qry_.update_("dbs_crud_ops", Db_crt_.Wildcard).Arg_obj_type_("name", val + "a", Db_val_type.Tid_nvarchar)); + fx.tst_ExecDml(1, Db_qry_.update_("dbs_crud_ops", Db_crt_.Wildcard).Val_obj_type("name", val + "a", Db_val_type.Tid_nvarchar)); Tfds.Eq(val + "a", ExecRdr_val(select)); } public void Backslash_hook() { this.Init(); String val = "\\"; - fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Arg_("id", 3).Arg_("name", val)); - Tfds.Eq(val, ExecRdr_val(Db_qry_.select_val_("dbs_crud_ops", "name", Db_crt_.eq_("id", 3)))); - Tfds.Eq(val, ExecRdr_val(Db_qry_.select_val_("dbs_crud_ops", "name", Db_crt_.eq_("name", "\\")))); + fx.tst_ExecDml(1, Db_qry_.insert_("dbs_crud_ops").Val_int("id", 3).Val_str("name", val)); + Tfds.Eq(val, ExecRdr_val(Db_qry_.select_val_("dbs_crud_ops", "name", Db_crt_.New_eq("id", 3)))); + Tfds.Eq(val, ExecRdr_val(Db_qry_.select_val_("dbs_crud_ops", "name", Db_crt_.New_eq("name", "\\")))); } - String ExecRdr_val(Db_qry__select_cmd select) {return (String)select.ExecRdr_val(fx.Conn());} + String ExecRdr_val(Db_qry__select_cmd select) {return (String)Db_qry_.Exec_as_obj(fx.Conn(), select);} } diff --git a/140_dbs/tst/gplx/dbs/engines/db_DataTypes_tst.java b/140_dbs/tst/gplx/dbs/engines/db_DataTypes_tst.java index b2cafa9a5..4eaa796db 100644 --- a/140_dbs/tst/gplx/dbs/engines/db_DataTypes_tst.java +++ b/140_dbs/tst/gplx/dbs/engines/db_DataTypes_tst.java @@ -59,7 +59,7 @@ class DataTypes_base_fxt { conn.Rls_conn(); } public void Select_hook(String floatStr) { - DataRdr rdr = Db_qry_.select_tbl_("dbs_multiple_data_types").Exec_qry_as_rdr(conn); + DataRdr rdr = conn.Exec_qry_as_old_rdr(Db_qry_.select_tbl_("dbs_multiple_data_types")); rdr.MoveNextPeer(); Tfds.Eq(rdr.ReadInt("unique_id"), 1); @@ -70,9 +70,9 @@ class DataTypes_base_fxt { Tfds.Eq_decimal(rdr.ReadDecimal("amount"), Decimal_adp_.parts_(12, 345)); } public void UpdateDate_hook() { - conn.Exec_qry(Db_qry_.update_("dbs_multiple_data_types", Db_crt_.eq_("unique_id", 1)).Arg_obj_("last_update", DateAdpClassXtn.Instance.XtoDb(DateAdp_.parse_gplx("20091115 220000.000")))); + conn.Exec_qry(Db_qry_.update_("dbs_multiple_data_types", Db_crt_.New_eq("unique_id", 1)).Val_obj("last_update", DateAdpClassXtn.Instance.XtoDb(DateAdp_.parse_gplx("20091115 220000.000")))); - DataRdr rdr = Db_qry_.select_tbl_("dbs_multiple_data_types").Exec_qry_as_rdr(conn); + DataRdr rdr = conn.Exec_qry_as_old_rdr(Db_qry_.select_tbl_("dbs_multiple_data_types")); rdr.MoveNextPeer(); Tfds.Eq_date(rdr.ReadDate("last_update"), DateAdp_.parse_gplx("20091115 220000.000")); } diff --git a/140_dbs/tst/gplx/dbs/groupBys/GroupBys_base_tst.java b/140_dbs/tst/gplx/dbs/groupBys/GroupBys_base_tst.java index 247993611..2e1f460b7 100644 --- a/140_dbs/tst/gplx/dbs/groupBys/GroupBys_base_tst.java +++ b/140_dbs/tst/gplx/dbs/groupBys/GroupBys_base_tst.java @@ -28,31 +28,31 @@ public abstract class GroupBys_base_tst { conn.Rls_conn(); } protected void GroupBy_1fld_hook() { - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 1)); - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 2)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 1)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 2)); - DataRdr rdr = Db_qry_.select_().From_("dbs_group_bys") + DataRdr rdr = conn.Exec_qry_as_old_rdr + (Db_qry_.select_().From_("dbs_group_bys") .Cols_("key1") - .GroupBy_("key1") - .Exec_qry_as_rdr(conn); + .GroupBy_("key1")); GfoNde nde = GfoNde_.rdr_(rdr); GfoNdeTstr.tst_ValsByCol(nde, "key1", "a"); } protected void GroupBy_2fld_hook() { - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("key2", "b").Arg_("val_int", 1)); - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("key2", "b").Arg_("val_int", 2)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_str("key2", "b").Val_int("val_int", 1)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_str("key2", "b").Val_int("val_int", 2)); - DataRdr rdr = Db_qry_.select_().From_("dbs_group_bys") + DataRdr rdr = conn.Exec_qry_as_old_rdr + (Db_qry_.select_().From_("dbs_group_bys") .Cols_("key1", "key2") - .GroupBy_("key1", "key2") - .Exec_qry_as_rdr(conn); + .GroupBy_("key1", "key2")); GfoNde nde = GfoNde_.rdr_(rdr); GfoNdeTstr.tst_ValsByCol(nde, "key1", "a"); GfoNdeTstr.tst_ValsByCol(nde, "key2", "b"); } protected void MinMax_hook(boolean min) { - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 1)); - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 2)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 1)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 2)); Db_qry__select_cmd qry = Db_qry_.select_().From_("dbs_group_bys") .Cols_("key1") @@ -63,31 +63,31 @@ public abstract class GroupBys_base_tst { else qry.Cols_groupBy_max("val_int", "val_int_func"); - DataRdr rdr = qry.Exec_qry_as_rdr(conn); + DataRdr rdr = conn.Exec_qry_as_old_rdr(qry); GfoNde nde = GfoNde_.rdr_(rdr); GfoNdeTstr.tst_ValsByCol(nde, "key1", "a"); GfoNdeTstr.tst_ValsByCol(nde, "val_int_func", expd); } protected void Count_hook() { - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 10)); - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 20)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 10)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 20)); - DataRdr rdr = Db_qry_.select_().From_("dbs_group_bys") + DataRdr rdr = conn.Exec_qry_as_old_rdr + (Db_qry_.select_().From_("dbs_group_bys") .Cols_("key1").Cols_groupBy_count("val_int", "val_int_func") - .GroupBy_("key1") - .Exec_qry_as_rdr(conn); + .GroupBy_("key1")); GfoNde nde = GfoNde_.rdr_(rdr); GfoNdeTstr.tst_ValsByCol(nde, "key1", "a"); GfoNdeTstr.tst_ValsByCol(nde, "val_int_func", 2); } protected void Sum_hook() { - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 10)); - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 20)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 10)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 20)); - DataRdr rdr = Db_qry_.select_().From_("dbs_group_bys") + DataRdr rdr = conn.Exec_qry_as_old_rdr + (Db_qry_.select_().From_("dbs_group_bys") .Cols_("key1").Cols_groupBy_sum("val_int", "val_int_func") - .GroupBy_("key1") - .Exec_qry_as_rdr(conn); + .GroupBy_("key1")); GfoNde nde = GfoNde_.rdr_(rdr); GfoNdeTstr.tst_ValsByCol(nde, "key1", "a"); GfoNdeTstr.tst_ValsByCol(nde, "val_int_func", 30); diff --git a/140_dbs/tst/gplx/dbs/insertIntos/InsertIntos_base_tst.java b/140_dbs/tst/gplx/dbs/insertIntos/InsertIntos_base_tst.java index 8c7cc032c..c74bbd2c5 100644 --- a/140_dbs/tst/gplx/dbs/insertIntos/InsertIntos_base_tst.java +++ b/140_dbs/tst/gplx/dbs/insertIntos/InsertIntos_base_tst.java @@ -29,31 +29,31 @@ public abstract class InsertIntos_base_tst { conn.Rls_conn(); } protected void Select_hook() { - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 1)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 1)); conn.Exec_qry (Db_qry_.insert_("dbs_insert_intos") .Cols_("key1", "val_int") .Select_ - ( Db_qry__select_cmd.new_().Cols_("key1", "val_int").From_("dbs_group_bys") + ( new Db_qry__select_cmd().Cols_("key1", "val_int").From_("dbs_group_bys") ) ); - DataRdr rdr = conn.Exec_qry_as_rdr(Db_qry__select_cmd.new_().Cols_("key1", "val_int").From_("dbs_insert_intos")); + DataRdr rdr = conn.Exec_qry_as_old_rdr(new Db_qry__select_cmd().Cols_("key1", "val_int").From_("dbs_insert_intos")); GfoNde nde = GfoNde_.rdr_(rdr); GfoNdeTstr.tst_ValsByCol(nde, "key1", "a"); } protected void GroupBy_hook() { - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 1)); - conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Arg_("key1", "a").Arg_("val_int", 2)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 1)); + conn.Exec_qry(Db_qry_.insert_("dbs_group_bys").Val_str("key1", "a").Val_int("val_int", 2)); conn.Exec_qry (Db_qry_.insert_("dbs_insert_intos") .Cols_("key1", "val_int") .Select_ - ( Db_qry__select_cmd.new_().Cols_("key1").Cols_groupBy_sum("val_int", "val_int_func") + ( new Db_qry__select_cmd().Cols_("key1").Cols_groupBy_sum("val_int", "val_int_func") .From_("dbs_group_bys").GroupBy_("key1") )); - DataRdr rdr = conn.Exec_qry_as_rdr(Db_qry__select_cmd.new_().Cols_("key1", "val_int").From_("dbs_insert_intos")); + DataRdr rdr = conn.Exec_qry_as_old_rdr(new Db_qry__select_cmd().Cols_("key1", "val_int").From_("dbs_insert_intos")); GfoNde nde = GfoNde_.rdr_(rdr); GfoNdeTstr.tst_ValsByCol(nde, "val_int", 3); } diff --git a/140_dbs/tst/gplx/dbs/joins/Joins_base_tst.java b/140_dbs/tst/gplx/dbs/joins/Joins_base_tst.java index e9e2adf67..a3fad16ad 100644 --- a/140_dbs/tst/gplx/dbs/joins/Joins_base_tst.java +++ b/140_dbs/tst/gplx/dbs/joins/Joins_base_tst.java @@ -28,13 +28,13 @@ public abstract class Joins_base_tst { conn.Rls_conn(); } protected void InnerJoin_hook() { - conn.Exec_qry(new Db_qry_insert("dbs_crud_ops").Arg_("id", 0).Arg_("name", "me")); - conn.Exec_qry(new Db_qry_insert("dbs_crud_ops").Arg_("id", 1).Arg_("name", "you")); - conn.Exec_qry(new Db_qry_insert("dbs_join1").Arg_("join_id", 0).Arg_("join_data", "data0")); - conn.Exec_qry(new Db_qry_insert("dbs_join1").Arg_("join_id", 1).Arg_("join_data", "data1")); - Db_qry__select_cmd select = Db_qry__select_cmd.new_().From_("dbs_crud_ops").Join_("dbs_join1", "j1", Sql_join_itm.new_("join_id", "dbs_crud_ops", "id")).Cols_("id", "name", "join_data"); + conn.Exec_qry(new Db_qry_insert("dbs_crud_ops").Val_int("id", 0).Val_str("name", "me")); + conn.Exec_qry(new Db_qry_insert("dbs_crud_ops").Val_int("id", 1).Val_str("name", "you")); + conn.Exec_qry(new Db_qry_insert("dbs_join1").Val_int("join_id", 0).Val_str("join_data", "data0")); + conn.Exec_qry(new Db_qry_insert("dbs_join1").Val_int("join_id", 1).Val_str("join_data", "data1")); + Db_qry__select_cmd select = new Db_qry__select_cmd().From_("dbs_crud_ops").Join_("dbs_join1", "j1", Db_qry_.New_join__join("join_id", "dbs_crud_ops", "id")).Cols_("id", "name", "join_data"); - DataRdr rdr = conn.Exec_qry_as_rdr(select); + DataRdr rdr = conn.Exec_qry_as_old_rdr(select); GfoNde table = GfoNde_.rdr_(rdr); Tfds.Eq(table.Subs().Count(), 2); Tfds.Eq(table.Subs().FetchAt_asGfoNde(0).Read("join_data"), "data0"); diff --git a/140_dbs/tst/gplx/dbs/orderBys/OrderBys_base_tst.java b/140_dbs/tst/gplx/dbs/orderBys/OrderBys_base_tst.java index e7848c2f7..94a4a6899 100644 --- a/140_dbs/tst/gplx/dbs/orderBys/OrderBys_base_tst.java +++ b/140_dbs/tst/gplx/dbs/orderBys/OrderBys_base_tst.java @@ -26,26 +26,26 @@ public abstract class OrderBys_base_tst { @After public void teardown() {conn.Rls_conn();} protected abstract Db_conn provider_(); protected Db_conn conn; protected void Basic_hook() { - fx.tst_ExecDml(1, new Db_qry_insert("dbs_crud_ops").Arg_("id", 1).Arg_("name", "you")); - fx.tst_ExecDml(1, new Db_qry_insert("dbs_crud_ops").Arg_("id", 0).Arg_("name", "me")); + fx.tst_ExecDml(1, new Db_qry_insert("dbs_crud_ops").Val_int("id", 1).Val_str("name", "you")); + fx.tst_ExecDml(1, new Db_qry_insert("dbs_crud_ops").Val_int("id", 0).Val_str("name", "me")); - fx.tst_ExecRdr(2, Db_qry__select_cmd.new_().From_("dbs_crud_ops").OrderBy_("id", true)); + fx.tst_ExecRdr(2, new Db_qry__select_cmd().From_("dbs_crud_ops").Order_("id", true)); fx.tst_RowAry(0, 0, "me"); fx.tst_RowAry(1, 1, "you"); - fx.tst_ExecRdr(2, Db_qry__select_cmd.new_().From_("dbs_crud_ops").OrderBy_("id", false)); + fx.tst_ExecRdr(2, new Db_qry__select_cmd().From_("dbs_crud_ops").Order_("id", false)); fx.tst_RowAry(0, 1, "you"); fx.tst_RowAry(1, 0, "me"); } protected void SameVals_hook() { - fx.tst_ExecDml(1, new Db_qry_insert("dbs_crud_ops").Arg_("id", 0).Arg_("name", "me")); - fx.tst_ExecDml(1, new Db_qry_insert("dbs_crud_ops").Arg_("id", 0).Arg_("name", "you")); + fx.tst_ExecDml(1, new Db_qry_insert("dbs_crud_ops").Val_int("id", 0).Val_str("name", "me")); + fx.tst_ExecDml(1, new Db_qry_insert("dbs_crud_ops").Val_int("id", 0).Val_str("name", "you")); - fx.tst_ExecRdr(2, Db_qry__select_cmd.new_().From_("dbs_crud_ops").OrderBy_("id", true)); + fx.tst_ExecRdr(2, new Db_qry__select_cmd().From_("dbs_crud_ops").Order_("id", true)); fx.tst_RowAry(0, 0, "me"); fx.tst_RowAry(1, 0, "you"); - fx.tst_ExecRdr(2, Db_qry__select_cmd.new_().From_("dbs_crud_ops").OrderBy_("id", false)); + fx.tst_ExecRdr(2, new Db_qry__select_cmd().From_("dbs_crud_ops").Order_("id", false)); fx.tst_RowAry(0, 0, "me"); fx.tst_RowAry(1, 0, "you"); } diff --git a/400_xowa/src/gplx/dbs/Db_diff_bldr.java b/400_xowa/src/gplx/dbs/Db_diff_bldr.java index bb7a93c07..a617dc82a 100644 --- a/400_xowa/src/gplx/dbs/Db_diff_bldr.java +++ b/400_xowa/src/gplx/dbs/Db_diff_bldr.java @@ -16,10 +16,10 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.dbs; import gplx.*; -import gplx.dbs.metas.*; import gplx.dbs.sqls.*; +import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*; class Db_diff_bldr { private final Bry_bfr bfr = Bry_bfr.new_(); - private final Db_sqlbldr__sqlite sql_bldr = new Db_sqlbldr__sqlite(); + private final Sql_schema_wtr sql_bldr = new Sql_schema_wtr(); public Db_diff_bldr() {sql_bldr.Bfr_(bfr);} public String Compare_db(String src_str, String trg_str) { // Io_url src_url = Io_url_.new_fil_(src_str); diff --git a/400_xowa/src/gplx/fsdb/data/Fsd_fil_tbl.java b/400_xowa/src/gplx/fsdb/data/Fsd_fil_tbl.java index f474f7e23..8d6823828 100644 --- a/400_xowa/src/gplx/fsdb/data/Fsd_fil_tbl.java +++ b/400_xowa/src/gplx/fsdb/data/Fsd_fil_tbl.java @@ -76,7 +76,7 @@ public class Fsd_fil_tbl implements Rls_able { } public Fsd_fil_itm Select_or_null(int dir_id, byte[] fil_name) { if (stmt_select_by_name == null) { - Db_qry__select_cmd qry = Db_qry__select_cmd.new_().From_(tbl_name).Cols_(flds.To_str_ary()).Where_(Db_crt_.eq_many_(fld_owner_id, fld_name)).Indexed_by_(idx_owner); + Db_qry__select_cmd qry = new Db_qry__select_cmd().From_(tbl_name).Cols_(flds.To_str_ary()).Where_(Db_crt_.eq_many_(fld_owner_id, fld_name)).Indexed_by_(idx_owner); stmt_select_by_name = conn.Stmt_new(qry); } Db_rdr rdr = stmt_select_by_name.Clear() diff --git a/400_xowa/src/gplx/xowa/Xoa_app_.java b/400_xowa/src/gplx/xowa/Xoa_app_.java index 8da0cec7e..688592fbc 100644 --- a/400_xowa/src/gplx/xowa/Xoa_app_.java +++ b/400_xowa/src/gplx/xowa/Xoa_app_.java @@ -34,7 +34,7 @@ public class Xoa_app_ { } } public static final String Name = "xowa"; - public static final String Version = "3.1.5.1"; + public static final String Version = "3.2.1.1"; public static String Build_date = "2012-12-30 00:00:00"; public static String Op_sys_str; public static String User_agent = ""; diff --git a/400_xowa/src/gplx/xowa/Xoa_test_.java b/400_xowa/src/gplx/xowa/Xoa_test_.java index 1d6728c3f..6cb69a06a 100644 --- a/400_xowa/src/gplx/xowa/Xoa_test_.java +++ b/400_xowa/src/gplx/xowa/Xoa_test_.java @@ -45,6 +45,18 @@ public class Xoa_test_ { Db_conn_bldr.Instance.Reg_default_sqlite(); } } + public static String Db__print_tbl_as_str(Bry_bfr bfr, Db_conn conn, String tbl, String... cols) { + int cols_len = cols.length; + Db_rdr rdr = conn.Stmt_select(tbl, cols).Exec_select__rls_auto(); + while (rdr.Move_next()) { + for (int i = 0; i < cols_len; ++i) { + bfr.Add_obj(rdr.Read_at(i)); + bfr.Add_byte(i == cols_len - 1 ? Byte_ascii.Nl : Byte_ascii.Pipe); + } + } + rdr.Rls(); + return bfr.To_str_and_clear(); + } public static void Inet__init() { Gfo_inet_conn_.new_prototype_(Gfo_inet_conn_.Tid__mem__hash); } diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_parse_all_src_sql.java b/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_parse_all_src_sql.java index 1a8dda740..adb4d84ea 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_parse_all_src_sql.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/Xob_parse_all_src_sql.java @@ -49,7 +49,7 @@ class Xob_dump_src_id { cur_text_db_idx = text_db_idx; Xowd_db_file text_db = db_mgr.Core_data_mgr().Dbs__get_at(text_db_idx); Db_conn conn = text_db.Conn(); - String sql = String_.Format(Sql_select, New_rdr__redirect_clause(redirect)); + String sql = String_.Format(Sql_select_itm, New_rdr__redirect_clause(redirect)); text_stmt = conn.Stmt_new(Db_qry_sql.rdr_(sql)); } return text_stmt.Clear().Val_int(prv_id).Val_int(cur_ns).Exec_select(); @@ -75,7 +75,7 @@ class Xob_dump_src_id { default: throw Err_.new_unhandled(redirect); } } - private static final String Sql_select = String_.Concat_lines_nl + private static final String Sql_select_itm = String_.Concat_lines_nl ( "SELECT p.page_id" , ", p.page_title" , ", t.text_data" diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_categorylinks_sql_tst.java b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_categorylinks_sql_tst.java index 9f59a854d..b50c19c2d 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_categorylinks_sql_tst.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/ctgs/Xob_categorylinks_sql_tst.java @@ -96,7 +96,7 @@ class Db_tst_qry { DataRdr rdr = DataRdr_.Null; Bry_bfr bfr = Bry_bfr.new_(); try { - rdr = conn.Exec_qry_as_rdr(qry); + rdr = conn.Exec_qry_as_old_rdr(qry); int expd_row_idx = 0, expd_row_max = rows.Count(); while (rdr.MoveNextPeer()) { if (expd_row_idx == expd_row_max) break; @@ -127,11 +127,11 @@ class Db_tst_qry { } if (!pass) { bfr.Add(Lbl_row_hdr).Add_int_variable(expd_row_idx).Add_byte_nl(); - bfr.Add_str_u8(qry.Xto_sql()).Add_byte(Byte_ascii.Semic); + bfr.Add_str_u8(qry.To_sql__exec(gplx.dbs.sqls.Sql_qry_wtr_.Sqlite)).Add_byte(Byte_ascii.Semic); throw Err_.new_wo_type(bfr.To_str_and_clear()); } } static final byte[] Lbl_row_hdr = Bry_.new_a7("row: "), Lbl_eq_y = Bry_.new_a7(" == "), Lbl_eq_n = Bry_.new_a7(" != "); - public static Db_tst_qry tbl_(String tbl_name, String order_by) {return new_(Db_qry_.select_tbl_(tbl_name).OrderBy_asc_(order_by));} + public static Db_tst_qry tbl_(String tbl_name, String order_by) {return new_(Db_qry_.select_tbl_(tbl_name).Order_asc_(order_by));} public static Db_tst_qry new_(Db_qry qry) { Db_tst_qry rv = new Db_tst_qry(); rv.qry = qry; diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xob_diff_build_cmd.java b/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xob_diff_build_cmd.java index 50386e344..65f157e08 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xob_diff_build_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xob_diff_build_cmd.java @@ -19,16 +19,19 @@ package gplx.xowa.bldrs.cmds.diffs; import gplx.*; import gplx.xowa.*; import gp public class Xob_diff_build_cmd implements Xob_cmd { private final Xob_bldr bldr; private final Xowe_wiki wiki; private String prev_url, curr_url, diff_url; private int commit_interval; + private int[] db_ids = Int_.Ary_empty; private String bld_name = "all"; public Xob_diff_build_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.bldr = bldr; this.wiki = wiki;} public String Cmd_key() {return Xob_cmd_keys.Key_diff_build;} public void Cmd_run() { - new Xob_diff_build_wkr(bldr, wiki, prev_url, curr_url, diff_url, commit_interval).Exec(); + new Xob_diff_build_wkr(bldr, wiki, prev_url, curr_url, diff_url, commit_interval, new Xowd_tbl_mapr(bld_name, db_ids)).Exec(); } public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk__prev_url_)) prev_url = m.ReadStr("v"); else if (ctx.Match(k, Invk__curr_url_)) curr_url = m.ReadStr("v"); else if (ctx.Match(k, Invk__diff_url_)) diff_url = m.ReadStr("v"); else if (ctx.Match(k, Invk__commit_interval_)) commit_interval = m.ReadInt("v"); + else if (ctx.Match(k, Invk__db_ids_)) db_ids = Int_.Ary_parse(m.ReadStr("v"), "|"); + else if (ctx.Match(k, Invk__bld_name_)) bld_name = m.ReadStr("v"); else return GfoInvkAble_.Rv_unhandled; return this; } @@ -36,5 +39,6 @@ public class Xob_diff_build_cmd implements Xob_cmd { public void Cmd_bgn(Xob_bldr bldr) {} public void Cmd_end() {} public void Cmd_term() {} - private static final String Invk__prev_url_ = "prev_url_", Invk__curr_url_ = "curr_url_", Invk__diff_url_ = "diff_url_", Invk__commit_interval_ = "commit_interval_"; + private static final String Invk__prev_url_ = "prev_url_", Invk__curr_url_ = "curr_url_", Invk__diff_url_ = "diff_url_" + , Invk__commit_interval_ = "commit_interval_", Invk__db_ids_ = "db_ids_", Invk__bld_name_ = "bld_name_"; } diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xob_diff_build_wkr.java b/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xob_diff_build_wkr.java index f99729a2f..177fa9b18 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xob_diff_build_wkr.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xob_diff_build_wkr.java @@ -17,33 +17,42 @@ along with this program. If not, see . */ package gplx.xowa.bldrs.cmds.diffs; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.cmds.*; import gplx.core.brys.*; import gplx.core.brys.fmtrs.*; -import gplx.dbs.*; import gplx.dbs.metas.*; import gplx.dbs.diffs.*; import gplx.dbs.diffs.builds.*; +import gplx.dbs.*; import gplx.dbs.metas.*; import gplx.dbs.diffs.*; import gplx.dbs.diffs.builds.*; import gplx.dbs.diffs.itms.*; +import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; class Xob_diff_build_wkr { private final Gfdb_diff_bldr dif_bldr = new Gfdb_diff_bldr(); + private final Xowe_wiki wiki; private Db_conn old_conn, new_conn, dif_conn; - public Xob_diff_build_wkr(Xob_bldr bldr, Xowe_wiki wiki, String old_url, String new_url, String dif_url, int commit_interval) { + private final Xowd_tbl_mapr tbl_mapr; + public Xob_diff_build_wkr(Xob_bldr bldr, Xowe_wiki wiki, String old_url, String new_url, String dif_url, int commit_interval, Xowd_tbl_mapr tbl_mapr) { + this.wiki = wiki; wiki.Init_by_wiki(); - Bry_fmt url_fmt = Bry_fmt.New("").Args_(New_url_args(wiki)); + Bry_fmt url_fmt = Bry_fmt.New("").Args_(New_url_args(wiki, tbl_mapr.Name)); Bry_bfr tmp_bfr = Bry_bfr.new_(); - old_conn = New_conn(Bool_.N, wiki, url_fmt, old_url, tmp_bfr); - new_conn = New_conn(Bool_.N, wiki, url_fmt, new_url, tmp_bfr); - dif_conn = New_conn(Bool_.Y, wiki, url_fmt, dif_url, tmp_bfr); + old_conn = New_conn(tmp_bfr, wiki, url_fmt, Bool_.N, old_url); + new_conn = New_conn(tmp_bfr, wiki, url_fmt, Bool_.N, new_url); + dif_conn = New_conn(tmp_bfr, wiki, url_fmt, Bool_.Y, dif_url); + this.tbl_mapr = tbl_mapr; } public void Exec() { - Gfdb_diff_db dif_db = new Gfdb_diff_db(dif_conn); + Gdif_core dif_core = new Gdif_core(dif_conn); + String name = String_.Format("{0}|{1}|diffs|{2}", wiki.Domain_str(), tbl_mapr.Name, wiki.Props().Modified_latest().XtoStr_fmt(DateAdp_.Fmt__yyyyMMdd)); // EX: "simple.wikipedia.org|text|diffs|20160112" + String made_by = wiki.App().User().Key(); + Gdif_job_itm job_itm = dif_core.New_job(name, made_by); + Gdif_bldr_ctx ctx = new Gdif_bldr_ctx().Init(dif_core, job_itm); + Gfdb_diff_wkr__db dif_wkr = new Gfdb_diff_wkr__db(); + Gdif_db dif_db = dif_core.Db(); dif_wkr.Init_conn(dif_db, 1000); dif_bldr.Init(dif_wkr); - Dbmeta_tbl_mgr old_tbl_mgr = old_conn.Meta_tbl_load_all(); - Dbmeta_tbl_mgr new_tbl_mgr = old_conn.Meta_tbl_load_all(); - int new_tbl_len = new_tbl_mgr.Len(); - int txn = -1; - for (int i = 0; i < new_tbl_len; ++i) { - Dbmeta_tbl_itm new_tbl = new_tbl_mgr.Get_at(i); - Dbmeta_tbl_itm old_tbl = old_tbl_mgr.Get_by(new_tbl.Name()); if (old_tbl == null) continue; - Gfdb_diff_tbl dif_tbl = Gfdb_diff_tbl.New(new_tbl); - dif_bldr.Compare(++txn, dif_tbl, old_conn, new_conn); - // save txn + + // wiki.Data__core_mgr().Db__core().Conn().Conn_info(); + Xowd_db_file[] db_files = wiki.Data__core_mgr().Db__core().Tbl__db().Select_all(wiki.Data__core_mgr().Props(), Io_url_.Empty); + int db_files_len = db_files.length; + for (int i = 0; i < db_files_len; ++i) { + Xowd_db_file db_file = db_files[i]; + if (tbl_mapr.Db_ids__has(db_file.Tid())) + Compare(ctx); } // int old_tbl_len = old_tbl_mgr.Len(); // for (int i = 0; i < old_tbl_len; ++i) { @@ -54,20 +63,35 @@ class Xob_diff_build_wkr { // } // } } - public static Db_conn New_conn(boolean autocreate, Xow_wiki wiki, Bry_fmt fmtr, String url_fmt, Bry_bfr tmp_bfr) { - fmtr.Fmt_(url_fmt).Bld_bfr_many(tmp_bfr); + private void Compare(Gdif_bldr_ctx ctx) { + Dbmeta_tbl_mgr old_tbl_mgr = old_conn.Meta_tbl_load_all(); + Dbmeta_tbl_mgr new_tbl_mgr = old_conn.Meta_tbl_load_all(); + int new_tbl_len = new_tbl_mgr.Len(); + for (int i = 0; i < new_tbl_len; ++i) { + Dbmeta_tbl_itm new_tbl = new_tbl_mgr.Get_at(i); + Dbmeta_tbl_itm old_tbl = old_tbl_mgr.Get_by(new_tbl.Name()); if (old_tbl == null) continue; + Gfdb_diff_tbl dif_tbl = Gfdb_diff_tbl.New(new_tbl); + dif_bldr.Compare(ctx, dif_tbl, old_conn, new_conn); + // save txn + } + } + public static Db_conn New_conn(Bry_bfr tmp_bfr, Xow_wiki wiki, Bry_fmt fmtr, boolean autocreate, String url_fmt) { + fmtr.Fmt_(url_fmt).Bld_many(tmp_bfr); return Db_conn_bldr.Instance.Get_or_autocreate(autocreate, Io_url_.new_any_(tmp_bfr.To_str_and_clear())); } - private static Bfr_fmt_arg[] New_url_args(Xow_wiki wiki) { + private static Bfr_fmt_arg[] New_url_args(Xow_wiki wiki, String db_mapr_name) { Bfr_fmt_arg[] rv = new Bfr_fmt_arg[] { new Bfr_fmt_arg(Bry_.new_a7(".dump_dir"), new Bfr_arg__dump_dir(wiki)) , new Bfr_fmt_arg(Bry_.new_a7(".dump_core"), new Bfr_arg__dump_core(wiki)) , new Bfr_fmt_arg(Bry_.new_a7(".dump_domain"), new Bfr_arg__dump_domain(wiki)) , new Bfr_fmt_arg(Bry_.new_a7(".dir_spr"), new Bfr_arg__dir_spr()) + , new Bfr_fmt_arg(Bry_.new_a7(".dif_name"), Bfr_arg_.New_bry(db_mapr_name)) }; return rv; - } + } //old_url='~{.dump_dir}-prev/~{.dump_core}'; //new_url='~{.dump_dir}/~{.dump_core}'; - //dif_url='~{.dump_dir}/~{.dump_domain}-diff.xowa'; + //dif_url='~{.dump_dir}/~{.dump_domain}-{.dif_name}-diff.xowa'; + // old_conn='data source="~{.dump_dir}/~{.dump_core}";url=' + // dif_conn='gplx_key=sqlite;url=' } diff --git a/140_dbs/src/gplx/dbs/sqls/Sql_order_by_itm.java b/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xowd_tbl_mapr.java similarity index 56% rename from 140_dbs/src/gplx/dbs/sqls/Sql_order_by_itm.java rename to 400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xowd_tbl_mapr.java index ea5566941..199fcd541 100644 --- a/140_dbs/src/gplx/dbs/sqls/Sql_order_by_itm.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/diffs/Xowd_tbl_mapr.java @@ -15,17 +15,20 @@ 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 . */ -package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*; -public class Sql_order_by_itm { - public String Name() {return name;} private String name; - public boolean Ascending() {return ascending;} private boolean ascending; - public String XtoSql() { - String ascString = ascending ? "" : " DESC"; - return name + ascString; +package gplx.xowa.bldrs.cmds.diffs; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.cmds.*; +import gplx.xowa.wikis.data.*; +class Xowd_tbl_mapr { + public Xowd_tbl_mapr(String name, int[] db_ids) { + this.Name = name; + this.Db_ids = db_ids; } - public static Sql_order_by_itm new_(String name, boolean ascending) { - Sql_order_by_itm rv = new Sql_order_by_itm(); - rv.name = name; rv.ascending = ascending; - return rv; - } Sql_order_by_itm() {} + public final String Name; + public final int[] Db_ids; + public boolean Db_ids__has(int id) {return true;} +// private static List_adp Fill_tbl_names(List_adp rv, int db_tid) { +// switch (db_tid) { +// case Xowd_db_file_.Tid_cat: +// return +// break; +// } } diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_diff_regy_make_cmd.java b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_diff_regy_make_cmd.java index 755a6474a..5c5d480d3 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_diff_regy_make_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_diff_regy_make_cmd.java @@ -48,7 +48,7 @@ public class Xob_diff_regy_make_cmd extends Xob_itm_basic_base implements Xob_cm Sqlite_engine_.Idx_create(make_db_provider, Xob_diff_regy_tbl.Idx_diff_regy__load); } private void Make_delete_sql(Db_conn make_db_provider) { - DataRdr rdr = make_db_provider.Exec_sql_as_rdr(Xob_diff_regy_tbl.Make_deletes); + DataRdr rdr = make_db_provider.Exec_sql_as_old_rdr(Xob_diff_regy_tbl.Make_deletes); int cur_db_id = -1, cur_count = 0; Bry_bfr atr_bfr = Bry_bfr.new_(), bin_bfr = Bry_bfr.new_(); Io_url sql_tmp_dir = wiki.App().Fsys_mgr().File_dir().GenSubDir_nest(wiki.Domain_str(), "tmp_sql"); diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_orig_regy_update_cmd.java b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_orig_regy_update_cmd.java index 446ea9981..fd5d2ddba 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_orig_regy_update_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_orig_regy_update_cmd.java @@ -49,7 +49,7 @@ public class Xob_orig_regy_update_cmd extends Xob_itm_basic_base implements Xob_ } */ } - public DataRdr Select(Db_conn p, byte prv_repo_id, byte[] prv_ttl) { + public DataRdr Select(Db_conn conn, byte prv_repo_id, byte[] prv_ttl) { String sql = String_.Concat_lines_nl_skip_last ( "SELECT lnki_ttl" , "FROM orig_regy" @@ -58,7 +58,7 @@ public class Xob_orig_regy_update_cmd extends Xob_itm_basic_base implements Xob_ , "AND oimg_orig_page_id = -1;" ); Db_qry select_qry = Db_qry_sql.rdr_(sql); - return p.Exec_qry_as_rdr(select_qry); + return conn.Exec_qry_as_old_rdr(select_qry); } public void Cmd_run() {} public void Cmd_end() {} diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_regy_tbl.java b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_regy_tbl.java index c3206d32b..b46214c72 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_regy_tbl.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_regy_tbl.java @@ -33,19 +33,19 @@ public class Xob_xfer_regy_tbl { p.Exec_sql(Sql_create_data_thumb); } public static void Create_index(Gfo_usr_dlg usr_dlg, Db_conn p) {Sqlite_engine_.Idx_create(usr_dlg, p, Xob_db_file.Name__file_make, Idx_lnki_page_id, Idx_lnki_ttl);} - public static DataRdr Select(Db_conn p, byte repo_id, byte[] ttl, int limit) { + public static DataRdr Select(Db_conn conn, byte repo_id, byte[] ttl, int limit) { Db_qry qry = Db_qry_.select_().Cols_all_() .From_(Tbl_name) - .Where_(gplx.core.criterias.Criteria_.And_many(Db_crt_.mte_(Fld_orig_repo, repo_id), Db_crt_.mt_(Fld_lnki_ttl, String_.new_u8(ttl)), Db_crt_.eq_(Fld_xfer_status, 0))) - .OrderBy_many_(Fld_xfer_status, Fld_orig_repo, Fld_lnki_ttl, Fld_file_w) + .Where_(gplx.core.criterias.Criteria_.And_many(Db_crt_.New_mte(Fld_orig_repo, repo_id), Db_crt_.New_mt(Fld_lnki_ttl, String_.new_u8(ttl)), Db_crt_.New_eq(Fld_xfer_status, 0))) + .Order_asc_many_(Fld_xfer_status, Fld_orig_repo, Fld_lnki_ttl, Fld_file_w) .Limit_(limit) ; - return p.Exec_qry_as_rdr(qry); + return conn.Exec_qry_as_old_rdr(qry); } - public static Db_stmt Select_by_page_id_stmt(Db_conn p) {return p.Stmt_new(Db_qry_sql.rdr_(Sql_select));} + public static Db_stmt Select_by_page_id_stmt(Db_conn p) {return p.Stmt_new(Db_qry_sql.rdr_(Sql_select_itm));} public static DataRdr Select_by_page_id(Db_stmt stmt, int page_id, int limit) {return stmt.Val_int(page_id).Val_int(limit).Exec_select();} private static final String - Sql_select = String_.Concat_lines_nl + Sql_select_itm = String_.Concat_lines_nl ( "SELECT *" , "FROM xfer_regy" , "WHERE xfer_status = 0" @@ -59,17 +59,17 @@ public class Xob_xfer_regy_tbl { , "WHERE xfer_status = 0" ) ; - public static DataRdr Select_by_tier_page(Db_conn p, int tier_id, int page_id, int select_interval) { + public static DataRdr Select_by_tier_page(Db_conn conn, int tier_id, int page_id, int select_interval) { Db_qry qry = Db_qry_.select_().Cols_all_() .From_(Tbl_name) - .Where_(gplx.core.criterias.Criteria_.And_many(Db_crt_.eq_(Fld_xfer_status, 0), Db_crt_.eq_(Fld_lnki_tier_id, tier_id), Db_crt_.mte_(Fld_lnki_page_id, page_id))) - .OrderBy_many_(Fld_lnki_tier_id, Fld_lnki_page_id, Fld_lnki_id) + .Where_(gplx.core.criterias.Criteria_.And_many(Db_crt_.New_eq(Fld_xfer_status, 0), Db_crt_.New_eq(Fld_lnki_tier_id, tier_id), Db_crt_.New_mte(Fld_lnki_page_id, page_id))) + .Order_asc_many_(Fld_lnki_tier_id, Fld_lnki_page_id, Fld_lnki_id) .Limit_(select_interval) ; - return p.Exec_qry_as_rdr(qry); + return conn.Exec_qry_as_old_rdr(qry); } public static int Select_total_pending(Db_conn p) { - DataRdr rdr = p.Exec_sql_as_rdr(Sql_select_total_pending); + DataRdr rdr = p.Exec_sql_as_old_rdr(Sql_select_total_pending); int rv = 0; if (rdr.MoveNextPeer()) rv = rdr.ReadInt("CountAll"); diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_temp_cmd_orig.java b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_temp_cmd_orig.java index 86f15e886..ee5deeb14 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_temp_cmd_orig.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_temp_cmd_orig.java @@ -30,7 +30,7 @@ public class Xob_xfer_temp_cmd_orig extends Xob_itm_basic_base implements Xob_cm Xob_xfer_temp_tbl.Create_table(conn); Db_stmt trg_stmt = Xob_xfer_temp_tbl.Insert_stmt(conn); conn.Txn_bgn("bldr__xfer_temp"); - DataRdr rdr = conn.Exec_sql_as_rdr(Sql_select); + DataRdr rdr = conn.Exec_sql_as_old_rdr(Sql_select_itm); long[] ext_maxs = Calc_ext_max(); while (rdr.MoveNextPeer()) { int lnki_ext = rdr.ReadByte(Xob_lnki_regy_tbl.Fld_lnki_ext); @@ -76,7 +76,7 @@ public class Xob_xfer_temp_cmd_orig extends Xob_itm_basic_base implements Xob_cm public void Cmd_end() {} public void Cmd_term() {} private static final String - Sql_select = String_.Concat_lines_nl + Sql_select_itm = String_.Concat_lines_nl ( "SELECT DISTINCT" , " l.lnki_id" // , ", lnki_ttl" diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_temp_cmd_thumb.java b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_temp_cmd_thumb.java index c6f79e4de..3570ab88c 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_temp_cmd_thumb.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/files/Xob_xfer_temp_cmd_thumb.java @@ -28,7 +28,7 @@ public class Xob_xfer_temp_cmd_thumb extends Xob_itm_basic_base implements Xob_c Xob_xfer_temp_tbl.Create_table(conn); Db_stmt trg_stmt = Xob_xfer_temp_tbl.Insert_stmt(conn); conn.Txn_bgn("bldr__xfer_temp_thumb"); - DataRdr rdr = conn.Exec_sql_as_rdr(Sql_select); + DataRdr rdr = conn.Exec_sql_as_old_rdr(Sql_select_itm); Xob_xfer_temp_itm temp_itm = new Xob_xfer_temp_itm(); Xof_img_size img_size = new Xof_img_size(); byte[] cur_ttl = Bry_.Empty; byte cur_repo = Byte_.Max_value_127; @@ -52,7 +52,7 @@ public class Xob_xfer_temp_cmd_thumb extends Xob_itm_basic_base implements Xob_c public void Cmd_end() {} public void Cmd_term() {} private static final String - Sql_select = String_.Concat_lines_nl + Sql_select_itm = String_.Concat_lines_nl ( "SELECT l.lnki_id" , ", l.lnki_tier_id" , ", l.lnki_page_id" diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_cmd.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_cmd.java index 6f939fb3f..3ae98a162 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_cmd.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_cmd.java @@ -37,6 +37,7 @@ public class Xob_search_sql_cmd extends Xob_itm_basic_base implements Xob_cmd { Db_conn search_conn = search_db.Conn(); Xowd_search_temp_tbl search_temp_tbl = new Xowd_search_temp_tbl(search_conn, db_mgr.Props().Schema_is_1()); search_temp_tbl.Create_tbl(); + search_conn.Exec_delete_all(search_temp_tbl.Tbl_name()); search_temp_tbl.Insert_bgn(); Xowd_page_tbl page_tbl = db_mgr.Tbl__page(); Db_rdr page_rdr = page_tbl.Select_all(); diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr.java index 6a563e5ae..e3a391899 100644 --- a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr.java +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr.java @@ -22,7 +22,7 @@ import gplx.xowa.langs.*; import gplx.xowa.wikis.data.*; import gplx.dbs.*; import gplx.dbs.engines.sqlite.*; import gplx.xowa.wikis.dbs.*; import gplx.xowa.wikis.data.tbls.*; public class Xob_search_sql_wkr extends Xob_search_base implements Io_make_cmd { // search version 2 private Xowd_db_mgr db_mgr; private Xowd_search_link_tbl search_page_tbl; private Xowd_search_word_tbl search_word_tbl; - private int search_id = 0; private byte[] prv_word = Bry_.Empty; private int page_count; + private int search_id = 0; private byte[] prv_word = null; private int page_count; public Xob_search_sql_wkr(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki);} @Override public String Wkr_key() {return Xob_cmd_keys.Key_text_search_wkr;} @Override public gplx.core.ios.Io_make_cmd Make_cmd_site() {return this;} @@ -35,20 +35,22 @@ public class Xob_search_sql_wkr extends Xob_search_base implements Io_make_cmd { this.search_word_tbl = db_mgr.Db__search().Tbl__search_word(); search_page_tbl.Insert_bgn(); search_word_tbl.Insert_bgn(); } - public void Sort_do(Io_line_rdr rdr) { - byte[] bry = rdr.Bfr(); - byte[] cur_word = Bry_.Mid(bry, rdr.Key_pos_bgn(), rdr.Key_pos_end()); - if (!Bry_.Eq(cur_word, prv_word)) { - search_word_tbl.Insert_cmd_by_batch(++search_id, prv_word, page_count); + public void Sort_do(Io_line_rdr rdr) {Sort_do(rdr.Bfr(), rdr.Key_pos_bgn(), rdr.Key_pos_end());} + public void Sort_do(byte[] line, int key_bgn, int key_end) {// EX: abc|123 + byte[] cur_word = Bry_.Mid(line, key_bgn, key_end); + if (!Bry_.Eq(cur_word, prv_word)) { // if new_word, insert old one + if (prv_word != null) // do not insert for 1st word + search_word_tbl.Insert_cmd_by_batch(search_id, prv_word, page_count); + ++search_id; prv_word = cur_word; page_count = 0; } - search_page_tbl.Insert_cmd_by_batch(search_id, Base85_.To_int_by_bry(bry, rdr.Key_pos_end() + 1, rdr.Key_pos_end() + 5)); // -1: ignore rdr_dlm + search_page_tbl.Insert_cmd_by_batch(search_id, Base85_.To_int_by_bry(line, key_end + 1, key_end + 5)); // -1: ignore rdr_dlm ++page_count; - if (search_id % 10000 == 0) - usr_dlg.Prog_many("", "", "creating title index: count=~{0}", search_id); + if (search_id % 10000 == 0) usr_dlg.Prog_many("", "", "creating title index: count=~{0}", search_id); } public void Sort_end() { + search_word_tbl.Insert_cmd_by_batch(search_id, prv_word, page_count); search_page_tbl.Insert_end(); search_word_tbl.Insert_end(); Xowd_db_file search_db = db_mgr.Db__search(); Xowd_search_temp_tbl search_temp_tbl = new Xowd_search_temp_tbl(search_db.Conn(), db_mgr.Props().Schema_is_1()); diff --git a/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr_tst.java b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr_tst.java new file mode 100644 index 000000000..2be2b4949 --- /dev/null +++ b/400_xowa/src/gplx/xowa/bldrs/cmds/texts/sqls/Xob_search_sql_wkr_tst.java @@ -0,0 +1,68 @@ +/* +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 . +*/ +package gplx.xowa.bldrs.cmds.texts.sqls; import gplx.*; import gplx.xowa.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.cmds.*; import gplx.xowa.bldrs.cmds.texts.*; +import org.junit.*; import gplx.dbs.*; import gplx.xowa.wikis.data.tbls.*; +public class Xob_search_sql_wkr_tst { + private final Xob_search_sql_wkr_fxt fxt = new Xob_search_sql_wkr_fxt(); + @Test public void Basic() { + fxt.Exec__sort + ( "a|!!!!#" + , "a|!!!!$" + , "b|!!!!#" + , "b|!!!!$" + , "b|!!!!%" + ); + fxt.Test__search_word + ( "1|a|2" + , "2|b|3" + ); + fxt.Test__search_link + ( "1|2" + , "1|3" + , "2|2" + , "2|3" + , "2|4" + ); + } +} +class Xob_search_sql_wkr_fxt { + private final Xob_search_sql_wkr wkr; + private final Xowe_wiki wiki; + private final Bry_bfr tmp_bfr = Bry_bfr.new_(); + public Xob_search_sql_wkr_fxt() { + Xoae_app app = Xoa_app_fxt.app_(); + this.wiki = Xoa_app_fxt.wiki_tst_(app); + Xoa_test_.Db__init__mem(wiki); + wkr = new Xob_search_sql_wkr(app.Bldr(), wiki); + } + public void Exec__sort(String... lines_str) { + byte[][] lines = Bry_.Ary(lines_str); + wkr.Sort_bgn(); + for (byte[] line : lines) + wkr.Sort_do(line, 0, Bry_find_.Find_fwd(line, Byte_ascii.Pipe)); + wkr.Sort_end(); + } + public void Test__search_word(String... lines) { + Xowd_search_word_tbl tbl = wiki.Data__core_mgr().Db__search().Tbl__search_word(); + Tfds.Eq_str_lines(String_.Concat_lines_nl(lines), Xoa_test_.Db__print_tbl_as_str(tmp_bfr, tbl.conn, tbl.Tbl_name(), tbl.Fld_id(), tbl.Fld_text(), tbl.Fld_page_count())); + } + public void Test__search_link(String... lines) { + Xowd_search_link_tbl tbl = wiki.Data__core_mgr().Db__search().Tbl__search_link(); + Tfds.Eq_str_lines(String_.Concat_lines_nl(lines), Xoa_test_.Db__print_tbl_as_str(tmp_bfr, tbl.conn, tbl.Tbl_name(), tbl.Fld_word_id(), tbl.Fld_page_id())); + } +} diff --git a/400_xowa/src/gplx/xowa/drds/Xod_app.java b/400_xowa/src/gplx/xowa/drds/Xod_app.java index 44fe6f4e5..bedcc4e6e 100644 --- a/400_xowa/src/gplx/xowa/drds/Xod_app.java +++ b/400_xowa/src/gplx/xowa/drds/Xod_app.java @@ -41,19 +41,19 @@ public class Xod_app { Xoa_url url = wiki.Utl__url_parser().Parse(random_ttl_bry); return Wiki__get_by_url(wiki, url); } - public String[] Wiki__search(Cancelable cancelable, Xow_wiki wiki, Xows_ui_async ui_async, String search) { - Xows_db_wkr search_wkr = new Xows_db_wkr(); - Xows_db_row[] rows = search_wkr.Search_by_drd(cancelable, wiki, ui_async, Bry_.new_u8(search), 50); - int len = rows.length; - String[] rv = new String[len]; - for (int i = 0; i < len; ++i) { - rv[i] = String_.new_u8(rows[i].Page_ttl().Page_txt()); - } - return rv; - } - public void Wiki__search(Cancelable cancelable, Xow_wiki wiki, Xows_ui_async ui_async, String search, Xod_search_cmd[] cmds) { +// public String[] Wiki__search(Cancelable cancelable, Srch_rslt_lnr rslt_lnr, Xow_wiki wiki, String search) { +// Srch_db_wkr search_wkr = new Srch_db_wkr(); +// Srch_rslt_itm[] rows = search_wkr.Search_by_drd(cancelable, wiki, ui_async, Bry_.new_u8(search), 50); +// int len = rows.length; +// String[] rv = new String[len]; +// for (int i = 0; i < len; ++i) { +// rv[i] = String_.new_u8(rows[i].page_ttl.Page_txt()); +// } +// return rv; +// } + public void Wiki__search(Cancelable cancelable, Srch_rslt_lnr rslt_lnr, Xow_wiki wiki, String search, Xod_search_cmd[] cmds) { for (Xod_search_cmd cmd : cmds) - cmd.Search(cancelable, wiki, ui_async, search); + cmd.Search(cancelable, rslt_lnr, wiki, search); } public void Page__load_files(Xow_wiki wiki, Xod_page_itm pg, Xog_js_wkr js_wkr) { file_mgr.Load_files(wiki, pg, js_wkr); diff --git a/400_xowa/src/gplx/xowa/drds/Xod_search_cmd.java b/400_xowa/src/gplx/xowa/drds/Xod_search_cmd.java index 815c00d0c..aee7eae07 100644 --- a/400_xowa/src/gplx/xowa/drds/Xod_search_cmd.java +++ b/400_xowa/src/gplx/xowa/drds/Xod_search_cmd.java @@ -18,5 +18,5 @@ along with this program. If not, see . package gplx.xowa.drds; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.search.*; public interface Xod_search_cmd { - void Search(Cancelable cancelable, Xow_wiki wiki, Xows_ui_async ui_async, String search); + void Search(Cancelable cancelable, Srch_rslt_lnr rslt_lnr, Xow_wiki wiki, String search); } diff --git a/400_xowa/src/gplx/xowa/drds/Xod_search_cmd_.java b/400_xowa/src/gplx/xowa/drds/Xod_search_cmd_.java index fd33b040f..7696109fd 100644 --- a/400_xowa/src/gplx/xowa/drds/Xod_search_cmd_.java +++ b/400_xowa/src/gplx/xowa/drds/Xod_search_cmd_.java @@ -27,24 +27,24 @@ public class Xod_search_cmd_ { ; } class Xod_search_cmd__page_eq implements Xod_search_cmd { - public void Search(Cancelable cancelable, Xow_wiki wiki, Xows_ui_async ui_async, String search) { + public void Search(Cancelable cancelable, Srch_rslt_lnr rslt_lnr, Xow_wiki wiki, String search) { Xowd_page_itm page_itm = new Xowd_page_itm(); if (wiki.Data__core_mgr().Tbl__page().Select_by_ttl(page_itm, wiki.Ns_mgr().Ns_main(), Bry_.Ucase__1st(Bry_.new_u8(search)))) { - Xows_db_row search_itm = new Xows_db_row(wiki.Domain_bry(), wiki.Ttl_parse(page_itm.Ttl_page_db()), page_itm.Id(), page_itm.Text_len()); - ui_async.Add(search_itm); + Srch_rslt_itm search_itm = new Srch_rslt_itm(wiki.Domain_bry(), wiki.Ttl_parse(page_itm.Ttl_page_db()), page_itm.Id(), page_itm.Text_len()); + rslt_lnr.Notify_rslt_found(search_itm); } } public static final Xod_search_cmd__page_eq Instance = new Xod_search_cmd__page_eq(); Xod_search_cmd__page_eq() {} } class Xod_search_cmd__page_like implements Xod_search_cmd {// NOTE: slow; takes at least 10+ seconds - public void Search(Cancelable cancelable, Xow_wiki wiki, Xows_ui_async ui_async, String search) { + public void Search(Cancelable cancelable, Srch_rslt_lnr rslt_lnr, Xow_wiki wiki, String search) { List_adp tmp_list = List_adp_.new_(); wiki.Data__core_mgr().Tbl__page().Select_by_search(cancelable, tmp_list, Bry_.Ucase__1st(Bry_.new_u8(search + "*")), 50); int len = tmp_list.Count(); for (int i = 0; i < len; ++i) { Xowd_page_itm page_itm = (Xowd_page_itm)tmp_list.Get_at(i); - Xows_db_row search_itm = new Xows_db_row(wiki.Domain_bry(), wiki.Ttl_parse(page_itm.Ttl_page_db()), page_itm.Id(), page_itm.Text_len()); - ui_async.Add(search_itm); + Srch_rslt_itm search_itm = new Srch_rslt_itm(wiki.Domain_bry(), wiki.Ttl_parse(page_itm.Ttl_page_db()), page_itm.Id(), page_itm.Text_len()); + rslt_lnr.Notify_rslt_found(search_itm); } } public static final Xod_search_cmd__page_like Instance = new Xod_search_cmd__page_like(); Xod_search_cmd__page_like() {} @@ -52,10 +52,10 @@ class Xod_search_cmd__page_like implements Xod_search_cmd {// NOTE: slow; takes class Xod_search_cmd__word_tbl implements Xod_search_cmd { private final boolean wildcard; private final int results_wanted; - private final Xows_db_wkr search_wkr = new Xows_db_wkr(); + private final Srch_db_wkr search_wkr = new Srch_db_wkr(); Xod_search_cmd__word_tbl(boolean wildcard, int results_wanted) {this.wildcard = wildcard; this.results_wanted = results_wanted;} - public void Search(Cancelable cancelable, Xow_wiki wiki, Xows_ui_async ui_async, String search) { - search_wkr.Search_by_drd(cancelable, wiki, ui_async, Bry_.new_u8(Standardize_search(search, wildcard)), results_wanted); + public void Search(Cancelable cancelable, Srch_rslt_lnr rslt_lnr, Xow_wiki wiki, String search) { + search_wkr.Search_by_drd(cancelable, rslt_lnr, wiki, Bry_.new_u8(Standardize_search(search, wildcard)), results_wanted); } public static final Xod_search_cmd__word_tbl Instance_eq = new Xod_search_cmd__word_tbl(Bool_.N, 10), Instance_like = new Xod_search_cmd__word_tbl(Bool_.Y, 50); private static String Standardize_search(String search, boolean wildcard) { diff --git a/400_xowa/src/gplx/xowa/files/origs/Xof_orig_tbl.java b/400_xowa/src/gplx/xowa/files/origs/Xof_orig_tbl.java index 1d7793328..042bbe6f5 100644 --- a/400_xowa/src/gplx/xowa/files/origs/Xof_orig_tbl.java +++ b/400_xowa/src/gplx/xowa/files/origs/Xof_orig_tbl.java @@ -95,7 +95,7 @@ class Xof_orig_tbl__in_wkr extends Db_in_wkr__base { public Xof_orig_tbl__in_wkr Init(Ordered_hash rv, List_adp itms) {this.itms = itms; this.rv = rv; return this;} @Override protected Db_qry Make_qry(int bgn, int end) { Object[] part_ary = In_ary(end - bgn); - return Db_qry_.select_cols_(tbl_name, Db_crt_.in_(fld_ttl, part_ary), flds.To_str_ary()); + return Db_qry_.select_cols_(tbl_name, Db_crt_.New_in(fld_ttl, part_ary), flds.To_str_ary()); } @Override protected void Fill_stmt(Db_stmt stmt, int bgn, int end) { for (int i = bgn; i < end; i++) { diff --git a/400_xowa/src/gplx/xowa/htmls/core/bldrs/Xob_hdump_img_cmd.java b/400_xowa/src/gplx/xowa/htmls/core/bldrs/Xob_hdump_img_cmd.java index 015ed33e9..39ef1f777 100644 --- a/400_xowa/src/gplx/xowa/htmls/core/bldrs/Xob_hdump_img_cmd.java +++ b/400_xowa/src/gplx/xowa/htmls/core/bldrs/Xob_hdump_img_cmd.java @@ -31,7 +31,7 @@ class Xob_hdump_img_cmd extends Xob_itm_basic_base implements Xob_cmd { private void Exec_main() { Bry_bfr bfr = Bry_bfr.reset_(Io_mgr.Len_mb); Db_conn conn = Xob_db_file.new__file_make(wiki.Fsys_mgr().Root_dir()).Conn(); - Db_rdr rdr = conn.Stmt_new(gplx.dbs.qrys.Db_qry_sql.rdr_(Sql_select)).Exec_select__rls_auto(); + Db_rdr rdr = conn.Stmt_new(gplx.dbs.qrys.Db_qry_sql.rdr_(Sql_select_itm)).Exec_select__rls_auto(); // html_tbl = new Xowd_html_tbl(conn, wiki.Db_mgr_as_sql().Core_data_mgr().Props().Zip_tid_text()); int cur_page_id = -1; while (rdr.Move_next()) { @@ -57,7 +57,7 @@ class Xob_hdump_img_cmd extends Xob_itm_basic_base implements Xob_cmd { if (page_id == -1 || data.length == 0) return; // html_tbl.Insert(page_id, Xohd_img_tid.Tid_img, data); } - private static final String Sql_select = String_.Concat_lines_nl_skip_last + private static final String Sql_select_itm = String_.Concat_lines_nl_skip_last ( "SELECT lt.lnki_page_id" , ", lt.html_uid" , ", lt.lnki_ttl" diff --git a/400_xowa/src/gplx/xowa/htmls/core/bldrs/Xob_redlink_mkr_cmd.java b/400_xowa/src/gplx/xowa/htmls/core/bldrs/Xob_redlink_mkr_cmd.java index 27563fd40..5f83b6644 100644 --- a/400_xowa/src/gplx/xowa/htmls/core/bldrs/Xob_redlink_mkr_cmd.java +++ b/400_xowa/src/gplx/xowa/htmls/core/bldrs/Xob_redlink_mkr_cmd.java @@ -35,7 +35,7 @@ public class Xob_redlink_mkr_cmd extends Xob_itm_basic_base implements Xob_cmd { Xowd_page_tbl page_tbl = core_db.Tbl__page(); int cur_html_db_id = -1, cur_page_id = -1; Xoh_redlink_tbl redlink_tbl = new Xoh_redlink_tbl(page_tbl.Conn()); - Db_rdr rdr = attach_rdr.Exec_as_rdr(Sql_select); + Db_rdr rdr = attach_rdr.Exec_as_rdr(Sql_select_itm); try { while (rdr.Move_next()) { // switch html_db if needed @@ -69,7 +69,7 @@ public class Xob_redlink_mkr_cmd extends Xob_itm_basic_base implements Xob_cmd { if ((commit_count % commit_interval ) == 0) redlink_tbl.Conn().Txn_sav(); } - private static final String Sql_select = String_.Concat_lines_nl_skip_last + private static final String Sql_select_itm = String_.Concat_lines_nl_skip_last ( "SELECT p.page_html_db_id" , ", p.page_id" , ", ld.src_html_uid" diff --git a/400_xowa/src/gplx/xowa/htmls/core/wkrs/lnkis/htmls/Xoh_file_html_fmtr__hdump.java b/400_xowa/src/gplx/xowa/htmls/core/wkrs/lnkis/htmls/Xoh_file_html_fmtr__hdump.java index fdceb4010..de8fe44b4 100644 --- a/400_xowa/src/gplx/xowa/htmls/core/wkrs/lnkis/htmls/Xoh_file_html_fmtr__hdump.java +++ b/400_xowa/src/gplx/xowa/htmls/core/wkrs/lnkis/htmls/Xoh_file_html_fmtr__hdump.java @@ -38,7 +38,7 @@ public class Xoh_file_html_fmtr__hdump extends Xoh_file_html_fmtr__base { , Gfh_utl.Escape_html_as_bry(img_alt), data_xowa_title, data_xowa_image, arg_img_core.Init(uid, Bry_.Empty, 0, 0), Xoh_img_cls_.To_html(img_cls, img_cls_other)); } public static void Bld_anch_n(Bry_bfr bfr, byte[] data_xowa_title, byte[] data_xowa_image, byte img_cls, byte[] img_cls_other, byte[] img_alt, byte[] img_xtra_atrs) { - fmtr_anch_n.Bld_bfr_many(bfr, data_xowa_title, data_xowa_image, Xoh_img_cls_.To_html(img_cls, img_cls_other), Gfh_utl.Escape_html_as_bry(img_alt), img_xtra_atrs); + fmtr_anch_n.Bld_many(bfr, data_xowa_title, data_xowa_image, Xoh_img_cls_.To_html(img_cls, img_cls_other), Gfh_utl.Escape_html_as_bry(img_alt), img_xtra_atrs); } public static byte[] Bld_xowa_image_data(Bry_bfr tmp_bfr, byte tid, int w, int h, double upright, double time, int page) { tmp_bfr.Add_byte_space().Add(Xoh_img_xoimg_data.Bry__data_xowa_image).Add_byte_eq().Add_byte_quote(); diff --git a/400_xowa/src/gplx/xowa/htmls/core/wkrs/thms/Xoh_thm_hzip_tst.java b/400_xowa/src/gplx/xowa/htmls/core/wkrs/thms/Xoh_thm_hzip_tst.java index eab68be9c..3f13417de 100644 --- a/400_xowa/src/gplx/xowa/htmls/core/wkrs/thms/Xoh_thm_hzip_tst.java +++ b/400_xowa/src/gplx/xowa/htmls/core/wkrs/thms/Xoh_thm_hzip_tst.java @@ -311,7 +311,7 @@ public class Xoh_thm_hzip_tst { fxt.Wiki().Ns_mgr().Init(); fxt.Init_mode_is_b256_(Bool_.N); - fxt.Exec_write_to_fsys(Io_url_.new_dir_("J:\\xowa\\dev_rls\\html\\"), "debug.html"); + fxt.Exec_write_to_fsys(Io_url_.new_dir_("J:\\xowa\\research\\html\\"), "debug.html"); fxt.Init_mode_is_b256_(Bool_.N); } } diff --git a/400_xowa/src/gplx/xowa/specials/randoms/Rndm_core_row.java b/400_xowa/src/gplx/xowa/specials/randoms/Rndm_core_row.java index f2e67587f..21341cb86 100644 --- a/400_xowa/src/gplx/xowa/specials/randoms/Rndm_core_row.java +++ b/400_xowa/src/gplx/xowa/specials/randoms/Rndm_core_row.java @@ -17,8 +17,9 @@ along with this program. If not, see . */ package gplx.xowa.specials.randoms; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; public class Rndm_core_row { - public Rndm_core_row(int type, int total, int interval) {this.type = type; this.total = total; this.interval = interval;} - public final int type; - public final int total; - public final int interval; + public void Load(int uid, String where_sql, int total, int interval) {this.uid = uid; this.where_sql = where_sql; this.total = total; this.interval = interval;} + public int uid; + public String where_sql; + public int total; + public int interval; } diff --git a/400_xowa/src/gplx/xowa/specials/randoms/Rndm_core_tbl.java b/400_xowa/src/gplx/xowa/specials/randoms/Rndm_core_tbl.java index f8bd41f44..828eddba3 100644 --- a/400_xowa/src/gplx/xowa/specials/randoms/Rndm_core_tbl.java +++ b/400_xowa/src/gplx/xowa/specials/randoms/Rndm_core_tbl.java @@ -19,31 +19,34 @@ package gplx.xowa.specials.randoms; import gplx.*; import gplx.xowa.*; import gp import gplx.core.ios.*; import gplx.dbs.*; import gplx.dbs.utls.*; public class Rndm_core_tbl implements Rls_able { private final String tbl_name = "rndm_core"; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_(); - private final String fld_rndm_uid, fld_rndm_total, fld_rndm_interval; - private final Db_conn conn; private Db_stmt stmt_select, stmt_insert; + private final String fld_uid, fld_where_sql, fld_total, fld_interval; + private final Db_conn conn; private Db_stmt stmt_select; public Rndm_core_tbl(Db_conn conn) { this.conn = conn; - fld_rndm_uid = flds.Add_int("rndm_uid"); - fld_rndm_total = flds.Add_int("rndm_total"); - fld_rndm_interval = flds.Add_int("rndm_interval"); + fld_uid = flds.Add_int_pkey("rndm_uid"); + fld_where_sql = flds.Add_str("rndm_where_sql", 1024); + fld_total = flds.Add_int("rndm_total"); + fld_interval = flds.Add_int("rndm_interval"); conn.Rls_reg(this); } - public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds, Dbmeta_idx_itm.new_unique_by_name(tbl_name, "core", fld_rndm_uid)));} - public void Insert(int uid, int total, int interval) { - if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds); - stmt_insert.Clear().Val_int(fld_rndm_uid, uid).Val_int(fld_rndm_total, total).Val_int(interval).Exec_insert(); + public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds, Dbmeta_idx_itm.new_unique_by_name(tbl_name, "core", fld_uid)));} + public void Upsert(int uid, String where_sql, int total, int interval) { + conn.Stmt_delete(tbl_name, fld_uid).Crt_int(fld_uid, uid).Exec_delete(); + conn.Stmt_insert(tbl_name, flds).Val_int(fld_uid, uid).Val_str(fld_where_sql, where_sql).Val_int(fld_total, total).Val_int(fld_interval, interval).Exec_insert(); } - public Rndm_core_row Select(int uid) { - if (stmt_select == null) stmt_select = conn.Stmt_select(tbl_name, flds, fld_rndm_uid); - Db_rdr rdr = stmt_select.Clear().Val_int(fld_rndm_uid, uid).Exec_select__rls_manual(); + public void Select(Rndm_core_row rv, int uid) { + if (stmt_select == null) stmt_select = conn.Stmt_select(tbl_name, flds, fld_uid); + Db_rdr rdr = stmt_select.Clear().Val_int(fld_uid, uid).Exec_select__rls_manual(); try { - int total = rdr.Read_int(fld_rndm_total); - int interval = rdr.Read_int(fld_rndm_interval); - return new Rndm_core_row(uid, total, interval); + if (rdr.Move_next()) { + String where_sql = rdr.Read_str(fld_where_sql); + int total = rdr.Read_int(fld_total); + int interval = rdr.Read_int(fld_interval); + rv.Load(uid, where_sql, total, interval); + } } finally {rdr.Rls();} } public void Rls() { stmt_select = Db_stmt_.Rls(stmt_select); - stmt_insert = Db_stmt_.Rls(stmt_insert); } } diff --git a/400_xowa/src/gplx/xowa/specials/randoms/Rndm_mgr.java b/400_xowa/src/gplx/xowa/specials/randoms/Rndm_mgr.java new file mode 100644 index 000000000..577823a29 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/randoms/Rndm_mgr.java @@ -0,0 +1,90 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.specials.randoms; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; +import gplx.core.primitives.*; import gplx.core.brys.fmtrs.*; +import gplx.dbs.*; import gplx.xowa.wikis.data.tbls.*; +public class Rndm_mgr implements Rls_able { + private Rndm_core_tbl core_tbl; private final Rndm_core_row core_row = new Rndm_core_row(); + private Rndm_range_tbl rng_tbl; + private Xowd_page_tbl page_tbl; private Db_stmt stmt__page__random; + public void Init(Db_conn conn, Xowd_page_tbl page_tbl) { + core_tbl = new Rndm_core_tbl(conn); + rng_tbl = new Rndm_range_tbl(conn); + this.page_tbl = page_tbl; + conn.Rls_reg(this); + } + public void Rebuild(int uid, String where_sql, int interval) { + int total_count = 0; List_adp rng_list = List_adp_.new_(); + Db_conn conn = page_tbl.Conn(); + Db_stmt stmt = conn.Stmt_select_order(page_tbl.Tbl_name(), String_.Ary(page_tbl.Fld_page_id()), String_.Ary_empty, page_tbl.Fld_page_id()); + Db_rdr rdr = stmt.Exec_select__rls_auto(); + try { + while (rdr.Move_next()) { + ++total_count; // add to total count first so (total_count % interval) is never 0 for total_count = 0 + if (total_count % interval == 0) { + int cur_page_id = rdr.Read_int(page_tbl.Fld_page_id()); + rng_list.Add(Int_obj_ref.new_(cur_page_id)); + } + } + } + finally {rdr.Rls();} + conn.Txn_bgn("rndm_rebuild"); + core_tbl.Upsert(uid, where_sql, total_count, interval); + int rng_ary_len = rng_list.Count(); + rng_tbl.Insert_bgn(uid); + for (int i = 0; i < rng_ary_len; ++i) { + Int_obj_ref rng_itm = (Int_obj_ref)rng_list.Get_at(i); + rng_tbl.Insert_itm(uid, i + 1, rng_itm.Val()); + } + rng_tbl.Insert_end(); + conn.Txn_end(); + } + public int Get_rndm_page(int uid) { // EX: ns=0;type_is_redirect=0 + synchronized (core_row) {core_tbl.Select(core_row, uid);} + int rndm_num = RandomAdp_.new_().Next(core_row.total); + int rng_idx = rndm_num / core_row.interval; + int itm_idx = rndm_num % core_row.interval; + int page_id_bgn = rng_idx == 0 ? 0 : rng_tbl.Select_or_neg_1(uid, rng_idx); + int rv = Select_by_offset(core_row.where_sql, page_id_bgn, itm_idx); + return rv; + } + private int Select_by_offset(String where_sql, int page_id_bgn, int offset) { + Bry_bfr bfr = Bry_bfr.new_(); + where_sql = fmt_where.Fmt_(where_sql).Bld_many_to_str(bfr, page_tbl.Fld_page_ns(), page_tbl.Fld_is_redirect()); + String sql = fmt_sql.Bld_many_to_str(bfr, page_tbl.Tbl_name(), page_tbl.Fld_page_id(), where_sql, page_id_bgn, offset); + Db_rdr rdr = Db_rdr_.Empty; + try { + rdr = page_tbl.Conn().Exec_sql_as_rdr_v2(sql); + return rdr.Move_next() ? rdr.Read_int(page_tbl.Fld_page_id()) : -1; + } + finally {rdr.Rls();} + } + public void Rls() { + stmt__page__random = Db_stmt_.Rls(stmt__page__random); + } + private static final Bry_fmt fmt_sql = Bry_fmt.New(String_.Concat_lines_nl_skip_last + ( "SELECT p.~{page_id}" + , "FROM ~{page} p" + , "WHERE p.~{~page_id} > ~{page_id_bgn}" + , "~{where_sql}" + , "ORDER BY ~{page_id}" + , "LIMIT 1" + , "OFFSET ~{offset};" + ), "page", "page_id", "where_sql", "page_id_bgn", "offset"); + private static final Bry_fmt fmt_where = Bry_fmt.New("", "page_namespace", "page_is_redirect"); +} diff --git a/400_xowa/src/gplx/xowa/specials/randoms/Rndm_range_tbl.java b/400_xowa/src/gplx/xowa/specials/randoms/Rndm_range_tbl.java index 2d72dbbf9..1645bd96a 100644 --- a/400_xowa/src/gplx/xowa/specials/randoms/Rndm_range_tbl.java +++ b/400_xowa/src/gplx/xowa/specials/randoms/Rndm_range_tbl.java @@ -29,29 +29,24 @@ public class Rndm_range_tbl implements Rls_able { conn.Rls_reg(this); } public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds, Dbmeta_idx_itm.new_unique_by_name(tbl_name, "core", fld_rng_uid, fld_rng_idx)));} - public void Insert(int uid, int idx, int page_id) { - if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds); + public void Insert_bgn(int uid) { + conn.Stmt_delete(tbl_name, fld_rng_uid).Crt_int(fld_rng_uid, uid).Exec_delete(); + stmt_insert = conn.Stmt_insert(tbl_name, flds); + } + public void Insert_itm(int uid, int idx, int page_id) { stmt_insert.Clear().Val_int(fld_rng_uid, uid).Val_int(fld_rng_idx, idx).Val_int(fld_rng_page_id, page_id).Exec_insert(); } - public void Select(int type) { -// if (stmt_select == null) stmt_select = conn.Stmt_select(tbl_name, flds, fld_rng_uid); -// Db_rdr rdr = stmt_select.Clear().Val_int(fld_rng_type, type).Exec_select__rls_manual(); -// try { -// int total = rdr.Read_int(fld_rng_total); -// int interval = rdr.Read_int(fld_rng_interval); -// return new Rndm_core_row(type, total, interval); -// } finally {rdr.Rls();} + public void Insert_end() { + stmt_insert = Db_stmt_.Rls(stmt_insert); + } + public int Select_or_neg_1(int core_uid, int rng_idx) { + if (stmt_select == null) stmt_select = conn.Stmt_select(tbl_name, flds, fld_rng_uid, fld_rng_idx); + Db_rdr rdr = stmt_select.Clear().Val_int(fld_rng_uid, core_uid).Val_int(fld_rng_idx, rng_idx).Exec_select__rls_manual(); + try {return rdr.Move_next() ? rdr.Read_int(fld_rng_page_id) : -1;} + catch (Exception e) {Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to get rndm_idx; url=~{0} core_uid=~{1} rng_idx=~{2} err=~{3}", conn.Conn_info().Xto_api(), core_uid, rng_idx, Err_.Message_gplx_log(e)); return -1;} + finally {rdr.Rls();} } public void Rls() { stmt_select = Db_stmt_.Rls(stmt_select); - stmt_insert = Db_stmt_.Rls(stmt_insert); - } - public void Get_random(int uid) { -// Rndm_core_row core_row = core_tbl.Get(uid); -// int rnd = RandomAdp_.new_().Next(core_row.total); -// int idx = rnd / core_row.interval; -// int off = rnd % core_row.interval; -// Rndm_rng_row rng_row = rng_tbl.Get(uid, idx); -// Xowd_page page = page_tbl.Get_by_page_offset(rng_row.page_id_bgn, off); } } diff --git a/400_xowa/src/gplx/xowa/specials/randoms/Xob_rnd_cmd.java b/400_xowa/src/gplx/xowa/specials/randoms/Xob_rnd_cmd.java new file mode 100644 index 000000000..fb518810d --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/randoms/Xob_rnd_cmd.java @@ -0,0 +1,40 @@ +/* +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 . +*/ +package gplx.xowa.specials.randoms; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; +import gplx.xowa.bldrs.*; +public class Xob_rnd_cmd implements Xob_cmd { + private final Xowe_wiki wiki; + private int rndm_uid = 0; private String rndm_where_sql = "AND ~{page_namespace} = 0 AND ~{page_is_redirect} = 0"; private int rndm_interval = 1000; + public Xob_rnd_cmd(Xob_bldr bldr, Xowe_wiki wiki) {this.wiki = wiki;} + public String Cmd_key() {return Xob_cmd_keys.Key_util_random;} + public void Cmd_run() { + wiki.Special_mgr().Page_random().Mgr().Rebuild(rndm_uid, rndm_where_sql, rndm_interval); + } + public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { + if (ctx.Match(k, Invk_rndm_uid_)) rndm_uid = m.ReadInt("v"); + else if (ctx.Match(k, Invk_rndm_where_sql_)) rndm_where_sql = m.ReadStr("v"); + else if (ctx.Match(k, Invk_rndm_interval_)) rndm_interval = m.ReadInt("v"); + else return GfoInvkAble_.Rv_unhandled; + return this; + } private static final String Invk_rndm_uid_ = "rndm_uid_", Invk_rndm_where_sql_ = "rndm_where_sql_", Invk_rndm_interval_ = "rndm_interval_"; + + public void Cmd_init(Xob_bldr bldr) {} + public void Cmd_bgn(Xob_bldr bldr) {} + public void Cmd_end() {} + public void Cmd_term() {} +} diff --git a/400_xowa/src/gplx/xowa/specials/randoms/Xows_page_random.java b/400_xowa/src/gplx/xowa/specials/randoms/Xows_page_random.java index f2a94815d..9b89207f2 100644 --- a/400_xowa/src/gplx/xowa/specials/randoms/Xows_page_random.java +++ b/400_xowa/src/gplx/xowa/specials/randoms/Xows_page_random.java @@ -19,6 +19,7 @@ package gplx.xowa.specials.randoms; import gplx.*; import gplx.xowa.*; import gp import gplx.xowa.wikis.nss.*; public class Xows_page_random implements Xows_page { public Xows_page_random(Xowe_wiki wiki) {} + public Rndm_mgr Mgr() {return mgr;} private final Rndm_mgr mgr = new Rndm_mgr(); public Xows_special_meta Special_meta() {return Xows_special_meta_.Itm__random;} public void Special_gen(Xowe_wiki wiki, Xoae_page page, Xoa_url url, Xoa_ttl ttl) { Xow_ns ns = wiki.Ns_mgr().Names_get_or_main(ttl.Rest_txt()); diff --git a/400_xowa/src/gplx/xowa/specials/search/Srch_db_wkr.java b/400_xowa/src/gplx/xowa/specials/search/Srch_db_wkr.java new file mode 100644 index 000000000..6458035f1 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/Srch_db_wkr.java @@ -0,0 +1,130 @@ +/* +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 . +*/ +package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; +import gplx.core.primitives.*; import gplx.core.brys.fmtrs.*; +import gplx.dbs.*; import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; +import gplx.xowa.wikis.nss.*; import gplx.xowa.langs.cases.*; +import gplx.xowa.specials.search.crts.*; +public class Srch_db_wkr { + private Xol_case_mgr drd_case_mgr; + public Srch_rslt_itm[] Search_by_drd(Cancelable cxl, Srch_rslt_lnr rslt_lnr, Xow_wiki wiki, byte[] search, int search_results_max) { + Xows_ns_mgr ns_mgr = new Xows_ns_mgr(); ns_mgr.Add_main_if_empty(); + Srch_qry qry = new Srch_qry(search, 0, search_results_max, ns_mgr, Bool_.Y, new gplx.xowa.wikis.domains.Xow_domain_itm[] {wiki.Domain_itm()}); + Srch_rslt_hash cache = new Srch_rslt_hash(); cache.Init_by_db(cxl, search, wiki.Data__core_mgr().Db__search().Tbl__search_word()); + if (drd_case_mgr == null) drd_case_mgr = Xol_case_mgr_.U8(); + Search(cxl, rslt_lnr, cache, wiki, drd_case_mgr, qry); + int len = cache.Count(); + Srch_rslt_itm[] rv = new Srch_rslt_itm[len]; + for (int i = 0; i < len; ++i) + rv[i] = cache.Get_at(i); + return rv; + } + @gplx.Internal protected void Search(Cancelable cxl, Srch_rslt_lnr rslt_lnr, Srch_rslt_hash cache, Xow_wiki wiki, Xol_case_mgr case_mgr, Srch_qry qry) { + // get search_words + Xowd_db_file search_db = wiki.Data__core_mgr().Db__search(); + Xoa_app_.Usr_dlg().Prog_many("", "", "search started (please wait)"); + Srch_crt_node ttl_matcher = cache.Ttl_matcher(); + if (ttl_matcher == null) { + cache.Init_by_db(cxl, case_mgr.Case_build_lower(qry.search_raw), search_db.Tbl__search_word()); // lower-case search + ttl_matcher = cache.Ttl_matcher(); + } + // do some init + int rslts_wanted = qry.itms_end - qry.itms_bgn; + Xowd_db_file core_db = wiki.Data__core_mgr().Db__core(); + Xowd_page_tbl page_tbl = core_db.Tbl__page(); + Xowd_search_link_tbl link_tbl = search_db.Tbl__search_link(); + Srch_word_row[] word_ary = cache.Words(); int word_ary_len = word_ary.length; + // read pages for each word from db + Db_attach_rdr attach_rdr = new Db_attach_rdr(search_db.Conn(), "page_db", core_db.Url()); + attach_rdr.Attach(); + int total_found = 0; + try { + while (true) { + boolean found_none = true; + for (int i = 0; i < word_ary_len; ++i) { // loop each word to get rslts_wanted + if (cxl.Canceled()) return; + Srch_word_row word = word_ary[i]; + if (word.Rslts_done()) continue; // last db_search for word returned 0 results; don't search again; + int offset = word.Rslts_offset(); + Xoa_app_.Usr_dlg().Prog_many("", "", "searching; wiki=~{0} total=~{1} offset=~{2} index=~{3} word=~{4}", wiki.Domain_str(), word_ary_len, offset, i, word.text); + String sql = search_fmt.Bld_many_to_str_auto_bfr(link_tbl.Tbl_name(), link_tbl.Fld_page_id(), link_tbl.Fld_word_id(), word.id, offset); // need to return enough results to fill qry.page_len as many results may be discarded below; DATE:2015-04-24 + int rslts_found = Search_pages(cxl, rslt_lnr, cache, wiki, case_mgr, qry, page_tbl, attach_rdr, sql, ttl_matcher, word, rslts_wanted); + total_found += rslts_found; + if (rslts_found == -1) return; // canceled + else if (rslts_found > 0) found_none = false; // NOTE: do not reverse and do rslts_found == 0; want to check if any word returns results; + } + if (found_none) {cache.Done_y_(); break;} + if (total_found >= rslts_wanted) break; + } + cache.Itms_end_(qry.itms_end); + cache.Sort(); + } + catch (Exception e) {Gfo_usr_dlg_.Instance.Warn_many("", "", "error during search; wiki=~{0} total=~{1} err=~{2}", wiki.Domain_str(), word_ary_len, Err_.Message_gplx_log(e));} + finally {attach_rdr.Detach();} + } + private int Search_pages(Cancelable cxl, Srch_rslt_lnr rslt_lnr, Srch_rslt_hash cache, Xow_wiki wiki, Xol_case_mgr case_mgr, Srch_qry qry + , Xowd_page_tbl page_tbl, Db_attach_rdr attach_rdr, String sql, Srch_crt_node ttl_matcher, Srch_word_row word, int rslts_wanted) { + int rslts_found = 0; + Xow_ns_mgr ns_mgr = wiki.Ns_mgr(); + Db_rdr rdr = attach_rdr.Exec_as_rdr(sql); + try { + while (rdr.Move_next()) { + if (cxl.Canceled()) return -1; + word.Rslts_offset_add_1(); + int page_ns = rdr.Read_int(page_tbl.Fld_page_ns()); + if (!qry.ns_mgr.Has(page_ns)) continue; // ignore: ns doesn't match + byte[] page_ttl = rdr.Read_bry_by_str(page_tbl.Fld_page_title()); + // Io_mgr.Instance.AppendFilStr("C:\\temp.txt", String_.new_u8(word.Text()) + "|" + Int_.To_str(page_ns) + "|" + String_.new_u8(page_ttl) + "\n"); + if (!ttl_matcher.Matches(case_mgr, page_ttl)) continue; // ignore: ttl doesn't match ttl_matcher + Xow_ns ns = ns_mgr.Ids_get_or_null(page_ns); + byte[] page_ttl_w_ns = ns.Gen_ttl(page_ttl); + if (cache.Has(page_ttl_w_ns)) continue; // ignore: page already added by another word; EX: "A B"; word is "B", but "A B" already added by "A" + Srch_rslt_itm row = new Srch_rslt_itm(wiki.Domain_bry(), wiki.Ttl_parse(page_ttl_w_ns), rdr.Read_int(page_tbl.Fld_page_id()), rdr.Read_int(page_tbl.Fld_page_len())); + rslt_lnr.Notify_rslt_found(row); + if (++rslts_found == rslts_wanted) break; // stop: found enough results; DATE:2015-04-24 + } + } finally {rdr.Rls();} + if (rslts_found == 0) word.Rslts_done_y_(); // read through entire rdr and nothing found; mark word done + return rslts_found; + } + public Db_stmt New_qry(Db_conn conn, String page_db_alias, Xowd_page_tbl page, Xowd_search_link_tbl link, int offset) { + Db_qry qry = Db_qry_.select_() + .Cols_w_tbl_("p", page.Fld_page_id(), page.Fld_page_ns(), page.Fld_page_title(), page.Fld_page_len()) + .From_(page_db_alias, page.Tbl_name(), "p") + .Join_(link.Tbl_name(), "l", Db_qry_.New_join__join(link.Fld_page_id(), page.Fld_page_id(), "p")) + .Where_(Db_crt_.New_eq("l", link.Fld_word_id(), -1)) + .Order_("p", page.Fld_page_len(), Bool_.N) + .Offset_(offset) + ; +// qry_mgr.Add_ns(qry, page); // qry.Where_and_(page.Fld_page_ns(), -1) + return conn.Stmt_new(qry); + } + private static final Bry_fmt search_fmt = Bry_fmt.New + ( String_.Concat_lines_nl_skip_last + ( "SELECT p.page_id" + , ", p.page_namespace" + , ", p.page_title" + , ", p.page_len" + , "FROM page p" + , " JOIN ~{tbl_link} l ON p.page_id = l.~{col_link_page_id} " + , "WHERE l.~{col_link_word_id} = ~{word_id}" + , "ORDER BY p.page_len DESC" + , "LIMIT -1" // NOTE:LIMIT needed when OFFSET is specified; -1 LIMIT means infinite; "If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned"; http://sqlite.org/lang_select.html + , "OFFSET ~{offset};" + ), "tbl_link", "col_link_page_id", "col_link_word_id", "word_id", "offset"); +} diff --git a/400_xowa/src/gplx/xowa/specials/search/Srch_qry.java b/400_xowa/src/gplx/xowa/specials/search/Srch_qry.java new file mode 100644 index 000000000..25e78fd93 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/Srch_qry.java @@ -0,0 +1,44 @@ +/* +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 . +*/ +package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; +import gplx.xowa.wikis.domains.*; +class Srch_qry { + private final List_adp cmd_list = List_adp_.new_(); + public Srch_qry(byte[] search_raw, int page_idx, int page_len, Xows_ns_mgr ns_mgr, boolean async_db, Xow_domain_itm[] wiki_domains) { + this.search_raw = search_raw; this.page_idx = page_idx; this.page_len = page_len; this.ns_mgr = ns_mgr; this.async_db = async_db; this.wiki_domains = wiki_domains; + this.itms_bgn = page_idx * page_len; + this.itms_end = itms_bgn + page_len; + this.page_max = page_idx; // default page_max to page_idx; adjust later when all results are known + this.key = Bry_.Add_w_dlm(Byte_ascii.Pipe, search_raw, ns_mgr.To_hash_key()); + this.special_link_base_href = Bry_.Add(Bry_.new_a7("Special:Search/"), search_raw, Bry_.new_a7("?fulltext=y")); + } + public final byte[] key; + public final byte[] search_raw; + public final int page_idx; + public final int page_len; + public final int itms_bgn; + public final int itms_end; + public final Xows_ns_mgr ns_mgr; + public final Xow_domain_itm[] wiki_domains; + public final byte[] special_link_base_href; + public final boolean async_db; + public int page_max; + public int Cmds__len() {return cmd_list.Count();} + public Xows_ui_cmd Cmds__get_at(int i) {return (Xows_ui_cmd)cmd_list.Get_at(i);} + public void Cmds__add(Xows_ui_cmd cmd) {cmd_list.Add(cmd);} +} diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java b/400_xowa/src/gplx/xowa/specials/search/Srch_rslt_hash.java similarity index 56% rename from 400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java rename to 400_xowa/src/gplx/xowa/specials/search/Srch_rslt_hash.java index 36bc69784..a76a1c620 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_cache.java +++ b/400_xowa/src/gplx/xowa/specials/search/Srch_rslt_hash.java @@ -16,27 +16,27 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -import gplx.xowa.specials.search.parsers_old.*; -class Xows_db_cache { // one cache per search term; EX: "Earth* AND (History OR Future) AND -"middle earth"" is one cache +import gplx.xowa.specials.search.crts.*; +class Srch_rslt_hash { // per search request; EX: 'Earth* AND (History OR Future) AND -"middle earth"' private final Ordered_hash hash = Ordered_hash_.New_bry(); - public Xows_db_word[] Words() {return words;} private Xows_db_word[] words; // words in cache; EX: earth, history, future but not "middle earth" (since not'ed) - public Xows_db_matcher Matcher() {return matcher;} private Xows_db_matcher matcher; // criteria - public boolean Done() {return done;} public void Done_y_() {done = true;} private boolean done; // marks if db search is done + public Srch_crt_node Ttl_matcher() {return ttl_matcher;} private Srch_crt_node ttl_matcher; + public Srch_word_row[] Words() {return words;} private Srch_word_row[] words; // words to search db; EX: earth, history, future but not "middle earth" (since not'ed) + public boolean Done() {return done;} public void Done_y_() {done = true;} private boolean done; // marks if db search is done public int Count() {return hash.Count();} public int Itms_end() {return itms_end;} public void Itms_end_(int v) {itms_end = v;} private int itms_end; public void Init_by_db(Cancelable cxl, byte[] raw, gplx.xowa.wikis.data.tbls.Xowd_search_word_tbl word_tbl) { - this.matcher = new Xow_search_parser().Parse(raw); - this.words = new Xows_db_matcher_bldr().Gather_words_for_db(cxl, matcher, word_tbl); + this.ttl_matcher = new Srch_crt_parser().Parse(raw); + this.words = new Xows_db_matcher_bldr().Gather_words_for_db(cxl, ttl_matcher, word_tbl); } - public boolean Has(byte[] key) {return hash.Has(key);} - public Xows_db_row Get_at(int i) {return (Xows_db_row)hash.Get_at(i);} - public void Add(Xows_db_row row) {hash.Add(row.Page_ttl().Full_db(), row);} - public void Get_between(Xows_ui_rslt search_ui, int bgn, int end) { + public boolean Has(byte[] key) {return hash.Has(key);} + public Srch_rslt_itm Get_at(int i) {return (Srch_rslt_itm)hash.Get_at(i);} + public void Add(Srch_rslt_itm itm) {hash.Add(itm.page_ttl.Full_db(), itm);} + public void Get_between(Srch_rslt_list search_ui, int bgn, int end) { if (bgn >= hash.Count()) return; // requested start not in cache; exit for (int i = bgn; i < end; ++i) { if (i >= hash.Count()) break; - search_ui.Add((Xows_db_row)hash.Get_at(i)); + search_ui.Add((Srch_rslt_itm)hash.Get_at(i)); } } - public void Sort() {hash.Sort_by(Xows_db_row_sorter.Page_len_dsc);} + public void Sort() {hash.Sort_by(Srch_rslt_itm_sorter.Page_len_dsc);} } diff --git a/400_xowa/src/gplx/xowa/specials/search/Srch_rslt_itm.java b/400_xowa/src/gplx/xowa/specials/search/Srch_rslt_itm.java new file mode 100644 index 000000000..69eb78732 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/Srch_rslt_itm.java @@ -0,0 +1,40 @@ +/* +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 . +*/ +package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; +public class Srch_rslt_itm { + public final byte[] key; + public final byte[] wiki_bry; + public final Xoa_ttl page_ttl; + public final int page_id; + public final int page_len; + public Srch_rslt_itm(byte[] wiki_bry, Xoa_ttl page_ttl, int page_id, int page_len) { + this.wiki_bry = wiki_bry; + this.page_ttl = page_ttl; + this.page_id = page_id; + this.page_len = page_len; + this.key = Bry_.Add(wiki_bry, Byte_ascii.Pipe_bry, page_ttl.Full_db()); + } +} +class Srch_rslt_itm_sorter implements gplx.core.lists.ComparerAble { + public int compare(Object lhsObj, Object rhsObj) { + Srch_rslt_itm lhs = (Srch_rslt_itm)lhsObj; + Srch_rslt_itm rhs = (Srch_rslt_itm)rhsObj; + return -Int_.Compare(lhs.page_len, rhs.page_len); + } + public static final Srch_rslt_itm_sorter Page_len_dsc = new Srch_rslt_itm_sorter(); Srch_rslt_itm_sorter() {} +} diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_rslt.java b/400_xowa/src/gplx/xowa/specials/search/Srch_rslt_list.java similarity index 75% rename from 400_xowa/src/gplx/xowa/specials/search/Xows_ui_rslt.java rename to 400_xowa/src/gplx/xowa/specials/search/Srch_rslt_list.java index 276a7b329..8b89c8a2a 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_rslt.java +++ b/400_xowa/src/gplx/xowa/specials/search/Srch_rslt_list.java @@ -16,9 +16,9 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -class Xows_ui_rslt { - private final List_adp rslt_list = List_adp_.new_(); - public int Len() {return rslt_list.Count();} - public void Add(Xows_db_row rslt) {rslt_list.Add(rslt);} - public Xows_db_row Get_at(int i) {return (Xows_db_row)rslt_list.Get_at(i);} +class Srch_rslt_list { + private final List_adp list = List_adp_.new_(); + public int Len() {return list.Count();} + public void Add(Srch_rslt_itm rslt) {list.Add(rslt);} + public Srch_rslt_itm Get_at(int i) {return (Srch_rslt_itm)list.Get_at(i);} } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async.java b/400_xowa/src/gplx/xowa/specials/search/Srch_rslt_lnr.java similarity index 90% rename from 400_xowa/src/gplx/xowa/specials/search/Xows_ui_async.java rename to 400_xowa/src/gplx/xowa/specials/search/Srch_rslt_lnr.java index a9815b5bd..0d32723bc 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async.java +++ b/400_xowa/src/gplx/xowa/specials/search/Srch_rslt_lnr.java @@ -16,6 +16,6 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -public interface Xows_ui_async { - void Add(Xows_db_row new_row); +public interface Srch_rslt_lnr { + void Notify_rslt_found(Srch_rslt_itm rslt); } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_word.java b/400_xowa/src/gplx/xowa/specials/search/Srch_word_row.java similarity index 61% rename from 400_xowa/src/gplx/xowa/specials/search/Xows_db_word.java rename to 400_xowa/src/gplx/xowa/specials/search/Srch_word_row.java index 25a7a4a27..46094355a 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_word.java +++ b/400_xowa/src/gplx/xowa/specials/search/Srch_word_row.java @@ -16,21 +16,21 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -public class Xows_db_word { - public Xows_db_word(int id, byte[] text, int page_count) {this.id = id; this.text = text; this.page_count = page_count;} - public int Id() {return id;} private final int id; - public byte[] Text() {return text;} private final byte[] text; - public int Page_count() {return page_count;} private final int page_count; +public class Srch_word_row { + public Srch_word_row(int id, byte[] text, int page_count) {this.id = id; this.text = text; this.page_count = page_count;} + public final int id; + public final byte[] text; + public final int page_count; public int Rslts_offset() {return rslts_offset;} private int rslts_offset; public boolean Rslts_done() {return rslts_done;} private boolean rslts_done; public void Rslts_offset_add_1() {++rslts_offset;} public void Rslts_done_y_() {rslts_done = true;} } -class Xows_db_word_sorter implements gplx.core.lists.ComparerAble { +class Srch_word_row_sorter implements gplx.core.lists.ComparerAble { public int compare(Object lhsObj, Object rhsObj) { - Xows_db_word lhs = (Xows_db_word)lhsObj; - Xows_db_word rhs = (Xows_db_word)rhsObj; - return -Int_.Compare(lhs.Page_count(), rhs.Page_count()); + Srch_word_row lhs = (Srch_word_row)lhsObj; + Srch_word_row rhs = (Srch_word_row)rhsObj; + return -Int_.Compare(lhs.page_count, rhs.page_count); } - public static final Xows_db_word_sorter Page_count_dsc = new Xows_db_word_sorter(); Xows_db_word_sorter() {} + public static final Srch_word_row_sorter Page_count_dsc = new Srch_word_row_sorter(); Srch_word_row_sorter() {} } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_core.java b/400_xowa/src/gplx/xowa/specials/search/Xows_core.java index 0199abf59..18cc50fa5 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_core.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_core.java @@ -24,17 +24,17 @@ class Xows_core { private boolean ask_for_upgrade = true; private final Hash_adp_bry upgraded_wikis = Hash_adp_bry.cs(); public Xows_core(Xoae_wiki_mgr wiki_mgr) {this.wiki_mgr = wiki_mgr;} private final Xows_html_wkr html_wkr = new Xows_html_wkr(); - public Xows_db_cache Get_cache_or_new(byte[] key) { - Xows_db_cache cache = (Xows_db_cache)cache_hash.Get_by_bry(key); + public Srch_rslt_hash Get_cache_or_new(byte[] key) { + Srch_rslt_hash cache = (Srch_rslt_hash)cache_hash.Get_by_bry(key); if (cache == null) { - cache = new Xows_db_cache(); + cache = new Srch_rslt_hash(); cache_hash.Add_bry_obj(key, cache); } return cache; } - public void Search(Xow_wiki search_wiki, Xoae_page page, Xows_ui_qry qry) { + public void Search(Xow_wiki search_wiki, Xoae_page page, Srch_qry qry) { // generate 1 cmd per wiki - Xow_domain_itm[] domain_ary = qry.Wiki_domains(); int domain_ary_len = domain_ary.length; + Xow_domain_itm[] domain_ary = qry.wiki_domains; int domain_ary_len = domain_ary.length; for (int i = 0; i < domain_ary_len; ++i) { Xow_domain_itm domain = domain_ary[i]; try { @@ -44,7 +44,7 @@ class Xows_core { qry.Cmds__add(cmd); } catch (Exception e) {Xoa_app_.Usr_dlg().Warn_many("", "", "search:wiki failed; wiki=~{0} err=~{1}", domain.Domain_str(), Err_.Message_lang(e));} // handle bad wikis, like "en.wikipedia.org-old"; DATE:2015-04-24 } - qry.Page_max_(Int_.Max_value); + qry.page_max = Int_.Max_value; // do search and generate html html_wkr.Init_by_wiki(search_wiki, search_wiki.Lang().Num_mgr(), qry); int cmds_len = qry.Cmds__len(); diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher.java b/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher.java deleted file mode 100644 index b1e083f33..000000000 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher.java +++ /dev/null @@ -1,68 +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 . -*/ -package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -import gplx.langs.regxs.*; -public class Xows_db_matcher { - private final Gfo_pattern raw_pattern; - public Xows_db_matcher(int tid, byte[] raw, Xows_db_matcher lhs, Xows_db_matcher rhs) { - this.tid = tid; this.raw = raw; this.lhs = lhs; this.rhs = rhs; - this.raw_pattern = Bry_.Has(raw, Byte_ascii.Star) ? new Gfo_pattern(raw) : null; - } - public int Tid() {return tid;} private final int tid; - public int Page_count() {return page_count;} public void Page_count_(int v) {page_count = v;} private int page_count; - public byte[] Raw() {return raw;} private final byte[] raw; - public Xows_db_matcher Lhs() {return lhs;} private final Xows_db_matcher lhs; - public Xows_db_matcher Rhs() {return rhs;} private final Xows_db_matcher rhs; - public boolean Matches(byte[] page_ttl_lc, byte[][] page_ttl_words) { - switch (tid) { - case Xows_db_matcher.Tid_word: { - int len = page_ttl_words.length; - for (int i = 0; i < len; ++i) { - byte[] word = page_ttl_words[i]; - if (raw_pattern == null) { - if (Bry_.Eq(word, raw)) return true; - } - else { - if (raw_pattern.Match(word)) return true; - } - } - return false; - } - case Xows_db_matcher.Tid_word_quote: // note that raw does not have quotes; EX: "B*" -> B* - return Bry_find_.Find_fwd(page_ttl_lc, raw) != Bry_find_.Not_found; - case Xows_db_matcher.Tid_not: - return !rhs.Matches(page_ttl_lc, page_ttl_words); - case Xows_db_matcher.Tid_or: - return lhs.Matches(page_ttl_lc, page_ttl_words) || rhs.Matches(page_ttl_lc, page_ttl_words); - case Xows_db_matcher.Tid_and: - return lhs.Matches(page_ttl_lc, page_ttl_words) && rhs.Matches(page_ttl_lc, page_ttl_words); - case Xows_db_matcher.Tid_null: return false; - default: throw Err_.new_unhandled(tid); - } - } - public static final Xows_db_matcher Null = new Xows_db_matcher(Xows_db_matcher.Tid_null, null, null, null); - public static Xows_db_matcher new_join(byte tid, Xows_db_matcher lhs, Xows_db_matcher rhs) {return new Xows_db_matcher(tid, null, lhs, rhs);} - public static final int - Tid_word = 0 - , Tid_and = 1 - , Tid_or = 2 - , Tid_not = 3 - , Tid_word_quote = 4 - , Tid_null = 5 - ; -} diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher_bldr.java b/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher_bldr.java index 07a3df887..6c6eb3069 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher_bldr.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_db_matcher_bldr.java @@ -17,47 +17,48 @@ along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.wikis.data.tbls.*; +import gplx.xowa.specials.search.crts.*; class Xows_db_matcher_bldr { - public Xows_db_word[] Gather_words_for_db(Cancelable cxl, Xows_db_matcher matcher, Xowd_search_word_tbl word_tbl) { + public Srch_word_row[] Gather_words_for_db(Cancelable cxl, Srch_crt_node matcher, Xowd_search_word_tbl word_tbl) { List_adp rv = List_adp_.new_(); Gather_words_for_db(cxl, matcher, rv, word_tbl); - rv.Sort_by(Xows_db_word_sorter.Page_count_dsc); - return (Xows_db_word[])rv.To_ary(Xows_db_word.class); + rv.Sort_by(Srch_word_row_sorter.Page_count_dsc); + return (Srch_word_row[])rv.To_ary(Srch_word_row.class); } - private void Gather_words_for_db(Cancelable cxl, Xows_db_matcher matcher, List_adp rv, Xowd_search_word_tbl word_tbl) { - switch (matcher.Tid()) { - case Xows_db_matcher.Tid_word: - byte[] word_text = matcher.Raw(); + private void Gather_words_for_db(Cancelable cxl, Srch_crt_node matcher, List_adp rv, Xowd_search_word_tbl word_tbl) { + switch (matcher.tid) { + case Srch_crt_node.Tid_word: + byte[] word_text = matcher.raw; if (Bry_.Has(word_text, Byte_ascii.Star)) Load_word_many(cxl, rv, word_text, word_tbl); else Load_word_one(rv, word_text, word_tbl); break; - case Xows_db_matcher.Tid_word_quote: + case Srch_crt_node.Tid_word_quote: List_adp tmp = List_adp_.new_(); - byte[][] words = Bry_split_.Split(matcher.Raw(), Byte_ascii.Space, Bool_.Y); + byte[][] words = Bry_split_.Split(matcher.raw, Byte_ascii.Space, Bool_.Y); int words_len = words.length; for (int i = 0; i < words_len; ++i) { byte[] word = words[i]; Load_word_one(tmp, word, word_tbl); } if (tmp.Count() == 0) return; // no words in db; EX: "xyz cba" - tmp.Sort_by(Xows_db_word_sorter.Page_count_dsc); + tmp.Sort_by(Srch_word_row_sorter.Page_count_dsc); rv.Add(tmp.Get_at(0)); // add lowest page_count word to db; EX: search for "earth and" should search for "earth" only, but match for "earth and" break; - case Xows_db_matcher.Tid_and: + case Srch_crt_node.Tid_and: List_adp lhs_tmp = List_adp_.new_(), rhs_tmp = List_adp_.new_(); - Gather_words_for_db(cxl, matcher.Lhs(), lhs_tmp, word_tbl); - Gather_words_for_db(cxl, matcher.Rhs(), rhs_tmp, word_tbl); + Gather_words_for_db(cxl, matcher.lhs, lhs_tmp, word_tbl); + Gather_words_for_db(cxl, matcher.rhs, rhs_tmp, word_tbl); List_adp_.Add_list(rv, Calc_lowest(lhs_tmp, rhs_tmp)); // calc side with lowest count; add to rv; break; - case Xows_db_matcher.Tid_or: - Gather_words_for_db(cxl, matcher.Lhs(), rv, word_tbl); - Gather_words_for_db(cxl, matcher.Rhs(), rv, word_tbl); + case Srch_crt_node.Tid_or: + Gather_words_for_db(cxl, matcher.lhs, rv, word_tbl); + Gather_words_for_db(cxl, matcher.rhs, rv, word_tbl); break; - case Xows_db_matcher.Tid_not: break; // never add "NOT" to db_search - case Xows_db_matcher.Tid_null: break; // should not happen - default: throw Err_.new_unhandled(matcher.Tid()); + case Srch_crt_node.Tid_not: break; // never add "NOT" to db_search + case Srch_crt_node.Tid_null: break; // should not happen + default: throw Err_.new_unhandled(matcher.tid); } } private List_adp Calc_lowest(List_adp lhs, List_adp rhs) { @@ -72,15 +73,15 @@ class Xows_db_matcher_bldr { int rv = 0; int len = list.Count(); for (int i = 0; i < len; ++i) { - Xows_db_word word = (Xows_db_word)list.Get_at(i); - rv += word.Page_count(); + Srch_word_row word = (Srch_word_row)list.Get_at(i); + rv += word.page_count; } return rv; } private void Load_word_one(List_adp rv, byte[] word_text, Xowd_search_word_tbl word_tbl) { Xoa_app_.Usr_dlg().Prog_many("", "", "search:word by text; word=~{0}", word_text); Xowd_search_word_row row = word_tbl.Select_by_or_null(word_text); if (row == Xowd_search_word_row.Null) return; - Xows_db_word word = new Xows_db_word(row.Id(), row.Text(), row.Page_count()); + Srch_word_row word = new Srch_word_row(row.Id(), row.Text(), row.Page_count()); rv.Add(word); } private void Load_word_many(Cancelable cxl, List_adp rv, byte[] word_text, Xowd_search_word_tbl word_tbl) { @@ -89,7 +90,7 @@ class Xows_db_matcher_bldr { int len = rows.length; for (int i = 0; i < len; ++i) { Xowd_search_word_row row = rows[i]; - rv.Add(new Xows_db_word(row.Id(), row.Text(), row.Page_count())); + rv.Add(new Srch_word_row(row.Id(), row.Text(), row.Page_count())); } } } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_row.java b/400_xowa/src/gplx/xowa/specials/search/Xows_db_row.java deleted file mode 100644 index 19525b5f4..000000000 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_row.java +++ /dev/null @@ -1,41 +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 . -*/ -package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -public class Xows_db_row { - public Xows_db_row(byte[] wiki_domain, Xoa_ttl page_ttl, int page_id, int page_len) { - this.wiki_domain = wiki_domain; - this.page_ttl = page_ttl; - this.page_id = page_id; - this.page_len = page_len; - this.key = Bry_.Add(wiki_domain, Byte_ascii.Pipe_bry, page_ttl.Full_db()); - } - public byte[] Key() {return key;} private final byte[] key; - public byte[] Wiki_domain() {return wiki_domain;} private final byte[] wiki_domain; - public Xoa_ttl Page_ttl() {return page_ttl;} private final Xoa_ttl page_ttl; - public int Page_id() {return page_id;} private final int page_id; - public int Page_len() {return page_len;} private final int page_len; - public static Xows_db_row[] Ary(Xows_db_row... v) {return v;} -} -class Xows_db_row_sorter implements gplx.core.lists.ComparerAble { - public int compare(Object lhsObj, Object rhsObj) { - Xows_db_row lhs = (Xows_db_row)lhsObj; - Xows_db_row rhs = (Xows_db_row)rhsObj; - return -Int_.Compare(lhs.Page_len(), rhs.Page_len()); - } - public static final Xows_db_row_sorter Page_len_dsc = new Xows_db_row_sorter(); Xows_db_row_sorter() {} -} diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_db_wkr.java b/400_xowa/src/gplx/xowa/specials/search/Xows_db_wkr.java deleted file mode 100644 index 159d9e030..000000000 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_db_wkr.java +++ /dev/null @@ -1,125 +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 . -*/ -package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -import gplx.core.primitives.*; import gplx.dbs.*; -import gplx.xowa.wikis.nss.*; -import gplx.xowa.wikis.data.*; import gplx.xowa.wikis.data.tbls.*; import gplx.xowa.langs.cases.*; -import gplx.gfui.*; -public class Xows_db_wkr { - private Xol_case_mgr drd_case_mgr; - public Xows_db_row[] Search_by_drd(Cancelable cancelable, Xow_wiki wiki, Xows_ui_async ui_async, byte[] search, int search_results_max) { - Xows_ns_mgr ns_mgr = new Xows_ns_mgr(); ns_mgr.Add_main_if_empty(); - Xows_ui_qry qry = new Xows_ui_qry(search, 0, search_results_max, Xosrh_rslt_itm_sorter.Tid_len_dsc, ns_mgr, Bool_.Y, new gplx.xowa.wikis.domains.Xow_domain_itm[] {wiki.Domain_itm()}); - Xows_ui_rslt rslt = new Xows_ui_rslt(); - Xows_db_cache cache = new Xows_db_cache(); cache.Init_by_db(Cancelable_.Never, search, wiki.Data__core_mgr().Db__search().Tbl__search_word()); - Xows_ui_cmd cmd = new Xows_ui_cmd(null, qry, wiki, null, null, null, cache, ui_async); - if (drd_case_mgr == null) drd_case_mgr = Xol_case_mgr_.U8(); - Search(cancelable, cmd, qry, rslt, cache, wiki, drd_case_mgr); - int len = cache.Count(); - Xows_db_row[] rv = new Xows_db_row[len]; - for (int i = 0; i < len; ++i) - rv[i] = cache.Get_at(i); - return rv; - } - @gplx.Internal protected void Search(Cancelable cancelable, Xows_ui_cmd cmd, Xows_ui_qry qry, Xows_ui_rslt rslt, Xows_db_cache cache, Xow_wiki wiki, Xol_case_mgr case_mgr) { - // assert matcher - Xowd_db_file search_db = wiki.Data__core_mgr().Db__search(); - Xoa_app_.Usr_dlg().Prog_many("", "", "search started (please wait)"); - Xows_db_matcher matcher = cache.Matcher(); - if (matcher == null) { - cache.Init_by_db - ( cmd - , wiki.Lang().Case_mgr().Case_build_lower(qry.Search_raw()) // lower-case search - , search_db.Tbl__search_word() - ); - matcher = cache.Matcher(); - } - // init - int rslts_wanted = qry.Itms_end() - qry.Itms_bgn(); - Xowd_db_file core_db = wiki.Data__core_mgr().Db__core(); - Xowd_page_tbl page_tbl = core_db.Tbl__page(); - Xowd_search_link_tbl link_tbl = search_db.Tbl__search_link(); - Xows_db_word[] word_ary = cache.Words(); int word_ary_len = word_ary.length; - // read pages for each word from db - Db_attach_rdr attach_rdr = new Db_attach_rdr(search_db.Conn(), "page_db", core_db.Url()); - attach_rdr.Attach(); - int total_found = 0; - try { - while (true) { - boolean found_none = true; - for (int i = 0; i < word_ary_len; ++i) { // loop each word to get rslts_wanted - if (cancelable.Canceled()) return; - Xows_db_word word = word_ary[i]; - if (word.Rslts_done()) continue; // last db_search for word returned 0 results; don't search again; - int offset = word.Rslts_offset(); - Xoa_app_.Usr_dlg().Prog_many("", "", "searching; wiki=~{0} total=~{1} offset=~{2} index=~{3} word=~{4}", wiki.Domain_str(), word_ary_len, offset, i, word.Text()); - String sql = String_.Format(Search_sql, link_tbl.Tbl_name(), link_tbl.Fld_page_id(), link_tbl.Fld_word_id(), word.Id(), "page_len", "DESC", Int_.Max_value, offset); // need to return enough results to fill qry.Page_len() as many results may be discarded below; DATE:2015-04-24 - int rslts_found = Search_pages(cancelable, cmd, qry, rslt, cache, wiki, case_mgr, page_tbl, attach_rdr, sql, word, matcher, rslts_wanted); - total_found += rslts_found; - if (rslts_found == -1) return; // canceled - else if (rslts_found > 0) found_none = false; // NOTE: do not reverse and do rslts_found == 0; want to check if any word returns results; - } - if (found_none) {cache.Done_y_(); break;} - if (total_found >= rslts_wanted) break; - } - cache.Itms_end_(qry.Itms_end()); - cache.Sort(); - } finally {attach_rdr.Detach();} - } - private int Search_pages(Cancelable cancelable, Xows_ui_cmd cmd, Xows_ui_qry qry, Xows_ui_rslt rslt, Xows_db_cache cache, Xow_wiki wiki, Xol_case_mgr case_mgr, Xowd_page_tbl page_tbl, Db_attach_rdr attach_rdr, String sql, Xows_db_word word, Xows_db_matcher matcher, int rslts_wanted) { - int rslts_found = 0; - Xow_ns_mgr ns_mgr = wiki.Ns_mgr(); - Db_rdr rdr = attach_rdr.Exec_as_rdr(sql); - try { - while (rdr.Move_next()) { - if (cancelable.Canceled()) return -1; - word.Rslts_offset_add_1(); - int page_ns = rdr.Read_int(page_tbl.Fld_page_ns()); - if (!qry.Ns_mgr().Has(page_ns)) continue; // ignore: ns doesn't match - byte[] page_ttl = rdr.Read_bry_by_str(page_tbl.Fld_page_title()); - // Io_mgr.Instance.AppendFilStr("C:\\temp.txt", String_.new_u8(word.Text()) + "|" + Int_.To_str(page_ns) + "|" + String_.new_u8(page_ttl) + "\n"); - byte[] page_ttl_lc = case_mgr.Case_build_lower(Xoa_ttl.Replace_unders(page_ttl)); - byte[][] page_ttl_words = Bry_split_.Split(page_ttl_lc, Byte_ascii.Space, Bool_.Y); - if (!matcher.Matches(page_ttl_lc, page_ttl_words)) continue; // ignore: ttl doesn't match matcher - int page_id = rdr.Read_int(page_tbl.Fld_page_id()); - int page_len = rdr.Read_int(page_tbl.Fld_page_len()); - Xow_ns ns = ns_mgr.Ids_get_or_null(page_ns); - byte[] page_ttl_w_ns = ns.Gen_ttl(page_ttl); - if (cache.Has(page_ttl_w_ns)) continue; // ignore: page already added by another word; EX: "A B"; word is "B", but "A B" already added by "A" - Xoa_ttl ttl = wiki.Ttl_parse(page_ttl_w_ns); - Xows_db_row row = new Xows_db_row(wiki.Domain_bry(), ttl, page_id, page_len); - cmd.Add_rslt(row); - if (++rslts_found == rslts_wanted) break; // stop: found enough results; DATE:2015-04-24 - } - } finally {rdr.Rls();} - if (rslts_found == 0) word.Rslts_done_y_(); // read through entire rdr and nothing found; mark word done - return rslts_found; - } - private static final String Search_sql = String_.Concat_lines_nl_skip_last - ( "SELECT cp.page_id" - , ", cp.page_namespace" - , ", cp.page_title" - , ", cp.page_len" - , "FROM {0} sp" - , " JOIN page cp ON cp.page_id = sp.{1} " - , "WHERE sp.{2} = {3}" - , "ORDER BY {4} {5}" - , "LIMIT {6}" - , "OFFSET {7};" - ); -} diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr.java b/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr.java index 057e18f66..8c5464c4e 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr.java @@ -20,34 +20,34 @@ import gplx.core.brys.fmtrs.*; import gplx.langs.htmls.*; import gplx.xowa.htmls.core.htmls.utls.*; import gplx.xowa.langs.numbers.*; class Xows_html_wkr { private final Bry_bfr tmp_bfr = Bry_bfr.new_(255); - private Xows_ui_qry qry; private Xow_wiki wiki; private Xol_num_mgr num_mgr; + private Srch_qry qry; private Xow_wiki wiki; private Xol_num_mgr num_mgr; private Xoh_lnki_bldr lnki_bldr; private Xoh_anchor_kv_bldr self_lnkr = new Xoh_anchor_kv_bldr(); private Xows_html_row html_rows; - public void Init_by_wiki(Xow_wiki wiki, Xol_num_mgr num_mgr, Xows_ui_qry qry) { + public void Init_by_wiki(Xow_wiki wiki, Xol_num_mgr num_mgr, Srch_qry qry) { this.wiki = wiki; this.num_mgr = num_mgr; this.qry = qry; this.lnki_bldr = wiki.App().Html__lnki_bldr(); this.html_rows = new Xows_html_row(lnki_bldr); - self_lnkr.Init_w_qarg(qry.Special_link_base_href()); + self_lnkr.Init_w_qarg(qry.special_link_base_href); } public byte[] Gen_page(byte[] tbls) { - byte[] rslts_hdr = fmtr_rslts.Bld_bry_many(tmp_bfr, num_mgr.Format_num(qry.Itms_bgn() + List_adp_.Base1), num_mgr.Format_num(qry.Itms_end()), qry.Search_raw()); + byte[] rslts_hdr = fmtr_rslts.Bld_bry_many(tmp_bfr, num_mgr.Format_num(qry.itms_bgn + List_adp_.Base1), num_mgr.Format_num(qry.itms_end), qry.search_raw); byte[] option_link = lnki_bldr.Href_(Bry_.new_a7("home"), wiki.Ttl_parse(Bry_.new_a7("Help:Options/Search"))).Img_16x16(Xoh_img_path.Img_option).Bld_to_bry(); fmtr_page.Bld_bfr_many(tmp_bfr, rslts_hdr, option_link, Paging_link(Bool_.N), Paging_link(Bool_.Y), tbls); return tmp_bfr.To_bry_and_clear(); } - public void Gen_tbl(Bry_bfr bfr, Xows_ui_rslt rslt, byte[] cmd_key, byte[] wiki_domain, boolean searching_db) { + public void Gen_tbl(Bry_bfr bfr, Srch_rslt_list rslt, byte[] cmd_key, byte[] wiki_domain, boolean searching_db) { html_rows.Init(rslt); byte[] search_link = lnki_bldr.Href_(wiki_domain, wiki.Ttl_parse(self_lnkr.Bld_to_bry())).Caption_(wiki_domain).Img_16x16(Xoh_img_path.Img_search).Img_pos_is_left_(Bool_.Y).Bld_to_bry(); fmtr_tbl.Bld_bfr_many(bfr, search_link, searching_db ? Cancel_link(wiki_domain, cmd_key) : Bry_.Empty, Bry_hdr_len, Bry_hdr_ttl, Xows_ui_async__html.Gen_insert_key(wiki_domain), html_rows); } private byte[] Cancel_link(byte[] domain, byte[] cmd_key) { lnki_bldr.Id_(Bry_.Add(Bry_.new_a7("xowa_cancel_"), domain)); - lnki_bldr.Href_(wiki, self_lnkr.Add_int(Xows_arg_mgr.Arg_bry_page_index, qry.Page_idx()).Add_bry(Xows_arg_mgr.Arg_bry_cancel, cmd_key).Bld_to_bry()); + lnki_bldr.Href_(wiki, self_lnkr.Add_int(Xows_arg_mgr.Arg_bry_page_index, qry.page_idx).Add_bry(Xows_arg_mgr.Arg_bry_cancel, cmd_key).Bld_to_bry()); lnki_bldr.Title_(Bry_cancel); lnki_bldr.Img_16x16(Xoh_img_path.Img_cancel); return lnki_bldr.Bld_to_bry(); } public byte[] Paging_link(boolean fwd) { - int paging_idx = qry.Page_idx(); + int paging_idx = qry.page_idx; byte[] title = null, img_path = Bry_.Empty; boolean img_pos_is_left = true; if (fwd) { @@ -92,24 +92,24 @@ class Xows_html_wkr { ; } class Xows_html_row implements gplx.core.brys.Bfr_arg { - private final Xoh_lnki_bldr lnki_bldr; private Xows_ui_rslt rslt; + private final Xoh_lnki_bldr lnki_bldr; private Srch_rslt_list rslt; private final Object thread_lock = new Object(); public Xows_html_row(Xoh_lnki_bldr lnki_bldr) {this.lnki_bldr = lnki_bldr;} - public Xows_html_row Init(Xows_ui_rslt rslt) {this.rslt = rslt; return this;} + public Xows_html_row Init(Srch_rslt_list rslt) {this.rslt = rslt; return this;} public void Bfr_arg__add(Bry_bfr bfr) { // A int len = rslt.Len(); for (int i = 0; i < len; ++i) { - Xows_db_row row = rslt.Get_at(i); + Srch_rslt_itm row = rslt.Get_at(i); Gen_html(bfr, row); } } - public void Gen_html(Bry_bfr bfr, Xows_db_row row) { + public void Gen_html(Bry_bfr bfr, Srch_rslt_itm row) { synchronized (thread_lock) { - lnki_bldr.Href_(row.Wiki_domain(), row.Page_ttl()); - byte[] title = row.Page_ttl().Full_txt(); + lnki_bldr.Href_(row.wiki_bry, row.page_ttl); + byte[] title = row.page_ttl.Full_txt(); lnki_bldr.Title_(title); lnki_bldr.Caption_(title); - fmtr.Bld_bfr_many(bfr, Gfh_utl.Encode_id_as_str(row.Key()), row.Page_len(), lnki_bldr.Bld_to_bry()); + fmtr.Bld_bfr_many(bfr, Gfh_utl.Encode_id_as_str(row.key), row.page_len, lnki_bldr.Bld_to_bry()); } } public Bry_fmtr Fmtr() {return fmtr;} private final Bry_fmtr fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr_tst.java b/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr_tst.java index 3ae71d046..cb426250b 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr_tst.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_html_wkr_tst.java @@ -28,7 +28,7 @@ public class Xows_html_wkr_tst { fxt.Test_paging(Bool_.N, 0, " "); } @Test public void Rows() { - fxt.Test_rows(Xows_db_row.Ary(fxt.Make_row(10, "A"), fxt.Make_row(20, "B")), String_.Concat_lines_nl_skip_last + fxt.Test_rows(new Srch_rslt_itm[] {fxt.Make_row(10, "A"), fxt.Make_row(20, "B")}, String_.Concat_lines_nl_skip_last ( "" , " " , " 10" @@ -56,14 +56,14 @@ class Xows_html_wkr_fxt { return this; } public void Test_paging(boolean fwd, int paging_idx, String expd) { - Xows_ui_qry qry = new Xows_ui_qry(Bry_.new_a7("A"), paging_idx, 100, Xosrh_rslt_itm_sorter.Tid_len_dsc, new Xows_ns_mgr(), true, new Xow_domain_itm[] {Xow_domain_itm_.parse(wiki.Domain_bry())}); - qry.Page_max_(2); + Srch_qry qry = new Srch_qry(Bry_.new_a7("A"), paging_idx, 100, new Xows_ns_mgr(), true, new Xow_domain_itm[] {Xow_domain_itm_.parse(wiki.Domain_bry())}); + qry.page_max = 2; html_mgr.Init_by_wiki(wiki, wiki.Lang().Num_mgr(), qry); byte[] paging_link = html_mgr.Paging_link(fwd); Tfds.Eq(expd, String_.new_a7(paging_link)); } - public void Test_rows(Xows_db_row[] rows, String expd) { - Xows_ui_rslt rslt = new Xows_ui_rslt(); + public void Test_rows(Srch_rslt_itm[] rows, String expd) { + Srch_rslt_list rslt = new Srch_rslt_list(); Xows_html_row html_row = new Xows_html_row(wiki.App().Html__lnki_bldr()); html_row.Init(rslt); for (int i = 0; i < rows.length; ++i) @@ -71,8 +71,8 @@ class Xows_html_wkr_fxt { html_row.Bfr_arg__add(tmp_bfr); Tfds.Eq_str_lines(expd, tmp_bfr.To_str_and_clear()); } - public Xows_db_row Make_row(int len, String ttl_str) { + public Srch_rslt_itm Make_row(int len, String ttl_str) { byte[] ttl_bry = Bry_.new_u8(ttl_str); - return new Xows_db_row(Bry_.new_a7("w"), wiki.Ttl_parse(ttl_bry), 1, len); + return new Srch_rslt_itm(Bry_.new_a7("w"), wiki.Ttl_parse(ttl_bry), 1, len); } } diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ns_mgr.java b/400_xowa/src/gplx/xowa/specials/search/Xows_ns_mgr.java index d1bca0b3d..474f91341 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ns_mgr.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_ns_mgr.java @@ -26,9 +26,9 @@ public class Xows_ns_mgr { ns_all = ns_main = false; } public boolean Has(int ns_id) { - return ns_all // all flag set + return ns_all // all flag set || ns_main && ns_id == Xow_ns_.Tid__main // main flag set - || ns_hash.Has(tmp_ns_id.Val_(ns_id)) // check against ns_hash + || ns_hash.Has(tmp_ns_id.Val_(ns_id)) // check against ns_hash ; } public void Add_by_id(int ns_id) { @@ -48,7 +48,7 @@ public class Xows_ns_mgr { int ns_enabled = Bry_.To_int_or_neg1(val); if (ns_enabled == 1) { // make sure set to 1; EX: ignore &ns0=0 int key_len = key.length; - if (key_len == 3 && key[2] == Byte_ascii.Star) // translate ns* as ns_all + if (key_len == 3 && key[2] == Byte_ascii.Star) // translate ns* as ns_all ns_all = true; else { int ns_id = Bry_.To_int_or(key, 2, key_len, Int_.Min_value); diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_page__search.java b/400_xowa/src/gplx/xowa/specials/search/Xows_page__search.java index 243c78991..08fea7f6d 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_page__search.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_page__search.java @@ -80,7 +80,7 @@ public class Xows_page__search implements Xows_page, GfoInvkAble, GfoEvObj { } page.Html_data().Html_restricted_n_(); page.Html_data().Xtn_search_text_(search_bry); - Xows_ui_qry qry = new Xows_ui_qry(search_bry, args_mgr.Paging_idx(), search_api.Results_per_page(), args_mgr.Sort_tid(), args_mgr.Ns_mgr(), search_api.Async_db(), search_domain_ary); + Srch_qry qry = new Srch_qry(search_bry, args_mgr.Paging_idx(), search_api.Results_per_page(), args_mgr.Ns_mgr(), search_api.Async_db(), search_domain_ary); search_mgr.Search(wiki, page, qry); } // page found; return it; diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async__html.java b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async__html.java index 50f7e5c11..01b17d270 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async__html.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async__html.java @@ -17,27 +17,27 @@ along with this program. If not, see . */ package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.langs.htmls.*; import gplx.xowa.files.gui.*; -class Xows_ui_async__html implements Xows_ui_async { +class Xows_ui_async__html implements Srch_rslt_lnr { private final Xows_html_row html_row; private final Xog_js_wkr js_wkr; - private final Xows_db_row[] rows; private final int rows_len; + private final Srch_rslt_itm[] rows; private final int rows_len; private final Bry_bfr bfr = Bry_bfr.new_(255); private final byte[] insert_new_key; private final Cancelable cxl; public Xows_ui_async__html(Cancelable cxl, Xows_html_row html_row, Xog_js_wkr js_wkr, int paging_len, byte[] wiki) { this.cxl = cxl; this.html_row = html_row; this.js_wkr = js_wkr; - this.rows = new Xows_db_row[paging_len]; + this.rows = new Srch_rslt_itm[paging_len]; this.rows_len = paging_len; this.insert_new_key = Gen_insert_key(wiki); } - public void Add(Xows_db_row new_row) { - Xows_db_row last_row = rows[rows_len - 1]; + public void Notify_rslt_found(Srch_rslt_itm new_row) { + Srch_rslt_itm last_row = rows[rows_len - 1]; if (last_row != null) { if (Compare(new_row, last_row) == CompareAble_.MoreOrSame) return; // new_row is < last_row; exit } int new_row_slot = Find_insert_slot(new_row); if (new_row_slot == -1) return; - Xows_db_row insert_row = rows[new_row_slot]; - byte[] insert_key = insert_row == null ? insert_new_key : insert_row.Key(); + Srch_rslt_itm insert_row = rows[new_row_slot]; + byte[] insert_key = insert_row == null ? insert_new_key : insert_row.key; Displace(new_row_slot, new_row); html_row.Gen_html(bfr, new_row); String html_tbl = bfr.To_str_and_clear(); @@ -45,25 +45,25 @@ class Xows_ui_async__html implements Xows_ui_async { js_wkr.Html_elem_append_above(Gfh_utl.Encode_id_as_str(insert_key), html_tbl); if (last_row != null) { if (cxl.Canceled()) return; - js_wkr.Html_elem_replace_html(Gfh_utl.Encode_id_as_str(last_row.Key()), ""); + js_wkr.Html_elem_replace_html(Gfh_utl.Encode_id_as_str(last_row.key), ""); } } - private int Find_insert_slot(Xows_db_row new_row) { + private int Find_insert_slot(Srch_rslt_itm new_row) { for (int i = 0; i < rows_len; ++i) { - Xows_db_row cur_row = rows[i]; + Srch_rslt_itm cur_row = rows[i]; if (cur_row == null) return i; if (Compare(new_row, cur_row) == CompareAble_.Less) return i; } return -1; } - private void Displace(int new_row_slot, Xows_db_row new_row) { + private void Displace(int new_row_slot, Srch_rslt_itm new_row) { for (int i = rows_len - 2; i >= new_row_slot; --i) { rows[i + 1] = rows[i]; } rows[new_row_slot] = new_row; } - private int Compare(Xows_db_row lhs, Xows_db_row rhs) { - return -Int_.Compare(lhs.Page_len(), rhs.Page_len()); + private int Compare(Srch_rslt_itm lhs, Srch_rslt_itm rhs) { + return -Int_.Compare(lhs.page_len, rhs.page_len); } public static byte[] Gen_insert_key(byte[] wiki) {return Bry_.Add(Bry_insert_key, wiki);} private static final byte[] Bry_insert_key = Bry_.new_a7("xowa_insert_"); diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async_tst.java b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async_tst.java index 86ee25688..78ddb0a17 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async_tst.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_async_tst.java @@ -42,14 +42,14 @@ class Xows_ui_async_fxt { html_row.Fmtr().Fmt_("~{page_key}"); async = new Xows_ui_async__html(Cancelable_.Never, html_row, js_wkr, 5, Bry_enwiki); } - public Xows_db_row Make_rslt(int len, String ttl) { + public Srch_rslt_itm Make_rslt(int len, String ttl) { byte[] ttl_bry = Bry_.new_a7(ttl); - return new Xows_db_row(Bry_enwiki, wiki.Ttl_parse(ttl_bry), 1, len); + return new Srch_rslt_itm(Bry_enwiki, wiki.Ttl_parse(ttl_bry), 1, len); } public Object[] Make_args_append(String uid, String html) {return Object_.Ary(Xog_js_wkr__log.Proc_append_above, uid, html);} public Object[] Make_args_replace(String uid) {return Object_.Ary(Xog_js_wkr__log.Proc_replace_html, uid, "");} - public void Test_add(Xows_db_row row, Object[]... expd) { - async.Add(row); + public void Test_add(Srch_rslt_itm row, Object[]... expd) { + async.Notify_rslt_found(row); int expd_len = expd.length; Tfds.Eq(expd_len, js_wkr.Log__len()); for (int i = 0; i < expd_len; ++i) { diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_cmd.java b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_cmd.java index 51dd963f3..20fdd22bd 100644 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_cmd.java +++ b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_cmd.java @@ -18,21 +18,21 @@ along with this program. If not, see . package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.core.threads.*; import gplx.langs.htmls.*; import gplx.xowa.wikis.*; import gplx.xowa.files.gui.*; import gplx.xowa.guis.views.*; -class Xows_ui_cmd implements GfoInvkAble, Cancelable, Xog_tab_close_lnr { - private final Xows_core mgr; private final Xows_ui_qry qry; private final Xows_ui_rslt rslt; +class Xows_ui_cmd implements GfoInvkAble, Cancelable, Srch_rslt_lnr, Xog_tab_close_lnr { + private final Xows_core mgr; private final Srch_qry qry; private final Srch_rslt_list rslt; private final Xow_wiki wiki; private final Xoae_page page; private final Xog_tab_close_mgr tab_close_mgr; private final Xog_js_wkr js_wkr; - private final boolean async; private Xows_ui_async async_wkr; - private Xows_db_cache cache; - public Xows_ui_cmd(Xows_core mgr, Xows_ui_qry qry, Xow_wiki wiki, Xoae_page page, Xog_tab_close_mgr tab_close_mgr, Xog_js_wkr js_wkr, Xows_db_cache cache, Xows_ui_async async_wkr) { + private final boolean async; private Srch_rslt_lnr async_wkr; + private Srch_rslt_hash cache; + public Xows_ui_cmd(Xows_core mgr, Srch_qry qry, Xow_wiki wiki, Xoae_page page, Xog_tab_close_mgr tab_close_mgr, Xog_js_wkr js_wkr, Srch_rslt_hash cache, Srch_rslt_lnr async_wkr) { this.mgr = mgr; this.qry = qry; this.wiki = wiki; this.page = page; this.tab_close_mgr = tab_close_mgr; this.js_wkr = js_wkr; this.async_wkr = async_wkr; - this.async = wiki.App().Mode().Tid_is_gui() && qry.Async_db(); - this.rslt = new Xows_ui_rslt(); - this.key = Gfh_utl.Encode_id_as_bry(Bry_.Add(qry.Key(), Byte_ascii.Pipe_bry, wiki.Domain_bry())); + this.async = wiki.App().Mode().Tid_is_gui() && qry.async_db; + this.rslt = new Srch_rslt_list(); + this.key = Gfh_utl.Encode_id_as_bry(Bry_.Add(qry.key, Byte_ascii.Pipe_bry, wiki.Domain_bry())); this.cache = cache; } public byte[] Key() {return key;} private final byte[] key; public Xow_wiki Wiki() {return wiki;} - public Xows_ui_rslt Rslt() {return rslt;} + public Srch_rslt_list Rslt() {return rslt;} public boolean Canceled() {return canceled;} private boolean canceled; public void Cancel() { Xoa_app_.Usr_dlg().Prog_many("", "", "search canceled: key=~{0}", key); @@ -43,10 +43,10 @@ class Xows_ui_cmd implements GfoInvkAble, Cancelable, Xog_tab_close_lnr { public boolean Search() { this.cache = mgr.Get_cache_or_new(key); boolean rv = false, fill_from_cache = true; - if (!cache.Done() && (qry.Itms_end() > cache.Itms_end())) { + if (!cache.Done() && (qry.itms_end > cache.Itms_end())) { if (async) { fill_from_cache = false; // NOTE: do not retrieve cached results to page, else ui_async cmd will add out of order; DATE:2015-04-24 - if (async_wkr == null) async_wkr = new Xows_ui_async__html(this, new Xows_html_row(new gplx.xowa.htmls.core.htmls.utls.Xoh_lnki_bldr(wiki.App(), wiki.App().Html__href_wtr())), js_wkr, qry.Page_len(), wiki.Domain_bry()); + if (async_wkr == null) async_wkr = new Xows_ui_async__html(this, new Xows_html_row(new gplx.xowa.htmls.core.htmls.utls.Xoh_lnki_bldr(wiki.App(), wiki.App().Html__href_wtr())), js_wkr, qry.page_len, wiki.Domain_bry()); Thread_adp_.invk_(gplx.xowa.apps.Xoa_thread_.Key_special_search_db, this, Invk_search_db).Start(); } else @@ -54,8 +54,8 @@ class Xows_ui_cmd implements GfoInvkAble, Cancelable, Xog_tab_close_lnr { rv = true; } if (fill_from_cache) { - cache.Get_between(rslt, qry.Itms_bgn(), qry.Itms_end()); - qry.Page_max_(cache.Count() / qry.Page_len()); + cache.Get_between(rslt, qry.itms_bgn, qry.itms_end); + qry.page_max = cache.Count() / qry.page_len; } return rv; } @@ -65,16 +65,16 @@ class Xows_ui_cmd implements GfoInvkAble, Cancelable, Xog_tab_close_lnr { while (!page.Html_data().Mode_wtxt_shown()) // NOTE:must check for wtxt_shown else async can happen first, and then be overwritten by wtxt; DATE:2015-04-26 Thread_adp_.Sleep(100); // show any existing items in the cache on screen; new updates wil bump these off; SEE:NOTE:show_existing;DATE:2015-04-26 - int qry_itms_bgn = qry.Itms_bgn(), cache_count = cache.Count(); + int qry_itms_bgn = qry.itms_bgn, cache_count = cache.Count(); for (int i = qry_itms_bgn; i < cache_count; ++i) - async_wkr.Add(cache.Get_at(i)); + async_wkr.Notify_rslt_found(cache.Get_at(i)); } - new Xows_db_wkr().Search(this, this, qry, rslt, cache, wiki, wiki.Lang().Case_mgr()); + new Srch_db_wkr().Search(this, this, cache, wiki, wiki.Lang().Case_mgr(), qry); mgr.Search_end(this); if (this.Canceled()) return; // NOTE: must check else throws SWT exception this.Hide_cancel_btn(); if (cache.Done()) - qry.Page_max_(cache.Count() / qry.Page_len()); + qry.page_max = cache.Count() / qry.page_len; Xoa_app_.Usr_dlg().Prog_many("", "", ""); } private void Hide_cancel_btn() { @@ -83,9 +83,9 @@ class Xows_ui_cmd implements GfoInvkAble, Cancelable, Xog_tab_close_lnr { private void Hide_cancel_btn_async() { js_wkr.Html_atr_set("xowa_cancel_" + wiki.Domain_str(), "style", "display:none;"); } - public void Add_rslt(Xows_db_row rslt) { + public void Notify_rslt_found(Srch_rslt_itm rslt) { cache.Add(rslt); - if (async) async_wkr.Add(rslt); + if (async) async_wkr.Notify_rslt_found(rslt); } public boolean When_close(Xog_tab_itm tab, Xoa_url url) { if (url != Xoa_url.Null) { // not called by close_tab (Ctrl+W) diff --git a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_qry.java b/400_xowa/src/gplx/xowa/specials/search/Xows_ui_qry.java deleted file mode 100644 index 9709c7c6d..000000000 --- a/400_xowa/src/gplx/xowa/specials/search/Xows_ui_qry.java +++ /dev/null @@ -1,45 +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 . -*/ -package gplx.xowa.specials.search; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; -import gplx.xowa.wikis.domains.*; -class Xows_ui_qry { - private final List_adp cmd_list = List_adp_.new_(); - public Xows_ui_qry(byte[] search_raw, int page_idx, int page_len, byte sort_tid, Xows_ns_mgr ns_mgr, boolean async_db, Xow_domain_itm[] wiki_domains) { - this.search_raw = search_raw; this.page_idx = page_idx; this.page_len = page_len; this.sort_tid = sort_tid; this.ns_mgr = ns_mgr; this.async_db = async_db; this.wiki_domains = wiki_domains; - this.itms_bgn = page_idx * page_len; - this.page_max = page_idx; // default page_max to page_idx; adjust later when all results are known - this.key = Bry_.Add_w_dlm(Byte_ascii.Pipe, search_raw, ns_mgr.To_hash_key()); - this.special_link_base_href = Bry_.Add(Bry_.new_a7("Special:Search/"), search_raw, Bry_.new_a7("?fulltext=y")); - } - public byte[] Key() {return key;} private final byte[] key; - public byte[] Search_raw() {return search_raw;} private final byte[] search_raw; - public boolean Async_db() {return async_db;} private boolean async_db; - public int Page_idx() {return page_idx;} private final int page_idx; - public int Page_max() {return page_max;} private int page_max; - public int Page_len() {return page_len;} private final int page_len; - public int Itms_bgn() {return itms_bgn;} private final int itms_bgn; - public int Itms_end() {return itms_bgn + page_len;} - public byte Sort_tid() {return sort_tid;} private final byte sort_tid; - public Xows_ns_mgr Ns_mgr() {return ns_mgr;} private final Xows_ns_mgr ns_mgr; - public Xow_domain_itm[] Wiki_domains() {return wiki_domains;} private final Xow_domain_itm[] wiki_domains; - public void Page_max_(int v) {this.page_max = v;} - public int Cmds__len() {return cmd_list.Count();} - public Xows_ui_cmd Cmds__get_at(int i) {return (Xows_ui_cmd)cmd_list.Get_at(i);} - public void Cmds__add(Xows_ui_cmd cmd) {cmd_list.Add(cmd);} - public byte[] Special_link_base_href() {return special_link_base_href;} private final byte[] special_link_base_href; -} diff --git a/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_node.java b/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_node.java new file mode 100644 index 000000000..aa9a02dee --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_node.java @@ -0,0 +1,73 @@ +/* +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 . +*/ +package gplx.xowa.specials.search.crts; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +import gplx.langs.regxs.*; +public class Srch_crt_node { + private final Gfo_pattern raw_pattern; + public Srch_crt_node(int tid, byte[] raw, Srch_crt_node lhs, Srch_crt_node rhs) { + this.tid = tid; this.raw = raw; this.lhs = lhs; this.rhs = rhs; + this.raw_pattern = Bry_.Has(raw, Byte_ascii.Star) ? new Gfo_pattern(raw) : null; + } + public final int tid; + public final byte[] raw; + public final Srch_crt_node lhs; + public final Srch_crt_node rhs; + + public boolean Matches(gplx.xowa.langs.cases.Xol_case_mgr case_mgr, byte[] ttl) { + byte[] ttl_lower = case_mgr.Case_build_lower(Xoa_ttl.Replace_unders(ttl)); + byte[][] ttl_words = Bry_split_.Split(ttl_lower, Byte_ascii.Space, Bool_.Y); + return Matches(ttl_lower, ttl_words); + } + private boolean Matches(byte[] ttl_lower, byte[][] ttl_words) { + switch (tid) { + case Srch_crt_node.Tid_word: { + int len = ttl_words.length; + for (int i = 0; i < len; ++i) { + byte[] word = ttl_words[i]; + if (raw_pattern == null) { + if (Bry_.Eq(word, raw)) return true; + } + else { + if (raw_pattern.Match(word)) return true; + } + } + return false; + } + case Srch_crt_node.Tid_word_quote: // note that raw does not have quotes; EX: "B*" -> B* + return Bry_find_.Find_fwd(ttl_lower, raw) != Bry_find_.Not_found; + case Srch_crt_node.Tid_not: + return !rhs.Matches(ttl_lower, ttl_words); + case Srch_crt_node.Tid_or: + return lhs.Matches(ttl_lower, ttl_words) || rhs.Matches(ttl_lower, ttl_words); + case Srch_crt_node.Tid_and: + return lhs.Matches(ttl_lower, ttl_words) && rhs.Matches(ttl_lower, ttl_words); + case Srch_crt_node.Tid_null: return false; + default: throw Err_.new_unhandled(tid); + } + } + + public static final Srch_crt_node Null = new Srch_crt_node(Srch_crt_node.Tid_null, null, null, null); + public static final int + Tid_word = 0 // EX: 'A' + , Tid_and = 1 // EX: 'A B' + , Tid_or = 2 // EX: 'A OR B' + , Tid_not = 3 // EX: '-A' + , Tid_word_quote = 4 // EX: '"A B"' + , Tid_null = 5 + ; +} diff --git a/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_parser.java b/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_parser.java new file mode 100644 index 000000000..fa4deef3a --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_parser.java @@ -0,0 +1,94 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.specials.search.crts; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +public class Srch_crt_parser { + private final Srch_parser_ctx parse_ctx = new Srch_parser_ctx(); private byte[] src; + public Srch_crt_node Parse(byte[] src) { + this.src = src; + Srch_crt_tkn[] tkns = new Srch_crt_scanner().Scan(src); + return Parse_itm_or(parse_ctx.Init(tkns)); + } + private Srch_crt_node Parse_itm_or(Srch_parser_ctx parse_ctx) { + Srch_crt_node lhs = Parse_itm_and(parse_ctx); + while (parse_ctx.Cur_tid(Srch_crt_tkn.Tid_or)) { + parse_ctx.Move_next(); + Srch_crt_node rhs = Parse_itm_and(parse_ctx); + lhs = New_join(Srch_crt_node.Tid_or, lhs, rhs); + } + return lhs; + } + private Srch_crt_node Parse_itm_and(Srch_parser_ctx parse_ctx) { + Srch_crt_node lhs = Parse_itm_not(parse_ctx); + while (parse_ctx.Cur_tid(Srch_crt_tkn.Tid_and)) { + parse_ctx.Move_next(); + Srch_crt_node rhs = Parse_itm_not(parse_ctx); + lhs = New_join(Srch_crt_node.Tid_and, lhs, rhs); + } + return lhs; + } + private Srch_crt_node Parse_itm_not(Srch_parser_ctx parse_ctx) { + Srch_crt_node lhs = Parse_itm_leaf(parse_ctx); + while (parse_ctx.Cur_tid(Srch_crt_tkn.Tid_not)) { + parse_ctx.Move_next(); + Srch_crt_node rhs = Parse_itm_leaf(parse_ctx); + lhs = New_join(Srch_crt_node.Tid_not, null, rhs); + } + return lhs; + } + private Srch_crt_node Parse_itm_leaf(Srch_parser_ctx parse_ctx) { + if (parse_ctx.Cur_tid(Srch_crt_tkn.Tid_paren_bgn)) { + parse_ctx.Move_next(); + Srch_crt_node lhs = Parse_itm_or(parse_ctx); + if (parse_ctx.Cur_tid(Srch_crt_tkn.Tid_paren_end)) parse_ctx.Move_next(); // skip token + return lhs; + } + else if (parse_ctx.Cur_tid(Srch_crt_tkn.Tid_eos)) + return Srch_crt_node.Null; + else { + Srch_crt_tkn word_tkn = parse_ctx.Move_next(); + if (word_tkn.tid == Srch_crt_tkn.Tid_not) { + word_tkn = parse_ctx.Move_next(); + if (word_tkn == null) return Srch_crt_node.Null; // occurs in "a -" + Srch_crt_node word_itm = New_word(word_tkn, src); + return New_join(Srch_crt_node.Tid_not, null, word_itm); + } + else + return New_word(word_tkn, src); + } + } + private static Srch_crt_node New_word(Srch_crt_tkn tkn, byte[] src) { + int tid = tkn.tid == Srch_crt_tkn.Tid_word ? Srch_crt_node.Tid_word : Srch_crt_node.Tid_word_quote; + return new Srch_crt_node(tid, tkn.val, null, null); + } + private static Srch_crt_node New_join(int tid, Srch_crt_node lhs, Srch_crt_node rhs) {return new Srch_crt_node(tid, null, lhs, rhs);} +} +class Srch_parser_ctx { + private Srch_crt_tkn[] ary; private int pos = 0; private int ary_len; + public Srch_parser_ctx Init(Srch_crt_tkn[] ary) { + this.ary = ary; + this.ary_len = ary.length; + this.pos = 0; + return this; + } + public boolean Cur_tid(byte tid) {return pos < ary_len ? tid == ary[pos].tid : tid == Srch_crt_tkn.Tid_eos;} + public Srch_crt_tkn Move_next() { + Srch_crt_tkn rv = null; + if (pos < ary_len) rv = ary[pos++]; + return rv; + } +} diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_scanner.java b/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_scanner.java similarity index 63% rename from 400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_scanner.java rename to 400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_scanner.java index 128982d36..64409d79c 100644 --- a/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_scanner.java +++ b/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_scanner.java @@ -15,12 +15,12 @@ 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 . */ -package gplx.xowa.specials.search.parsers_old; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +package gplx.xowa.specials.search.crts; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; import gplx.core.primitives.*; import gplx.core.btries.*; -class Xow_search_scanner { +class Srch_crt_scanner { private final List_adp tkns = List_adp_.new_(); private byte[] src; private int src_len, pos, txt_bgn; private final Ordered_hash tmp_list = Ordered_hash_.New(); private final Bry_bfr tmp_bfr = Bry_bfr.new_(); - public Xow_search_tkn[] Scan(byte[] src) { + public Srch_crt_tkn[] Scan(byte[] src) { this.src = src; this.src_len = src.length; tkns.Clear(); pos = 0; txt_bgn = -1; while (pos < src_len) { @@ -35,27 +35,27 @@ class Xow_search_scanner { byte cur_tid = ((Byte_obj_val)cur_obj).Val(); if (Cur_join_is_word(cur_tid, pos_end)) continue; // ignore words containing "and", "or"; EX: "random"; "for" if (txt_bgn != -1) { // pending word; create - Tkns_add_word(Xow_search_tkn.Tid_word, txt_bgn, pos); + Tkns_add_word(Srch_crt_tkn.Tid_word, txt_bgn, pos); txt_bgn = -1; } switch (cur_tid) { - case Xow_search_tkn.Tid_space: // discard spaces + case Srch_crt_tkn.Tid_space: // discard spaces pos = Bry_find_.Find_fwd_while(src, pos, src_len, Byte_ascii.Space); break; - case Xow_search_tkn.Tid_quote: // find end quote and add as word + case Srch_crt_tkn.Tid_quote: // find end quote and add as word int quote_bgn = pos + 1; int quote_end = Bry_find_.Find_fwd(src, Byte_ascii.Quote, quote_bgn, src_len); if (quote_end == Bry_find_.Not_found) throw Err_.new_wo_type("could not find end quote", "src", String_.new_u8(src)); - Tkns_add_word(Xow_search_tkn.Tid_word_quoted, quote_bgn, quote_end); + Tkns_add_word(Srch_crt_tkn.Tid_word_quoted, quote_bgn, quote_end); pos = quote_end + 1; // +1 to place after quote break; - case Xow_search_tkn.Tid_not: - Tkns_add_word(Xow_search_tkn.Tid_not, pos, pos_end); + case Srch_crt_tkn.Tid_not: + Tkns_add_word(Srch_crt_tkn.Tid_not, pos, pos_end); pos = pos_end; break; - case Xow_search_tkn.Tid_paren_bgn: case Xow_search_tkn.Tid_paren_end: - case Xow_search_tkn.Tid_and: case Xow_search_tkn.Tid_or: - tkns.Add(new_tkn(cur_tid, pos, pos_end)); + case Srch_crt_tkn.Tid_paren_bgn: case Srch_crt_tkn.Tid_paren_end: + case Srch_crt_tkn.Tid_and: case Srch_crt_tkn.Tid_or: + tkns.Add(new_tkn(cur_tid, src, pos, pos_end)); pos = pos_end; break; default: throw Err_.new_unhandled(cur_tid); @@ -63,20 +63,20 @@ class Xow_search_scanner { } } if (txt_bgn != -1) { // pending word; create - Tkns_add_word(Xow_search_tkn.Tid_word, txt_bgn, pos); + Tkns_add_word(Srch_crt_tkn.Tid_word, txt_bgn, pos); txt_bgn = -1; } - return (Xow_search_tkn[])tkns.To_ary_and_clear(Xow_search_tkn.class); + return (Srch_crt_tkn[])tkns.To_ary_and_clear(Srch_crt_tkn.class); } private boolean Cur_join_is_word(byte cur_tid, int pos_end) { // extra logic to handle and / or occuring in unquoted strings; EX: "random"; "for" switch (cur_tid) { default: return false; // only look at AND, OR, - - case Xow_search_tkn.Tid_and: case Xow_search_tkn.Tid_or: case Xow_search_tkn.Tid_not: + case Srch_crt_tkn.Tid_and: case Srch_crt_tkn.Tid_or: case Srch_crt_tkn.Tid_not: break; } boolean join_is_word = true; if (txt_bgn == -1) { // no pending word; - if (cur_tid == Xow_search_tkn.Tid_not) return false; // NOT is only operator if no pending tkn; EX: -abc -> NOT abc; a-b -> a-b + if (cur_tid == Srch_crt_tkn.Tid_not) return false; // NOT is only operator if no pending tkn; EX: -abc -> NOT abc; a-b -> a-b byte nxt_b = pos_end < src_len ? src[pos_end] : Byte_ascii.Null; Object nxt_obj = trie.Match_bgn_w_byte(nxt_b, src, pos_end, src_len); if (nxt_obj == null) // next tkn is text; join must be word @@ -84,11 +84,11 @@ class Xow_search_scanner { else { // next tkn is tkn byte nxt_tid = ((Byte_obj_val)nxt_obj).Val(); switch (nxt_tid) { - case Xow_search_tkn.Tid_space: case Xow_search_tkn.Tid_quote: - case Xow_search_tkn.Tid_paren_bgn: case Xow_search_tkn.Tid_paren_end: + case Srch_crt_tkn.Tid_space: case Srch_crt_tkn.Tid_quote: + case Srch_crt_tkn.Tid_paren_bgn: case Srch_crt_tkn.Tid_paren_end: join_is_word = false; // next tkn is sym; and/or is not word; EX: a AND ; a AND"b"; a AND(b) break; - case Xow_search_tkn.Tid_not: case Xow_search_tkn.Tid_and: case Xow_search_tkn.Tid_or: + case Srch_crt_tkn.Tid_not: case Srch_crt_tkn.Tid_and: case Srch_crt_tkn.Tid_or: join_is_word = true; // next tkn is and or not; and/or is word; EX: andor; oror; or-abc; break; default: throw Err_.new_unhandled(cur_tid); @@ -104,18 +104,18 @@ class Xow_search_scanner { return true; } if (txt_bgn != -1) { - Tkns_add_word(Xow_search_tkn.Tid_word, txt_bgn, pos); // create word + Tkns_add_word(Srch_crt_tkn.Tid_word, txt_bgn, pos); // create word txt_bgn = -1; } return false; } private void Tkns_add_word(byte tid, int src_bgn, int src_end) { if (tkns.Count() > 0) { // at least 1 tkn; check for "auto-and" - Xow_search_tkn last_tkn = (Xow_search_tkn)tkns.Get_at_last(); - if (last_tkn.Tid() == Xow_search_tkn.Tid_word) // previous tkn is word; auto "AND" words; EX: A B -> A AND B - tkns.Add(Xow_search_tkn.new_bry(Xow_search_tkn.Tid_and, Bry_and)); + Srch_crt_tkn last_tkn = (Srch_crt_tkn)tkns.Get_at_last(); + if (last_tkn.tid == Srch_crt_tkn.Tid_word) // previous tkn is word; auto "AND" words; EX: A B -> A AND B + tkns.Add(new Srch_crt_tkn(Srch_crt_tkn.Tid_and, Bry_and)); } - if (tid == Xow_search_tkn.Tid_word) { // if word has symbol, convert to quoted; EX: a-b should become "a-b"; otherwise searcher would search for a single word a-b + if (tid == Srch_crt_tkn.Tid_word) { // if word has symbol, convert to quoted; EX: a-b should become "a-b"; otherwise searcher would search for a single word a-b byte[] cur_word = Bry_.Mid(src, src_bgn, src_end); byte[][] words = gplx.xowa.bldrs.cmds.texts.Xob_search_base.Split_ttl_into_words(null, tmp_list, tmp_bfr, cur_word); int words_len = words.length; @@ -123,22 +123,22 @@ class Xow_search_scanner { && !Bry_.Eq(words[0], cur_word) // split word not same as raw && Bry_find_.Find_fwd(cur_word, Byte_ascii.Star) == -1 // no asterisk ) { - tkns.Add(Xow_search_tkn.new_bry(tid, words[0])); + tkns.Add(new Srch_crt_tkn(tid, words[0])); return; } if (words.length > 1) // multiple words; add as quoted-term; EX: "a-b" - tid = Xow_search_tkn.Tid_word_quoted; + tid = Srch_crt_tkn.Tid_word_quoted; } - tkns.Add(new_tkn(tid, src_bgn, src_end)); + tkns.Add(new_tkn(tid, src, src_bgn, src_end)); } - private Xow_search_tkn new_tkn(byte tid, int val_bgn, int val_end) {return Xow_search_tkn.new_pos(tid, val_bgn, val_end);} + private Srch_crt_tkn new_tkn(byte tid, byte[] src, int val_bgn, int val_end) {return new Srch_crt_tkn(tid, Bry_.Mid(src, val_bgn, val_end));} private static final byte[] Bry_and = Bry_.new_a7("AND"); private static final Btrie_slim_mgr trie = Btrie_slim_mgr.ci_a7()// NOTE:ci.ascii:OR / AND only - .Add_str_byte(" " , Xow_search_tkn.Tid_space) - .Add_str_byte("\"" , Xow_search_tkn.Tid_quote) - .Add_str_byte("-" , Xow_search_tkn.Tid_not) - .Add_str_byte("(" , Xow_search_tkn.Tid_paren_bgn) - .Add_str_byte(")" , Xow_search_tkn.Tid_paren_end) - .Add_str_byte("or" , Xow_search_tkn.Tid_or) - .Add_str_byte("and" , Xow_search_tkn.Tid_and); + .Add_str_byte(" " , Srch_crt_tkn.Tid_space) + .Add_str_byte("\"" , Srch_crt_tkn.Tid_quote) + .Add_str_byte("-" , Srch_crt_tkn.Tid_not) + .Add_str_byte("(" , Srch_crt_tkn.Tid_paren_bgn) + .Add_str_byte(")" , Srch_crt_tkn.Tid_paren_end) + .Add_str_byte("or" , Srch_crt_tkn.Tid_or) + .Add_str_byte("and" , Srch_crt_tkn.Tid_and); } diff --git a/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_tkn.java b/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_tkn.java new file mode 100644 index 000000000..0e49d255b --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/crts/Srch_crt_tkn.java @@ -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 . +*/ +package gplx.xowa.specials.search.crts; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; +class Srch_crt_tkn { + public final byte tid; + public final byte[] val; + public Srch_crt_tkn(byte tid, byte[] val) {this.tid = tid; this.val = val;} + + public static final byte + Tid_root = 1 + , Tid_word = 2 + , Tid_word_quoted = 3 + , Tid_space = 4 + , Tid_quote = 5 + , Tid_not = 6 + , Tid_paren_bgn = 7 + , Tid_paren_end = 8 + , Tid_or = 9 + , Tid_and = 10 + , Tid_eos = 11 + ; +} diff --git a/400_xowa/src/gplx/xowa/specials/search/dbs/Srch_db_mgr.java b/400_xowa/src/gplx/xowa/specials/search/dbs/Srch_db_mgr.java new file mode 100644 index 000000000..699fc8f47 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/dbs/Srch_db_mgr.java @@ -0,0 +1,80 @@ +/* +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 . +*/ +//namespace gplx.xowa.specials.search.dbs { +// using gplx.dbs; using gplx.xowa.wikis.data.tbls; +// using gplx.xowa.langs.cases; using gplx.xowa.wikis.nss; +// // workset_count +// // workset_score_min +// class Srch_db_mgr { +// private Srch_word_tbl srch_word_tbl = new Srch_word_tbl(null, null); +// private Srch_page_tbl srch_page_tbl = new Srch_page_tbl(); +// private Page_tbl page_tbl = new Page_tbl(); +// public void Search(Srch_request req) { +// List_adp results = req.results; +// int curr = results.Count(); +// int need = curr + req.req__count; +// while (curr < need) { +// // foreach (word) +// srch_word_tbl.Get(req, null); // read words +// srch_page_tbl.Get(req); // get pages for every words +// // add to potential results; skip if failed and / not (but can't do quote) +// page_tbl.Get(req); // get actual page and check for ns; quote; redirect +// // repeat until matched +// need = results.Count(); +// } +// } +// // get all pages in word_id set sorted by page_search_score +// // stop if +// // - no more pages; normal case +// // - page_score < workset_score_min; case with many pages (1000 pages) +//// private int Get_word_id_pages +//// ( Cancelable cancelable, Xow_wiki wiki, Xol_case_mgr case_mgr +//// , Srch_request req, Xows_ui_cmd cmd, Srch_qry qry, Srch_rslt_hash cache +//// , Db_attach_rdr attach_rdr, String sql, Xowd_page_tbl page_tbl +//// , Srch_word_row word, Srch_crt_node matcher, int rslts_wanted, int workset_score_min) { +//// int rslts_found = 0; +//// Xow_ns_mgr ns_mgr = wiki.Ns_mgr(); +//// Db_rdr rdr = attach_rdr.Exec_as_rdr(sql); +//// try { +//// while (rdr.Move_next()) { +//// if (cancelable.Canceled()) return -1; +//// word.Rslts_offset_add_1(); +//// int page_ns = rdr.Read_int(page_tbl.Fld_page_ns()); +//// if (!qry.Ns_mgr().Has(page_ns)) continue; // ignore: ns doesn't match +//// byte[] page_ttl = rdr.Read_bry_by_str(page_tbl.Fld_page_title()); +//// // Io_mgr.Instance.AppendFilStr("C:\\temp.txt", String_.new_u8(word.Text()) + "|" + Int_.To_str(page_ns) + "|" + String_.new_u8(page_ttl) + "\n"); +//// byte[] page_ttl_lc = case_mgr.Case_build_lower(Xoa_ttl.Replace_unders(page_ttl)); +//// byte[][] page_ttl_words = Bry_split_.Split(page_ttl_lc, Byte_ascii.Space, Bool_.Y); +//// if (!matcher.Matches(page_ttl_lc, page_ttl_words)) continue; // ignore: ttl doesn't match matcher +//// int page_id = rdr.Read_int(page_tbl.Fld_page_id()); +//// int page_len = rdr.Read_int(page_tbl.Fld_page_len()); +//// int page_link_score = 0; //rdr.Read_int(page_tbl.Fld_page_link_score()); +//// Xow_ns ns = ns_mgr.Ids_get_or_null(page_ns); +//// byte[] page_ttl_w_ns = ns.Gen_ttl(page_ttl); +//// if (cache.Has(page_ttl_w_ns)) continue; // ignore: page already added by another word; EX: "A B"; word is "B", but "A B" already added by "A" +//// Xoa_ttl ttl = wiki.Ttl_parse(page_ttl_w_ns); +//// Srch_rslt_itm row = new Srch_rslt_itm(wiki.Domain_bry(), ttl, page_id, page_len); +//// cmd.Add_rslt(row); +//// if (++rslts_found == rslts_wanted) break; // stop: found enough results; DATE:2015-04-24 +//// } +//// } finally {rdr.Rls();} +//// if (rslts_found == 0) word.Rslts_done_y_(); // read through entire rdr and nothing found; mark word done +//// return rslts_found; +//// } +// } +//} diff --git a/400_xowa/src/gplx/xowa/specials/search/dbs/Srch_word_row.java b/400_xowa/src/gplx/xowa/specials/search/dbs/Srch_word_row.java new file mode 100644 index 000000000..dc702ce24 --- /dev/null +++ b/400_xowa/src/gplx/xowa/specials/search/dbs/Srch_word_row.java @@ -0,0 +1,125 @@ +/* +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 . +*/ +//namespace gplx.xowa.specials.search.dbs { +// using gplx.dbs; using gplx.xowa.wikis.data.tbls; +// // a +// // a b +// // a* +// class Srch_word_tbl { +// private final Db_conn conn; +// private final Xowd_search_word_tbl tbl; +// public Srch_word_tbl(Db_conn conn, Xowd_search_word_tbl tbl) {this.conn = conn; this.tbl = tbl;} +// public void Get(Srch_request req, Srch_cache_word cache_word) { +// // int req_count = req.req__count; +// // conn.Stmt_select_order(tbl.Tbl_name(), String_.Ary(tbl.Fld_id(), tbl.Fld_w())); +// // SELECT word_id, word_text FROM search_word WHERE word_text LIKE "~{word}%" AND word_text > '' ORDER BY word_page_score DESC OFFSET 0; +// Db_qry qry = Db_qry_.select_() +// .From_(tbl.Tbl_name()) +// .Cols_(tbl.Fld_id(), tbl.Fld_text(), tbl.Fld_page_count(), tbl.Fld_page_score_max()) +// .Where_(Db_crt_.New_like(tbl.Fld_text(), "")) +// .OrderBy_(tbl.Fld_page_score_max(), false) +// // .Offset_(); +// ; +// Db_stmt stmt = conn.Stmt_new(qry); +// stmt.Clear().Crt_str(tbl.Fld_text(), req.search); +// Db_rdr rdr = stmt.Exec_select__rls_auto(); +// int cur_count = 0; +// while (rdr.Move_next()) { +// int word_id = rdr.Read_int(tbl.Fld_id()); +// byte[] word_text = rdr.Read_bry_by_str(tbl.Fld_text()); +// int page_count = rdr.Read_int(tbl.Fld_page_count()); +// int page_score_max = rdr.Read_int(tbl.Fld_page_score_max()); +// Srch_word_row row = new Srch_word_row(word_id, word_text, page_count, page_score_max); +// cache_word.words.Add(row); +// cur_count += page_count; +// ++cache_word.offset; +// if (cur_count >= (req.req__count * 2)) break; +// } +// /* +// Get_rng; now in set of 100, scores may range from 1234 to 50; search every word to get minimum +// */ +// } +// } +// class Srch_page_tbl { +// public void Get(Srch_request req) { +// } +// } +// class Page_tbl { +// public void Get(Srch_request req) {} +// } +// class Srch_word_row { +// public int word_id; +// public byte[] text; +// public int page_count; +// public int page_score_max; +// public int rslts_offset; +// public boolean rslts_done; +// public Srch_word_row(int word_id, byte[] text, int page_count, int page_score_max) { +// this.word_id = word_id; this.text = text; this.page_count = page_count; this.page_score_max = page_score_max; +// rslts_offset = 0; rslts_done = false; +// } +// public void Rslts_offset_add_1() {++rslts_offset;} +// public void Rslts_done_y_() {rslts_done = true;} +// } +// class Srch_page_row { +// public int word_id; +// public int page_id; +// public void Load(int word_id, int page_id) { +// this.word_id = word_id; this.page_id = page_id; +// } +// } +// class Srch_cache_word { +// public byte[] search; +// public final List_adp words = List_adp_.new_(); +// public int offset; +// public void Init_new(byte[] search) { +// this.search = search; +// words.Clear(); +// offset = 0; +// } +// } +// class Srch_request { +// public String search; +// public int req__count; +// public boolean wildcard; +// public String bmk__word__text; +// public int bmk__page__word_id; +// public int bmk__page__page_id; +// // all_pages; +// // view_pages +// public final List_adp results = List_adp_.new_(); +// public final Srch_cache_word tbl__word = new Srch_cache_word(); +// public void Init_new(String search, boolean wildcard, int req__count) { +// this.search = search; this.wildcard = wildcard; this.req__count = req__count; +// this.bmk__word__text = ""; +// this.bmk__page__word_id = -1; +// this.bmk__page__page_id = -1; +// tbl__word.Init_new(Bry_.new_a7(search)); +// results.Clear(); +// } +// public void Init_continue(int req__count) { +// } +// } +// class Srch_query { +// public String raw; +// public Srch_query(String raw) { +// this.raw = raw; +// // separate to words +// } +// } +//} diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_parser.java b/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_parser.java deleted file mode 100644 index 232d972e8..000000000 --- a/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_parser.java +++ /dev/null @@ -1,94 +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 . -*/ -package gplx.xowa.specials.search.parsers_old; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; -public class Xow_search_parser { - private Xow_search_parser_ctx parse_ctx = new Xow_search_parser_ctx(); private byte[] src; - public Xows_db_matcher Parse(byte[] src) { - this.src = src; - Xow_search_tkn[] tkns = new Xow_search_scanner().Scan(src); - return Parse_itm_or(parse_ctx.Init(tkns)); - } - private Xows_db_matcher Parse_itm_or(Xow_search_parser_ctx parse_ctx) { - Xows_db_matcher lhs = Parse_itm_and(parse_ctx); - while (parse_ctx.Cur_tid(Xow_search_tkn.Tid_or)) { - parse_ctx.Move_next(); - Xows_db_matcher rhs = Parse_itm_and(parse_ctx); - lhs = new_join(Xows_db_matcher.Tid_or, lhs, rhs); - } - return lhs; - } - private Xows_db_matcher Parse_itm_and(Xow_search_parser_ctx parse_ctx) { - Xows_db_matcher lhs = Parse_itm_not(parse_ctx); - while (parse_ctx.Cur_tid(Xow_search_tkn.Tid_and)) { - parse_ctx.Move_next(); - Xows_db_matcher rhs = Parse_itm_not(parse_ctx); - lhs = new_join(Xows_db_matcher.Tid_and, lhs, rhs); - } - return lhs; - } - private Xows_db_matcher Parse_itm_not(Xow_search_parser_ctx parse_ctx) { - Xows_db_matcher lhs = Parse_itm_leaf(parse_ctx); - while (parse_ctx.Cur_tid(Xow_search_tkn.Tid_not)) { - parse_ctx.Move_next(); - Xows_db_matcher rhs = Parse_itm_leaf(parse_ctx); - lhs = new_join(Xows_db_matcher.Tid_not, null, rhs); - } - return lhs; - } - private Xows_db_matcher Parse_itm_leaf(Xow_search_parser_ctx parse_ctx) { - if (parse_ctx.Cur_tid(Xow_search_tkn.Tid_paren_bgn)) { - parse_ctx.Move_next(); - Xows_db_matcher lhs = Parse_itm_or(parse_ctx); - if (parse_ctx.Cur_tid(Xow_search_tkn.Tid_paren_end)) parse_ctx.Move_next(); // skip token - return lhs; - } - else if (parse_ctx.Cur_tid(Xow_search_tkn.Tid_eos)) - return Xows_db_matcher.Null; - else { - Xow_search_tkn word_tkn = parse_ctx.Move_next(); - if (word_tkn.Tid() == Xow_search_tkn.Tid_not) { - word_tkn = parse_ctx.Move_next(); - if (word_tkn == null) return Xows_db_matcher.Null; // occurs in "a -" - Xows_db_matcher word_itm = new_word(word_tkn, src); - return new_join(Xows_db_matcher.Tid_not, null, word_itm); - } - else - return new_word(word_tkn, src); - } - } - private static Xows_db_matcher new_word(Xow_search_tkn tkn, byte[] src) { - int tid = tkn.Tid() == Xow_search_tkn.Tid_word ? Xows_db_matcher.Tid_word : Xows_db_matcher.Tid_word_quote; - return new Xows_db_matcher(tid, tkn.Val(src), null, null); - } - private static Xows_db_matcher new_join(int tid, Xows_db_matcher lhs, Xows_db_matcher rhs) {return new Xows_db_matcher(tid, null, lhs, rhs);} -} -class Xow_search_parser_ctx { - private Xow_search_tkn[] ary; private int pos = 0; private int ary_len; - public Xow_search_parser_ctx Init(Xow_search_tkn[] ary) { - this.ary = ary; - this.ary_len = ary.length; - this.pos = 0; - return this; - } - public boolean Cur_tid(byte tid) {return pos < ary_len ? tid == ary[pos].Tid(): tid == Xow_search_tkn.Tid_eos;} - public Xow_search_tkn Move_next() { - Xow_search_tkn rv = null; - if (pos < ary_len) rv = ary[pos++]; - return rv; - } -} diff --git a/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_tkn.java b/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_tkn.java deleted file mode 100644 index 7f78f56f8..000000000 --- a/400_xowa/src/gplx/xowa/specials/search/parsers_old/Xow_search_tkn.java +++ /dev/null @@ -1,40 +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 . -*/ -package gplx.xowa.specials.search.parsers_old; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; -class Xow_search_tkn { - private final int val_bgn, val_end; - private final byte[] val_bry; - Xow_search_tkn(byte tid, int val_bgn, int val_end, byte[] val_bry) {this.tid = tid; this.val_bgn = val_bgn; this.val_end = val_end; this.val_bry = val_bry;} - public byte Tid() {return tid;} private final byte tid; - public byte[] Val(byte[] src) {return val_bry == null ? Bry_.Mid(src, val_bgn, val_end) : val_bry;} - public static Xow_search_tkn new_pos(byte tid, int val_bgn, int val_end) {return new Xow_search_tkn(tid, val_bgn, val_end, null);} - public static Xow_search_tkn new_bry(byte tid, byte[] val_bry) {return new Xow_search_tkn(tid, -1, -1, val_bry);} - public static final byte - Tid_root = 1 - , Tid_word = 2 - , Tid_word_quoted = 3 - , Tid_space = 4 - , Tid_quote = 5 - , Tid_not = 6 - , Tid_paren_bgn = 7 - , Tid_paren_end = 8 - , Tid_or = 9 - , Tid_and = 10 - , Tid_eos = 11 - ; -} diff --git a/400_xowa/src/gplx/xowa/specials/search/quicks/Xoa_search_itm.java b/400_xowa/src/gplx/xowa/specials/search/quicks/Xoa_search_itm.java deleted file mode 100644 index 6ce7ad273..000000000 --- a/400_xowa/src/gplx/xowa/specials/search/quicks/Xoa_search_itm.java +++ /dev/null @@ -1,27 +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 . -*/ -package gplx.xowa.specials.search.quicks; import gplx.*; import gplx.xowa.*; import gplx.xowa.specials.*; import gplx.xowa.specials.search.*; -public class Xoa_search_itm { - public Xoa_search_itm(byte[] url, byte[] name, byte[] descrip, byte[] img) { - this.url = url; this.name = name; this.descrip = descrip; this.img = img; - } - public byte[] Url() {return url;} private final byte[] url; // EX: en.wikipedia.org/wiki/Earth - public byte[] Name() {return name;} private final byte[] name; // EX: Earth - public byte[] Descrip() {return descrip;} private final byte[] descrip; // EX: Third planet from the Sun - public byte[] Img() {return img;} private final byte[] img; // EX: Earth.png -} diff --git a/400_xowa/src/gplx/xowa/specials/xowa/diags/Db_rdr_utl.java b/400_xowa/src/gplx/xowa/specials/xowa/diags/Db_rdr_utl.java index c2a55629d..0864160b3 100644 --- a/400_xowa/src/gplx/xowa/specials/xowa/diags/Db_rdr_utl.java +++ b/400_xowa/src/gplx/xowa/specials/xowa/diags/Db_rdr_utl.java @@ -25,7 +25,7 @@ class Db_rdr_utl { } public static Mem_qry_set Load_as_qry_set(Db_conn conn, Dbmeta_fld_list fld_list, String sql) { Mem_qry_set qry_set = new Mem_qry_set(); - DataRdr rdr = conn.Exec_sql_as_rdr(sql); + DataRdr rdr = conn.Exec_sql_as_old_rdr(sql); try { int fld_count = rdr.FieldCount(); while (rdr.MoveNextPeer()) { @@ -42,7 +42,7 @@ class Db_rdr_utl { } public static Object[][] Load(Db_conn conn, String sql) { List_adp list = List_adp_.new_(); - DataRdr rdr = conn.Exec_sql_as_rdr(sql); + DataRdr rdr = conn.Exec_sql_as_old_rdr(sql); try { int fld_count = rdr.FieldCount(); while (rdr.MoveNextPeer()) { diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_cat_core_tbl__in_wkr.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_cat_core_tbl__in_wkr.java index b3d0683b5..0cafcc646 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_cat_core_tbl__in_wkr.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_cat_core_tbl__in_wkr.java @@ -26,7 +26,7 @@ class Xowd_cat_core_tbl__in_wkr extends Db_in_wkr__base { public void Init(Ordered_hash hash) {this.hash = hash;} @Override protected Db_qry Make_qry(int bgn, int end) { Object[] part_ary = In_ary(end - bgn); - return Db_qry_.select_cols_(tbl_name, Db_crt_.in_(fld_cat_id, part_ary), flds.To_str_ary()); + return Db_qry_.select_cols_(tbl_name, Db_crt_.New_in(fld_cat_id, part_ary), flds.To_str_ary()); } @Override protected void Fill_stmt(Db_stmt stmt, int bgn, int end) { for (int i = bgn; i < end; i++) { diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_cat_link_tbl.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_cat_link_tbl.java index d5ee84a3a..473da0b19 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_cat_link_tbl.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_cat_link_tbl.java @@ -54,11 +54,11 @@ public class Xowd_cat_link_tbl implements Rls_able { public int Select_by_type(List_adp list, int cat_page_id, byte arg_tid, byte[] arg_sortkey, boolean arg_is_from, int limit) { String arg_sortkey_str = arg_sortkey == null ? "" : String_.new_u8(arg_sortkey); gplx.core.criterias.Criteria comp_crt = !arg_is_from - ? Db_crt_.mte_(fld_sortkey, arg_sortkey_str) // from: sortkey >= 'val' - : Db_crt_.lte_(fld_sortkey, arg_sortkey_str); // until: sortkey <= 'val' + ? Db_crt_.New_mte(fld_sortkey, arg_sortkey_str) // from: sortkey >= 'val' + : Db_crt_.New_lte(fld_sortkey, arg_sortkey_str); // until: sortkey <= 'val' Db_qry__select_cmd qry = Db_qry_.select_().Cols_(fld_from, fld_sortkey).From_(tbl_name) - .Where_(gplx.core.criterias.Criteria_.And_many(Db_crt_.eq_(fld_to_id, -1), Db_crt_.eq_(fld_type_id, arg_tid), comp_crt)) - .OrderBy_(fld_sortkey, !arg_is_from) + .Where_(gplx.core.criterias.Criteria_.And_many(Db_crt_.New_eq(fld_to_id, -1), Db_crt_.New_eq(fld_type_id, arg_tid), comp_crt)) + .Order_(fld_sortkey, !arg_is_from) .Limit_(limit + 1); // + 1 to get last_plus_one for next page / previous page Db_rdr rdr = conn.Stmt_new(qry).Crt_int(fld_to_id, cat_page_id).Crt_byte(fld_type_id, arg_tid).Crt_str(fld_sortkey, arg_sortkey_str).Exec_select__rls_auto(); int count = 0; diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_tbl.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_tbl.java index 7f8a608f4..1950f7c3e 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_tbl.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_tbl.java @@ -31,6 +31,7 @@ public class Xowd_page_tbl implements Rls_able { public String Fld_page_title() {return fld_title;} public String Fld_page_len() {return fld_len;} public String Fld_html_db_id() {return fld_html_db_id;} + public String Fld_is_redirect() {return fld_is_redirect;} public String Fld_redirect_id() {return fld_redirect_id;} public String[] Flds_select_idx() {return flds_select_idx;} public String[] Flds_select_all() {return flds_select_all;} @@ -111,7 +112,7 @@ public class Xowd_page_tbl implements Rls_able { return false; } public Db_rdr Select_all() { - Db_qry__select_cmd qry = Db_qry__select_cmd.new_().From_(tbl_name).Cols_(fld_id, fld_title).OrderBy_asc_(fld_id); + Db_qry__select_cmd qry = new Db_qry__select_cmd().From_(tbl_name).Cols_(fld_id, fld_title).Order_asc_(fld_id); return conn.Stmt_new(qry).Exec_select__rls_auto(); } public int Select_id(int ns_id, byte[] ttl) { @@ -167,7 +168,7 @@ public class Xowd_page_tbl implements Rls_able { } public void Select_by_search(Cancelable cancelable, List_adp rv, byte[] search, int results_max) { if (Bry_.Len_eq_0(search)) return; // do not allow empty search - Criteria crt = Criteria_.And_many(Db_crt_.eq_(fld_ns, Xow_ns_.Tid__main), Db_crt_.like_(fld_title, "")); + Criteria crt = Criteria_.And_many(Db_crt_.New_eq(fld_ns, Xow_ns_.Tid__main), Db_crt_.New_like(fld_title, "")); Db_qry__select_cmd qry = Db_qry_.select_().From_(tbl_name).Cols_(fld_id, fld_len, fld_ns, fld_title).Where_(crt); // NOTE: use fields from main index only search = Bry_.Replace(search, Byte_ascii.Star, Byte_ascii.Percent); Db_rdr rdr = conn.Stmt_new(qry).Clear().Crt_int(fld_ns, Xow_ns_.Tid__main).Val_bry_as_str(fld_title, search).Exec_select__rls_auto(); @@ -207,16 +208,16 @@ public class Xowd_page_tbl implements Rls_able { } private Db_rdr Load_ttls_starting_with_rdr(int ns_id, byte[] ttl_frag, boolean include_redirects, int max_results, int min_page_len, int browse_len, boolean fwd, boolean search_suggest) { String ttl_frag_str = String_.new_u8(ttl_frag); - Criteria crt_ttl = fwd ? Db_crt_.mte_(fld_title, ttl_frag_str) : Db_crt_.lt_(fld_title, ttl_frag_str); - Criteria crt = Criteria_.And_many(Db_crt_.eq_(fld_ns, ns_id), crt_ttl, Db_crt_.mte_(fld_len, min_page_len)); + Criteria crt_ttl = fwd ? Db_crt_.New_mte(fld_title, ttl_frag_str) : Db_crt_.New_lt(fld_title, ttl_frag_str); + Criteria crt = Criteria_.And_many(Db_crt_.New_eq(fld_ns, ns_id), crt_ttl, Db_crt_.New_mte(fld_len, min_page_len)); if (!include_redirects) - crt = Criteria_.And(crt, Db_crt_.eq_(fld_is_redirect, Byte_.Zero)); + crt = Criteria_.And(crt, Db_crt_.New_eq(fld_is_redirect, Byte_.Zero)); String[] cols = search_suggest ? flds_select_idx : flds_select_all ; int limit = fwd ? max_results + 1 : max_results; // + 1 to get next item - Db_qry__select_cmd qry = Db_qry_.select_cols_(tbl_name, crt, cols).Limit_(limit).OrderBy_(fld_title, fwd); + Db_qry__select_cmd qry = Db_qry_.select_cols_(tbl_name, crt, cols).Limit_(limit).Order_(fld_title, fwd); Db_stmt stmt = conn.Stmt_new(qry).Crt_int(fld_ns, ns_id).Crt_str(fld_title, ttl_frag_str).Crt_int(fld_len, min_page_len); if (!include_redirects) stmt.Crt_bool_as_byte(fld_is_redirect, include_redirects); diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_tbl__in_wkrs.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_tbl__in_wkrs.java index 9cd211a20..f51576b38 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_tbl__in_wkrs.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_tbl__in_wkrs.java @@ -28,7 +28,7 @@ class Xowd_page_tbl__ttl_ns extends Xowd_page_tbl__in_wkr__base { Criteria[] crt_ary = new Criteria[len]; String fld_ns = tbl.Fld_page_ns(); String fld_ttl = tbl.Fld_page_title(); for (int i = 0; i < len; i++) - crt_ary[i] = Criteria_.And(Db_crt_.eq_(fld_ns, 0), Db_crt_.eq_(fld_ttl, Bry_.Empty)); + crt_ary[i] = Criteria_.And(Db_crt_.New_eq(fld_ns, 0), Db_crt_.New_eq(fld_ttl, Bry_.Empty)); return Criteria_.Or_many(crt_ary); } @Override protected void Fill_stmt(Db_stmt stmt, int bgn, int end) { @@ -55,7 +55,7 @@ class Xowd_page_tbl__ttl extends Xowd_page_tbl__in_wkr__base { Criteria[] crt_ary = new Criteria[len]; String fld_ns = tbl.Fld_page_ns(); String fld_ttl = tbl.Fld_page_title(); for (int i = 0; i < len; i++) - crt_ary[i] = Criteria_.And(Db_crt_.eq_(fld_ns, in_ns), Db_crt_.eq_(fld_ttl, Bry_.Empty)); + crt_ary[i] = Criteria_.And(Db_crt_.New_eq(fld_ns, in_ns), Db_crt_.New_eq(fld_ttl, Bry_.Empty)); return Criteria_.Or_many(crt_ary); } @Override protected void Fill_stmt(Db_stmt stmt, int bgn, int end) { @@ -73,7 +73,7 @@ class Xowd_page_tbl__id extends Xowd_page_tbl__in_wkr__base { public void Init(List_adp list, Ordered_hash hash) {this.list = list; this.hash = hash; this.Fill_idx_fields_only_(true);} @Override protected boolean Show_progress() {return true;} @Override protected Criteria In_filter(Object[] part_ary) { - return Db_crt_.in_(this.In_fld_name(), part_ary); + return Db_crt_.New_in(this.In_fld_name(), part_ary); } @Override protected void Fill_stmt(Db_stmt stmt, int bgn, int end) { for (int i = bgn; i < end; i++) { diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_link_tbl.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_link_tbl.java index 5b18fd72d..61d413f24 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_link_tbl.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_link_tbl.java @@ -21,7 +21,7 @@ import gplx.dbs.*; import gplx.dbs.utls.*; public class Xowd_search_link_tbl { private final String tbl_name; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_(); private final String fld_word_id, fld_page_id; - private final Db_conn conn; private Db_stmt stmt_insert; private final Xowd_search_page_tbl__in_wkr in_wkr = new Xowd_search_page_tbl__in_wkr(); + public final Db_conn conn; private Db_stmt stmt_insert; private final Xowd_search_page_tbl__in_wkr in_wkr = new Xowd_search_page_tbl__in_wkr(); public Xowd_search_link_tbl(Db_conn conn, boolean schema_is_1) { this.conn = conn; String fld_prefix = ""; @@ -56,7 +56,7 @@ class Xowd_search_page_tbl__in_wkr extends Db_in_wkr__base { public void Init(List_adp words, List_adp pages) {this.words = words; this.pages = pages;} @Override protected Db_qry Make_qry(int bgn, int end) { Object[] part_ary = In_ary(end - bgn); - return Db_qry_.select_cols_(tbl_name, Db_crt_.in_(fld_word_id, part_ary), flds.To_str_ary()); + return Db_qry_.select_cols_(tbl_name, Db_crt_.New_in(fld_word_id, part_ary), flds.To_str_ary()); } @Override protected void Fill_stmt(Db_stmt stmt, int bgn, int end) { for (int i = bgn; i < end; i++) { diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_temp_tbl.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_temp_tbl.java index c42838dd0..a13f8908b 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_temp_tbl.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_temp_tbl.java @@ -18,7 +18,7 @@ along with this program. If not, see . package gplx.xowa.wikis.data.tbls; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; import gplx.xowa.wikis.data.*; import gplx.dbs.*; import gplx.dbs.engines.sqlite.*; public class Xowd_search_temp_tbl { - private final String tbl_name = "search_temp"; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_(); + private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_(); private final String fld_page_id, fld_word_text; private final Db_conn conn; private Db_stmt stmt_insert; private final String sql_create_word, sql_create_link; @@ -26,10 +26,12 @@ public class Xowd_search_temp_tbl { this.conn = conn; if (schema_is_1) {sql_create_word = Sql_create_word_v1; sql_create_link = Sql_create_link_v1;} else {sql_create_word = Sql_create_word_v2; sql_create_link = Sql_create_link_v2;} + // flds.Add_int_dflt("word_id", -1); flds.Add_int_pkey_autonum("word_id"); fld_page_id = flds.Add_int("page_id"); fld_word_text = flds.Add_str("word_text", 255); } + public String Tbl_name() {return tbl_name;} private final String tbl_name = "search_temp"; public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds));} public void Insert_bgn() {conn.Txn_bgn("schema__search_temp__insert"); stmt_insert = conn.Stmt_insert(tbl_name, flds);} public void Insert_end() {conn.Txn_end(); stmt_insert = Db_stmt_.Rls(stmt_insert);} @@ -40,7 +42,9 @@ public class Xowd_search_temp_tbl { } public void Make_data(Gfo_usr_dlg usr_dlg, Xowd_search_link_tbl search_link_tbl, Xowd_search_word_tbl search_word_tbl) { conn.Ddl_create_idx(usr_dlg, Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "main", fld_word_text, fld_page_id)); + conn.Exec_delete_all(search_word_tbl.Tbl_name()); conn.Exec_sql_plog_txn("search_temp.create_word", sql_create_word); + conn.Exec_delete_all(search_link_tbl.Tbl_name()); conn.Exec_sql_plog_txn("search_temp.create_link", sql_create_link); Create_idx(usr_dlg, search_link_tbl, search_word_tbl); conn.Env_vacuum(); @@ -55,6 +59,23 @@ public class Xowd_search_temp_tbl { search_link_tbl.Create_idx_normal();; } } + public void Update_word_id(Db_conn cur_conn, Io_url prv_url) { + String sql = String_.Concat_lines_nl_skip_last + ( "REPLACE INTO search_temp (word_id, page_id, word_text)" + , "SELECT Coalesce(prv.word_id, cur.word_id), cur.page_id, cur.word_text" + , "FROM search_temp cur" + , " LEFT JOIN search_word prv ON cur.word_text = prv.word_text" + ); + Db_attach_cmd.new_(cur_conn, "prv_db", prv_url).Add_fmt("updating_word_ids", sql).Exec(); + Db_stmt update_stmt = cur_conn.Stmt_update(tbl_name, String_.Ary(fld_word_text), fld_page_id); + Db_rdr rdr = cur_conn.Stmt_select(tbl_name, flds, String_.Ary(fld_page_id)).Crt_int(fld_page_id, -1).Exec_select__rls_auto(); + int nxt_page_id = 1000; + try { + while (rdr.Move_next()) { + update_stmt.Crt_int(fld_page_id, ++nxt_page_id).Exec_update(); + } + } finally {rdr.Rls();} + } private static final String Sql_create_word_v1 = String_.Concat_lines_nl ( "INSERT INTO search_title_word (stw_word_id, stw_word)" , "SELECT word_id" diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_word_tbl.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_word_tbl.java index 6c1913ab0..41f892e1e 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_word_tbl.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_search_word_tbl.java @@ -20,7 +20,7 @@ import gplx.core.primitives.*; import gplx.dbs.*; import gplx.dbs.cfgs.*; import public class Xowd_search_word_tbl implements Rls_able { private final String tbl_name; private final Dbmeta_fld_list flds = Dbmeta_fld_list.new_(); private final String fld_id, fld_text; private String fld_page_count; private boolean page_count_exists; - private final Db_conn conn; private Db_stmt stmt_insert, stmt_select_by, stmt_select_in; + public final Db_conn conn; private Db_stmt stmt_insert, stmt_select_by, stmt_select_in; public Xowd_search_word_tbl(Db_conn conn, boolean schema_is_1, boolean page_count_exists) { this.conn = conn; this.page_count_exists = page_count_exists; String fld_prefix = "", fld_text_name = "word_text"; @@ -31,6 +31,11 @@ public class Xowd_search_word_tbl implements Rls_able { this.fld_page_count = page_count_exists ? flds.Add_int_dflt("word_page_count", 0) : Dbmeta_fld_itm.Key_null; conn.Rls_reg(this); } + public String Tbl_name() {return tbl_name;} + public String Fld_id() {return fld_id;} + public String Fld_text() {return fld_text;} + public String Fld_page_count() {return fld_page_count;} + public String Fld_page_score_max() {return Dbmeta_fld_itm.Key_null;} public void Create_tbl() {conn.Ddl_create_tbl(Dbmeta_tbl_itm.New(tbl_name, flds));} public void Create_idx() {conn.Ddl_create_idx(Xoa_app_.Usr_dlg(), Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "main", fld_text, fld_id, fld_page_count));} public void Insert_bgn() {conn.Txn_bgn("schema__search_word__insert"); stmt_insert = conn.Stmt_insert(tbl_name, flds);} @@ -52,7 +57,7 @@ public class Xowd_search_word_tbl implements Rls_able { } public Xowd_search_word_row[] Select_in(Cancelable cxl, byte[] word) { if (stmt_select_in == null) { - Db_qry__select_cmd qry = Db_qry_.select_().From_(tbl_name).OrderBy_(fld_page_count, Bool_.N).Where_(Db_crt_.like_(fld_text, "")); // order by highest page count to look at most common words + Db_qry__select_cmd qry = Db_qry_.select_().From_(tbl_name).Order_(fld_page_count, Bool_.N).Where_(Db_crt_.New_like(fld_text, "")); // order by highest page count to look at most common words stmt_select_in = conn.Stmt_new(qry); } List_adp list = List_adp_.new_(); @@ -74,10 +79,10 @@ public class Xowd_search_word_tbl implements Rls_able { gplx.core.criterias.Criteria crt = null; if (Bry_.Has(search, Byte_ascii.Star)) { search = Bry_.Replace(search, Byte_ascii.Star, Byte_ascii.Percent); - crt = Db_crt_.like_ (fld_text, String_.new_u8(search)); + crt = Db_crt_.New_like (fld_text, String_.new_u8(search)); } else - crt = Db_crt_.eq_ (fld_text, String_.new_u8(search)); + crt = Db_crt_.New_eq (fld_text, String_.new_u8(search)); Db_qry__select_cmd qry = Db_qry_.select_().Cols_(fld_id).From_(tbl_name).Where_(crt); List_adp words = List_adp_.new_(); diff --git a/400_xowa/src/gplx/xowa/wikis/dbs/Xodb_upgrade_mgr.java b/400_xowa/src/gplx/xowa/wikis/dbs/Xodb_upgrade_mgr.java index fb1e8bfd2..55ebd3270 100644 --- a/400_xowa/src/gplx/xowa/wikis/dbs/Xodb_upgrade_mgr.java +++ b/400_xowa/src/gplx/xowa/wikis/dbs/Xodb_upgrade_mgr.java @@ -51,7 +51,7 @@ class Xodb_upgrade_mgr { // } // } // private static void Fix_category_version(Db_conn p, Xodb_mgr_sql db_mgr) { -// Db_qry qry = Db_qry_.select_().From_(Xodb_categorylinks_tbl.Tbl_name).Cols_(Xodb_categorylinks_tbl.Fld_cl_type_id).Where_(Db_crt_.eq_(Xodb_categorylinks_tbl.Fld_cl_type_id, )); +// Db_qry qry = Db_qry_.select_().From_(Xodb_categorylinks_tbl.Tbl_name).Cols_(Xodb_categorylinks_tbl.Fld_cl_type_id).Where_(Db_crt_.New_eq(Xodb_categorylinks_tbl.Fld_cl_type_id, )); // Db_stmt stmt = Db_stmt_.Null; // DataRdr rdr = DataRdr_.Null; // int types = 0; diff --git a/400_xowa/src/gplx/xowa/wikis/pages/Xopg_page_heading.java b/400_xowa/src/gplx/xowa/wikis/pages/Xopg_page_heading.java index d4eda1c0b..3f7a9ac00 100644 --- a/400_xowa/src/gplx/xowa/wikis/pages/Xopg_page_heading.java +++ b/400_xowa/src/gplx/xowa/wikis/pages/Xopg_page_heading.java @@ -27,7 +27,7 @@ public class Xopg_page_heading implements Bfr_arg { } public void Bfr_arg__add(Bry_bfr bfr) { if (html_data.Xtn_pgbnr() != null) return; // pgbnr exists; don't add title - fmtr.Bld_bfr_many(bfr, page_ttl.Page_txt()); + fmtr.Bld_many(bfr, page_ttl.Page_txt()); } private final Bry_fmt fmtr = Bry_fmt.New(Bry_.New_u8_nl_apos("

~{page_title}

"), "page_title"); } diff --git a/400_xowa/src/gplx/xowa/xtns/pagebanners/Pgbnr_icon.java b/400_xowa/src/gplx/xowa/xtns/pagebanners/Pgbnr_icon.java index 323326440..2bf9de7ae 100644 --- a/400_xowa/src/gplx/xowa/xtns/pagebanners/Pgbnr_icon.java +++ b/400_xowa/src/gplx/xowa/xtns/pagebanners/Pgbnr_icon.java @@ -22,7 +22,7 @@ public class Pgbnr_icon implements Mustache_doc_itm { private final byte[] name, title, href, html; public Pgbnr_icon(Bry_bfr tmp_bfr, byte[] name, byte[] title, byte[] href) { this.name = name; this.title = title; this.href = href; - fmt.Bld_bfr_many(tmp_bfr, name, title); + fmt.Bld_many(tmp_bfr, name, title); this.html = tmp_bfr.To_bry_and_clear(); } public byte[] Get_prop(String key) { diff --git a/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-file-user.xowa b/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-file-user.xowa new file mode 100644 index 000000000..086415eb2 Binary files /dev/null and b/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-file-user.xowa differ diff --git a/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-file.xowa b/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-file.xowa new file mode 100644 index 000000000..0d52b08f0 Binary files /dev/null and b/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-file.xowa differ diff --git a/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-text.xowa b/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-text.xowa index 880196eaa..57dd77fd8 100644 Binary files a/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-text.xowa and b/tst/400_xowa/root/wiki/en.wikipedia.org/en.wikipedia.org-text.xowa differ