1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2016-02-07 23:20:20 -05:00
parent 6d179ca59d
commit de67253a9c
215 changed files with 3387 additions and 2055 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,8 +15,9 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <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 org.junit.*; import gplx.core.strings.*; import gplx.dbs.sqls.*;
import gplx.dbs.sqls.wtrs.*;
public class Db_obj_ary_tst {
@Before public void init() {} private Db_obj_ary_fxt fxt = new Db_obj_ary_fxt();
@Test public void Int() {
@@ -27,16 +28,17 @@ public class Db_obj_ary_tst {
}
}
class Db_obj_ary_fxt {
private Db_obj_ary_crt crt = new Db_obj_ary_crt();
public Db_obj_ary_fxt Init_fld(String name, int tid) {flds_list.Add(new Db_fld(name, tid)); return this;} private List_adp flds_list = List_adp_.new_();
private final Db_obj_ary_crt crt = new Db_obj_ary_crt();
private final Sql_wtr_ctx ctx = new Sql_wtr_ctx(false);
public Db_obj_ary_fxt Init_fld(String name, int tid) {flds_list.Add(new Db_obj_ary_fld(name, tid)); return this;} private List_adp flds_list = List_adp_.new_();
public Db_obj_ary_fxt Init_vals(Object... ary) {vals_list.Add(ary); return this;} private List_adp vals_list = List_adp_.new_();
public Db_obj_ary_fxt Test_sql(String expd) {
Sql_qry_wtr_ansi cmd_wtr = (Sql_qry_wtr_ansi)Sql_qry_wtr_.Instance;
String_bldr sb = String_bldr_.new_();
crt.Flds_((Db_fld[])flds_list.To_ary_and_clear(Db_fld.class));
Sql_core_wtr cmd_wtr = (Sql_core_wtr)Sql_qry_wtr_.Basic;
crt.Flds_((Db_obj_ary_fld[])flds_list.To_ary_and_clear(Db_obj_ary_fld.class));
crt.Vals_((Object[][])vals_list.To_ary_and_clear(Object[].class));
cmd_wtr.Append_db_obj_ary(sb, crt);
Tfds.Eq(expd, sb.To_str_and_clear());
Bry_bfr bfr = Bry_bfr.new_();
cmd_wtr.Where_wtr().Bld_where__db_obj(bfr, ctx, crt);
Tfds.Eq(expd, bfr.To_str_and_clear());
return this;
}
}

View File

@@ -15,13 +15,12 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <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.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
public class Sql_from_itm {
public Sql_from_itm(Sql_tbl_itm base_tbl) {
this.Base_tbl = base_tbl;
Tbls.Add(base_tbl);
}
public final List_adp Tbls = List_adp_.new_();
public final Sql_tbl_itm Base_tbl;
}

View File

@@ -15,14 +15,14 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
public class Sql_group_by {
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
public class Sql_group_itm {
public List_adp Flds() {return flds;} List_adp flds = List_adp_.new_();
public static Sql_group_by new_(String... ary) {
Sql_group_by rv = new Sql_group_by();
public static Sql_group_itm new_(String... ary) {
Sql_group_itm rv = new Sql_group_itm();
for (String itm : ary)
rv.flds.Add(itm);
return rv;
} Sql_group_by() {}
} Sql_group_itm() {}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
public class Sql_join_itm {
public Sql_join_itm(String trg_fld, String src_tbl, String src_fld) {
this.Trg_fld = trg_fld;
this.Src_tbl = src_tbl;
this.Src_fld = src_fld;
}
public final String Src_tbl;
public final String Src_fld;
public final String Trg_fld;
public static final Sql_join_itm[] Ary__empty = new Sql_join_itm[0];
}

View File

@@ -0,0 +1,37 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
public class Sql_order_fld {
public Sql_order_fld(String tbl, String name, byte sort) {this.Tbl = tbl; this.Name = name; this.Sort = sort;}
public final String Tbl;
public final String Name;
public final byte Sort;
public String To_sql() {
String rv = this.Name;
if (Tbl != null) rv = Tbl + "." + rv;
switch (Sort) {
case Sort__asc: rv += " ASC"; break;
case Sort__dsc: rv += " DESC"; break;
case Sort__nil: break;
}
return rv;
}
public static final String Tbl__null = String_.Null;
public static final byte Sort__asc = Bool_.Y_byte, Sort__dsc = Bool_.N_byte, Sort__nil = Bool_.__byte;
}

View File

@@ -15,26 +15,26 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <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.gfo_ndes.*;
import gplx.core.lists.*;
public class Sql_order_by_sorter implements ComparerAble {
public class Sql_order_fld_sorter implements ComparerAble {
public int compare(Object lhsObj, Object rhsObj) {
GfoNde lhs = (GfoNde)lhsObj; GfoNde rhs = (GfoNde)rhsObj;
Sql_order_by_itm item = null; Object lhsData = null, rhsData = null;
Sql_order_fld item = null; Object lhsData = null, rhsData = null;
for (int i = 0; i < items.length; i++) {
item = items[i];
lhsData = lhs.Read(item.Name()); rhsData = rhs.Read(item.Name());
lhsData = lhs.Read(item.Name); rhsData = rhs.Read(item.Name);
int compare = CompareAble_.Compare_obj(lhsData, rhsData);
if (compare == CompareAble_.Same) continue;
int ascendingVal = item.Ascending() ? 1 : -1;
int ascendingVal = item.Sort == Sql_order_fld.Sort__dsc ? -1 : 1;
return compare * ascendingVal;
}
return CompareAble_.Same;
}
Sql_order_by_itm[] items;
public static ComparerAble new_(Sql_order_by_itm[] items) {
Sql_order_by_sorter rv = new Sql_order_by_sorter();
Sql_order_fld[] items;
public static ComparerAble new_(Sql_order_fld[] items) {
Sql_order_fld_sorter rv = new Sql_order_fld_sorter();
rv.items = items;
return rv;
}

View File

@@ -15,9 +15,8 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
public class Db_fld {
public Db_fld(String name, int type_tid) {this.name = name; this.type_tid = type_tid;}
public String Name() {return name;} public Db_fld Name_(String v) {name = v; return this;} private String name;
public int Type_tid() {return type_tid;} public Db_fld Type_tid_(int v) {type_tid = v; return this;} private int type_tid;
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
public class Sql_order_itm {
public Sql_order_itm(Sql_order_fld[] flds) {this.Flds = flds;}
public final Sql_order_fld[] Flds;
}

View File

@@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import gplx.core.gfo_ndes.*; import gplx.core.type_xtns.*;
public abstract class Sql_select_fld {
public Sql_select_fld(String tbl, String fld, String alias) {
this.Tbl = tbl; this.Fld = fld; this.Alias = alias;
}
public final String Tbl;
public final String Fld;
public final String Alias;
public abstract String To_sql();
public static final String Tbl_null = null;
public static Sql_select_fld New_fld (String tbl, String fld, String alias) {return new Sql_select_fld_col(tbl, fld, alias);}
public static Sql_select_fld New_count (String tbl, String fld, String alias) {return new Sql_select_fld_count(tbl, fld, alias);}
public static Sql_select_fld New_sum (String tbl, String fld, String alias) {return new Sql_select_fld_sum(tbl, fld, alias);}
public static Sql_select_fld New_min (String tbl, String fld, String alias) {return new Sql_select_fld_minMax(CompareAble_.Less, tbl, fld, alias);}
public static Sql_select_fld New_max (String tbl, String fld, String alias) {return new Sql_select_fld_minMax(CompareAble_.More, tbl, fld, alias);}
// tdb related functions
public ClassXtn Val_type() {return val_type;} public void Val_type_(ClassXtn val) {val_type = val;} private ClassXtn val_type = ObjectClassXtn.Instance;
public abstract Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type);
@gplx.Virtual public void GroupBy_type(ClassXtn type) {this.Val_type_(type);}
}
class Sql_select_fld_wild extends Sql_select_fld { Sql_select_fld_wild() {super(Tbl_null, Fld_wildcard, Fld_wildcard);}
@Override public String To_sql() {return Fld_wildcard;}
public static final Sql_select_fld_wild Instance = new Sql_select_fld_wild();
public static final String Fld_wildcard = "*";
// tdb-related functions
@Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) {throw Err_.new_wo_type("group by eval not allowed on *");}
@Override public void GroupBy_type(ClassXtn type) {throw Err_.new_wo_type("group by type not allowed on *");}
}
class Sql_select_fld_col extends Sql_select_fld { public Sql_select_fld_col(String tbl, String fld, String alias) {super(tbl, fld, alias);}
@Override public String To_sql() {
String rv = Fld;
if (this.Tbl != Tbl_null)
rv = this.Tbl + "." + Fld;
if (!String_.Eq(Alias, Fld))
rv = rv + " AS " + Alias;
return rv;
}
// tdb-related functions
@Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) {return curVal;}
}

View File

@@ -0,0 +1,52 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import gplx.core.type_xtns.*;
abstract class Sql_select_fld_func extends Sql_select_fld { public Sql_select_fld_func(String tbl, String fld, String alias) {super(tbl, fld, alias);}
public abstract String XtoSql_functionName();
@Override public String To_sql() {
return String_.Format("{0}({1}) AS {2}", XtoSql_functionName(), Fld, Alias);
}
}
class Sql_select_fld_count extends Sql_select_fld_func { public Sql_select_fld_count(String tbl, String fld, String alias) {super(tbl, fld, alias);}
@Override public String XtoSql_functionName() {return "COUNT";}
@Override public void GroupBy_type(ClassXtn type) {this.Val_type_(IntClassXtn.Instance);}
@Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) {
if (groupByVal == null) return 1;
return Int_.cast(groupByVal) + 1;
}
}
class Sql_select_fld_sum extends Sql_select_fld_func { public Sql_select_fld_sum(String tbl, String fld, String alias) {super(tbl, fld, alias);}
@Override public String XtoSql_functionName() {return "SUM";}
@Override public void GroupBy_type(ClassXtn type) {this.Val_type_(IntClassXtn.Instance);}
@Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) {
if (groupByVal == null) return Int_.cast(curVal);
return Int_.cast(groupByVal) + Int_.cast(curVal);
}
}
class Sql_select_fld_minMax extends Sql_select_fld_func { private final int compareType;
public Sql_select_fld_minMax(int compareType, String tbl, String fld, String alias) {super(tbl, fld, alias);
this.compareType = compareType;
}
@Override public String XtoSql_functionName() {return compareType == CompareAble_.Less ? "MIN" : "MAX";}
@Override public Object GroupBy_eval(Object groupByVal, Object curVal, ClassXtn type) {
if (groupByVal == null) return curVal;
int compareVal = CompareAble_.Compare_obj(curVal, groupByVal);
return compareVal * compareType > 0 ? curVal : groupByVal;
}
}

View File

@@ -0,0 +1,24 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
public class Sql_select_fld_list {
private final Ordered_hash hash = Ordered_hash_.New();
public int Len() {return hash.Count();}
public Sql_select_fld Get_at(int i) {return (Sql_select_fld)hash.Get_at(i);}
public void Add(Sql_select_fld fld) {hash.Add(fld.Alias, fld);}
}

View File

@@ -0,0 +1,25 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
public class Sql_select_itm {
public boolean Distinct = false;
public final Sql_select_fld_list Flds = new Sql_select_fld_list();
public static final Sql_select_itm All = all_();
private static Sql_select_itm all_() {Sql_select_itm rv = new Sql_select_itm(); rv.Flds.Add(Sql_select_fld_wild.Instance); return rv;}
}

View File

@@ -0,0 +1,43 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
public class Sql_tbl_itm {
public Sql_tbl_itm(int join_tid, String db, String name, String alias, Sql_join_itm[] join_flds) {
this.Join_tid = join_tid;
this.Db = db;
this.Name = name;
this.Alias = alias;
this.Join_flds = join_flds;
}
public final int Join_tid;
public final String Db;
public final String Name;
public final String Alias;
public final Sql_join_itm[] Join_flds;
public static final String Alias__null = String_.Null;
public static final String Db__null = String_.Null;
public static final int
Tid__from = 0 // "FROM"
, Tid__inner = 1 // "INNER JOIN"
, Tid__left = 2 // "LEFT JOIN"
, Tid__right = 3 // "RIGHT JOIN"
, Tid__outer = 4 // "OUTER JOIN"
, Tid__cross = 5 // "CROSS JOIN"
;
}

View File

@@ -15,14 +15,11 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
public class Sql_order_by {
public List_adp Flds() {return flds;} List_adp flds = List_adp_.new_();
package gplx.dbs.sqls.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import gplx.core.criterias.*;
public class Sql_where_itm {
public Criteria Root = Criteria_.All;
public static final Object Where__null = null;
public static Sql_order_by new_(Sql_order_by_itm... ary) {
Sql_order_by rv = new Sql_order_by();
for (Sql_order_by_itm itm : ary)
rv.flds.Add(itm);
return rv;
} Sql_order_by() {}
public static final Sql_where_itm All = new Sql_where_itm();
}

View File

@@ -0,0 +1,104 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import gplx.core.criterias.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.wtrs.*; import gplx.dbs.sqls.itms.*;
public class Sql_core_wtr implements Sql_qry_wtr {
private final Bry_bfr bfr = Bry_bfr.new_(64);
public byte[] Seq__nl = Byte_ascii.Space_bry;
public byte Seq__quote = Byte_ascii.Apos, Seq__escape = Byte_ascii.Backslash;
public Sql_core_wtr() {
this.val_wtr = Make__val_wtr();
this.from_wtr = Make__from_wtr();
this.where_wtr = Make__where_wtr(this, val_wtr);
this.select_wtr = Make__select_wtr(this);
this.schema_wtr = Make__schema_wtr();
}
public Sql_schema_wtr Schema_wtr() {return schema_wtr;} private final Sql_schema_wtr schema_wtr;
public Sql_val_wtr Val_wtr() {return val_wtr;} private final Sql_val_wtr val_wtr;
public Sql_from_wtr From_wtr() {return from_wtr;} private final Sql_from_wtr from_wtr;
public Sql_where_wtr Where_wtr() {return where_wtr;} private final Sql_where_wtr where_wtr;
public Sql_select_wtr Select_wtr() {return select_wtr;} private final Sql_select_wtr select_wtr;
public String To_sql_str(Db_qry qry, boolean mode_is_prep) {
synchronized (bfr) {
Sql_wtr_ctx ctx = new Sql_wtr_ctx(mode_is_prep);
switch (qry.Tid()) {
case Db_qry_.Tid_insert: return Bld_qry_insert(ctx, (Db_qry_insert)qry);
case Db_qry_.Tid_delete: return Bld_qry_delete(ctx, (Db_qry_delete)qry);
case Db_qry_.Tid_update: return Bld_qry_update(ctx, (Db_qry_update)qry);
case Db_qry_.Tid_select_in_tbl:
case Db_qry_.Tid_select: select_wtr.Bld_qry_select(bfr, ctx, (Db_qry__select_cmd)qry); return bfr.To_str_and_clear();
case Db_qry_.Tid_sql: return ((Db_qry_sql)qry).To_sql__exec(this);
default: throw Err_.new_unhandled(qry.Tid());
}
}
}
private String Bld_qry_delete(Sql_wtr_ctx ctx, Db_qry_delete qry) {
bfr.Add_str_u8_many("DELETE FROM ", qry.Base_table());
where_wtr.Bld_where(bfr, ctx, qry.Where());
return bfr.To_str_and_clear();
}
private String Bld_qry_insert(Sql_wtr_ctx ctx, Db_qry_insert qry) {
if (qry.Select() != null) {
bfr.Add_str_u8_many("INSERT INTO ", qry.Base_table(), " (");
int cols_len = qry.Cols().Len();
for (int i = 0; i < cols_len; i++) {
Sql_select_fld fld = qry.Cols().Get_at(i);
bfr.Add_str_a7(fld.Alias);
bfr.Add_str_a7(i == cols_len - 1 ? ") " : ", ");
}
select_wtr.Bld_qry_select(bfr, ctx, qry.Select());
return bfr.To_str_and_clear();
}
int arg_count = qry.Args().Count(); if (arg_count == 0) throw Err_.new_wo_type("Db_qry_insert has no columns", "base_table", qry.Base_table());
int last = arg_count - 1;
bfr.Add_str_u8_many("INSERT INTO ", qry.Base_table(), " (");
for (int i = 0; i < arg_count; i++) {
KeyVal pair = qry.Args().Get_at(i);
this.Bld_col_name(bfr, pair.Key());
bfr.Add_str_a7(i == last ? ")" : ", ");
}
bfr.Add_str_a7(" VALUES (");
for (int i = 0; i < arg_count; i++) {
KeyVal pair = qry.Args().Get_at(i);
Db_arg arg = (Db_arg)pair.Val();
val_wtr.Bld_val(bfr, ctx, arg.Val);
bfr.Add_str_a7(i == last ? ")" : ", ");
}
return bfr.To_str_and_clear();
}
private String Bld_qry_update(Sql_wtr_ctx ctx, Db_qry_update qry) {
int arg_count = qry.Args().Count(); if (arg_count == 0) throw Err_.new_wo_type("Db_qry_update has no columns", "base_table", qry.Base_table());
bfr.Add_str_u8_many("UPDATE ", qry.Base_table(), " SET ");
for (int i = 0; i < arg_count; i++) {
KeyVal pair = qry.Args().Get_at(i);
if (i > 0) bfr.Add_str_a7(", ");
this.Bld_col_name(bfr, pair.Key());
bfr.Add_str_a7("=");
Db_arg arg = (Db_arg)pair.Val();
val_wtr.Bld_val(bfr, ctx, arg.Val);
}
where_wtr.Bld_where(bfr, ctx, qry.Where());
return bfr.To_str_and_clear();
}
public void Bld_col_name(Bry_bfr bfr, String key) {bfr.Add_str_u8(key);}
@gplx.Virtual protected Sql_val_wtr Make__val_wtr () {return new Sql_val_wtr();}
@gplx.Virtual protected Sql_from_wtr Make__from_wtr () {return new Sql_from_wtr();}
@gplx.Virtual protected Sql_select_wtr Make__select_wtr(Sql_core_wtr qry_wtr) {return new Sql_select_wtr(qry_wtr);}
@gplx.Virtual protected Sql_where_wtr Make__where_wtr (Sql_core_wtr qry_wtr, Sql_val_wtr val_wtr) {return new Sql_where_wtr(qry_wtr, val_wtr);}
@gplx.Virtual protected Sql_schema_wtr Make__schema_wtr() {return new Sql_schema_wtr();}
}

View File

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

View File

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

View File

@@ -0,0 +1,36 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import gplx.core.criterias.*;
class Sql_core_wtr_fxt {
private final Sql_core_wtr__sqlite wtr = new Sql_core_wtr__sqlite();
private final Sql_wtr_ctx ctx = new Sql_wtr_ctx(false);
private final Bry_bfr bfr = Bry_bfr.new_();
public Sql_core_wtr_fxt Sql_wtr_(Sql_qry_wtr v) {sql_wtr = v; return this;} private Sql_qry_wtr sql_wtr = Sql_qry_wtr_.Sqlite;
public void Test__val(Object val, String expd) {
wtr.Val_wtr().Bld_val(bfr, ctx, val);
Tfds.Eq_str(expd, bfr.To_str_and_clear());
}
public void Test__where(Criteria crt, String... expd) {
wtr.Where_wtr().Bld_where_elem(bfr, ctx, crt);
Tfds.Eq_str_lines(String_.Concat_lines_nl_skip_last(expd), bfr.To_str_and_clear());
}
public void Test__qry(Db_qry qry, String expd) {
Tfds.Eq_str_lines(expd, sql_wtr.To_sql_str(qry, Bool_.N));
}
}

View File

@@ -0,0 +1,54 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import gplx.dbs.sqls.itms.*;
public class Sql_from_wtr {
public void Bld_clause_from(Bry_bfr bfr, Sql_from_itm from) {
List_adp tbls = from.Tbls; int tbls_len = tbls.Count();
for (int i = 0; i < tbls_len; ++i) {
Sql_tbl_itm tbl = (Sql_tbl_itm)tbls.Get_at(i);
bfr.Add_byte_space().Add_str_a7(Bld_join(tbl.Join_tid)).Add_byte_space();
if (tbl.Db != Sql_tbl_itm.Db__null)
bfr.Add_str_u8(tbl.Db).Add_byte_dot();
bfr.Add_str_u8(tbl.Name);
if (tbl.Alias != Sql_tbl_itm.Alias__null)
bfr.Add_byte_space().Add_str_u8(tbl.Alias);
String tbl_alias = tbl.Alias == null ? tbl.Name : tbl.Alias;
Sql_join_itm[] flds = tbl.Join_flds; int flds_len = flds.length;
for (int j = 0; j < flds_len; ++j) {
Sql_join_itm join_fld = flds[j];
bfr.Add_str_a7(j == 0 ? " ON " : " AND ");
bfr.Add_str_u8(join_fld.Src_tbl).Add_byte_dot().Add_str_u8(join_fld.Src_fld);
bfr.Add(Bry__join_eq);
bfr.Add_str_u8(tbl_alias).Add_byte_dot().Add_str_u8(join_fld.Trg_fld);
}
}
}
private String Bld_join(int tid) {
switch (tid) {
case Sql_tbl_itm.Tid__from : return "FROM";
case Sql_tbl_itm.Tid__inner : return "INNER JOIN";
case Sql_tbl_itm.Tid__left : return "LEFT JOIN";
case Sql_tbl_itm.Tid__right : return "RIGHT JOIN";
case Sql_tbl_itm.Tid__outer : return "OUTER JOIN";
case Sql_tbl_itm.Tid__cross : return "CROSS JOIN";
default : throw Err_.new_unhandled_default(tid);
}
}
private static final byte[] Bry__join_eq = Bry_.new_a7(" = ");
}

View File

@@ -15,17 +15,19 @@ 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")
;
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import org.junit.*;
public class Sql_from_wtr_tst {
private final Sql_core_wtr_fxt fxt = new Sql_core_wtr_fxt();
@Test public void Abrv() {
fxt.Test__qry(Db_qry_.select_().Cols_all_().From_("tbl", "t"), "SELECT * FROM tbl t");
}
@Test public void Db() {
fxt.Test__qry(Db_qry_.select_().Cols_all_().From_("db", "tbl", "t"), "SELECT * FROM db.tbl t");
}
@Test public void Join() {
fxt.Test__qry
( Db_qry_.select_().Cols_all_().From_("src", "s").Join_("trg", "t", Db_qry_.New_join__join("trg_id", "s", "src_id"))
, "SELECT * FROM src s INNER JOIN trg t ON s.src_id = t.trg_id");
}
}

View File

@@ -15,28 +15,28 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import org.junit.*;
import gplx.core.criterias.*; import gplx.dbs.sqls.*;
public class Sql_qry_wtr_ansi_tst {
Sql_qry_wtr sqlWtr = Sql_qry_wtr_.new_ansi();
public class Sql_qry_wtr__ansi__tst {
Sql_qry_wtr sqlWtr = Sql_qry_wtr_.Basic;
@Test public void Insert() {
tst_XtoSql
( Db_qry_.insert_("people").Arg_("id", 1).Arg_("name", "me")
( Db_qry_.insert_("people").Val_int("id", 1).Val_str("name", "me")
, "INSERT INTO people (id, name) VALUES (1, 'me')"
);
}
@Test public void Delete() {
Criteria crt = Db_crt_.eq_("id", 1);
Criteria crt = Db_crt_.New_eq("id", 1);
tst_XtoSql
( Db_qry_.delete_("people", crt)
, "DELETE FROM people WHERE id=1"
, "DELETE FROM people WHERE id = 1"
);
}
@Test public void Update() {
tst_XtoSql
( Db_qry_.update_("people", Db_crt_.eq_("id", 1)).Arg_("name", "me")
, "UPDATE people SET name='me' WHERE id=1"
( Db_qry_.update_("people", Db_crt_.New_eq("id", 1)).Val_str("name", "me")
, "UPDATE people SET name='me' WHERE id = 1"
);
}
@Test public void SelectAll() {
@@ -53,14 +53,14 @@ public class Sql_qry_wtr_ansi_tst {
}
@Test public void SelectOrderBy() {
tst_XtoSql
( Db_qry_.select_().From_("people").OrderBy_("name", false)
( Db_qry_.select_().From_("people").Order_("name", false)
, "SELECT * FROM people ORDER BY name DESC"
);
}
@Test public void SelectWhere() {
tst_XtoSql
( Db_qry_.select_().From_("people").Where_(Db_crt_.eq_("id", 1))
, "SELECT * FROM people WHERE id=1"
( Db_qry_.select_().From_("people").Where_(Db_crt_.New_eq("id", 1))
, "SELECT * FROM people WHERE id = 1"
);
}
@Test public void Select_From_Alias() {
@@ -71,29 +71,29 @@ public class Sql_qry_wtr_ansi_tst {
}
@Test public void Select_Join_Alias() {
tst_XtoSql
( Db_qry_.select_().From_("people", "p").Join_("roles", "r", Sql_join_itm.same_("p", "id"))
, "SELECT * FROM people p INNER JOIN roles r ON p.id=r.id"
( Db_qry_.select_().From_("people", "p").Join_("roles", "r", Db_qry_.New_join__same("p", "id"))
, "SELECT * FROM people p INNER JOIN roles r ON p.id = r.id"
);
}
@Test public void Prepare() {
tst_XtoSql
( Db_qry_.insert_("people").Arg_("id", 1).Arg_("name", "me")
( Db_qry_.insert_("people").Val_int("id", 1).Val_str("name", "me")
, "INSERT INTO people (id, name) VALUES (?, ?)"
, true
);
tst_XtoSql
( Db_qry_.delete_("people", Db_crt_.eq_("id", 1))
, "DELETE FROM people WHERE id=?"
( Db_qry_.delete_("people", Db_crt_.New_eq("id", 1))
, "DELETE FROM people WHERE id = ?"
, true
);
tst_XtoSql
( Db_qry_.update_("people", Db_crt_.eq_("id", 1)).Arg_("name", "me")
, "UPDATE people SET name=? WHERE id=?"
( Db_qry_.update_("people", Db_crt_.New_eq("id", 1)).Val_str("name", "me")
, "UPDATE people SET name=? WHERE id = ?"
, true
);
}
void tst_XtoSql(Db_qry cmd, String expd) {tst_XtoSql(cmd, expd, false);}
void tst_XtoSql(Db_qry cmd, String expd, boolean prepare) {Tfds.Eq(expd, sqlWtr.Xto_str(cmd, prepare));}
void tst_XtoSql(Db_qry cmd, String expd, boolean prepare) {Tfds.Eq(expd, sqlWtr.To_sql_str(cmd, prepare));}
}

View File

@@ -15,46 +15,47 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import org.junit.*; import gplx.core.strings.*;
import gplx.core.criterias.*; /*Criteria_base*/
import gplx.core.ios.*; import gplx.dbs.sqls.*;
public class Sql_qry_wtr_iosql_tst {
import gplx.core.ios.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*;
public class Sql_qry_wtr__iosql__tst {
@Test public void Type() {
fld = IoItm_base_.Prop_Type;
tst_Write("type=1", ioCrt_(fld, Criteria_.eq_(IoItmDir.Type_Dir)));
tst_Write("type=2", ioCrt_(fld, Criteria_.eq_(IoItmFil.Type_Fil)));
tst_Write("type = 1", ioCrt_(fld, Criteria_.eq_(IoItmDir.Type_Dir)));
tst_Write("type = 2", ioCrt_(fld, Criteria_.eq_(IoItmFil.Type_Fil)));
}
@Test public void Ext() {
fld = IoItm_base_.Prop_Ext;
tst_Write("ext='.txt'", ioCrt_(fld, Criteria_.eq_(".txt")));
tst_Write("ext = '.txt'", ioCrt_(fld, Criteria_.eq_(".txt")));
tst_Write("ext IN ('.txt', '.xml', '.html')", ioCrt_(fld, Criteria_.in_(".txt", ".xml", ".html")));
tst_Write("ext NOT IN ('.dll', '.exe')", ioCrt_(fld, Criteria_.inn_(".dll", ".exe")));
}
@Test public void Title() {
fld = IoItm_base_.Prop_Title;
tst_Write("title='bin'", ioCrt_(fld, Criteria_.eq_("bin")));
tst_Write("title = 'bin'", ioCrt_(fld, Criteria_.eq_("bin")));
tst_Write("title NOT IN ('bin', 'obj')", ioCrt_(fld, Criteria_.inn_("bin", "obj")));
}
@Test public void Url() {
fld = IoItm_base_.Prop_Path;
tst_Write("url='C:\\fil.txt'", ioCrt_(fld, Criteria_.eq_("C:\\fil.txt")));
tst_Write("url = 'C:\\fil.txt'", ioCrt_(fld, Criteria_.eq_("C:\\fil.txt")));
tst_Write("url IOMATCH '*.txt'", ioCrt_(fld, Criteria_ioMatch.parse(true, "*.txt", false)));
}
@Test public void Binary() {
// parentheses around lhs and rhs
tst_Write(
"(type=1 OR type=2)"
"(type = 1 OR type = 2)"
, Criteria_.Or
( ioCrt_(IoItm_base_.Prop_Type, Criteria_.eq_(IoItmDir.Type_Dir)), ioCrt_(IoItm_base_.Prop_Type, Criteria_.eq_(IoItmFil.Type_Fil))
));
}
Criteria ioCrt_(String fld, Criteria crt) {return Criteria_fld.new_(fld, crt);}
String fld;
private final Sql_wtr_ctx ctx = new Sql_wtr_ctx(false);
void tst_Write(String expd, Criteria crt) {
String_bldr sb = String_bldr_.new_();
Sql_qry_wtr_ansi whereWtr = (Sql_qry_wtr_ansi)Sql_qry_wtr_.new_ansi();
whereWtr.Bld_where_val(sb, crt);
Tfds.Eq(expd, sb.To_str());
Sql_where_wtr where_wtr = ((Sql_core_wtr)Sql_qry_wtr_.Basic).Where_wtr();
Bry_bfr bfr = Bry_bfr.new_();
where_wtr.Bld_where_elem(bfr, ctx, crt);
Tfds.Eq(expd, bfr.To_str_and_clear());
}
}

View File

@@ -15,12 +15,11 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import gplx.dbs.metas.*;
interface Db_sqlbldr {}
public class Db_sqlbldr__sqlite implements Db_sqlbldr {
private Bry_bfr tmp_bfr = Bry_bfr.reset_(1024);
public Db_sqlbldr__sqlite Bfr_(Bry_bfr bfr) {this.tmp_bfr = bfr; return this;}
public class Sql_schema_wtr {
private Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
public Sql_schema_wtr Bfr_(Bry_bfr bfr) {this.tmp_bfr = bfr; return this;}
public String Bld_create_idx(Dbmeta_idx_itm idx) {
tmp_bfr.Add_str_a7("CREATE ");
if (idx.Unique())
@@ -101,5 +100,5 @@ public class Db_sqlbldr__sqlite implements Db_sqlbldr {
default: throw Err_.new_unhandled(tid);
}
}
public static final Db_sqlbldr__sqlite Instance = new Db_sqlbldr__sqlite();
// public static final Sql_schema_wtr Instance = new Sql_schema_wtr();
}

View File

@@ -15,10 +15,10 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import org.junit.*;
public class Db_sqlbldr_tst {
@Before public void setup() {} private final Db_sqlbldr_fxt fxt = new Db_sqlbldr_fxt();
public class Sql_schema_wtr_tst {
@Before public void setup() {} private final Sql_schema_wtr_fxt fxt = new Sql_schema_wtr_fxt();
@Test public void Idx_unique() {
fxt.Test_create_idx(Dbmeta_idx_itm.new_unique_by_tbl("tbl_name", "idx_name", "fld_1", "fld_2")
, "CREATE UNIQUE INDEX IF NOT EXISTS tbl_name__idx_name ON tbl_name (fld_1, fld_2);"
@@ -60,8 +60,8 @@ public class Db_sqlbldr_tst {
fxt.Test_alter_tbl_add("tbl_name", flds.Get_by("fld_str"), "ALTER TABLE tbl_name ADD fld_str varchar(255) NOT NULL DEFAULT 'a';");
}
}
class Db_sqlbldr_fxt {
private Db_sqlbldr__sqlite sqlbldr = Db_sqlbldr__sqlite.Instance;
class Sql_schema_wtr_fxt {
private Sql_schema_wtr sqlbldr = Sql_qry_wtr_.Sqlite.Schema_wtr();
public void Test_create_idx(Dbmeta_idx_itm idx, String expd) {Tfds.Eq(expd, sqlbldr.Bld_create_idx(idx));}
public void Test_create_tbl(Dbmeta_tbl_itm tbl, String expd) {Tfds.Eq_str_lines(expd, sqlbldr.Bld_create_tbl(tbl));}
public void Test_alter_tbl_add(String tbl, Dbmeta_fld_itm fld, String expd) {Tfds.Eq_str_lines(expd, sqlbldr.Bld_alter_tbl_add(tbl, fld));}

View File

@@ -0,0 +1,80 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import gplx.dbs.qrys.*; import gplx.dbs.sqls.itms.*;
public class Sql_select_wtr {
private final Sql_core_wtr qry_wtr;
public Sql_select_wtr(Sql_core_wtr qry_wtr) {this.qry_wtr = qry_wtr;}
public void Bld_qry_select(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry) {
bfr.Add_str_a7("SELECT ");
if (qry.Cols().Distinct) bfr.Add_str_a7("DISTINCT ");
Sql_select_fld_list flds = qry.Cols().Flds;
int flds_len = flds.Len();
if (flds_len == 0) bfr.Add_str_a7("*");
for (int i = 0; i < flds_len; i++) {
Sql_select_fld fld = (Sql_select_fld)flds.Get_at(i);
if (i > 0) bfr.Add_str_a7(", ");
qry_wtr.Bld_col_name(bfr, fld.To_sql());
}
qry_wtr.From_wtr().Bld_clause_from(bfr, qry.From());
Bld_indexed_by(bfr, ctx, qry, qry.Indexed_by());
qry_wtr.Where_wtr().Bld_where(bfr, ctx, qry.Where_itm());
Bld_select_group_by(bfr, ctx, qry, qry.GroupBy());
Bld_select_order_by(bfr, ctx, qry, qry.Order());
Bld_select_limit(bfr, ctx, qry, qry.Limit());
if (qry.Offset() != Db_qry__select_cmd.Offset__disabled)
Bld_offset(bfr, ctx, qry, qry.Offset());
}
private void Bld_select_group_by(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, Sql_group_itm groupBy) {
if (groupBy == null) return;
bfr.Add_str_a7(" GROUP BY ");
for (int i = 0; i < groupBy.Flds().Count(); i++) {
String item = (String)groupBy.Flds().Get_at(i);
if (i > 0) bfr.Add_str_a7(", ");
bfr.Add_str_a7(item);
}
}
private void Bld_select_order_by(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, Sql_order_itm orderBy) {
if (orderBy == null) return;
bfr.Add_str_a7(" ORDER BY ");
int len = orderBy.Flds.length;
for (int i = 0; i < len; ++i) {
Sql_order_fld item = orderBy.Flds[i];
if (i > 0) bfr.Add_str_a7(", ");
bfr.Add_str_a7(item.To_sql());
}
}
protected void Bld_select_limit(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, int limit) {
if (limit == Db_qry__select_cmd.Limit__disabled) return;
bfr.Add_str_a7(" LIMIT ").Add_int_variable(limit);
}
@gplx.Virtual protected void Bld_offset(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, int offset) {
bfr.Add_str_a7(" OFFSET ").Add_int_variable(offset);
}
private void Bld_indexed_by(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, String idx_name) {
if (idx_name == null) return;
// ( "SELECT {0}, {1}, {2}, {3} FROM {4} INDEXED BY {4}__title WHERE {1} = {5} AND {2} BETWEEN '{6}' AND '{7}' ORDER BY {3} DESC LIMIT {8};"
bfr.Add_str_a7(" INDEXED BY ").Add_str_a7(idx_name);
}
}
class Sql_select_wtr_sqlite extends Sql_select_wtr { public Sql_select_wtr_sqlite(Sql_core_wtr qry_wtr) {super(qry_wtr);}
@Override protected void Bld_offset(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_qry__select_cmd qry, int offset) {
if (qry.Limit() == Db_qry__select_cmd.Limit__disabled) Bld_select_limit(bfr, ctx, qry, -1); // SQLite requires a LIMIT if OFFSET is specified
super.Bld_offset(bfr, ctx, qry, offset);
}
}

View File

@@ -15,17 +15,14 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
public class Sql_order_by_itm {
public String Name() {return name;} private String name;
public boolean Ascending() {return ascending;} private boolean ascending;
public String XtoSql() {
String ascString = ascending ? "" : " DESC";
return name + ascString;
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import org.junit.*;
public class Sql_select_wtr_tst {
private final Sql_core_wtr_fxt fxt = new Sql_core_wtr_fxt();
@Test public void Offset__automatically_add_limit() {
fxt.Test__qry(Db_qry_.select_tbl_("tbl").Offset_(1), "SELECT * FROM tbl LIMIT -1 OFFSET 1");
}
@Test public void Offset__do_not_overwrite_limit() {
fxt.Test__qry(Db_qry_.select_tbl_("tbl").Limit_(20).Offset_(1), "SELECT * FROM tbl LIMIT 20 OFFSET 1");
}
public static Sql_order_by_itm new_(String name, boolean ascending) {
Sql_order_by_itm rv = new Sql_order_by_itm();
rv.name = name; rv.ascending = ascending;
return rv;
} Sql_order_by_itm() {}
}

View File

@@ -0,0 +1,91 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
public class Sql_val_wtr {
// private final Bry_bfr tmp_bfr = Bry_bfr.new_(32);
public byte Seq__quote = Byte_ascii.Apos, Seq__escape = Byte_ascii.Backslash;
public void Bld_val(Bry_bfr bfr, Sql_wtr_ctx ctx, Object val) {
if (ctx.Mode_is_prep) {
bfr.Add_byte(Byte_ascii.Question);
return;
}
if (val == null) {
bfr.Add_str_a7("NULL");
return;
}
int tid_type = Type_adp_.To_tid_type(val.getClass());
switch (tid_type) {
case Type_adp_.Tid__bool: Bld_val__bool (bfr, Bool_.cast(val)); break;
case Type_adp_.Tid__byte: Bld_val__byte (bfr, Byte_.cast(val)); break;
case Type_adp_.Tid__short: Bld_val__short (bfr, Short_.cast(val)); break;
case Type_adp_.Tid__int: Bld_val__int (bfr, Int_.cast(val)); break;
case Type_adp_.Tid__long: Bld_val__long (bfr, Long_.cast(val)); break;
case Type_adp_.Tid__float: Bld_val__float (bfr, Float_.cast(val)); break;
case Type_adp_.Tid__double: Bld_val__double (bfr, Double_.cast(val)); break;
case Type_adp_.Tid__decimal: Bld_val__decimal (bfr, Decimal_adp_.cast(val)); break;
case Type_adp_.Tid__str: Bld_val__str (bfr, String_.cast(val)); break;
case Type_adp_.Tid__date: Bld_val__date (bfr, DateAdp_.cast(val)); break;
case Type_adp_.Tid__obj: Bld_val__str (bfr, Object_.Xto_str_strict_or_null(val)); break;
}
}
@gplx.Virtual public void Bld_val__bool (Bry_bfr bfr, boolean val) {bfr.Add_int_digits(1, val ? 1 : 0);} // NOTE: save boolean to 0 or 1 b/c sqlite doesn't support true / false //{bfr.Add_str_a7(val ? "true" : "false");}
@gplx.Virtual public void Bld_val__byte (Bry_bfr bfr, byte val) {bfr.Add_byte_variable(val);}
@gplx.Virtual public void Bld_val__short (Bry_bfr bfr, short val) {bfr.Add_short_variable(val);}
@gplx.Virtual public void Bld_val__int (Bry_bfr bfr, int val) {bfr.Add_int_variable(val);}
@gplx.Virtual public void Bld_val__long (Bry_bfr bfr, long val) {bfr.Add_long_variable(val);}
@gplx.Virtual public void Bld_val__float (Bry_bfr bfr, float val) {bfr.Add_float(val);}
@gplx.Virtual public void Bld_val__double (Bry_bfr bfr, double val) {bfr.Add_double(val);}
@gplx.Virtual public void Bld_val__date (Bry_bfr bfr, DateAdp val) {bfr.Add_str_u8_many("'", val.XtoStr_gplx_long(), "'");}
@gplx.Virtual public void Bld_val__decimal (Bry_bfr bfr, Decimal_adp val) {bfr.Add_str_u8_many("'", val.To_str(), "'");}
@gplx.Virtual public void Bld_val__str (Bry_bfr bfr, String val) {
// byte[] bry = Bry_.new_u8(val); int len = bry.length; int pos = 0; int prv = -1; boolean dirty = false;
// while (true) {
// if (pos == len) break;
// byte b = bry[pos];
// if (b == Seq__quote) {
// if (!dirty) {dirty = true; if (prv != -1) {tmp_bfr.Add_mid(bry, prv, pos); prv = -1;}}
// tmp_bfr.Add_byte(Seq__quote).Add_byte(Seq__quote); // double-up
// }
//// else if (b == Seq__escape) {
//// if (!dirty) {dirty = true; if (prv != -1) {tmp_bfr.Add_mid(bry, prv, pos); prv = -1;}}
//// tmp_bfr.Add_byte(Seq__escape).Add_byte(Seq__escape); // double-up
//// }
// else
// if (prv == -1) prv = pos;
// ++pos;
// }
// if (dirty && prv != -1) tmp_bfr.Add_mid(bry, prv, len);
bfr.Add_byte(Seq__quote);
bfr.Add_str_u8(String_.Replace(val, "'", "''"));
// if (dirty)
// bfr.Add_bfr_and_clear(tmp_bfr);
// else
// bfr.Add(bry);
bfr.Add_byte(Seq__quote);
}
}
class Sql_val_wtr_sqlite extends Sql_val_wtr { @Override public void Bld_val__bool(Bry_bfr bfr, boolean val) {
bfr.Add_int_digits(1, val ? 1 : 0); // NOTE: save boolean to 0 or 1 b/c sqlite doesn't support true / false
}
}
class Sql_val_wtr_mysql extends Sql_val_wtr { @Override public void Bld_val__str(Bry_bfr bfr, String val) {
if (String_.Has(val, "\\")) val = String_.Replace(val, "\\", "\\\\");
super.Bld_val__str(bfr, val);
}
}

View File

@@ -0,0 +1,39 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import org.junit.*;
public class Sql_val_wtr_tst {
private final Sql_core_wtr_fxt fxt = new Sql_core_wtr_fxt();
@Test public void Null() {fxt.Test__val(null , "NULL");}
@Test public void Bool__n() {fxt.Test__val(Bool_.N , "0");}
@Test public void Bool__y() {fxt.Test__val(Bool_.Y , "1");}
@Test public void Byte() {fxt.Test__val(Byte_.By_int(2) , "2");}
@Test public void Short() {fxt.Test__val(Short_.By_int(3) , "3");}
@Test public void Int() {fxt.Test__val(4 , "4");}
@Test public void Long() {fxt.Test__val(5 , "5");}
@Test public void Float() {fxt.Test__val(6.1f , "6.1");}
@Test public void Double() {fxt.Test__val(7.1d , "7.1");}
@Test public void Decimal() {fxt.Test__val(Decimal_adp_.float_(8) , "'8'");}
@Test public void Str() {fxt.Test__val("abc" , "'abc'");}
@Test public void Str__apos_mid() {fxt.Test__val("a'b" , "'a''b'");}
@Test public void Str__apos_bgn() {fxt.Test__val("'ab" , "'''ab'");}
@Test public void Str__apos_end() {fxt.Test__val("ab'" , "'ab'''");}
@Test public void Str__apos_many() {fxt.Test__val("a'b'c" , "'a''b''c'");}
@Test public void Str__back() {fxt.Test__val("a\\b" , "'a\\b'");}
@Test public void Date() {fxt.Test__val(DateAdp_.parse_gplx("2016-02-03") , "'2016-02-03 00:00:00.000'");}
}

View File

@@ -0,0 +1,145 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import gplx.core.criterias.*; import gplx.dbs.sqls.itms.*;
public class Sql_where_wtr {
private final Sql_core_wtr qry_wtr;
private final Sql_val_wtr val_wtr;
public Sql_where_wtr(Sql_core_wtr qry_wtr, Sql_val_wtr val_wtr) {this.qry_wtr = qry_wtr; this.val_wtr = val_wtr;}
public void Bld_where(Bry_bfr bfr, Sql_wtr_ctx ctx, Sql_where_itm where_itm) {
if (where_itm == Sql_where_itm.Where__null) return;
Bld_where(bfr, ctx, where_itm.Root);
}
public void Bld_where(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria crt) {
if (crt == null) return;
if (crt.Tid() == Criteria_.Tid_wrapper) {
Criteria_fld crt_fld = (Criteria_fld)crt;
Criteria crt_inner = crt_fld.Crt();
switch (crt_inner.Tid()) {
case Criteria_.Tid_const:
case Criteria_.Tid_not:
case Criteria_.Tid_and:
case Criteria_.Tid_or: crt = crt_inner; break;
default: break;
}
}
if (crt.Tid() == Criteria_.Tid_const) return;
bfr.Add_str_a7(" WHERE ");
Bld_where_elem(bfr, ctx, crt);
}
public void Bld_where_elem(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria crt) {
if (crt == null) return; // handle empty crt; EX: SELECT * FROM tbl;
Criteria_bool_base crt_bool = Criteria_bool_base.as_(crt);
if (crt_bool != null) {
bfr.Add_str_a7("(");
Bld_where_elem(bfr, ctx, crt_bool.Lhs());
bfr.Add_str_u8_many(" ", crt_bool.Op_literal(), " ");
Bld_where_elem(bfr, ctx, crt_bool.Rhs());
bfr.Add_str_a7(")");
return;
}
if (crt.Tid() == Criteria_.Tid_db_obj_ary) {
Bld_where__db_obj(bfr, ctx, (Db_obj_ary_crt)crt);
}
else {
Criteria_fld leaf = Criteria_fld.as_(crt); if (leaf == null) throw Err_.new_invalid_op(crt.To_str());
String leaf_pre = leaf.Pre(); if (leaf_pre != Criteria_fld.Pre_null) bfr.Add_str_u8(leaf_pre).Add_byte_dot();
qry_wtr.Bld_col_name(bfr, leaf.Key());
Criteria leaf_crt = leaf.Crt();
switch (leaf_crt.Tid()) {
case Criteria_.Tid_eq: Bld_where__eq (bfr, ctx, (Criteria_eq)leaf_crt); break;
case Criteria_.Tid_comp: Bld_where__comp (bfr, ctx, (Criteria_comp)leaf_crt); break;
case Criteria_.Tid_between: Bld_where__between (bfr, ctx, (Criteria_between)leaf_crt); break;
case Criteria_.Tid_in: Bld_where__in (bfr, ctx, (Criteria_in)leaf_crt); break;
case Criteria_.Tid_like: Bld_where__like (bfr, ctx, (Criteria_like)leaf_crt); break;
case Criteria_.Tid_iomatch: Bld_where__iomatch (bfr, ctx, (Criteria_ioMatch)leaf_crt); break;
default: throw Err_.new_unhandled(leaf_crt);
}
}
}
private void Bld_where__eq(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_eq crt) {
bfr.Add_str_a7(crt.Neg() ? " != " : " = ");
val_wtr.Bld_val(bfr, ctx, crt.Val());
}
private void Bld_where__comp(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_comp crt) {
int comp_tid = crt.Comp_mode();
bfr.Add_byte_space();
bfr.Add_byte(comp_tid < CompareAble_.Same ? Byte_ascii.Angle_bgn : Byte_ascii.Angle_end);
if (comp_tid % 2 == CompareAble_.Same) bfr.Add_byte_eq();
bfr.Add_byte_space();
val_wtr.Bld_val(bfr, ctx, crt.Val());
}
private void Bld_where__between(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_between crt) {
bfr.Add_str_a7(crt.Neg() ? " NOT BETWEEN " : " BETWEEN ");
val_wtr.Bld_val(bfr, ctx, crt.Lo());
bfr.Add_str_a7(" AND ");
val_wtr.Bld_val(bfr, ctx, crt.Hi());
}
private void Bld_where__like(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_like crt) {
bfr.Add_str_a7(crt.Neg() ? " NOT LIKE " : " LIKE ");
val_wtr.Bld_val(bfr, ctx, crt.Pattern().Raw());
bfr.Add_str_u8(String_.Format(" ESCAPE '{0}'", crt.Pattern().Escape()));
}
private void Bld_where__in(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_in crt) {
bfr.Add_str_a7(crt.Neg() ? " NOT IN " : " IN ");
Object[] ary = crt.Ary();
int len = crt.Ary_len();
for (int i = 0; i < len; ++i) {
if (i == 0)
bfr.Add_byte(Byte_ascii.Paren_bgn);
else
bfr.Add_byte(Byte_ascii.Comma).Add_byte_space();
val_wtr.Bld_val(bfr, ctx, ary[i]);
}
bfr.Add_byte(Byte_ascii.Paren_end);
}
private void Bld_where__iomatch(Bry_bfr bfr, Sql_wtr_ctx ctx, Criteria_ioMatch crt) {
bfr.Add_str_a7(crt.Neg() ? " NOT IOMATCH " : " IOMATCH ");
val_wtr.Bld_val(bfr, ctx, crt.Pattern().Raw());
}
public void Bld_where__db_obj(Bry_bfr bfr, Sql_wtr_ctx ctx, Db_obj_ary_crt crt) {
Object[][] ary = crt.Vals();
int ary_len = ary.length;
Db_obj_ary_fld[] flds = crt.Flds();
for (int i = 0; i < ary_len; i++) {
Object[] itm = (Object[])ary[i];
int itm_len = itm.length;
if (i != 0) bfr.Add_str_a7(" OR ");
bfr.Add_str_a7("(");
for (int j = 0; j < itm_len; j++) {
if (j != 0) bfr.Add_str_a7(" AND ");
Db_obj_ary_fld fld = flds[j];
Object val = itm[j];
boolean quote = false;
switch (fld.Type_tid()) {
case Type_adp_.Tid__str:
case Type_adp_.Tid__char:
case Type_adp_.Tid__date:
quote = true;
break;
}
bfr.Add_str_a7(fld.Name());
bfr.Add_str_a7("=");
if (quote) bfr.Add_str_a7("'");
bfr.Add_str_a7(Object_.Xto_str_strict_or_empty(val));
if (quote) bfr.Add_str_a7("'");
}
bfr.Add_str_a7(")");
}
}
}

View File

@@ -0,0 +1,55 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls.wtrs; import gplx.*; import gplx.dbs.*; import gplx.dbs.sqls.*;
import org.junit.*; import gplx.core.criterias.*;
public class Sql_where_wtr_tst {
private final Sql_core_wtr_fxt fxt = new Sql_core_wtr_fxt();
@Test public void Eq() {fxt.Test__where(Db_crt_.New_eq ("fld", 1) , "fld = 1");}
@Test public void Eq_not() {fxt.Test__where(Db_crt_.New_eq_not ("fld", 1) , "fld != 1");}
@Test public void Eq_pre() {fxt.Test__where(Db_crt_.New_eq ("a", "fld", 1) , "a.fld = 1");}
@Test public void Lt() {fxt.Test__where(Db_crt_.New_lt ("fld", 1) , "fld < 1");}
@Test public void Lte() {fxt.Test__where(Db_crt_.New_lte ("fld", 1) , "fld <= 1");}
@Test public void Mt() {fxt.Test__where(Db_crt_.New_mt ("fld", 1) , "fld > 1");}
@Test public void Mte() {fxt.Test__where(Db_crt_.New_mte ("fld", 1) , "fld >= 1");}
@Test public void Between() {fxt.Test__where(Db_crt_.New_between ("fld", 1, 3) , "fld BETWEEN 1 AND 3");}
@Test public void In() {fxt.Test__where(Db_crt_.New_in ("fld", 1, 2, 3) , "fld IN (1, 2, 3)");}
@Test public void Like() {fxt.Test__where(Db_crt_.New_like ("fld", "A%") , "fld LIKE 'A%' ESCAPE '|'");}
@Test public void And__subs__2() {
fxt.Test__where
( Criteria_.And
( Db_crt_.New_eq("id", 1)
, Db_crt_.New_eq("name", "me")
), "(id = 1 AND name = 'me')");
}
@Test public void Or__subs__2() {
fxt.Test__where
( Criteria_.Or
( Db_crt_.New_eq("id", 1)
, Db_crt_.New_eq("name", "me")
), "(id = 1 OR name = 'me')");
}
@Test public void Nested() {
fxt.Test__where
( Criteria_.Or
( Db_crt_.New_eq("id", 1)
, Criteria_.And
( Db_crt_.New_eq("name", "me")
, Db_crt_.New_eq("id", 2))
), "(id = 1 OR (name = 'me' AND id = 2))");
}
}

View File

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