v3.3.4 v3.2.1.1
gnosygnu 8 years ago
parent 6d179ca59d
commit de67253a9c

@ -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) {

@ -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");}

@ -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";
}

@ -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);}

@ -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");
}

@ -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;}
}

@ -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) {

@ -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());
}
}

@ -17,24 +17,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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);}
}

@ -17,21 +17,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;}
}

@ -17,9 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;}

@ -17,8 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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) {

@ -17,30 +17,32 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;}
}

@ -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;

@ -18,19 +18,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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;}
}

@ -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);

@ -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;}

@ -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;
}

@ -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();}

@ -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;

@ -16,10 +16,14 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.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));}
}

@ -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);

@ -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) {

@ -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();
}

@ -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;

@ -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);
}

@ -16,9 +16,9 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; 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() {}
}

@ -16,16 +16,16 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
public class 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() {}
}

@ -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 "";}
}

@ -16,36 +16,48 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.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;
}

@ -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);
}

@ -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();
}

@ -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() {}
}

@ -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");}

@ -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();

@ -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) {

@ -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)

@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; 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

@ -16,12 +16,12 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; 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);}

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}

@ -16,13 +16,13 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*;
public class Gfdb_diff_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

@ -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;
}

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

@ -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();

@ -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() {}

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
public interface Gfdb_diff_wkr {
void Init_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();

@ -16,37 +16,47 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import 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());

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}

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

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

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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);

@ -16,10 +16,11 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines; import gplx.*; import gplx.dbs.*;
import gplx.core.stores.*; import gplx.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

@ -18,26 +18,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.dbs.engines; import gplx.*; import gplx.dbs.*;
import java.sql.*;
import gplx.core.stores.*;
import gplx.dbs.engines.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.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);

@ -16,12 +16,13 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.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);}

@ -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() {}
}

@ -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_();

@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.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();

@ -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);

@ -16,10 +16,11 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.nulls; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.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;}

@ -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);

@ -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";
}

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import java.sql.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.engines.sqlite.*; import gplx.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());
}
}

@ -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);
}
}

@ -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();
}

@ -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;}

@ -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);
}

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.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;}
}

@ -16,19 +16,19 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.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;

@ -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;}

@ -17,8 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;
}

@ -16,18 +16,18 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.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);
}

@ -16,116 +16,101 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.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);}
}

@ -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 ");

@ -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;
}

@ -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));}
}

@ -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;

@ -16,40 +16,39 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.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;
}
}

@ -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));}
}

@ -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);}

@ -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')"
);
}
}

@ -17,45 +17,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;
}
}

@ -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;

@ -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();

@ -31,5 +31,6 @@ public class Db_val_type {
, Tid_varchar = 10
, Tid_nvarchar = 11
, Tid_rdr = 12
, Tid_text = 13
;
}

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

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

@ -16,7 +16,8 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
import gplx.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();
}

@ -16,9 +16,12 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
import gplx.dbs.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 = ?;
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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());
}
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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() {}
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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());
}
}

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

@ -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 <http://www.gnu.org/licenses/>.
*/
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() {}
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}

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

Loading…
Cancel
Save