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
2015-07-12 21:10:02 -04:00
commit 794b5a232f
3099 changed files with 238212 additions and 0 deletions

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; import gplx.*; import gplx.dbs.*;
public class Db_fld {
public Db_fld(String name, byte 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 byte Type_tid() {return type_tid;} public Db_fld Type_tid_(byte v) {type_tid = v; return this;} private byte type_tid;
}

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; import gplx.*; import gplx.dbs.*;
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 Object[][] Vals() {return vals;} public void Vals_(Object[][] v) {this.vals = v;} private Object[][] vals;
public void Val_from_args(Hash_adp args) {throw Exc_.new_unimplemented();}
public void Val_as_obj_(Object v) {throw Exc_.new_unimplemented();}
public boolean Matches(Object obj) {return false;}
public String XtoStr() {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_by_type(byte type_tid, String... names) {
int len = names.length;
Db_fld[] flds = new Db_fld[len];
for (int i = 0; i < len; i++)
flds[i] = new Db_fld(names[i], type_tid);
return new Db_obj_ary_crt().Flds_(flds);
}
}

View File

@@ -0,0 +1,42 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
import org.junit.*; import gplx.core.strings.*; import gplx.dbs.sqls.*;
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() {
fxt.Init_fld("fld_0", ClassAdp_.Tid_int).Init_fld("fld_1", ClassAdp_.Tid_int).Init_vals(1, 10).Init_vals(2, 20).Test_sql("(fld_0=1 AND fld_1=10) OR (fld_0=2 AND fld_1=20)");
}
@Test public void Str() {
fxt.Init_fld("fld_0", ClassAdp_.Tid_int).Init_fld("fld_1", ClassAdp_.Tid_str).Init_vals(1, "a").Init_vals(2, "b").Test_sql("(fld_0=1 AND fld_1='a') OR (fld_0=2 AND fld_1='b')");
}
}
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, byte tid) {flds_list.Add(new Db_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_.I;
String_bldr sb = String_bldr_.new_();
crt.Flds_((Db_fld[])flds_list.To_ary_and_clear(Db_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.Xto_str_and_clear());
return this;
}
}

View File

@@ -0,0 +1,99 @@
/*
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.*;
interface Db_sqlbldr {}
public class Db_sqlbldr__sqlite implements Db_sqlbldr {
private final Bry_bfr tmp_bfr = Bry_bfr.reset_(1024);
public String Bld_create_idx(Db_meta_idx idx) {
tmp_bfr.Add_str_a7("CREATE ");
if (idx.Unique())
tmp_bfr.Add_str_a7("UNIQUE ");
tmp_bfr.Add_str_a7("INDEX ");
tmp_bfr.Add_str_a7("IF NOT EXISTS ");
tmp_bfr.Add_str_a7(idx.Name());
tmp_bfr.Add_str_a7(" ON ");
tmp_bfr.Add_str_a7(idx.Tbl());
tmp_bfr.Add_str_a7(" (");
String[] flds = idx.Flds();
int flds_len = flds.length;
for (int i = 0; i < flds_len; ++i) {
String fld = flds[i];
if (i != 0) tmp_bfr.Add_str_a7(", ");
tmp_bfr.Add_str_a7(fld);
}
tmp_bfr.Add_str_a7(");");
return tmp_bfr.Xto_str_and_clear();
}
public String Bld_create_tbl(Db_meta_tbl tbl) {
tmp_bfr.Add_str_a7("CREATE TABLE IF NOT EXISTS ").Add_str_a7(tbl.Name()).Add_byte_nl();
Db_meta_fld[] flds = tbl.Flds();
int flds_len = flds.length;
for (int i = 0; i < flds_len; ++i) {
Db_meta_fld fld = flds[i];
tmp_bfr.Add_byte(i == 0 ? Byte_ascii.Paren_bgn : Byte_ascii.Comma).Add_byte_space();
Bld_fld(tmp_bfr, fld);
tmp_bfr.Add_byte_nl();
}
tmp_bfr.Add_str_a7(");");
return tmp_bfr.Xto_str_and_clear();
}
public String Bld_alter_tbl_add(String tbl, Db_meta_fld fld) {
tmp_bfr.Add_str_a7("ALTER TABLE ").Add_str_a7(tbl).Add_str_a7(" ADD ");
Bld_fld(tmp_bfr, fld);
tmp_bfr.Add_byte_semic();
return tmp_bfr.Xto_str_and_clear();
}
public String Bld_drop_tbl(String tbl) {
return String_.Format("DROP TABLE IF EXISTS {0};", tbl);
}
private void Bld_fld(Bry_bfr tmp_bfr, Db_meta_fld fld) {
tmp_bfr.Add_str_a7(fld.Name()).Add_byte_space();
Tid_to_sql(tmp_bfr, fld.Tid(), fld.Len()); tmp_bfr.Add_byte_space();
tmp_bfr.Add_str_a7(fld.Nullable() ? "NULL " : "NOT NULL ");
if (fld.Default() != Db_meta_fld.Default_value_null) {
tmp_bfr.Add_str_a7("DEFAULT ");
boolean quote = Bool_.N;
switch (fld.Tid()) {
case Db_meta_fld.Tid_str: case Db_meta_fld.Tid_text: quote = Bool_.Y; break;
}
if (quote) tmp_bfr.Add_byte_apos();
tmp_bfr.Add_str_u8(Object_.Xto_str_strict_or_null(fld.Default()));
if (quote) tmp_bfr.Add_byte_apos();
tmp_bfr.Add_byte_space();
}
if (fld.Primary()) tmp_bfr.Add_str_a7("PRIMARY KEY ");
if (fld.Autonum()) tmp_bfr.Add_str_a7("AUTOINCREMENT ");
tmp_bfr.Del_by_1(); // remove trailing space
}
public static void Tid_to_sql(Bry_bfr tmp_bfr, int tid, int len) {// REF: https://www.sqlite.org/datatype3.html
switch (tid) {
case Db_meta_fld.Tid_bool: tmp_bfr.Add_str_a7("boolean"); break;
case Db_meta_fld.Tid_byte: tmp_bfr.Add_str_a7("tinyint"); break;
case Db_meta_fld.Tid_short: tmp_bfr.Add_str_a7("smallint"); break;
case Db_meta_fld.Tid_int: tmp_bfr.Add_str_a7("integer"); break; // NOTE: must be integer, not int, else "int PRIMARY KEY AUTONUMBER" will fail; DATE:2015-02-12
case Db_meta_fld.Tid_long: tmp_bfr.Add_str_a7("bigint"); break;
case Db_meta_fld.Tid_float: tmp_bfr.Add_str_a7("float"); break;
case Db_meta_fld.Tid_double: tmp_bfr.Add_str_a7("double"); break;
case Db_meta_fld.Tid_str: tmp_bfr.Add_str_a7("varchar(").Add_int_variable(len).Add_byte(Byte_ascii.Paren_end); break;
case Db_meta_fld.Tid_text: tmp_bfr.Add_str_a7("text"); break;
case Db_meta_fld.Tid_bry: tmp_bfr.Add_str_a7("blob"); break;
default: throw Exc_.new_unhandled(tid);
}
}
public static final Db_sqlbldr__sqlite I = new Db_sqlbldr__sqlite(); Db_sqlbldr__sqlite() {}
}

View File

@@ -0,0 +1,68 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.sqls; import gplx.*; import gplx.dbs.*;
import org.junit.*;
public class Db_sqlbldr_tst {
@Before public void setup() {} private final Db_sqlbldr_fxt fxt = new Db_sqlbldr_fxt();
@Test public void Idx_unique() {
fxt.Test_create_idx(Db_meta_idx.new_unique_by_tbl("tbl_name", "idx_name", "fld_1", "fld_2")
, "CREATE UNIQUE INDEX IF NOT EXISTS tbl_name__idx_name ON tbl_name (fld_1, fld_2);"
);
}
@Test public void Tbl_basic() {
Db_meta_fld_list flds = Db_meta_fld_list.new_();
flds.Add_int_pkey("fld_int_pkey");
flds.Add_bool("fld_bool");
flds.Add_short("fld_short");
flds.Add_int("fld_int");
flds.Add_long("fld_long");
flds.Add_float("fld_float");
flds.Add_double("fld_double");
flds.Add_str("fld_str", 123);
flds.Add_text("fld_text");
flds.Add_bry("fld_bry");
fxt.Test_create_tbl(Db_meta_tbl.new_("tbl_name", flds.To_fld_ary())
, String_.Concat_lines_nl_skip_last
( "CREATE TABLE IF NOT EXISTS tbl_name"
, "( fld_int_pkey integer NOT NULL PRIMARY KEY"
, ", fld_bool boolean NOT NULL"
, ", fld_short smallint NOT NULL"
, ", fld_int integer NOT NULL"
, ", fld_long bigint NOT NULL"
, ", fld_float float NOT NULL"
, ", fld_double double NOT NULL"
, ", fld_str varchar(123) NOT NULL"
, ", fld_text text NOT NULL"
, ", fld_bry blob NOT NULL"
, ");"
));
}
@Test public void Tbl_alter_tbl_add() {
Db_meta_fld_list flds = Db_meta_fld_list.new_();
flds.Add_int_dflt("fld_int", -1);
flds.Add_str_dflt("fld_str", 255, "a");
fxt.Test_alter_tbl_add("tbl_name", flds.Get_by("fld_int"), "ALTER TABLE tbl_name ADD fld_int integer NOT NULL DEFAULT -1;");
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.I;
public void Test_create_idx(Db_meta_idx idx, String expd) {Tfds.Eq(expd, sqlbldr.Bld_create_idx(idx));}
public void Test_create_tbl(Db_meta_tbl tbl, String expd) {Tfds.Eq_str_lines(expd, sqlbldr.Bld_create_tbl(tbl));}
public void Test_alter_tbl_add(String tbl, Db_meta_fld fld, String expd) {Tfds.Eq_str_lines(expd, sqlbldr.Bld_alter_tbl_add(tbl, fld));}
}

View File

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

View File

@@ -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.sqls; import gplx.*; import gplx.dbs.*;
public class Sql_group_by {
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();
for (String itm : ary)
rv.flds.Add(itm);
return rv;
} Sql_group_by() {}
}

View File

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

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

View File

@@ -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.sqls; import gplx.*; import gplx.dbs.*;
public class Sql_order_by {
public List_adp Flds() {return flds;} List_adp flds = List_adp_.new_();
public static Sql_order_by new_(Sql_order_by_itm... ary) {
Sql_order_by rv = new Sql_order_by();
for (Sql_order_by_itm itm : ary)
rv.flds.Add(itm);
return rv;
} Sql_order_by() {}
}

View File

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

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; import gplx.*; import gplx.dbs.*;
import gplx.core.criterias.*;
public interface Sql_qry_wtr {
String Xto_str(Db_qry qry, boolean prepare);
}

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; import gplx.*; import gplx.dbs.*;
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 I = new Sql_qry_wtr_ansi();
public static String Gen_placeholder_parameters(Db_qry qry) {return Sql_qry_wtr_.I.Xto_str(qry, true);} // replace arguments with ?; EX: UPDATE a SET b = ? WHERE c = ?;
}

View File

@@ -0,0 +1,300 @@
/*
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 Exc_.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.Xto_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.Xto_str_and_clear();
}
int arg_count = cmd.Args().Count(); if (arg_count == 0) throw Exc_.new_("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.Xto_str_and_clear();
}
private String Bld_qry_update(Db_qry_update cmd) {
int arg_count = cmd.Args().Count(); if (arg_count == 0) throw Exc_.new_("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.Xto_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.Xto_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 Exc_.new_null("ColName");
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_.Xto_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 == DecimalAdp.class) {
DecimalAdp valDecimal = (DecimalAdp)val;
sb.Add(valDecimal.Xto_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 Exc_.new_invalid_op(crt.XtoStr());
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 Exc_.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 ClassAdp_.Tid_str:
case ClassAdp_.Tid_char:
case ClassAdp_.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

@@ -0,0 +1,99 @@
/*
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.criterias.*; import gplx.dbs.sqls.*;
public class Sql_qry_wtr_ansi_tst {
Sql_qry_wtr sqlWtr = Sql_qry_wtr_.new_ansi();
@Test public void Insert() {
tst_XtoSql
( Db_qry_.insert_("people").Arg_("id", 1).Arg_("name", "me")
, "INSERT INTO people (id, name) VALUES (1, 'me')"
);
}
@Test public void Delete() {
Criteria crt = Db_crt_.eq_("id", 1);
tst_XtoSql
( Db_qry_.delete_("people", crt)
, "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"
);
}
@Test public void SelectAll() {
tst_XtoSql
( Db_qry_.select_().From_("people")
, "SELECT * FROM people"
);
}
@Test public void SelectFlds() {
tst_XtoSql
( Db_qry_.select_().Cols_("id", "name").From_("people")
, "SELECT id, name FROM people"
);
}
@Test public void SelectOrderBy() {
tst_XtoSql
( Db_qry_.select_().From_("people").OrderBy_("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"
);
}
@Test public void Select_From_Alias() {
tst_XtoSql
( Db_qry_.select_().From_("people", "p")
, "SELECT * FROM people p"
);
}
@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"
);
}
@Test public void Prepare() {
tst_XtoSql
( Db_qry_.insert_("people").Arg_("id", 1).Arg_("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=?"
, true
);
tst_XtoSql
( Db_qry_.update_("people", Db_crt_.eq_("id", 1)).Arg_("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));}
}

View File

@@ -0,0 +1,60 @@
/*
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.*; /*Criteria_base*/
import gplx.ios.*; import gplx.dbs.sqls.*;
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)));
}
@Test public void Ext() {
fld = IoItm_base_.Prop_Ext;
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 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 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)"
, 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;
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.XtoStr());
}
}

View File

@@ -0,0 +1,60 @@
/*
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.XtoStr());
}
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.XtoStr());
}
}

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; 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._); return rv;}
public static Sql_select new_() {return new Sql_select();} Sql_select() {}
}

View File

@@ -0,0 +1,69 @@
/*
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_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._);}
@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._);}
@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

@@ -0,0 +1,45 @@
/*
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 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._;
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 Exc_.new_("group by eval not allowed on *");}
@Override public void GroupBy_type(GfoFld fld) {throw Exc_.new_("group by type not allowed on *");}
@Override public String XtoSql() {return "*";}
public static final Sql_select_fld_wild _ = 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

@@ -0,0 +1,57 @@
/*
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_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 Exc_.new_("fld not found in tbl", "fldName", selectFld.Fld(), "tblName", tbl.Name(), "tblFlds", tbl.Flds().XtoStr());
if (rv.Has(selectFld.Alias())) throw Exc_.new_("alias is not unique", "fldName", selectFld.Fld(), "flds", rv.XtoStr());
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 XtoStr() {
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.XtoStr();
}
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

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