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,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; import gplx.*;
public class Db_cmd_mode {
Db_cmd_mode(int val) {this.val = val;}
public int Val() {return val;} int val;
public Db_cmd_mode MarkUpdated() {return this == Retrieved ? Updated : this;} // Created/Deleted noops
public boolean Modified() {return this == Created || this == Updated;}
public static final byte Tid_create = 1, Tid_update = 2, Tid_delete = 3, Tid_ignore = 4;
public static final Db_cmd_mode
Created = new Db_cmd_mode(Tid_create)
, Updated = new Db_cmd_mode(Tid_update)
, Deleted = new Db_cmd_mode(Tid_delete)
, Retrieved = new Db_cmd_mode(Tid_ignore)
;
public static byte To_update(byte cur) {
switch (cur) {
case Tid_create: // ignore update if item is already marked for create
case Tid_delete: // ignore update if item is already marked for delete (might want to throw error)
return cur;
case Tid_ignore: // must mark for update
case Tid_update: // return self
return Tid_update;
default: throw Exc_.new_unhandled(cur);
}
}
}

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; import gplx.*;
import gplx.dbs.engines.*; import gplx.dbs.qrys.*;
public class Db_conn {
private final List_adp rls_list = List_adp_.new_(); private final Db_engine engine;
public Db_conn(Db_engine engine) {this.engine = engine;}
public Db_conn_info Conn_info() {return engine.Conn_info();}
public boolean Eq(Db_conn comp) {return String_.Eq(engine.Conn_info().Xto_api(), comp.Conn_info().Xto_api());}
public void Txn_bgn() {engine.Txn_bgn("");}
public void Txn_bgn(String name) {engine.Txn_bgn(name);}
public void Txn_end() {engine.Txn_end();}
public void Txn_cxl() {engine.Txn_cxl();}
public void Txn_sav() {engine.Txn_sav();}
public Db_stmt Stmt_insert(String tbl, Db_meta_fld_list flds) {return engine.New_stmt_prep(Db_qry_insert.new_(tbl, flds.To_str_ary_wo_autonum()));}
public Db_stmt Stmt_insert(String tbl, String... cols) {return engine.New_stmt_prep(Db_qry_insert.new_(tbl, cols));}
public Db_stmt Stmt_update(String tbl, String[] where, String... cols) {return engine.New_stmt_prep(Db_qry_update.new_(tbl, where, cols));}
public Db_stmt Stmt_update_exclude(String tbl, Db_meta_fld_list flds, String... where) {return engine.New_stmt_prep(Db_qry_update.new_(tbl, where, flds.To_str_ary_exclude(where)));}
public Db_stmt Stmt_delete(String tbl, String... where) {return engine.New_stmt_prep(Db_qry_delete.new_(tbl, where));}
public Db_stmt Stmt_select(String tbl, String[] cols, String... where) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, cols, null));}
public Db_stmt Stmt_select(String tbl, Db_meta_fld_list flds, String... where) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, flds.To_str_ary(), null));}
public Db_stmt Stmt_select_max(String tbl, String col, String... where) {
Db_qry__select_in_tbl qry = new Db_qry__select_in_tbl(tbl, String_.Ary(String_.Format("Max({0}) AS {0}", col)), where, null, null, null, null);
return engine.New_stmt_prep(qry);
}
public Db_stmt Stmt_select_order(String tbl, Db_meta_fld_list flds, String[] where, String... orderbys) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, flds.To_str_ary(), orderbys));}
public Db_stmt Stmt_select_order(String tbl, String[] flds, String[] where, String... orderbys) {return engine.New_stmt_prep(Db_qry__select_in_tbl.new_(tbl, where, flds, orderbys));}
public Db_stmt Stmt_new(Db_qry qry) {return engine.New_stmt_prep(qry);}
public void Env_db_attach(String alias, Io_url db_url) {engine.Env_db_attach(alias, db_url);}
public void Env_db_detach(String alias) {engine.Env_db_detach(alias);}
public void Env_vacuum() {Exec_sql_plog_ntx("vacuuming: url=" + this.Conn_info().Xto_api(), "VACUUM;");}
public void Ddl_create_tbl(Db_meta_tbl meta) {engine.Ddl_create_tbl(meta); engine.Ddl_create_idx(Gfo_usr_dlg_.Noop, meta.Idxs());}
public void Ddl_create_idx(Db_meta_idx... idxs) {engine.Ddl_create_idx(Gfo_usr_dlg_.I, idxs);}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... idxs) {engine.Ddl_create_idx(usr_dlg, idxs);}
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {engine.Ddl_append_fld(tbl, fld);}
public void Ddl_delete_tbl(String tbl) {engine.Ddl_delete_tbl(tbl);}
public boolean Meta_tbl_exists(String tbl) {return engine.Meta_tbl_exists(tbl);}
public boolean Meta_fld_exists(String tbl, String fld) {return engine.Meta_fld_exists(tbl, fld);}
public void Rls_reg(RlsAble rls) {rls_list.Add(rls);}
public void Rls_conn() {
int len = rls_list.Count();
for (int i = 0; i < len; ++i) {
RlsAble itm = (RlsAble)rls_list.Get_at(i);
itm.Rls();
}
engine.Conn_term();
Db_conn_pool.I.Del(engine.Conn_info());
}
public int Exec_sql(String sql) {return this.Exec_qry(Db_qry_sql.dml_(sql));}
public Db_rdr Exec_sql_as_rdr_v2(String sql) {return this.Stmt_new(Db_qry_sql.dml_(sql)).Exec_select__rls_auto();}
public int Exec_sql_plog_ntx(String msg, String sql) {return Exec_sql_plog(Bool_.N, msg, sql);}
public int Exec_sql_plog_txn(String msg, String sql) {return Exec_sql_plog(Bool_.Y, msg, sql);}
public int Exec_sql_plog(boolean txn, String msg, String sql) {
Gfo_usr_dlg_.I.Plog_many("", "", msg);
if (txn) this.Txn_bgn();
int rv = Exec_sql(sql);
if (txn) this.Txn_end();
Gfo_usr_dlg_.I.Plog_many("", "", "done:" + msg);
return rv;
}
public int Exec_qry(Db_qry qry) {return Int_.cast_(engine.Exec_as_obj(qry));}
public DataRdr Exec_qry_as_rdr(Db_qry qry) {return DataRdr_.cast_(engine.Exec_as_obj(qry));}
public int Exec_sql_args(String sql, Object... args) {return this.Exec_qry(Db_qry_sql.dml_(String_.Format(sql, args)));}
public DataRdr Exec_sql_as_rdr(String sql) {return this.Exec_qry_as_rdr(Db_qry_sql.rdr_(sql));}
}

View File

@@ -0,0 +1,38 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.qrys.*;
public class Db_conn_ {
public static final Db_conn Noop = Db_conn_pool.I.Get_or_new(Db_conn_info_.Null);
public static int Select_fld0_as_int_or(Db_conn p, String sql, int or) {
DataRdr rdr = DataRdr_.Null;
try {
rdr = p.Exec_qry_as_rdr(Db_qry_sql.rdr_(sql));
int rv = or;
if (rdr.MoveNextPeer()) {
Object rv_obj = rdr.ReadAt(0);
if (rv_obj != null) // Max(fil_id) will be NULL if tbl is empty
rv = Int_.cast_or_(rv_obj, or);
}
return rv;
}
finally {
rdr.Rls();
}
}
}

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; import gplx.*;
public class Db_conn_bldr {
private Db_conn_bldr_wkr wkr;
public void Reg_default_sqlite() {wkr = Db_conn_bldr_wkr__sqlite.I; wkr.Clear_for_tests();}
public void Reg_default_mem() {wkr = Db_conn_bldr_wkr__mem.I; wkr.Clear_for_tests();}
public boolean Exists(Io_url url) {return wkr.Exists(url);}
public Db_conn Get(Io_url url) {return wkr.Get(url);}
public Db_conn New(Io_url url) {return wkr.New(url);}
public Db_conn_bldr_data Get_or_new(Io_url url) {
boolean exists = wkr.Exists(url);
Db_conn conn = exists ? Get(url) : New(url);
return new Db_conn_bldr_data(conn, exists);
}
public Db_conn Get_or_noop(Io_url url) {
Db_conn rv = wkr.Get(url);
return rv == null ? Db_conn_.Noop : rv;
}
public static final Db_conn_bldr I = new Db_conn_bldr(); Db_conn_bldr() {}
}

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; import gplx.*;
public class Db_conn_bldr_data {
public Db_conn_bldr_data(Db_conn conn, boolean exists) {this.conn = conn; this.exists = exists;}
public Db_conn Conn() {return conn;} private final Db_conn conn;
public boolean Exists() {return exists;} private final boolean exists;
public boolean Created() {return !exists;}
}

View File

@@ -0,0 +1,62 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.engines.sqlite.*;
public interface Db_conn_bldr_wkr {
void Clear_for_tests();
boolean Exists(Io_url url);
Db_conn Get(Io_url url);
Db_conn New(Io_url url);
}
class Db_conn_bldr_wkr__sqlite implements Db_conn_bldr_wkr {
public void Clear_for_tests() {}
public boolean Exists(Io_url url) {return Io_mgr.I.ExistsFil(url);}
public Db_conn Get(Io_url url) {
if (!Io_mgr.I.ExistsFil(url)) return null;
Db_conn_info db_url = Db_conn_info_.sqlite_(url);
return Db_conn_pool.I.Get_or_new(db_url);
}
public Db_conn New(Io_url url) {
Io_mgr.I.CreateDirIfAbsent(url.OwnerDir()); // must assert that dir exists
Db_conn_info db_url = Sqlite_conn_info.make_(url);
Db_conn conn = Db_conn_pool.I.Get_or_new(db_url);
Sqlite_engine_.Pragma_page_size(conn, 4096);
// conn.Conn_term(); // close conn after PRAGMA adjusted
return conn;
}
public static final Db_conn_bldr_wkr__sqlite I = new Db_conn_bldr_wkr__sqlite(); Db_conn_bldr_wkr__sqlite() {}
}
class Db_conn_bldr_wkr__mem implements Db_conn_bldr_wkr {
private final Hash_adp hash = Hash_adp_.new_();
public void Clear_for_tests() {hash.Clear(); Db_conn_pool.I.Clear();}
public boolean Exists(Io_url url) {
String io_url_str = url.Xto_api();
return hash.Has(io_url_str);
}
public Db_conn Get(Io_url url) {
String io_url_str = url.Xto_api();
if (!hash.Has(io_url_str)) return null;
return Db_conn_pool.I.Get_or_new__mem(url.Xto_api());
}
public Db_conn New(Io_url url) {
String io_url_str = url.Xto_api();
hash.Add(io_url_str, io_url_str);
return Db_conn_pool.I.Get_or_new__mem(url.Xto_api());
}
public static final Db_conn_bldr_wkr__mem I = new Db_conn_bldr_wkr__mem(); Db_conn_bldr_wkr__mem() {}
}

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; import gplx.*;
public interface Db_conn_info {
String Tid();
String Database();
String Xto_raw();
String Xto_api();
Db_conn_info New_self(String raw, GfoMsg m);
}

View File

@@ -0,0 +1,56 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.engines.nulls.*; import gplx.dbs.engines.mems.*; import gplx.dbs.engines.sqlite.*; import gplx.dbs.engines.tdbs.*;
import gplx.dbs.engines.mysql.*; import gplx.dbs.engines.postgres.*;
public class Db_conn_info_ {
public static final Db_conn_info Null = Noop_conn_info.I;
public static final Db_conn_info Test = Mysql_conn_info.new_("127.0.0.1", "unit_tests", "root", "mysql7760");
public static Db_conn_info parse_(String raw) {return Db_conn_info_pool._.Parse(raw);}
public static Db_conn_info sqlite_(Io_url url) {return Sqlite_conn_info.load_(url);}
public static Db_conn_info tdb_(Io_url url) {return Tdb_conn_info.new_(url);}
public static Db_conn_info mem_(String db) {return Db_conn_info__mem.new_(db);}
public static final String Key_tdb = Tdb_conn_info.Tid_const;
}
class Db_conn_info_pool {
private Ordered_hash regy = Ordered_hash_.new_();
public Db_conn_info_pool() {
this.Add(Noop_conn_info.I).Add(Tdb_conn_info._).Add(Mysql_conn_info._).Add(Postgres_conn_info._).Add(Sqlite_conn_info._);
this.Add(Db_conn_info__mem.I);
}
public Db_conn_info_pool Add(Db_conn_info itm) {regy.Add_if_dupe_use_nth(itm.Tid(), itm); return this;}
public Db_conn_info Parse(String raw) {// assume each pair has format of: name=val;
try {
GfoMsg m = GfoMsg_.new_parse_("db_url");
String[] terms = String_.Split(raw, ";");
String url_tid = "";
for (String term : terms) {
if (String_.Len(term) == 0) continue;
String[] kv = String_.Split(term, "=");
if (String_.Eq(kv[0], "gplx_key"))
url_tid = kv[1]; // NOTE: do not add to GfoMsg; will not be part of ApiStr
else
m.Add(kv[0], kv[1]);
}
Db_conn_info prototype = (Db_conn_info)regy.Get_by(url_tid);
return prototype.New_self(raw, m);
}
catch(Exception exc) {throw Exc_.new_parse_exc(exc, Db_conn_info.class, raw);}
}
public static final Db_conn_info_pool _ = new Db_conn_info_pool();
}

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; import gplx.*;
import gplx.core.strings.*;
public abstract class Db_conn_info__base implements Db_conn_info {
public abstract String Tid();
public String Xto_raw() {return raw;} private String raw = "";
public String Xto_api() {return api;} private String api = "";
public String Database() {return database;} protected String database = "";
public String Server() {return server;} private String server = "";
public abstract Db_conn_info New_self(String raw, GfoMsg m);
protected void Ctor(String server, String database, String raw, String api) {this.server = server; this.database = database; this.raw = raw; this.api = api;}
protected static String BldApi(GfoMsg m, KeyVal... xtnAry) {
String_bldr sb = String_bldr_.new_();
Hash_adp hash = Hash_adp_.new_();
for (int i = 0; i < m.Args_count(); i++) {
KeyVal kv = m.Args_getAt(i);
sb.Add_fmt("{0}={1};", kv.Key(), kv.Val_to_str_or_empty());
hash.Add_as_key_and_val(kv.Key());
}
for (KeyVal xtn : xtnAry) {
if (hash.Has(xtn.Key())) continue;
sb.Add_fmt("{0}={1};", xtn.Key(), xtn.Val_to_str_or_empty());
}
return sb.XtoStr();
}
protected static String Bld_raw(String... ary) {
Bry_bfr bfr = Bry_bfr.reset_(255);
int len = ary.length;
for (int i = 0; i < len; ++i) {
String itm = ary[i];
bfr.Add_str_u8(itm);
bfr.Add_byte(i % 2 == 0 ? Byte_ascii.Eq : Byte_ascii.Semic);
}
return bfr.Xto_str();
}
}

View File

@@ -0,0 +1,46 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import org.junit.*;
public class Db_conn_info_tst {
@Before public void setup() {
regy.Add(Db_conn_info_mock._);
} private final Db_conn_info_pool regy = new Db_conn_info_pool();
@Test public void Parse() {
tst_Parse("gplx_key=mock;id=1;", kv_("id", "1")); // one; gplx_key removed
tst_Parse("gplx_key=mock;id=1;name=me;", kv_("id", "1"), kv_("name", "me")); // many
tst_Parse("gplx_key=mock;id=1;name=me" , kv_("id", "1"), kv_("name", "me")); // no semi-colon at end
}
private KeyVal kv_(String key, Object val) {return KeyVal_.new_(key, val);}
private void tst_Parse(String raw, KeyVal... expd) {
Db_conn_info_mock mock = (Db_conn_info_mock)regy.Parse(raw);
Tfds.Eq_ary_str(expd, mock.Kvs());
}
}
class Db_conn_info_mock extends Db_conn_info__base {
public KeyVal[] Kvs() {return kvs;} KeyVal[] kvs;
@Override public String Tid() {return Tid_const;} public static final String Tid_const = "mock";
@Override public Db_conn_info New_self(String raw, GfoMsg m) {
Db_conn_info_mock rv = new Db_conn_info_mock();
rv.kvs = new KeyVal[m.Args_count()];
for (int i = 0; i < m.Args_count(); i++)
rv.kvs[i] = m.Args_getAt(i);
return rv;
}
public static final Db_conn_info_mock _ = new Db_conn_info_mock(); Db_conn_info_mock() {}
}

View File

@@ -0,0 +1,46 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.engines.*; import gplx.dbs.engines.nulls.*; import gplx.dbs.engines.mems.*; import gplx.dbs.engines.tdbs.*;
import gplx.dbs.engines.sqlite.*; import gplx.dbs.engines.mysql.*; import gplx.dbs.engines.postgres.*;
public class Db_conn_pool {
private final Hash_adp conn_hash = Hash_adp_.new_(); private final Hash_adp engine_hash = Hash_adp_.new_();
public void Clear() {conn_hash.Clear();}
public void Del(Db_conn_info url) {conn_hash.Del(url.Xto_api());}
public Db_conn Get_or_new__mem(String db) {return Get_or_new(Db_conn_info__mem.new_(db));}
public Db_conn Get_or_new__sqlite(Io_url url) {return Get_or_new(Db_conn_info_.sqlite_(url));}
public Db_conn Get_or_new(String s) {return Get_or_new(Db_conn_info_.parse_(s));}
public Db_conn Get_or_new(Db_conn_info url) {
Db_conn rv = (Db_conn)conn_hash.Get_by(url.Xto_api());
if (rv == null) {
Db_engine prime = (Db_engine)engine_hash.Get_by(url.Tid()); if (prime == null) Exc_.new_("db engine prototype not found", "tid", url.Tid());
Db_engine clone = prime.New_clone(url);
rv = new Db_conn(clone);
conn_hash.Add(url.Xto_api(), rv);
}
return rv;
}
public void Engines__add(Db_engine... ary) {
for (Db_engine itm : ary)
engine_hash.Add(itm.Tid(), itm);
}
public static final Db_conn_pool I = new Db_conn_pool(); Db_conn_pool() {this.Init();}
private void Init() {
this.Engines__add(Noop_engine._, TdbEngine._, Mysql_engine._, Postgres_engine._, Sqlite_engine._, Db_engine__mem._);
}
}

View File

@@ -0,0 +1,64 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.core.criterias.*;
public class Db_crt_ {
public static final Criteria Wildcard = Criteria_.All;
public static Criteria_fld eq_(String key, Object val) {return Criteria_fld.new_(key, Criteria_.eq_(val));}
public static Criteria_fld eqn_(String key, Object val) {return Criteria_fld.new_(key, Criteria_.eqn_(val));}
public static Criteria_fld lt_(String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.lt_(val));}
public static Criteria_fld lte_(String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.lte_(val));}
public static Criteria_fld mt_(String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.mt_(val));}
public static Criteria_fld mte_(String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.mte_(val));}
public static Criteria_fld between_(String key, Comparable lhs, Comparable rhs) {return Criteria_fld.new_(key, Criteria_.between_(lhs, rhs));}
public static Criteria_fld in_(String key, Object... vals) {return Criteria_fld.new_(key, Criteria_.in_(vals));}
public static Criteria_fld like_(String key, String pattern) {return Criteria_fld.new_(key, Criteria_.like_(pattern));}
public static Criteria_fld liken_(String key, String pattern) {return Criteria_fld.new_(key, Criteria_.liken_(pattern));}
public static Criteria_fld eq_(String key) {return Criteria_fld.new_(key, Criteria_.eq_(null));}
public static Criteria eq_many_(String... ary) {
Criteria rv = null;
int len = ary.length;
for (int i = 0; i < len; i++) {
Criteria crt = Db_crt_.eq_(ary[i], null);
rv = (i == 0)? crt : Criteria_.And(rv, crt);
}
return rv;
}
public static Criteria eq_many_wo_null(String... ary) {
Criteria rv = null;
int len = ary.length;
int crt_idx = 0;
for (int i = 0; i < len; i++) {
String itm = ary[i]; if (itm == Db_meta_fld.Key_null) continue;
Criteria crt = Db_crt_.eq_(itm, null);
rv = (crt_idx == 0) ? crt : Criteria_.And(rv, crt);
++crt_idx;
}
return rv;
}
public static Criteria eq_many_(KeyVal... array) {
Criteria rv = null;
for (int i = 0; i < array.length; i++) {
KeyVal pair = array[i];
Criteria crt = Db_crt_.eq_(pair.Key(), pair.Val());
rv = (i == 0)? crt : Criteria_.And(rv, crt);
}
return rv;
}
public static Criteria_fld wrap_(String key, Criteria crt) {return Criteria_fld.new_(key, crt);}
}

View File

@@ -0,0 +1,53 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import org.junit.*;
import gplx.core.criterias.*;
public class Db_crt_tst {
@Before public void setup() {
row = GfoNde_.vals_(GfoFldList_.new_().Add("id", IntClassXtn._).Add("name", StringClassXtn._), Object_.Ary(1, "me"));
}
@Test public void EqualTest() {
crt = Db_crt_.eq_("id", 1);
tst_Match(true, row, crt);
}
@Test public void EqualFalseTest() {
crt = Db_crt_.eq_("id", 2);
tst_Match(false, row, crt);
}
@Test public void AndCompositeTest() {
crt = Criteria_.And(Db_crt_.eq_("id", 1), Db_crt_.eq_("name", "me"));
tst_Match(true, row, crt);
crt = Criteria_.And(Db_crt_.eq_("id", 1), Db_crt_.eq_("name", "you"));
tst_Match(false, row, crt);
}
@Test public void OrCompositeTest() {
crt = Criteria_.Or(Db_crt_.eq_("id", 1), Db_crt_.eq_("name", "you"));
tst_Match(true, row, crt);
crt = Criteria_.Or(Db_crt_.eq_("id", 2), Db_crt_.eq_("name", "you"));
tst_Match(false, row, crt);
}
void tst_Match(boolean epxd, GfoNde row, Criteria crt) {
boolean actl = crt.Matches(row);
Tfds.Eq(epxd, actl);
}
GfoNde row; Criteria crt;
}

View File

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

View File

@@ -0,0 +1,47 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
public class Db_meta_fld {
public Db_meta_fld(String name, int tid, int len) {
this.name = name; this.tid = tid; this.len = len;
this.nullable = false; this.primary = false; this.autonum = false; this.default_val = Default_value_null;
}
public int Tid() {return tid;} private final int tid;
public String Name() {return name;} private final String name;
public int Len() {return len;} private final int len;
public boolean Nullable() {return nullable;} public Db_meta_fld Nullable_y_() {nullable = true; return this;} private boolean nullable;
public boolean Primary() {return primary;} public Db_meta_fld Primary_y_() {primary = true; return this;} private boolean primary;
public boolean Autonum() {return autonum;} public Db_meta_fld Autonum_y_() {autonum = true; return this;} private boolean autonum;
public Object Default() {return default_val;} public Db_meta_fld Default_(Object v) {default_val = v; return this;} private Object default_val;
public static final int Tid_bool = 0, Tid_byte = 1, Tid_short = 2, Tid_int = 3, Tid_long = 4, Tid_float = 5, Tid_double = 6, Tid_str = 7, Tid_text = 8, Tid_bry = 9, Tid_decimal = 10, Tid_date = 11;
public static final String Key_null = null;
public static final int Len_null = -1;
public static final Object Default_value_null = null;
public static final String[] Ary_empty = String_.Ary_empty;
public static Db_meta_fld new_bool(String name) {return new Db_meta_fld(name, Tid_bool , Len_null);}
public static Db_meta_fld new_byte(String name) {return new Db_meta_fld(name, Tid_byte , Len_null);}
public static Db_meta_fld new_short(String name) {return new Db_meta_fld(name, Tid_short , Len_null);}
public static Db_meta_fld new_int(String name) {return new Db_meta_fld(name, Tid_int , Len_null);}
public static Db_meta_fld new_long(String name) {return new Db_meta_fld(name, Tid_long , Len_null);}
public static Db_meta_fld new_float(String name) {return new Db_meta_fld(name, Tid_float , Len_null);}
public static Db_meta_fld new_double(String name) {return new Db_meta_fld(name, Tid_double, Len_null);}
public static Db_meta_fld new_text(String name) {return new Db_meta_fld(name, Tid_text , Len_null);}
public static Db_meta_fld new_bry(String name) {return new Db_meta_fld(name, Tid_bry , Len_null);}
public static Db_meta_fld new_str(String name, int len) {return new Db_meta_fld(name, Tid_str , len);}
}

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

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

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

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; import gplx.*;
public interface Db_qry {
int Tid();
boolean Exec_is_rdr();
String Base_table();
String Xto_sql();
}

View File

@@ -0,0 +1,51 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.core.criterias.*; import gplx.dbs.qrys.*;
public class Db_qry_ {
public static Db_qry__select_cmd select_cols_(String tbl, Criteria crt, String... cols){return select_().From_(tbl).Where_(crt).Cols_(cols);}
public static Db_qry__select_cmd select_val_(String tbl, String col, Criteria crt) {return select_().From_(tbl).Where_(crt).Cols_(col);}
public static Db_qry__select_cmd select_tbl_(String tbl) {return select_().From_(tbl);}
public static Db_qry__select_cmd select_() {return Db_qry__select_cmd.new_();}
public static Db_qry_delete delete_(String tbl, Criteria crt) {return Db_qry_delete.new_(tbl, crt);}
public static Db_qry_delete delete_tbl_(String tbl) {return Db_qry_delete.new_(tbl);}
public static Db_qry_insert insert_(String tbl) {return new Db_qry_insert(tbl);}
public static Db_qry_insert insert_common_(String tbl, KeyVal... pairs) {
Db_qry_insert cmd = new Db_qry_insert(tbl);
for (KeyVal pair : pairs)
cmd.Arg_obj_(pair.Key(), pair.Val());
return cmd;
}
public static Db_qry_update update_(String tbl, Criteria crt) {
Db_qry_update update = Db_qry_update.new_();
update.From_(tbl);
update.Where_(crt);
return update;
}
public static Db_qry_update update_common_(String tbl, Criteria crt, KeyVal... pairs) {
Db_qry_update cmd = Db_qry_update.new_();
cmd.From_(tbl); cmd.Where_(crt);
for (KeyVal pair : pairs)
cmd.Arg_obj_(pair.Key(), pair.Val());
return cmd;
}
public static final Object WhereAll = null;
public static Db_qry as_(Object obj) {return obj instanceof Db_qry ? (Db_qry)obj : null;}
public static final int Tid_insert = 0, Tid_delete = 1, Tid_update = 2, Tid_select = 3, Tid_sql = 4, Tid_select_in_tbl = 5, Tid_flush = 6;
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
public interface Db_rdr {
boolean Move_next();
byte[] Read_bry(String k);
void Save_bry_in_parts(Io_url url, String tbl, String fld, String crt_key, Object crt_val);
byte[] Read_bry_by_str(String k);
String Read_str(String k);
byte Read_byte(String k);
int Read_int(String k);
long Read_long(String k);
float Read_float(String k);
double Read_double(String k);
DateAdp Read_date_by_str(String k);
boolean Read_bool_by_byte(String k);
Object Read_obj(String k);
void Rls();
}

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; import gplx.*;
public class Db_rdr_ {
public static final Db_rdr Empty = new Db_rdr__empty();
}
class Db_rdr__empty implements Db_rdr {
public boolean Move_next() {return false;}
public byte[] Read_bry(String k) {return Bry_.Empty;}
public byte[] Read_bry_by_str(String k) {return Bry_.Empty;}
public void Save_bry_in_parts(Io_url url, String tbl, String fld, String crt_key, Object crt_val) {}
public byte Read_byte(String k) {return Byte_.Max_value_127;}
public String Read_str(String k) {return String_.Empty;}
public DateAdp Read_date_by_str(String k) {return DateAdp_.MinValue;}
public int Read_int(String k) {return Int_.MinValue;}
public long Read_long(String k) {return Long_.MinValue;}
public float Read_float(String k) {return Float_.NaN;}
public double Read_double(String k) {return Double_.NaN;}
public boolean Read_bool_by_byte(String k) {return false;}
public Object Read_obj(String k) {return null;}
public void Rls() {}
}

View File

@@ -0,0 +1,46 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import java.sql.ResultSet;
public class Db_rdr__basic implements Db_rdr {
protected ResultSet rdr;
private Db_stmt stmt;
public void Ctor(Db_stmt stmt, ResultSet rdr, String sql) {this.stmt = stmt; this.rdr = rdr; this.sql = sql;}
public String Sql() {return sql;} private String sql;
public boolean Move_next() {
try {return rdr.next();}
catch (Exception e) {throw Exc_.new_exc(e, "db", "move_next failed; check column casting error in SQL", "sql", sql);}
}
@gplx.Virtual public byte[] Read_bry(String k) {try {return (byte[])rdr.getObject(k);} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", Bry_.Cls_val_name);}}
@gplx.Virtual public byte[] Read_bry_by_str(String k) {try {return Bry_.new_u8((String)rdr.getObject(k));} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", String_.Cls_val_name);}}
@gplx.Virtual public void Save_bry_in_parts(Io_url url, String tbl, String fld, String crt_key, Object crt_val) {throw Exc_.new_unimplemented();}
@gplx.Virtual public String Read_str(String k) {try {return (String)rdr.getObject(k);} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", String_.Cls_val_name);}}
@gplx.Virtual public DateAdp Read_date_by_str(String k) {return DateAdp_.parse_iso8561(Read_str(k));}
@gplx.Virtual public int Read_int(String k) {try {return Int_.cast_(rdr.getObject(k));} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", Int_.Cls_val_name);}}
@gplx.Virtual public long Read_long(String k) {try {return Long_.cast_(rdr.getObject(k));} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", Long_.Cls_val_name);}}
@gplx.Virtual public float Read_float(String k) {try {return Float_.cast_(rdr.getObject(k));} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", Float_.Cls_val_name);}}
@gplx.Virtual public double Read_double(String k) {try {return Double_.cast_(rdr.getObject(k));} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", Double_.Cls_val_name);}}
@gplx.Virtual public byte Read_byte(String k) {try {return Byte_.cast_(rdr.getObject(k));} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", Byte_.Cls_val_name);}}
@gplx.Virtual public boolean Read_bool_by_byte(String k) {try {return Byte_.cast_(rdr.getObject(k)) == 1;} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", Bool_.Cls_val_name);}}
@gplx.Virtual public Object Read_obj(String k) {try {return rdr.getObject(k);} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "key", k, "type", Object_.Cls_val_name);}}
@gplx.Virtual public void Rls() {
try {rdr.close();}
catch (Exception e) {throw Exc_.new_exc(e, "db", "close failed");}
if (stmt != null) stmt.Rls();
}
}

View File

@@ -0,0 +1,78 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.core.criterias.*;
interface Db_sql_qry {
String Tbl_main();
}
class Db_sql_qry__select {
public Db_sql_qry__select(String from) {this.from = from;}
public String From() {return from;} private final String from;
public Db_sql_col[] Select() {return select;} private Db_sql_col[] select;
// public Criteria Where() {return where;} private Criteria where;
// public Db_sql_col[] Group_bys() {return group_bys;} private Db_sql_col[] group_bys;
// public Db_sql_col[] Order_bys() {return order_bys;} private Db_sql_col[] order_bys;
// public int Limit() {return limit;} private int limit;
// public int Offset() {return offset;} private int offset;
public Db_sql_qry__select Select_all_() {this.select = Db_sql_col_.Ary(new Db_sql_col__all(0, from)); return this;}
public Db_sql_qry__select Select_flds_(String... ary) {this.select = Db_sql_col_bldr.I.new_fld_many(ary); return this;}
public static Db_sql_qry__select new_(String from) {return new Db_sql_qry__select(from);}
}
class Db_sql_bldr {
public void Test() {
// Db_sql_qry__select qry = null;
// qry = Db_sql_qry__select.new_("tbl").Select_all_();
// qry = Db_sql_qry__select.new_("tbl").Select_flds_("fld1", "fld2");
// qry = Db_sql_qry__select.new_("tbl").Select_flds_("fld1", "fld2").Where_("fld3");
// , String_.Ary("col1", "col2"), String_.Ary("col3")).Limit_(10).;
// Db_sql_qry__select qry = Db_sql_qry__select_.new_("tbl").Cols_("col1", "col2").Where_eq_one("col3").Limit_(10);
}
}
interface Db_sql_col {
int Ord();
String Alias();
}
class Db_sql_col_ {
public static Db_sql_col[] Ary(Db_sql_col... v) {return v;}
}
class Db_sql_col_bldr {
private final List_adp tmp_list = List_adp_.new_();
public Db_sql_col[] new_fld_many(String[] ary) {
tmp_list.Clear();
int ord = -1;
for (int i = 0; i < ary.length; ++i) {
String fld_key = ary[i];
if (fld_key == Db_meta_fld.Key_null) continue;
Db_sql_col__name fld = new Db_sql_col__name(++ord, fld_key);
tmp_list.Add(fld);
}
return (Db_sql_col[])tmp_list.To_ary_and_clear(Db_sql_col.class);
}
public static final Db_sql_col_bldr I = new Db_sql_col_bldr(); Db_sql_col_bldr() {}
}
class Db_sql_col__name {
public Db_sql_col__name(int ord, String key) {this.ord = ord; this.key = key;}
public int Ord() {return ord;} private final int ord;
public String Key() {return key;} private final String key;
}
class Db_sql_col__all implements Db_sql_col {
public Db_sql_col__all(int ord, String tbl) {this.ord = ord; this.tbl = tbl;}
public int Ord() {return ord;} private final int ord;
public String Tbl() {return tbl;} private final String tbl;
public String Alias() {return "*";}
}

View File

@@ -0,0 +1,62 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.engines.*;
public interface Db_stmt extends RlsAble {
Db_stmt Crt_bool_as_byte(String k, boolean v);
Db_stmt Val_bool_as_byte(String k, boolean v);
Db_stmt Val_bool_as_byte(boolean v);
Db_stmt Crt_byte(String k, byte v);
Db_stmt Val_byte(String k, byte v);
Db_stmt Val_byte(byte v);
Db_stmt Crt_int(String k, int v);
Db_stmt Val_int(String k, int v);
Db_stmt Val_int(int v);
Db_stmt Crt_long(String k, long v);
Db_stmt Val_long(String k, long v);
Db_stmt Val_long(long v);
Db_stmt Crt_float(String k, float v);
Db_stmt Val_float(String k, float v);
Db_stmt Val_float(float v);
Db_stmt Crt_double(String k, double v);
Db_stmt Val_double(String k, double v);
Db_stmt Val_double(double v);
Db_stmt Crt_decimal(String k, DecimalAdp v);
Db_stmt Val_decimal(String k, DecimalAdp v);
Db_stmt Val_decimal(DecimalAdp v);
Db_stmt Crt_bry(String k, byte[] v);
Db_stmt Val_bry(String k, byte[] v);
Db_stmt Val_bry(byte[] v);
Db_stmt Crt_str(String k, String v);
Db_stmt Val_str(String k, String v);
Db_stmt Val_str(String v);
Db_stmt Crt_bry_as_str(String k, byte[] v);
Db_stmt Val_bry_as_str(String k, byte[] v);
Db_stmt Val_bry_as_str(byte[] v);
Db_stmt Val_rdr_(gplx.ios.Io_stream_rdr rdr, long rdr_len);
boolean Exec_insert();
int Exec_update();
int Exec_delete();
DataRdr Exec_select();
Db_rdr Exec_select__rls_manual();
Db_rdr Exec_select__rls_auto();
Object Exec_select_val();
void Ctor_stmt(Db_engine engine, Db_qry qry);
Db_stmt Clear();
Db_stmt Reset_stmt();
}

View File

@@ -0,0 +1,58 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.qrys.*;
public class Db_stmt_ {
public static final Db_stmt Null = new Db_stmt_sql();
public static Db_stmt new_insert_(Db_conn conn, String tbl, String... flds) {
Db_qry qry = Db_qry_insert.new_(tbl, flds);
return conn.Stmt_new(qry);
}
public static Db_stmt new_update_(Db_conn conn, String tbl, String[] where, String... flds) {
Db_qry qry = Db_qry_update.new_(tbl, where, flds);
return conn.Stmt_new(qry);
}
public static Db_stmt new_delete_(Db_conn conn, String tbl, String... where) {
Db_qry_delete qry = Db_qry_.delete_(tbl, Db_crt_.eq_many_(where));
return conn.Stmt_new(qry);
}
public static Db_stmt new_select_(Db_conn conn, String tbl, String[] where, String... flds) {
Db_qry__select_cmd qry = Db_qry_.select_cols_(tbl, Db_crt_.eq_many_(where), flds);
return conn.Stmt_new(qry);
}
public static Db_stmt new_select_in_(Db_conn conn, String tbl, String in_fld, Object[] in_vals, String... flds) {
Db_qry__select_cmd qry = Db_qry_.select_cols_(tbl, Db_crt_.in_(in_fld, in_vals), flds).OrderBy_asc_(in_fld);
return conn.Stmt_new(qry);
}
public static Db_stmt new_select_all_(Db_conn conn, String tbl) {
return conn.Stmt_new(Db_qry_.select_tbl_(tbl));
}
public static Db_stmt new_select_as_rdr(Db_conn conn, Db_qry__select_in_tbl qry) {
return conn.Stmt_new(qry);
}
public static Db_stmt new_select_as_rdr(Db_conn conn, String sql) {
return conn.Stmt_new(Db_qry_sql.rdr_(sql));
}
public static Err err_(Exception e, Db_stmt stmt, String proc) {
throw Exc_.new_exc(e, "db", "db stmt failed", "proc", proc);
}
public static Err err_(Exception e, String tbl, String proc) {
throw Exc_.new_exc(e, "core", "db call failed", "tbl", tbl, "proc", proc);
}
public static Db_stmt Rls(Db_stmt v) {if (v != null) v.Rls(); return null;}
}

View File

@@ -0,0 +1,48 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
public class Db_stmt_bldr {
private Db_conn conn; private Db_stmt create, update, delete;
private String tbl_name; private String[] flds_keys, flds_vals, flds_all;
public void Conn_(Db_conn v, String tbl_name, Db_meta_fld_list flds, String... flds_keys) {
Conn_(v, tbl_name, flds.To_str_ary(), flds.To_str_ary_exclude(flds_keys), flds_keys);
}
public void Conn_(Db_conn v, String tbl_name, String[] flds_vals, String... flds_keys) {
Conn_(v, tbl_name, String_.Ary_add(flds_keys, flds_vals), flds_vals, flds_keys);
}
private void Conn_(Db_conn v, String tbl_name, String[] flds_all, String[] flds_vals, String... flds_keys) {
this.conn = v; this.tbl_name = tbl_name;
this.flds_all = flds_all; this.flds_vals = flds_vals; this.flds_keys = flds_keys;
}
public Db_stmt Get(byte cmd_mode) {
switch (cmd_mode) {
case Db_cmd_mode.Tid_create: if (create == null) create = conn.Stmt_insert(tbl_name, flds_all); return create;
case Db_cmd_mode.Tid_update: if (update == null) update = conn.Stmt_update(tbl_name, flds_keys, flds_vals); return update;
case Db_cmd_mode.Tid_delete: if (delete == null) delete = conn.Stmt_delete(tbl_name, flds_keys); return delete;
case Db_cmd_mode.Tid_ignore: return Db_stmt_.Null;
default: throw Exc_.new_unhandled(cmd_mode);
}
}
public void Batch_bgn() {conn.Txn_bgn(tbl_name);}
public void Batch_end() {conn.Txn_end();}
public void Rls() {
create = Db_stmt_.Rls(create);
update = Db_stmt_.Rls(update);
delete = Db_stmt_.Rls(delete);
}
}

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.engines; import gplx.*; import gplx.dbs.*;
public interface Db_engine {
String Tid();
Db_conn_info Conn_info();
Db_engine New_clone(Db_conn_info url);
Db_rdr New_rdr__rls_manual (Object rdr_obj, String sql); // Object o:ResultSet if desktop; Cursor if android
Db_rdr New_rdr__rls_auto (Db_stmt stmt, Object rdr_obj, String sql); // Object o:ResultSet if desktop; Cursor if android
Db_stmt New_stmt_prep(Db_qry qry);
Object New_stmt_prep_as_obj(String sql);
DataRdr New_rdr(java.sql.ResultSet rdr, String sql);
void Txn_bgn(String name);
void Txn_end();
void Txn_cxl();
void Txn_sav();
void Conn_open();
void Conn_term();
Object Exec_as_obj(Db_qry qry);
void Ddl_create_tbl(Db_meta_tbl meta);
void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary);
void Ddl_append_fld(String tbl, Db_meta_fld fld);
void Ddl_delete_tbl(String tbl);
void Env_db_attach(String alias, Io_url db_url);
void Env_db_detach(String alias);
boolean Meta_tbl_exists(String tbl);
boolean Meta_fld_exists(String tbl, String fld);
}

View File

@@ -0,0 +1,109 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines; import gplx.*; import gplx.dbs.*;
import java.sql.*;
import gplx.dbs.engines.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*;
public abstract class Db_engine_sql_base implements Db_engine {
@gplx.Internal protected void Ctor(Db_conn_info conn_info) {this.conn_info = conn_info;}
public abstract String Tid();
public Db_conn_info Conn_info() {return conn_info;} protected Db_conn_info conn_info;
public abstract Db_engine New_clone(Db_conn_info conn_info);
public Db_rdr New_rdr__rls_manual(Object rdr_obj, String sql) {return New_rdr(null, rdr_obj, sql);}
public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {return New_rdr(stmt, rdr_obj, sql);}
@gplx.Virtual public Db_rdr New_rdr_clone() {return new Db_rdr__basic();}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_cmd(this, qry);}
@gplx.Virtual public void Txn_bgn(String name) {Exec_as_obj(Db_qry_sql.xtn_("BEGIN TRANSACTION;"));}
@gplx.Virtual public void Txn_end() {Exec_as_obj(Db_qry_sql.xtn_("COMMIT TRANSACTION;"));}
@gplx.Virtual public void Txn_cxl() {Exec_as_obj(Db_qry_sql.xtn_("ROLLBACK TRANSACTION;"));}
@gplx.Virtual public void Txn_sav() {this.Txn_end(); this.Txn_bgn("");}
public Object Exec_as_obj(Db_qry qry) {
if (qry.Tid() == Db_qry_.Tid_flush) return null; // ignore flush (delete-db) statements
String sql = this.SqlWtr().Xto_str(qry, false); // DBG: Tfds.Write(sql);
return qry.Exec_is_rdr() ? (Object)this.Exec_as_rdr(sql) : this.Exec_as_int(sql);
}
protected int Exec_as_int(String sql) {
try {
Statement cmd = New_stmt_exec(sql);
return cmd.executeUpdate(sql);
}
catch (Exception e) {throw Exc_.new_exc(e, "db", "db.engine:exec failed", "url", conn_info.Xto_api(), "sql", sql);}
}
private DataRdr Exec_as_rdr(String sql) {
try {
Statement cmd = New_stmt_exec(sql);
cmd.execute(sql);
ResultSet rdr = cmd.getResultSet();
return New_rdr(rdr, sql);
}
catch (Exception e) {throw Exc_.new_exc(e, "db", "db.engine:rdr failed", "url", conn_info.Xto_api(), "sql", sql);}
}
public void Ddl_create_tbl(Db_meta_tbl tbl) {Exec_as_int(tbl.To_sql_create());}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary) {
int len = ary.length;
for (int i = 0; i < len; ++i) {
Db_meta_idx idx = ary[i];
usr_dlg.Plog_many("", "", "creating database index (please wait); db=~{0} idx=~{1}", conn_info.Database(), idx.Name());
Exec_as_int(idx.To_sql_create());
}
}
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {
Gfo_usr_dlg_.I.Plog_many("", "", "adding column to table: db=~{0} tbl=~{1} fld=~{2}", conn_info.Database(), tbl, fld.Name());
try {
Exec_as_int(Db_sqlbldr__sqlite.I.Bld_alter_tbl_add(tbl, fld));
Gfo_usr_dlg_.I.Plog_many("", "", "column added to table: db=~{0} tbl=~{1} fld=~{2}", conn_info.Database(), tbl, fld.Name());
}
catch (Exception e) { // catch error if column already added to table
Gfo_usr_dlg_.I.Warn_many("", "", "column not added to table: db=~{0} tbl=~{1} fld=~{2} err=~{3}", conn_info.Database(), tbl, fld.Name(), Err_.Message_gplx(e));
}
}
public void Ddl_delete_tbl(String tbl) {Exec_as_int(Db_sqlbldr__sqlite.I.Bld_drop_tbl(tbl));}
@gplx.Virtual public void Env_db_attach(String alias, Io_url db_url) {}
@gplx.Virtual public void Env_db_detach(String alias) {}
@gplx.Virtual public boolean Meta_tbl_exists(String tbl) {return false;}
@gplx.Virtual public boolean Meta_fld_exists(String tbl, String fld) {return false;}
@gplx.Virtual public DataRdr New_rdr(ResultSet rdr, String sql) {return gplx.stores.Db_data_rdr_.new_(rdr, sql);}
@gplx.Virtual public Sql_qry_wtr SqlWtr() {return Sql_qry_wtr_.new_ansi();}
private Db_rdr New_rdr(Db_stmt stmt, Object rdr, String sql) {
Db_rdr__basic rv = (Db_rdr__basic)New_rdr_clone();
rv.Ctor(stmt, (ResultSet)rdr, sql);
return rv;
}
@gplx.Internal protected abstract Connection Conn_new();
protected Connection connection;
public void Conn_open() {connection = Conn_new();}
public void Conn_term() {
if (connection == null) return; // connection never opened; just exit
try {connection.close();}
catch (Exception e) {throw Exc_.new_exc(e, "db", "Conn_term failed", "url", conn_info.Xto_raw());}
connection = null;
}
public Object New_stmt_prep_as_obj(String sql) {
if (connection == null) connection = Conn_new(); // auto-open connection
try {return connection.prepareStatement(sql);}
catch (Exception e) {throw Exc_.new_exc(e, "db", "New_stmt_prep failed", "sql", sql);}
}
private Statement New_stmt_exec(String sql) {
if (connection == null) connection = Conn_new(); // auto-open connection
try {return connection.createStatement();}
catch (Exception e) {throw Exc_.new_exc(e, "db", "New_stmt_exec failed", "sql", sql);}
}
protected Connection Conn_make_by_url(String url, String uid, String pwd) {
try {return DriverManager.getConnection(url, uid, pwd);}
catch (SQLException e) {throw Exc_.new_exc(e, "db", "connection open failed", "info", Conn_info().Xto_raw());}
}
}

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Db_conn_info__mem extends Db_conn_info__base {
@Override public String Tid() {return Tid_const;} public static final String Tid_const = "mem";
@Override public Db_conn_info New_self(String raw, GfoMsg m) {
Db_conn_info__mem rv = new Db_conn_info__mem();
rv.Ctor("", m.ReadStr("database"), raw, raw);
return rv;
}
public static Db_conn_info new_(String database) {
return Db_conn_info_.parse_(Bld_raw
( "gplx_key", Tid_const
, "database", database
));
}
public static final Db_conn_info__mem I = new Db_conn_info__mem(); Db_conn_info__mem() {}
}

View File

@@ -0,0 +1,56 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Db_engine__mem implements Db_engine {
private final Hash_adp tbl_hash = Hash_adp_.new_();
Db_engine__mem(Db_conn_info conn_info) {this.conn_info = conn_info;}
public String Tid() {return Db_conn_info__mem.Tid_const;}
public Db_conn_info Conn_info() {return conn_info;} private Db_conn_info conn_info;
public Db_engine New_clone(Db_conn_info conn_info) {return new Db_engine__mem(conn_info);}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt__mem(this, qry);}
public Mem_tbl Tbls_get(String name) {return (Mem_tbl)tbl_hash.Get_by(name);}
public void Txn_bgn(String name) {++txn_count;} private int txn_count = 0;
public void Txn_end() {--txn_count;}
public void Txn_cxl() {--txn_count;}
public void Txn_sav() {this.Txn_end(); this.Txn_bgn("");}
public Object Exec_as_obj(Db_qry qry) {throw Exc_.new_unimplemented();}
public void Conn_open() {}
public void Conn_term() {
if (txn_count != 0) throw Exc_.new_("Conn_term.txns still open", "txn_count", txn_count);
}
public Db_rdr New_rdr__rls_manual(Object rdr_obj, String sql) {throw Exc_.new_unimplemented();}
public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {throw Exc_.new_unimplemented();}
public DataRdr New_rdr(java.sql.ResultSet rdr, String sql) {throw Exc_.new_unimplemented();}
public Object New_stmt_prep_as_obj(String sql) {throw Exc_.new_unimplemented();}
public void Ddl_create_tbl(Db_meta_tbl meta) {
Mem_tbl mem_tbl = new Mem_tbl(meta);
tbl_hash.Add_if_dupe_use_nth(meta.Name(), mem_tbl);
}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary) {} // TODO: implement unique index
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {}
public void Ddl_delete_tbl(String tbl) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public boolean Meta_tbl_exists(String tbl) {return tbl_hash.Has(tbl);}
public boolean Meta_fld_exists(String tbl, String fld) {
Mem_tbl mem_tbl = (Mem_tbl)tbl_hash.Get_by(tbl); if (mem_tbl == null) return false;
return mem_tbl.Meta().Flds_has(fld);
}
// public boolean Meta_fld_exists(String name) {return tbl_hash.Has(name);}
public static final Db_engine__mem _ = new Db_engine__mem(); Db_engine__mem() {}
}

View File

@@ -0,0 +1,44 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Db_rdr__mem implements Db_rdr {
private final Mem_row[] rows; private int row_idx = -1; private final int rows_len;
private Mem_row row;
public Db_rdr__mem(String[] cols, Mem_row[] rows) {
this.rows = rows; this.rows_len = rows.length;
}
public boolean Move_next() {
boolean rv = ++row_idx < rows_len;
if (rv)
row = rows[row_idx];
return rv;
}
public byte[] Read_bry(String k) {return (byte[])row.Get_by(k);}
public String Read_str(String k) {return (String)row.Get_by(k);}
public byte[] Read_bry_by_str(String k) {return Bry_.new_u8_safe((String)row.Get_by(k));} // NOTE: null b/c db can have NULL
@gplx.Virtual public void Save_bry_in_parts(Io_url url, String tbl, String fld, String crt_key, Object crt_val) {throw Exc_.new_unimplemented();}
public DateAdp Read_date_by_str(String k) {return DateAdp_.parse_iso8561((String)row.Get_by(k));}
public byte Read_byte(String k) {return Byte_.cast_(row.Get_by(k));}
public int Read_int(String k) {return Int_.cast_(row.Get_by(k));}
public long Read_long(String k) {return Long_.cast_(row.Get_by(k));}
public float Read_float(String k) {return Float_.cast_(row.Get_by(k));}
public double Read_double(String k) {return Double_.cast_(row.Get_by(k));}
public boolean Read_bool_by_byte(String k) {return Byte_.cast_(row.Get_by(k)) == 1;}
public Object Read_obj(String k) {return row.Get_by(k);}
public void Rls() {}
}

View File

@@ -0,0 +1,140 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Db_stmt__mem implements Db_stmt {
private static final String Key_na = ""; // key is not_available; only called by procs with signature of Val(<type> v);
private final Ordered_hash val_list = Ordered_hash_.new_();
public Db_stmt__mem(Db_engine__mem engine, Db_qry qry) {Ctor_stmt(engine, qry);} private Db_engine__mem engine;
public void Ctor_stmt(Db_engine engine, Db_qry qry) {this.engine = (Db_engine__mem)engine; this.qry = qry;}
public Hash_adp Crts() {return crt_hash;} private final Hash_adp crt_hash = Hash_adp_.new_();
public int Args_len() {return val_list.Count();}
public Object Args_get_at(int i) {return val_list.Get_at(i);}
public Object Args_get_by(String k) {return val_list.Get_by(k);}
public Db_qry Qry() {return qry;} private Db_qry qry;
public Db_stmt Reset_stmt() {return this;}
public Db_stmt Clear() {
val_list.Clear();
crt_hash.Clear();
return this;
}
public void Rls() {this.Clear();}
public Db_stmt Crt_bool_as_byte(String k, boolean v) {return Add_byte_by_bool(Bool_.Y, k, v);}
public Db_stmt Val_bool_as_byte(String k, boolean v) {return Add_byte_by_bool(Bool_.N, k, v);}
public Db_stmt Val_bool_as_byte(boolean v) {return Add_byte_by_bool(Bool_.N, Key_na, v);}
private Db_stmt Add_byte_by_bool(boolean where, String k, boolean v) {return Add_byte(where, k, v ? Bool_.Y_byte : Bool_.N_byte);}
public Db_stmt Crt_byte(String k, byte v) {return Add_byte(Bool_.Y, k, v);}
public Db_stmt Val_byte(String k, byte v) {return Add_byte(Bool_.N, k, v);}
public Db_stmt Val_byte(byte v) {return Add_byte(Bool_.N, Key_na, v);}
private Db_stmt Add_byte(boolean where, String k, byte v) {
try {Add(k, where, v);} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "byte", "val", v);}
return this;
}
public Db_stmt Crt_int(String k, int v) {return Add_int(Bool_.Y, k, v);}
public Db_stmt Val_int(String k, int v) {return Add_int(Bool_.N, k, v);}
public Db_stmt Val_int(int v) {return Add_int(Bool_.N, Key_na, v);}
private Db_stmt Add_int(boolean where, String k, int v) {
try {Add(k, where, v);} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "int", "val", v);}
return this;
}
public Db_stmt Crt_long(String k, long v) {return Add_long(Bool_.Y, k, v);}
public Db_stmt Val_long(String k, long v) {return Add_long(Bool_.N, k, v);}
public Db_stmt Val_long(long v) {return Add_long(Bool_.N, Key_na, v);}
private Db_stmt Add_long(boolean where, String k, long v) {
try {Add(k, where, v);} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "long", "val", v);}
return this;
}
public Db_stmt Crt_float(String k, float v) {return Add_float(Bool_.Y, k, v);}
public Db_stmt Val_float(String k, float v) {return Add_float(Bool_.N, k, v);}
public Db_stmt Val_float(float v) {return Add_float(Bool_.N, Key_na, v);}
private Db_stmt Add_float(boolean where, String k, float v) {
try {Add(k, where, v);} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "float", "val", v);}
return this;
}
public Db_stmt Crt_double(String k, double v) {return Add_double(Bool_.Y, k, v);}
public Db_stmt Val_double(String k, double v) {return Add_double(Bool_.N, k, v);}
public Db_stmt Val_double(double v) {return Add_double(Bool_.N, Key_na, v);}
private Db_stmt Add_double(boolean where, String k, double v) {
try {Add(k, where, v);} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "double", "val", v);}
return this;
}
public Db_stmt Crt_decimal(String k, DecimalAdp v) {return Add_decimal(Bool_.Y, k, v);}
public Db_stmt Val_decimal(String k, DecimalAdp v) {return Add_decimal(Bool_.N, k, v);}
public Db_stmt Val_decimal(DecimalAdp v) {return Add_decimal(Bool_.N, Key_na, v);}
private Db_stmt Add_decimal(boolean where, String k, DecimalAdp v) {
try {Add(k, where, v);} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "decimal", "val", v);}
return this;
}
public Db_stmt Crt_bry(String k, byte[] v) {return Add_bry(Bool_.Y, k, v);}
public Db_stmt Val_bry(String k, byte[] v) {return Add_bry(Bool_.N, k, v);}
public Db_stmt Val_bry(byte[] v) {return Add_bry(Bool_.N, Key_na, v);}
private Db_stmt Add_bry(boolean where, String k, byte[] v) {
try {Add(k, where, v);} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "byte[]", "val", v.length);}
return this;
}
public Db_stmt Crt_bry_as_str(String k, byte[] v) {return Add_bry_as_str(Bool_.Y, k, v);}
public Db_stmt Val_bry_as_str(String k, byte[] v) {return Add_bry_as_str(Bool_.N, k, v);}
public Db_stmt Val_bry_as_str(byte[] v) {return Add_bry_as_str(Bool_.N, Key_na, v);}
private Db_stmt Add_bry_as_str(boolean where, String k, byte[] v) {return Add_str(where, k, String_.new_u8(v));}
public Db_stmt Crt_str(String k, String v) {return Add_str(Bool_.Y, k, v);}
public Db_stmt Val_str(String k, String v) {return Add_str(Bool_.N, k, v);}
public Db_stmt Val_str(String v) {return Add_str(Bool_.N, Key_na, v);}
private Db_stmt Add_str(boolean where, String k, String v) {
try {Add(k, where, v);} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "String", "val", v);}
return this;
}
public Db_stmt Val_rdr_(gplx.ios.Io_stream_rdr v, long rdr_len) {
try {
Bry_bfr bfr = Bry_bfr.new_();
gplx.ios.Io_stream_rdr_.Load_all_to_bfr(bfr, v);
Add("", Bool_.N, bfr.Xto_str_and_clear());
} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "rdr", "val", v);}
return this;
}
public boolean Exec_insert() {
Mem_tbl tbl = engine.Tbls_get(qry.Base_table());
if (tbl == null) throw Exc_.new_("must call Create_tbl", "tbl", qry.Base_table());
return tbl.Insert(this) == 1;
}
public int Exec_update() {
Mem_tbl tbl = engine.Tbls_get(qry.Base_table());
return tbl.Update(this);
}
public int Exec_delete() {
Mem_tbl tbl = engine.Tbls_get(qry.Base_table());
return tbl.Delete(this);
}
public DataRdr Exec_select() {throw Exc_.new_unimplemented();}
public Db_rdr Exec_select__rls_auto() {return this.Exec_select__rls_manual();}
public Db_rdr Exec_select__rls_manual() {
Mem_tbl tbl = engine.Tbls_get(qry.Base_table());
return tbl.Select(this);
}
public Object Exec_select_val() {throw Exc_.new_unimplemented();}
private void Add(String k, boolean where, Object v) {
if (k == Db_meta_fld.Key_null) return; // key is explicitly null; ignore; allows schema_2+ type definitions
val_list.Add_if_dupe_use_1st(k, v); // NOTE: only add if new; WHERE with IN will call Add many times; fld_ttl IN ('A.png', 'B.png');
if (where) {
List_adp list = (List_adp)crt_hash.Get_by(k);
if (list == null) {
list = List_adp_.new_();
crt_hash.Add(k, list);
}
list.Add(v);
}
}
}

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.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Mem_qry_set {
private final List_adp rows = List_adp_.new_();
public int Len() {return rows.Count();}
public Mem_row Get_at(int i) {return (Mem_row)rows.Get_at(i);}
public void Add(Mem_row row) {rows.Add(row);}
}

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.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Mem_row implements GfoInvkAble {
private final Ordered_hash hash = Ordered_hash_.new_();
public Object Get_by(String key) {return hash.Get_by(key);}
public Object Get_at(int i) {return hash.Get_at(i);}
public void Set_by(String key, Object val) {hash.Add_if_dupe_use_nth(key, val);}
public void Add(String key, Object val) {hash.Add(key, val);}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
Object rv = Get_by(k);
if (rv == null) return GfoInvkAble_.Rv_unhandled;
return rv;
}
}

View File

@@ -0,0 +1,95 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.primitives.*; import gplx.core.criterias.*; import gplx.dbs.qrys.*;
public class Mem_tbl {
private final List_adp rows = List_adp_.new_(); private final List_adp where_rows = List_adp_.new_();
private final Hash_adp autonum_hash = Hash_adp_.new_();
public Mem_tbl(Db_meta_tbl meta) {this.meta = meta;}
public Db_meta_tbl Meta() {return meta;} private final Db_meta_tbl meta;
public int Insert(Db_stmt__mem stmt) {
Mem_row itm = new Mem_row();
Db_meta_fld[] flds = meta.Flds();
int len = flds.length;
for (int i = 0; i < len; ++i) {
Db_meta_fld fld = flds[i];
String fld_name = fld.Name();
Object val = fld.Autonum() ? Autonum_calc(fld_name) : stmt.Args_get_by(fld_name);
itm.Set_by(fld_name, val);
}
rows.Add(itm);
return 1;
}
private int Autonum_calc(String name) {
Int_obj_ref autonum_itm = (Int_obj_ref)autonum_hash.Get_by(name);
if (autonum_itm == null) {
autonum_itm = Int_obj_ref.new_(0);
autonum_hash.Add(name, autonum_itm);
}
return autonum_itm.Val_add();
}
public int Update(Db_stmt__mem stmt) {
Db_qry_update qry = (Db_qry_update)stmt.Qry();
qry.Where().Val_from_args(stmt.Crts());
Select_rows_where(where_rows, stmt, qry.Where());
int where_rows_len = where_rows.Count();
String[] update_cols = qry.Cols_for_update(); int update_cols_len = update_cols.length;
for (int i = 0; i < where_rows_len; ++i) {
Mem_row itm = (Mem_row)where_rows.Get_at(i);
for (int j = 0; j < update_cols_len; ++j)
itm.Set_by(update_cols[j], stmt.Args_get_at(j));
}
return where_rows_len;
}
public int Delete(Db_stmt__mem stmt) {
Db_qry_delete qry = (Db_qry_delete)stmt.Qry();
qry.Where().Val_from_args(stmt.Crts());
Select_rows_where(where_rows, stmt, qry.Where());
int where_rows_len = where_rows.Count();
for (int i = 0; i < where_rows_len; ++i) {
Mem_row itm = (Mem_row)where_rows.Get_at(i);
rows.Del(itm);
}
return where_rows_len;
}
public Db_rdr Select(Db_stmt__mem stmt) {
String[] select = null; Criteria where = null;
Db_qry__select_in_tbl qry = Db_qry__select_in_tbl.as_(stmt.Qry());
if (qry == null) {
Db_qry__select_cmd qry2 = (Db_qry__select_cmd)stmt.Qry();
select = qry2.Cols_ary();
where = qry2.Where();
}
else {
select = qry.Select_flds();
where = qry.Where();
}
where.Val_from_args(stmt.Crts());
Select_rows_where(where_rows, stmt, where);
return new Db_rdr__mem(select, (Mem_row[])where_rows.To_ary_and_clear(Mem_row.class));
}
private void Select_rows_where(List_adp rv, Db_stmt__mem stmt, Criteria crt) {
rv.Clear();
int rows_len = rows.Count();
for (int i = 0; i < rows_len; ++i) {
Mem_row itm = (Mem_row)rows.Get_at(i);
if (crt.Matches(itm))
rv.Add(itm);
}
}
}

View File

@@ -0,0 +1,41 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mysql; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Mysql_conn_info extends Db_conn_info__base {
@Override public String Tid() {return Tid_const;} public static final String Tid_const = "mysql";
public String Uid() {return uid;} private String uid;
public String Pwd() {return pwd;} private String pwd;
public static Db_conn_info new_(String server, String database, String uid, String pwd) {
return Db_conn_info_.parse_(Bld_raw
( "gplx_key", Tid_const
, "server", server
, "database", database
, "uid", uid
, "pwd", pwd
, "charset", "utf8"
));
}
@Override public Db_conn_info New_self(String raw, GfoMsg m) {
Mysql_conn_info rv = new Mysql_conn_info();
rv.Ctor(m.ReadStr("server"), m.ReadStr("database"), raw, BldApi(m, KeyVal_.new_("charset", "utf8")));
rv.uid = m.ReadStr("uid");
rv.pwd = m.ReadStr("pwd");
return rv;
}
public static final Mysql_conn_info _ = new Mysql_conn_info(); Mysql_conn_info() {}
}

View File

@@ -0,0 +1,48 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mysql; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*;
import java.sql.*;
public class Mysql_engine extends Db_engine_sql_base {
@Override public String Tid() {return Mysql_conn_info.Tid_const;}
@Override public Sql_qry_wtr SqlWtr() {return Sql_qry_wtr_.new_escape_backslash();}
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
Mysql_engine rv = new Mysql_engine();
rv.Ctor(connectInfo);
return rv;
}
@Override public DataRdr New_rdr(ResultSet rdr, String commandText) {return Mysql_rdr.new_(rdr, commandText);}
@gplx.Internal @Override protected Connection Conn_new() {
Mysql_conn_info conn_info_as_mysql = (Mysql_conn_info)conn_info;
return Conn_make_by_url("jdbc:mysql://localhost/" + conn_info_as_mysql.Database() + "?characterEncoding=UTF8", conn_info_as_mysql.Uid(), conn_info_as_mysql.Pwd());
}
public static final Mysql_engine _ = new Mysql_engine(); Mysql_engine() {}
}
class Mysql_rdr extends Db_data_rdr {
//PATCH:MYSQL:byte actually returned as int by Jdbc ResultSet (or MYSQL impmentation); convert to byte
@Override public byte ReadByte(String key) {return ReadByteOr(key, Byte.MAX_VALUE);}
@Override public byte ReadByteOr(String key, byte or) {
Object val = Read(key);
return val == null ? or : ((Integer)val).byteValue();
}
public static Mysql_rdr new_(ResultSet rdr, String commandText) {
Mysql_rdr rv = new Mysql_rdr();
rv.ctor_db_data_rdr(rdr, commandText);
return rv;
} Mysql_rdr() {}
}

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.engines.nulls; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Noop_conn_info extends Db_conn_info__base {
@Override public String Tid() {return Tid_const;} public static final String Tid_const = "null_db";
@Override public Db_conn_info New_self(String raw, GfoMsg m) {return this;}
public static final Noop_conn_info I = new Noop_conn_info(); Noop_conn_info() {this.Ctor("", "", "gplx_key=null_db", "");}
}

View File

@@ -0,0 +1,44 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.nulls; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Noop_engine implements Db_engine {
public String Tid() {return Noop_conn_info.Tid_const;}
public Db_conn_info Conn_info() {return Db_conn_info_.Null;}
public void Conn_open() {}
public void Conn_term() {}
public Db_engine New_clone(Db_conn_info url) {return this;}
public Db_rdr New_rdr__rls_manual (Object rdr_obj, String sql) {return Db_rdr_.Empty;}
public Db_rdr New_rdr__rls_auto (Db_stmt stmt, Object rdr_obj, String sql) {return Db_rdr_.Empty;}
public Db_stmt New_stmt_prep(Db_qry qry) {return Db_stmt_.Null;}
public Object New_stmt_prep_as_obj(String sql) {throw Exc_.new_unimplemented();}
public DataRdr New_rdr(java.sql.ResultSet rdr, String sql) {return DataRdr_.Null;}
public void Txn_bgn(String name) {}
public void Txn_end() {}
public void Txn_cxl() {}
public void Txn_sav() {}
public Object Exec_as_obj(Db_qry cmd) {return cmd.Exec_is_rdr() ? (Object)DataRdr_.Null : -1;}
public void Ddl_create_tbl(Db_meta_tbl meta) {}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary) {}
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {}
public void Ddl_delete_tbl(String tbl) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public boolean Meta_tbl_exists(String tbl) {return false;}
public boolean Meta_fld_exists(String tbl, String fld) {return false;}
public static final Noop_engine _ = new Noop_engine(); Noop_engine() {}
}

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.engines.postgres; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Postgres_conn_info extends Db_conn_info__base {
@Override public String Tid() {return Tid_const;} public static final String Tid_const = "postgresql";
public String Uid() {return uid;} private String uid;
public String Pwd() {return pwd;} private String pwd;
public static Db_conn_info new_(String server, String database, String uid, String pwd) {
return Db_conn_info_.parse_(Bld_raw
( "gplx_key", Tid_const
, "server", server
, "database", database
, "port", "5432"
, "user id", uid
, "password", pwd
, "encoding", "unicode" // needed for 1.1 conn; otherwise, ascii
));
}
@Override public Db_conn_info New_self(String raw, GfoMsg m) {
Postgres_conn_info rv = new Postgres_conn_info();
rv.Ctor(m.ReadStr("server"), m.ReadStr("database"), raw, BldApi(m, KeyVal_.new_("encoding", "unicode")));
rv.uid = m.ReadStr("user id");
rv.pwd = m.ReadStr("password");
return rv;
}
public static final Postgres_conn_info _ = new Postgres_conn_info(); Postgres_conn_info() {}
}

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.engines.postgres; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*;
import java.sql.*;
public class Postgres_engine extends Db_engine_sql_base {
@Override public String Tid() {return Postgres_conn_info.Tid_const;}
@Override public Sql_qry_wtr SqlWtr() {return Sql_qry_wtr_.new_escape_backslash();}
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
Postgres_engine rv = new Postgres_engine();
rv.Ctor(connectInfo);
return rv;
}
@Override public DataRdr New_rdr(ResultSet rdr, String commandText) {return Db_data_rdr_.new_(rdr, commandText);}
@gplx.Internal @Override protected Connection Conn_new() {
Postgres_conn_info conn_info_as_postgres = (Postgres_conn_info)conn_info;
return Conn_make_by_url("jdbc:" + conn_info_as_postgres.Tid() + "://localhost/" + conn_info_as_postgres.Database(), conn_info_as_postgres.Uid(), conn_info_as_postgres.Pwd());
}
public static final Postgres_engine _ = new Postgres_engine(); Postgres_engine() {}
}

View File

@@ -0,0 +1,47 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Sqlite_conn_info extends Db_conn_info__base {
@Override public String Tid() {return Tid_const;} public static final String Tid_const = "sqlite";
public Io_url Url() {return url;} private Io_url url;
@Override public Db_conn_info New_self(String raw, GfoMsg m) {
Sqlite_conn_info rv = new Sqlite_conn_info();
String url = m.ReadStr("data source");
rv.url = Io_url_.new_any_(url);
rv.Ctor("", url, raw, BldApi(m, KeyVal_.new_("version", "3")));
rv.database = rv.url.NameOnly();
return rv;
}
public static Db_conn_info load_(Io_url url) {
return Db_conn_info_.parse_(Bld_raw
( "gplx_key" , Tid_const
, "data source" , url.Xto_api()
, "version" , "3"
));
}
public static Db_conn_info make_(Io_url url) {
Io_mgr.I.CreateDirIfAbsent(url.OwnerDir());
return Db_conn_info_.parse_(Bld_raw
( "gplx_key" , Tid_const
, "data source" , url.Xto_api()
, "version" , "3"
));
}
public static final Sqlite_conn_info _ = new Sqlite_conn_info(); Sqlite_conn_info() {}
}

View File

@@ -0,0 +1,130 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import java.sql.*;
import gplx.stores.*; import gplx.dbs.engines.*; import gplx.dbs.engines.sqlite.*;
import gplx.dbs.qrys.*;
public class Sqlite_engine extends Db_engine_sql_base {
private final Sqlite_txn_mgr txn_mgr; private final Sqlite_schema_mgr schema_mgr;
Sqlite_engine() {
this.txn_mgr = new Sqlite_txn_mgr(this);
this.schema_mgr = new Sqlite_schema_mgr(this);
}
@Override public String Tid() {return Sqlite_conn_info.Tid_const;}
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
Sqlite_engine rv = new Sqlite_engine();
rv.Ctor(connectInfo);
return rv;
}
@Override public DataRdr New_rdr(ResultSet rdr, String commandText) {return Sqlite_rdr.new_(rdr, commandText);}
@Override public Db_rdr New_rdr_clone() {return new Db_rdr__sqlite();}
@Override public void Env_db_attach(String alias, Io_url db_url) {Exec_as_int(String_.Format("ATTACH '{0}' AS {1};", db_url.Raw(), alias));}
@Override public void Env_db_detach(String alias) {Exec_as_int(String_.Format("DETACH {0};", alias));}
@Override public void Txn_bgn(String name) {txn_mgr.Txn_bgn(name);}
@Override public void Txn_end() {txn_mgr.Txn_end();}
@Override public void Txn_cxl() {txn_mgr.Txn_cxl();}
@Override public void Txn_sav() {txn_mgr.Txn_sav();}
@Override public boolean Meta_tbl_exists(String tbl) {return schema_mgr.Tbl_exists(tbl);}
@Override public boolean Meta_fld_exists(String tbl, String fld) {return schema_mgr.Fld_exists(tbl, fld);}
static boolean loaded = false;
@gplx.Internal @Override protected Connection Conn_new() {
if (!loaded) {
try {
Class.forName("org.sqlite.JDBC");
}
catch (ClassNotFoundException e) {throw Exc_.new_exc(e, "db", "could not load sqlite jdbc driver");}
loaded = true;
}
Sqlite_conn_info conn_info_as_sqlite = (Sqlite_conn_info)conn_info;
Connection rv = Conn_make_by_url("jdbc:sqlite://" + String_.Replace(conn_info_as_sqlite.Url().Raw(), "\\", "/"), "", "");
return rv;
}
public static final Sqlite_engine _ = new Sqlite_engine();
}
class Db_rdr__sqlite extends Db_rdr__basic { @Override public byte Read_byte(String k) {try {return (byte)Int_.cast_(rdr.getObject(k));} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "k", k, "type", Byte_.Cls_val_name);}}
@Override public boolean Read_bool_by_byte(String k) {
try {
int val = rdr.getInt(k);
return val == 1;
} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "i", k, "type", Bool_.Cls_val_name);}
}
@Override public long Read_long(String k) {
try {
long val = rdr.getLong(k);
Number n = (Number)val;
return n.longValue();
} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "i", k, "type", Long_.Cls_val_name);}
}
@Override public float Read_float(String k) {
try {
Double val = (Double)rdr.getDouble(k);
return val == null ? Float.NaN : val.floatValue();
} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed:", "i", k, "type", Float_.Cls_val_name);}
}
@Override public DateAdp Read_date_by_str(String k) {
try {
String val = rdr.getString(k);
return val == null ? null : DateAdp_.parse_fmt(val, "yyyyMMdd_HHmmss");
} catch (Exception e) {throw Exc_.new_exc(e, "db", "read failed", "i", k, "type", DateAdp_.Cls_ref_type);}
}
// @Override public DecimalAdp ReadDecimalOr(String key, DecimalAdp or) {
// Object val = Read(key);
// Double d = ((Double)val);
// return val == null ? null : DecimalAdp_.double_(d);
// }
}
class Sqlite_rdr extends Db_data_rdr { @Override public float ReadFloat(String key) {return ReadFloatOr(key, Float.NaN);}
@Override public float ReadFloatOr(String key, float or) {
Object val = Read(key);
Double d = ((Double)val);
return val == null ? or : d.floatValue();
}
@Override public DecimalAdp ReadDecimal(String key) {return ReadDecimalOr(key, null);}
@Override public DecimalAdp ReadDecimalOr(String key, DecimalAdp or) {
Object val = Read(key);
Double d = ((Double)val);
return val == null ? or : DecimalAdp_.double_(d);
}
@Override public DateAdp ReadDate(String key) {return ReadDateOr(key, null);}
@Override public DateAdp ReadDateOr(String key, DateAdp or) {
Object val = Read(key);
return val == null ? or : DateAdp_.parse_fmt((String)val, "M/dd/yyyy hh:mm tt");
}
@Override public boolean ReadBool(String key) {return ReadBoolOr(key, false);}
@Override public boolean ReadBoolOr(String key, boolean or) {
Object val = Read(key);
return val == null ? or : Int_.cast_(val) == 1;
}
@Override public byte ReadByte(String key) {return ReadByteOr(key, Byte_.Zero);}
@Override public byte ReadByteOr(String key, byte or) {
Object val = Read(key);
return val == null ? or : (byte)Int_.cast_(val);
}
@Override public long ReadLong(String key) {return ReadLongOr(key, Long_.MinValue);}
@Override public long ReadLongOr(String key, long or) {
Object val = Read(key);
if (val == null) return or;
Number n = (Number)val;
return n.longValue();
}
public static Sqlite_rdr new_(ResultSet rdr, String commandText) {
Sqlite_rdr rv = new Sqlite_rdr();
rv.ctor_db_data_rdr(rdr, commandText);
return rv;
} Sqlite_rdr() {}
}

View File

@@ -0,0 +1,92 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.primitives.*; import gplx.dbs.qrys.*; import gplx.dbs.utls.*; import gplx.dbs.engines.*; import gplx.dbs.engines.sqlite.*;
public class Sqlite_engine_ {
public static void Db_attach(Db_conn p, String alias, String url) {
String s = String_.Format("ATTACH '{0}' AS {1};", url, alias);
Db_qry qry = Db_qry_sql.xtn_(s);
p.Exec_qry(qry);
}
public static void Db_detach(Db_conn p, String alias) {
String s = String_.Format("DETACH '{0}';", alias);
Db_qry qry = Db_qry_sql.xtn_(s);
p.Exec_qry(qry);
}
public static void Tbl_create_and_delete(Db_conn p, String tbl_name, String tbl_sql) {
Tbl_delete(p, tbl_name);
Db_qry qry = Db_qry_sql.ddl_(tbl_sql);
p.Exec_qry(qry);
}
public static void Tbl_create(Db_conn p, String tbl_name, String tbl_sql) {
Db_qry qry = Db_qry_sql.ddl_(tbl_sql);
p.Exec_qry(qry);
}
public static void Tbl_delete_many(Db_conn p, String... tbls) {
int len = tbls.length;
for (int i = 0; i < len; i++)
Tbl_delete(p, tbls[i]);
}
public static void Tbl_delete(Db_conn p, String tbl) {
Db_qry qry = Db_qry_sql.ddl_("DROP TABLE IF EXISTS " + tbl + ";");
p.Exec_qry(qry);
}
public static void Tbl_rename(Db_conn p, String src, String trg) {
Db_qry qry = Db_qry_sql.ddl_(String_.Format("ALTER TABLE {0} RENAME TO {1};", src, trg));
p.Exec_qry(qry);
}
public static void Pragma_page_size(Db_conn p, int val) {
Db_qry qry = Db_qry_sql.ddl_("PRAGMA page_size = " + Int_.Xto_str(val) + ";");
p.Exec_qry(qry);
}
public static void Idx_create(Gfo_usr_dlg usr_dlg, Db_conn conn, String tbl, Db_meta_idx[] idx_ary) {
int len = idx_ary.length;
for (int i = 0; i < len; ++i) {
Db_meta_idx idx = idx_ary[i];
String idx_sql = idx.To_sql_create();
usr_dlg.Plog_many("", "", "creating index: ~{0} ~{1}", tbl, idx_sql);
conn.Exec_qry(Db_qry_sql.ddl_(idx.To_sql_create()));
usr_dlg.Log_many("", "", "index created: ~{0} ~{1}", tbl, idx_sql);
}
}
public static void Idx_create(Db_conn p, Db_idx_itm... idxs) {Idx_create(Gfo_usr_dlg_.Noop, p, "", idxs);}
public static void Idx_create(Gfo_usr_dlg usr_dlg, Db_conn p, String file_id, Db_idx_itm... idxs) {
int len = idxs.length;
for (int i = 0; i < len; i++) {
String index = idxs[i].Xto_sql();
usr_dlg.Plog_many("", "", "creating index: ~{0} ~{1}", file_id, index);
p.Exec_qry(Db_qry_sql.ddl_(index));
usr_dlg.Log_many("", "", "index created: ~{0} ~{1}", file_id, index);
}
}
public static Db_conn Conn_load_or_make_(Io_url url, Bool_obj_ref created) {
boolean exists = Io_mgr.I.ExistsFil(url);
created.Val_(!exists);
Db_conn_info connect = exists ? Sqlite_conn_info.load_(url) : Sqlite_conn_info.make_(url);
Db_conn p = Db_conn_pool.I.Get_or_new(connect);
if (!exists)
Pragma_page_size(p, 4096);
return p;
}
public static final int Stmt_arg_max = 999; // 999 is max number of variables allowed by sqlite
public static final boolean Supports_read_binary_stream = false;
public static final boolean Supports_indexed_by = true;
public static String X_date_to_str(DateAdp v) {return v == Date_null ? "" : v.XtoStr_fmt_iso_8561();}
public static final DateAdp Date_null = null;
public static final byte Wildcard_byte = Byte_ascii.Hash;
}

View File

@@ -0,0 +1,66 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.dbs.qrys.*;
import gplx.dbs.metas.*; import gplx.dbs.metas.parsers.*;
public class Sqlite_schema_mgr {
private final Db_engine engine; private boolean init = true;
public Sqlite_schema_mgr(Db_engine engine) {this.engine = engine;}
public Meta_tbl_mgr Tbl_mgr() {return tbl_mgr;} private final Meta_tbl_mgr tbl_mgr = new Meta_tbl_mgr();
public Meta_idx_mgr Idx_mgr() {return idx_mgr;} private final Meta_idx_mgr idx_mgr = new Meta_idx_mgr();
public boolean Tbl_exists(String name) {
if (init) Init(engine);
return tbl_mgr.Has(name);
}
public boolean Fld_exists(String tbl, String fld) {
if (init) Init(engine);
Meta_tbl_itm tbl_itm = tbl_mgr.Get_by(tbl);
return (tbl_itm == null) ? false : tbl_itm.Flds().Has(fld);
}
private void Init(Db_engine engine) {
init = false;
Gfo_usr_dlg_.I.Log_many("", "", "db.schema.load.bgn: conn=~{0}", engine.Conn_info().Xto_api());
Meta_parser__tbl tbl_parser = new Meta_parser__tbl();
Db_qry__select_in_tbl qry = Db_qry__select_in_tbl.new_("sqlite_master", String_.Ary_empty, String_.Ary("type", "name", "sql"), Db_qry__select_in_tbl.Order_by_null);
Db_rdr rdr = engine.New_stmt_prep(qry).Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
String type_str = rdr.Read_str("type");
String name = rdr.Read_str("name");
String sql = rdr.Read_str("sql");
int type_int = Meta_itm_tid.Xto_int(type_str);
switch (type_int) {
case Meta_itm_tid.Tid_table:
if (String_.Eq(name, "sqlite_sequence")) continue; // ignore b/c of non-orthodox syntax; EX: "CREATE TABLE sqlite_sequence(name, seq)";
// Meta_tbl_itm tbl_itm = new Meta_tbl_itm(tbl_name, tbl_sql);
Meta_tbl_itm tbl_itm = tbl_parser.Parse(Bry_.new_u8(sql));
tbl_mgr.Add(tbl_itm);
break;
case Meta_itm_tid.Tid_index:
Meta_idx_itm idx_itm = new Meta_idx_itm(name, sql);
idx_mgr.Add(idx_itm);
break;
default:
Gfo_usr_dlg_.I.Log_many("", "", "db.schema.unknown type: conn=~{0} type=~{1} name=~{2} sql=~{3}", engine.Conn_info().Xto_api(), type_str, name, sql);
break;
}
}
} finally {rdr.Rls();}
Gfo_usr_dlg_.I.Log_many("", "", "db.schema.load.end");
}
}

View File

@@ -0,0 +1,70 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.dbs.qrys.*;
public class Sqlite_txn_mgr {
private final List_adp txn_list = List_adp_.new_();
public Sqlite_txn_mgr(Db_engine engine) {this.engine = engine;} private final Db_engine engine;
private boolean pragma_needed = Bool_.Y, txn_started = Bool_.N; // NOTE: txns only support 1 level; SQLite fails when nesting transactions; DATE:2015-03-11
public void Txn_bgn(String name) {
if (String_.Len_eq_0(name)) name = "unnamed";
if (pragma_needed) {
pragma_needed = false;
engine.Exec_as_obj(Db_qry_sql.xtn_("PRAGMA synchronous = OFF;"));
}
// Execute(Db_qry_sql.xtn_("PRAGMA ENCODING=\"UTF-8\";"));
// Execute(Db_qry_sql.xtn_("PRAGMA journal_mode = OFF;")); // will cause out of memory
// Execute(Db_qry_sql.xtn_("PRAGMA journal_mode = MEMORY;"));
// Execute(Db_qry_sql.xtn_("PRAGMA temp_store = MEMORY;"));
// Execute(Db_qry_sql.xtn_("PRAGMA locking_mode = EXCLUSIVE;"));
// Execute(Db_qry_sql.xtn_("PRAGMA cache_size=4000;")); // too many will also cause out of memory
if (txn_started) {
engine.Exec_as_obj(Db_qry_sql.xtn_(String_.Format("SAVEPOINT {0};", name)));
}
else {
txn_started = true;
engine.Exec_as_obj(Db_qry_sql.xtn_("BEGIN TRANSACTION;"));
}
txn_list.Add(name);
}
public void Txn_end() {
if (txn_list.Count() == 0) {Gfo_usr_dlg_.I.Warn_many("", "", "no txns in stack;"); return;}
String txn_last = (String)List_adp_.Pop_last(txn_list);
if (txn_list.Count() == 0) {// no txns left; commit it
engine.Exec_as_obj(Db_qry_sql.xtn_("COMMIT TRANSACTION;"));
txn_started = false;
}
else
engine.Exec_as_obj(Db_qry_sql.xtn_(String_.Format("RELEASE SAVEPOINT {0};", txn_last)));
}
public void Txn_cxl() {
if (txn_list.Count() == 0) {Gfo_usr_dlg_.I.Warn_many("", "", "no txns in stack;"); return;}
String txn_last = (String)List_adp_.Pop_last(txn_list);
if (txn_list.Count() == 0) {// no txns left; rollback
engine.Exec_as_obj(Db_qry_sql.xtn_("ROLLBACK TRANSACTION;"));
txn_started = false;
}
else
engine.Exec_as_obj(Db_qry_sql.xtn_(String_.Format("ROLBACK TRANSACTION TO SAVEPOINT {0};", txn_last)));
}
public void Txn_sav() {
if (txn_list.Count() == 0) {Gfo_usr_dlg_.I.Warn_many("", "", "no txns in stack;"); return;}
String name = (String)txn_list.Get_at(txn_list.Count() - 1);
this.Txn_end(); this.Txn_bgn(name);
}
}

View File

@@ -0,0 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import org.junit.*;
public class TdbConnectInfo_tst {
@Test public void Full() {
Db_conn_info connectInfo = Db_conn_info_.parse_("gplx_key=tdb;url=C:\\dir\\xmpl.tdb;format=dsv;");
tst_Parse(connectInfo, Io_url_.new_any_("C:\\dir\\xmpl.tdb"), "dsv");
}
@Test public void DefaultFormat() {
Db_conn_info connectInfo = Db_conn_info_.parse_("gplx_key=tdb;url=C:\\dir\\xmpl.tdb"); // dsv Format inferred
tst_Parse(connectInfo, Io_url_.new_any_("C:\\dir\\xmpl.tdb"), "dsv");
}
void tst_Parse(Db_conn_info connectInfo, Io_url url, String format) {
Tfds.Eq(((Tdb_conn_info)connectInfo).Url(), url);
}
}

View File

@@ -0,0 +1,47 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class TdbDatabase {
public String Name() {return name;} public void Name_set(String v) {name = v;} private String name = "xmpl";
public Io_url DbUrl() {return dbInfo;} Io_url dbInfo;
public TdbFileList Files() {return files;} TdbFileList files;
public TdbTableList Tables() {return tables;} TdbTableList tables;
@gplx.Internal protected boolean IsNew() {return isNew;} @gplx.Internal protected void IsNew_set(boolean v) {isNew = v;} private boolean isNew;
@gplx.Internal protected TdbFile MakeFile(Io_url url) {
TdbFile rv = TdbFile.new_(FileId_next++, url);
files.Add(rv);
return rv;
}
@gplx.Internal protected TdbTable MakeTbl(String name, int fileId) {
TdbFile file = files.Get_by_or_fail(fileId);
TdbTable rv = TdbTable.new_(TableId_next++, name, file);
tables.Add(rv);
return rv;
}
public static TdbDatabase new_(Io_url dbInfo) {TdbDatabase rv = new TdbDatabase(); rv.ctor(dbInfo); return rv;}
void ctor(Io_url dbInfo) {
this.dbInfo = dbInfo;
TdbFile mainFile = TdbFile.new_(TdbFile.MainFileId, dbInfo);
files = TdbFileList.new_(dbInfo, mainFile);
tables = TdbTableList.new_(dbInfo);
}
int FileId_next = TdbFile.MainFileId + 1;
int TableId_next = 1;
// public static Io_url UrlOf(Db_conn_info url) {return Io_url_.new_any_(url.ServerName());}
}

View File

@@ -0,0 +1,49 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
class TdbDbLoadMgr {
public TdbDatabase LoadTbls(Io_url dbInfo) {
TdbDatabase db = TdbDatabase.new_(dbInfo);
if (!Io_mgr.I.ExistsFil(dbInfo)) {
db.IsNew_set(true);
return db;
}
DataRdr rdr = MakeDataRdr(dbInfo);
LoadTblsByRdr(db, rdr);
return db;
}
public void LoadTbl(TdbDatabase db, TdbTable tbl) {
DataRdr rootRdr = MakeDataRdr(tbl.File().Path());
LoadTblsByRdr(db, rootRdr);
}
void LoadTblsByRdr(TdbDatabase db, DataRdr rootRdr) {
DataRdr rdr = rootRdr.Subs();
while (rdr.MoveNextPeer()) {
String name = rdr.NameOfNode();
if (String_.Eq(name, TdbFileList.StoreTblName)) db.Files().DataObj_Rdr(rdr);
else if (String_.Eq(name, TdbTableList.StoreTableName)) db.Tables().DataObj_Rdr(rdr, db.Files());
else db.Tables().Get_by_or_fail(rdr.NameOfNode()).DataObj_Rdr(rdr);
}
if (db.Files().Count() == 0) throw Exc_.new_("fatal error: db has no files", "connectInfo", db.DbUrl());
}
DataRdr MakeDataRdr(Io_url fil) {
String text = Io_mgr.I.LoadFilStr(fil);
return TdbStores.rdr_(text);
}
public static TdbDbLoadMgr new_() {return new TdbDbLoadMgr();} TdbDbLoadMgr() {}
}

View File

@@ -0,0 +1,101 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import org.junit.*;
import gplx.stores.*; /*DsvDataRdr*/ import gplx.stores.dsvs.*; /*DsvDataWtr*/
public class TdbDbLoadMgr_tst {
@Before public void setup() {
Io_url dbInfo = Io_url_.mem_fil_("mem/dir/db0.dsv");
db = TdbDatabase.new_(dbInfo);
wtr = DsvDataWtr_.new_();
}
TdbDatabase db; TdbDbLoadMgr loadMgr = TdbDbLoadMgr.new_(); TdbDbSaveMgr saveMgr = TdbDbSaveMgr.new_();
DataRdr rdr; DataWtr wtr;
@Test public void ReadDbFiles() {
String raw = String_.Concat_lines_crlf
( "=======DIF======================, ,\" \",//"
, "_files, ,\" \",#"
, "==DEF==DIF======================, ,\" \",//"
, "int," + StringClassXtn.Key_const + "," + StringClassXtn.Key_const + ", ,\" \",$"
, "id,url,format, ,\" \",@"
, "==DATA=DIF======================, ,\" \",//"
, "1,mem/dir/db0.dsv,dsv"
, "2,C:\\file.dsv,dsv"
);
rdr = rdr_(raw);
db.Files().DataObj_Rdr(rdr);
Tfds.Eq(db.Files().Count(), 2);
TdbFile file2 = db.Files().Get_by_or_fail(2);
Tfds.Eq(file2.Path().Raw(), "C:\\file.dsv");
db.Files().DataObj_Wtr(wtr);
Tfds.Eq(wtr.XtoStr(), raw);
}
@Test public void ReadDbTbls() {
String raw = String_.Concat_lines_crlf
( "=======DIF======================, ,\" \",//"
, "_tables, ,\" \",#"
, "==DEF==DIF======================, ,\" \",//"
, "int," + StringClassXtn.Key_const + ",int, ,\" \",$"
, "id,name,file_id, ,\" \",@"
, "==DATA=DIF======================, ,\" \",//"
, "1,tbl1,1"
);
rdr = rdr_(raw);
db.Tables().DataObj_Rdr(rdr, db.Files());
Tfds.Eq(db.Tables().Count(), 1);
TdbTable table = db.Tables().Get_by_or_fail("tbl1");
Tfds.Eq(table.Name(), "tbl1");
Tfds.Eq(table.File().Id(), 1);
db.Tables().DataObj_Wtr(wtr);
Tfds.Eq(wtr.XtoStr(), raw);
}
@Test public void ReadTbl() {
String raw = String_.Concat_lines_crlf
( "=======DIF======================, ,\" \",//"
, "tbl0, ,\" \",#"
, "==DEF==DIF======================, ,\" \",//"
, "int," + StringClassXtn.Key_const + ", ,\" \",$"
, "id,name, ,\" \",@"
, "==DATA=DIF======================, ,\" \",//"
, "0,me"
);
rdr = rdr_(raw);
db.MakeTbl("tbl0", TdbFile.MainFileId);
db.Tables().Get_by_or_fail(rdr.NameOfNode()).DataObj_Rdr(rdr);
Tfds.Eq(db.Tables().Count(), 1);
TdbTable tbl = db.Tables().Get_by_or_fail("tbl0");
Tfds.Eq(tbl.Rows().Count(), 1);
GfoNde row = tbl.Rows().FetchAt_asGfoNde(0);
Tfds.Eq(row.Read("id"), 0);
Tfds.Eq(row.Read("name"), "me");
tbl.DataObj_Wtr(wtr);
Tfds.Eq(wtr.XtoStr(), raw);
}
DataRdr rdr_(String raw) {
DataRdr rdr = DsvDataRdr_.dsv_(raw);
rdr.MoveNextPeer(); // must move next as cur is not set and ReadProcs assume cur is set
return rdr;
}
}

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.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
class TdbDbSaveMgr {
public void SaveDb(TdbDatabase db) {
for (Object filObj : db.Files()) {
TdbFile fil = (TdbFile)filObj;
SaveFile(db, fil);
}
}
public void SaveFile(TdbDatabase db, TdbFile fil) {
List_adp tbls = FetchTablesWithSamePath(db, fil.Path());
boolean isSaveNeeded = db.IsNew();
for (Object tblObj : tbls) {
TdbTable tbl = (TdbTable)tblObj;
if (tbl.IsDirty()) {
isSaveNeeded = true;
break;
}
}
if (isSaveNeeded) {
SaveTblsToFile(db, fil, tbls);
db.IsNew_set(false);
}
}
void SaveTblsToFile(TdbDatabase db, TdbFile fil, List_adp tbls) {
DataWtr wtr = TdbStores.wtr_();
if (fil.Id() == TdbFile.MainFileId) { // if MainFile, save critical Files and Tables data
db.Files().DataObj_Wtr(wtr);
db.Tables().DataObj_Wtr(wtr);
}
for (Object tblObj : tbls) {
TdbTable tbl = (TdbTable)tblObj;
tbl.DataObj_Wtr(wtr);
}
Io_mgr.I.SaveFilStr(fil.Path(), wtr.XtoStr());
}
List_adp FetchTablesWithSamePath(TdbDatabase db, Io_url filPath) {
List_adp list = List_adp_.new_();
for (Object tblObj : db.Tables()) {
TdbTable tbl = (TdbTable)tblObj;
if (tbl.File().Path().Eq (filPath))
list.Add(tbl);
}
return list;
}
public static TdbDbSaveMgr new_() {return new TdbDbSaveMgr();} TdbDbSaveMgr() {}
}

View File

@@ -0,0 +1,77 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import org.junit.*;
import gplx.stores.dsvs.*; /*DsvDataWtr*/
public class TdbDbSaveMgr_tst {
@Before public void setup() {
Io_url dbInfo = Io_url_.mem_fil_("mem/dir/db0.dsv");
db = TdbDatabase.new_(dbInfo);
wtr.Clear();
} TdbDatabase db; TdbDbSaveMgr saveMgr = TdbDbSaveMgr.new_(); DataWtr wtr = DsvDataWtr_.new_();
@Test public void WriteDbFils() {
String expd = String_.Concat_lines_crlf
( ""
, ""
, "================================, ,\" \",//"
, "_files, ,\" \",#"
, "================================, ,\" \",//"
, "int," + StringClassXtn.Key_const + "," + StringClassXtn.Key_const + ", ,\" \",$"
, "id,url,format, ,\" \",@"
, "================================, ,\" \",//"
, "1,mem/dir/db0.dsv,dsv"
);
db.Files().DataObj_Wtr(wtr);
String actl = wtr.XtoStr();
Tfds.Eq(expd, actl);
}
@Test public void WriteDbTbls() {
String expd = String_.Concat_lines_crlf
( ""
, ""
, "================================, ,\" \",//"
, "_tables, ,\" \",#"
, "================================, ,\" \",//"
, "int," + StringClassXtn.Key_const + ",int, ,\" \",$"
, "id,name,file_id, ,\" \",@"
, "================================, ,\" \",//"
);
db.Tables().DataObj_Wtr(wtr);
String actl = wtr.XtoStr();
Tfds.Eq(expd, actl);
}
@Test public void WriteTbl() {
String expd = String_.Concat_lines_crlf
( ""
, ""
, "================================, ,\" \",//"
, "tbl, ,\" \",#"
, "================================, ,\" \",//"
, "int," + StringClassXtn.Key_const + ", ,\" \",$"
, "id,name, ,\" \",@"
, "================================, ,\" \",//"
);
TdbTable tbl = db.MakeTbl("tbl", TdbFile.MainFileId);
tbl.Flds().Add("id", IntClassXtn._);
tbl.Flds().Add("name", StringClassXtn._);
tbl.DataObj_Wtr(wtr);
String actl = wtr.XtoStr();
Tfds.Eq(expd, actl);
}
}

View File

@@ -0,0 +1,47 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.criterias.*; import gplx.lists.*; /*GfoNde*/ import gplx.dbs.qrys.*;
class TdbDeleteWkr implements Db_qryWkr {
public Object Exec(Db_engine engineObj, Db_qry cmdObj) {
TdbEngine engine = TdbEngine.cast_(engineObj); Db_qry_delete cmd = (Db_qry_delete)cmdObj;
TdbTable tbl = engine.FetchTbl(cmd.Base_table());
List_adp deleted = List_adp_.new_();
int rv = 0;
if (cmd.Where() == Db_qry_.WhereAll) {
rv = tbl.Rows().Count();
tbl.Rows().Clear();
}
else {
Criteria crt = cmd.Where();
for (int i = 0; i < tbl.Rows().Count(); i++) {
GfoNde row = tbl.Rows().FetchAt_asGfoNde(i);
if (crt.Matches(row))
deleted.Add(row);
}
for (int i = 0; i < deleted.Count(); i++) {
GfoNde row = (GfoNde)deleted.Get_at(i);
tbl.Rows().Del(row);
rv++;
}
}
if (rv > 0) tbl.IsDirty_set(true);
return rv;
}
public static TdbDeleteWkr new_() {TdbDeleteWkr rv = new TdbDeleteWkr(); return rv;}
}

View File

@@ -0,0 +1,90 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.dbs.qrys.*; import gplx.dbs.sqls.*;
public class TdbEngine implements Db_engine {
public String Tid() {return Tdb_conn_info.Tid_const;}
public Db_conn_info Conn_info() {return conn_info;} private Db_conn_info conn_info;
public TdbDatabase Db() {return db;} TdbDatabase db;
public void Conn_open() {
Tdb_conn_info tdb_url = (Tdb_conn_info)conn_info;
String url_str = tdb_url.Server();
db = loadMgr.LoadTbls(Io_url_.new_any_(url_str));
}
public void Conn_term() {}
public void Txn_bgn(String name) {}
public void Txn_end() {}
public void Txn_cxl() {}
public void Txn_sav() {}
public Db_engine New_clone(Db_conn_info conn_info) {
TdbEngine rv = new TdbEngine();
rv.CtorTdbEngine(conn_info);
rv.Conn_open();
return rv;
}
public Object Exec_as_obj(Db_qry qry) {
Db_qryWkr wkr = (Db_qryWkr)wkrs.Get_by_or_fail(qry.Tid());
return wkr.Exec(this, qry);
}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_sql().Parse(qry, Sql_qry_wtr_.I.Xto_str(qry, true));}
public Object New_stmt_prep_as_obj(String sql) {throw Exc_.new_unimplemented();}
public Db_rdr New_rdr__rls_manual(Object rdr_obj, String sql) {return Db_rdr_.Empty;}
public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {return Db_rdr_.Empty;}
public DataRdr New_rdr(java.sql.ResultSet rdr, String sql) {return DataRdr_.Null;}
public TdbTable FetchTbl(String name) {
TdbTable tbl = db.Tables().Get_by_or_fail(name);
if (!tbl.IsLoaded()) loadMgr.LoadTbl(db, tbl);
return tbl;
}
public void FlushAll() {
saveMgr.SaveDb(db);
}
public void FlushTbl(TdbTable tbl) {
saveMgr.SaveFile(db, tbl.File());
}
public void Ddl_create_tbl(Db_meta_tbl meta) {throw Exc_.new_unimplemented();}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Db_meta_idx... ary) {throw Exc_.new_unimplemented();}
public void Ddl_append_fld(String tbl, Db_meta_fld fld) {throw Exc_.new_unimplemented();}
public void Ddl_delete_tbl(String tbl) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public boolean Meta_tbl_exists(String name) {return false;}
public boolean Meta_fld_exists(String tbl, String fld) {return false;}
Hash_adp wkrs = Hash_adp_.new_(); TdbDbLoadMgr loadMgr = TdbDbLoadMgr.new_(); TdbDbSaveMgr saveMgr = TdbDbSaveMgr.new_();
public static final TdbEngine _ = new TdbEngine();
void CtorTdbEngine(Db_conn_info conn_info) {
this.conn_info = conn_info;
wkrs.Add(Db_qry_.Tid_select, TdbSelectWkr._);
wkrs.Add(Db_qry_.Tid_insert, TdbInsertWkr.new_());
wkrs.Add(Db_qry_.Tid_update, TdbUpdateWkr.new_());
wkrs.Add(Db_qry_.Tid_delete, TdbDeleteWkr.new_());
wkrs.Add(Db_qry_.Tid_flush, TdbFlushWkr.new_());
}
public static TdbEngine as_(Object obj) {return obj instanceof TdbEngine ? (TdbEngine)obj : null;}
public static TdbEngine cast_(Object obj) {try {return (TdbEngine)obj;} catch(Exception exc) {throw Exc_.new_type_mismatch_w_exc(exc, TdbEngine.class, obj);}}
}
interface Db_qryWkr {
Object Exec(Db_engine engine, Db_qry cmd);
}
class Db_qryWkr_ {
public static final Db_qryWkr Null = new Db_qryWrk_null();
}
class Db_qryWrk_null implements Db_qryWkr {
public Object Exec(Db_engine engine, Db_qry cmd) {return null;}
}

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.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class TdbFile {
public int Id() {return id;} int id;
public Io_url Path() {return url;} Io_url url;
public static TdbFile new_(int id, Io_url url) {
TdbFile rv = new TdbFile();
rv.id = id; rv.url = url;
return rv;
}
public static final int MainFileId = 1;
public static TdbFile as_(Object obj) {return obj instanceof TdbFile ? (TdbFile)obj : null;}
public static TdbFile cast_(Object obj) {try {return (TdbFile)obj;} catch(Exception exc) {throw Exc_.new_type_mismatch_w_exc(exc, TdbFile.class, obj);}}
}

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.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.lists.*; /*Ordered_hash_base*/ import gplx.stores.dsvs.*; /*DsvStoreLayout*/
public class TdbFileList extends Ordered_hash_base {
public TdbFile Get_by_or_fail(int id) {return TdbFile.as_(FetchOrFail_base(id));}
public void Add(TdbFile src) {Add_base(src.Id(), src);}
Io_url dbInfo;
public static TdbFileList new_(Io_url dbInfo, TdbFile mainFile) {
TdbFileList rv = new TdbFileList();
rv.dbInfo = dbInfo;
rv.Add(mainFile);
rv.layout = DsvStoreLayout.dsv_full_();
return rv;
} TdbFileList() {}
@gplx.Internal protected void DataObj_Wtr(DataWtr wtr) {
wtr.InitWtr(DsvStoreLayout.Key_const, layout);
wtr.WriteTableBgn(StoreTblName, FldList);
for (Object filObj : this) {
TdbFile fil = (TdbFile)filObj;
wtr.WriteLeafBgn("fil");
wtr.WriteData(Fld_id, fil.Id());
wtr.WriteData(Fld_path, fil.Path());
wtr.WriteData("format", "dsv");
wtr.WriteLeafEnd();
}
wtr.WriteNodeEnd();
}
@gplx.Internal protected void DataObj_Rdr(DataRdr rdr) {
layout = TdbStores.FetchLayout(rdr);
this.Clear();
DataRdr subRdr = rdr.Subs();
while (subRdr.MoveNextPeer()) {
int id = subRdr.ReadInt(Fld_id);
String url = subRdr.ReadStrOr(Fld_path, dbInfo.Raw());
TdbFile file = (id == TdbFile.MainFileId)
? TdbFile.new_(TdbFile.MainFileId, dbInfo) // not redundant; prevents error of MainFile in different url/format than connectInfo
: TdbFile.new_(id, Io_url_.new_any_(url));
this.Add(file);
}
}
DsvStoreLayout layout;
public static final String StoreTblName = "_files";
static final String Fld_id = "id"; static final String Fld_path = "url";
static final GfoFldList FldList = GfoFldList_.new_().Add(Fld_id, IntClassXtn._).Add(Fld_path, StringClassXtn._).Add("format", StringClassXtn._);
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.lists.*; /*GfoNde*/ import gplx.dbs.qrys.*;
class TdbFlushWkr implements Db_qryWkr {
public Object Exec(Db_engine engineObj, Db_qry cmdObj) {
TdbEngine engine = TdbEngine.cast_(engineObj); Db_qry_flush cmd = Db_qry_flush.cast_(cmdObj);
if (Array_.Len(cmd.TableNames()) == 0)
engine.FlushAll();
else {
for (String tblName : cmd.TableNames()) {
TdbTable tbl = engine.FetchTbl(tblName);
if (tbl.IsDirty()) engine.FlushTbl(tbl);
}
}
return 1;
}
public static TdbFlushWkr new_() {TdbFlushWkr rv = new TdbFlushWkr(); return rv;}
}

View File

@@ -0,0 +1,119 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import org.junit.*;
import gplx.ios.*; /*IoMgrFxt*/ import gplx.dbs.qrys.*;
public class TdbFlush_tst {
@Before public void setup() {
Io_mgr.I.InitEngine_mem();
engine = fx_engine.run_MakeEngine(dbPath);
}
TdbEngine engine; Io_url dbPath = Io_url_.mem_fil_("mem/dir/db0.dsv"); DateAdp time = DateAdp_.parse_gplx("2001-01-01");
TdbEngineFxt fx_engine = TdbEngineFxt.new_(); IoMgrFxt fx_io = IoMgrFxt.new_();
@Test public void FlushNewDb() {
fx_engine.tst_FilesCount(engine, 1);
fx_engine.tst_File(engine, 0, TdbFile.MainFileId, Io_url_.mem_fil_("mem/dir/db0.dsv"), "dsv");
fx_io.tst_Exists(false, dbPath);
engine.FlushAll();
fx_io.tst_Exists(true, dbPath);
}
@Test public void IgnoreFlushedDb() {
engine.FlushAll();
fx_io.tst_Exists(true, dbPath);
fx_io.run_UpdateFilModifiedTime(dbPath, time);
engine.FlushAll();
fx_io.tst_QueryFilModified(true, dbPath, time);
}
@Test public void FlushNewTbl() {
engine.FlushAll();
fx_engine.run_MakeTbl(engine, "tbl0", TdbFile.MainFileId);
fx_io.run_UpdateFilModifiedTime(dbPath, time);
engine.FlushAll();
fx_io.tst_QueryFilModified(false, dbPath, time);
}
@Test public void IgnoreFlushedTbl() {
fx_engine.run_MakeTbl(engine, "tbl0", TdbFile.MainFileId);
engine.FlushAll();
fx_io.run_UpdateFilModifiedTime(dbPath, time);
engine.FlushAll();
fx_io.tst_QueryFilModified(true, dbPath, time);
}
@Test public void FlushDirtyTbl() {
fx_engine.run_MakeTbl(engine, "tbl0", TdbFile.MainFileId);
engine.FlushAll();
fx_io.run_UpdateFilModifiedTime(dbPath, time);
fx_engine.run_InsertRow(engine, "tbl0", 1);
engine.FlushAll();
fx_io.tst_QueryFilModified(false, dbPath, time);
}
@Test public void FlushDirtyFilOnly() {
Io_url dbPathOther = Io_url_.mem_fil_("mem/dir/db1.dsv");
TdbFile filOther = fx_engine.run_MakeFile(engine, dbPathOther); Tfds.Eq(false, Object_.Eq(filOther.Id(), TdbFile.MainFileId));
fx_engine.run_MakeTbl(engine, "tbl0", TdbFile.MainFileId); fx_engine.run_MakeTbl(engine, "tbl1", filOther.Id());
engine.FlushAll();
fx_io.run_UpdateFilModifiedTime(dbPath, time); fx_io.run_UpdateFilModifiedTime(dbPathOther, time);
fx_engine.run_InsertRow(engine, "tbl1", 1);
engine.FlushAll();
fx_io.tst_QueryFilModified(true, dbPath, time);
fx_io.tst_QueryFilModified(false, dbPathOther, time);
}
}
class TdbEngineFxt {
public TdbEngine run_MakeEngine(Io_url url) {
Db_conn_info connectInfo = Db_conn_info_.tdb_(url);
TdbEngine engine = (TdbEngine)TdbEngine._.New_clone(connectInfo);
engine.Conn_open();
return engine;
}
public TdbFile run_MakeFile(TdbEngine engine, Io_url url) {return engine.Db().MakeFile(url);}
public TdbTable run_MakeTbl(TdbEngine engine, String tblName, int srcId) {
TdbTable rv = engine.Db().MakeTbl(tblName, srcId);
rv.Flds().Add("id", IntClassXtn._);
return rv;
}
public void run_InsertRow(TdbEngine engine, String tblName, int idVal) {
Db_qry_insert cmd = new Db_qry_insert(tblName);
cmd.Arg_("id", idVal);
engine.Exec_as_obj(cmd);
}
public void tst_FilesCount(TdbEngine engine, int count) {Tfds.Eq(engine.Db().Files().Count(), count);}
public void tst_File(TdbEngine engine, int index, int id, Io_url url, String format) {
TdbFile src = engine.Db().Files().Get_by_or_fail(id);
Tfds.Eq(src.Path().Raw(), url.Raw());
}
public static TdbEngineFxt new_() {return new TdbEngineFxt();} TdbEngineFxt() {}
}
class IoMgrFxt {
public void run_UpdateFilModifiedTime(Io_url url, DateAdp val) {Io_mgr.I.UpdateFilModifiedTime(url, val);}
public void tst_QueryFilModified(boolean expdMatch, Io_url url, DateAdp expt) {
IoItmFil filItem = Io_mgr.I.QueryFil(url);
DateAdp actl = filItem.ModifiedTime();
boolean actlMatch = String_.Eq(expt.XtoStr_gplx(), actl.XtoStr_gplx());
Tfds.Eq(expdMatch, actlMatch, expt.XtoStr_gplx() + (expdMatch ? "!=" : "==") + actl.XtoStr_gplx());
}
public void tst_Exists(boolean expd, Io_url url) {Tfds.Eq(expd, Io_mgr.I.ExistsFil(url));}
public static IoMgrFxt new_() {return new IoMgrFxt();} IoMgrFxt() {}
}

View File

@@ -0,0 +1,59 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.lists.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*;
class TdbInsertWkr implements Db_qryWkr {
public Object Exec(Db_engine engineObj, Db_qry cmdObj) {
TdbEngine engine = TdbEngine.cast_(engineObj); Db_qry_insert cmd = (Db_qry_insert)cmdObj;
TdbTable tbl = engine.FetchTbl(cmd.Base_table());
tbl.IsDirty_set(true);
return cmd.Select() == null
? InsertRowsByVals(engine, tbl, cmd)
: InsertRowsBySelect(engine, tbl, cmd);
}
int InsertRowsBySelect(TdbEngine engine, TdbTable tbl, Db_qry_insert insert) {
int count = 0;
DataRdr rdr = (DataRdr)TdbSelectWkr._.Exec(engine, insert.Select());
Sql_select_fld_list insertFlds = insert.Cols(); int insertFldsCount = insertFlds.Count();
GfoFldList selectFldsForNewRow = null;
try {selectFldsForNewRow = insertFlds.XtoGfoFldLst(tbl);}
catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to generate flds for new row");}
if (insertFldsCount > selectFldsForNewRow.Count()) throw Exc_.new_("insert flds cannot exceed selectFlds", "insertFlds", insertFlds.XtoStr(), "selectFlds", selectFldsForNewRow.XtoStr());
while (rdr.MoveNextPeer()) {
count++;
GfoNde row = GfoNde_.vals_(selectFldsForNewRow, new Object[insertFldsCount]);
for (int i = 0; i < insertFldsCount; i++) {
row.WriteAt(i, rdr.ReadAt(i)); // NOTE: SELECT and INSERT flds are in same order; ex: INSERT INTO (a, b) SELECT (b, a)
}
tbl.Rows().Add(row);
}
return count;
}
int InsertRowsByVals(TdbEngine engine, TdbTable tbl, Db_qry_insert insert) {
GfoNde row = GfoNde_.vals_(tbl.Flds(), new Object[tbl.Flds().Count()]);
for (int i = 0; i < insert.Args().Count(); i++) {
KeyVal kv = insert.Args().Get_at(i);
Db_arg arg = (Db_arg)kv.Val();
row.Write(kv.Key(), arg.Val());
}
tbl.Rows().Add(row);
return 1;
}
public static TdbInsertWkr new_() {TdbInsertWkr rv = new TdbInsertWkr(); return rv;}
}

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.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.criterias.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*;
import gplx.lists.*; /*ComparerAble*/ import gplx.stores.*; /*GfoNdeRdr*/
class TdbSelectWkr implements Db_qryWkr {
public Object Exec(Db_engine engineObj, Db_qry cmdObj) {
TdbEngine engine = TdbEngine.cast_(engineObj); Db_qry__select_cmd cmd = (Db_qry__select_cmd)cmdObj;
if (cmd.From().Tbls().Count() > 1) throw Exc_.new_w_type("gplx.tdbs", "joins not supported for tdbs", "sql", cmd.Xto_sql());
TdbTable tbl = engine.FetchTbl(cmd.From().BaseTable().TblName());
GfoNdeList rv = (cmd.Where() == Db_qry_.WhereAll && cmd.Limit() == Db_qry__select_cmd.Limit_disabled) ? rv = tbl.Rows() : FilterRecords(tbl, cmd.Where(), cmd.Limit());
if (cmd.GroupBy() != null)
rv = TdbGroupByWkr.GroupByExec(cmd, rv, tbl);
if (cmd.OrderBy() != null) { // don't use null pattern here; if null ORDER BY, then don't call .Sort on GfoNdeList
ComparerAble comparer = Sql_order_by_sorter.new_((Sql_order_by_itm[])cmd.OrderBy().Flds().To_ary(Sql_order_by_itm.class));
rv.Sort_by(comparer);
}
return GfoNdeRdr_.peers_(rv, false);
}
GfoNdeList FilterRecords(TdbTable tbl, Criteria crt, int limit) {
GfoNdeList rv = GfoNdeList_.new_();
int count = 0;
for (int i = 0; i < tbl.Rows().Count(); i++) {
GfoNde row = (GfoNde)tbl.Rows().FetchAt_asGfoNde(i);
if (crt.Matches(row)) rv.Add(row);
++count;
if (count == limit) break;
}
return rv;
}
public static final TdbSelectWkr _ = new TdbSelectWkr(); TdbSelectWkr() {}
}
class TdbGroupByWkr {
public static GfoNdeList GroupByExec(Db_qry__select_cmd select, GfoNdeList selectRows, TdbTable tbl) {
GfoNdeList rv = GfoNdeList_.new_();
Ordered_hash groupByHash = Ordered_hash_.new_();
List_adp groupByFlds = select.GroupBy().Flds();
GfoFldList selectFldsForNewRow = select.Cols().Flds().XtoGfoFldLst(tbl);
Sql_select_fld_list selectFlds = select.Cols().Flds();
for (int rowIdx = 0; rowIdx < selectRows.Count(); rowIdx++) {
GfoNde selectRow = selectRows.FetchAt_asGfoNde(rowIdx);
GfoNde groupByRow = FindOrNew(selectFldsForNewRow, groupByFlds, selectRow, groupByHash, rv);
for (int i = 0; i < selectFlds.Count(); i++) {
Sql_select_fld_base selectFld = selectFlds.Get_at(i);
Object val = groupByRow.Read(selectFld.Alias()); // groupByRow is keyed by Alias; EX: Count(Id) AS CountOf
groupByRow.WriteAt(i, selectFld.GroupBy_eval(val, selectRow.Read(selectFld.Fld()), selectFld.ValType()));
}
}
return rv;
}
static GfoNde FindOrNew(GfoFldList selectFldsForNewRow, List_adp groupByFlds, GfoNde selectRow, Ordered_hash groupByRows, GfoNdeList rslt) {
int len = groupByFlds.Count();
Ordered_hash curHash = groupByRows;
GfoNde rv = null;
for (int i = 0; i < len; i++) {
String fld = (String)groupByFlds.Get_at(i);
boolean last = i == len - 1;
Object val = selectRow.Read(fld);
Object o = curHash.Get_by(val);
if (last) {
if (o == null) {
Object[] valAry = new Object[selectFldsForNewRow.Count()];
rv = GfoNde_.vals_(selectFldsForNewRow, valAry);
curHash.Add(val, rv);
rslt.Add(rv);
}
else
rv = GfoNde_.as_(o);
}
else {
if (o == null) {
Ordered_hash nextHash = Ordered_hash_.new_();
curHash.Add(val, nextHash);
curHash = nextHash;
}
else {
curHash = (Ordered_hash)o;
}
}
}
return rv;
}
}

View File

@@ -0,0 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.stores.*;
import gplx.stores.xmls.*; /*XmlDataRdr*/
import gplx.stores.dsvs.*; /*DsvDataWtr*/
import gplx.lists.*; /*GfoNdeRdr*/
class TdbStores {
public static final String Dsv = "dsv";
public static final String Xml = "xml";
public static DataRdr rdr_(String text) {return DsvDataRdr_.dsv_(text);}
public static DataWtr wtr_() {return DsvDataWtr_.new_();}
@gplx.Internal protected static DsvStoreLayout FetchLayout(DataRdr rdr) {
GfoNdeRdr ndeRdr = GfoNdeRdr_.as_(rdr); if (ndeRdr == null) return null; // can happen for non-Dsv Rdrs (ex: Xml)
return DsvStoreLayout.as_(ndeRdr.UnderNde().EnvVars().Get_by(DsvStoreLayout.Key_const));
}
}

View File

@@ -0,0 +1,65 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.*; /*GfoNdeList*/ import gplx.stores.*; import gplx.stores.dsvs.*; /*DsvStoreLayout*/
public class TdbTable {
public int Id() {return id;} int id;
public String Name() {return name;} private String name;
public GfoFldList Flds() {return flds;} GfoFldList flds = GfoFldList_.new_();
public GfoNdeList Rows() {return rows;} GfoNdeList rows = GfoNdeList_.new_();
@gplx.Internal protected TdbFile File() {return file;} TdbFile file;
@gplx.Internal protected boolean IsLoaded() {return isLoaded;} private boolean isLoaded = true;
@gplx.Internal protected boolean IsDirty() {return isDirty;} public void IsDirty_set(boolean v) {isDirty = v;} private boolean isDirty = false;
public static TdbTable new_(int id, String name, TdbFile file) {TdbTable rv = new TdbTable(); rv.ctor(id, name, file); rv.isDirty = true; return rv;} TdbTable() {}
public static TdbTable load_(int id, String name, TdbFile file) {TdbTable rv = new TdbTable(); rv.ctor(id, name, file); rv.isLoaded = false; return rv;}
void ctor(int id, String name, TdbFile file) {
this.id = id; this.name = name; this.file = file;
layout = DsvStoreLayout.dsv_full_();
}
@gplx.Internal protected void DataObj_Wtr(DataWtr wtr) {
wtr.InitWtr(DsvStoreLayout.Key_const, layout);
wtr.WriteTableBgn(name, flds);
for (int rowIdx = 0; rowIdx < rows.Count(); rowIdx++) {
GfoNde drow = rows.FetchAt_asGfoNde(rowIdx);
wtr.WriteLeafBgn("row");
for (int i = 0; i < drow.Flds().Count(); i++)
wtr.WriteData(drow.Flds().Get_at(i).Key(), drow.ReadAt(i));
wtr.WriteLeafEnd();
}
wtr.WriteNodeEnd();
isDirty = false;
}
@gplx.Internal protected void DataObj_Rdr(DataRdr rdr) {
layout = TdbStores.FetchLayout(rdr);
GfoNdeRdr ndeRdr = GfoNdeRdr_.as_(rdr );
if (ndeRdr != null) {
if (ndeRdr.UnderNde() == null) throw Exc_.new_("ndeRdr.UnderNde is null", "name", rdr.NameOfNode());
rows = ndeRdr.UnderNde().Subs();
flds = ndeRdr.UnderNde().SubFlds();
}
else { // XmlRdr needs to load each row again...
throw Exc_.new_invalid_op("TableLoad not implemented").Args_add("rdrType", ClassAdp_.NameOf_obj(rdr), "rdrName", rdr.NameOfNode());
}
isLoaded = true;
}
DsvStoreLayout layout;
public static TdbTable as_(Object obj) {return obj instanceof TdbTable ? (TdbTable)obj : null;}
public static TdbTable cast_(Object obj) {try {return (TdbTable)obj;} catch(Exception exc) {throw Exc_.new_type_mismatch_w_exc(exc, TdbTable.class, obj);}}
}

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.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.lists.*; /*Ordered_hash_base*/ import gplx.stores.dsvs.*; /*DsvStoreLayout*/
public class TdbTableList extends Ordered_hash_base {
public TdbTable Get_by(String name) {return TdbTable.as_(Fetch_base(name));}
public TdbTable Get_by_or_fail(String name) {
TdbTable rv = TdbTable.as_(Get_by(name)); if (rv == null) throw Exc_.new_("could not find table; database file may not exist", "table", name);
return rv;
}
public void Add(TdbTable dataTable) {Add_base(dataTable.Name(), dataTable);}
public static TdbTableList new_(Io_url dbInfo) {
TdbTableList rv = new TdbTableList();
rv.layout = DsvStoreLayout.dsv_full_();
return rv;
}
@gplx.Internal protected void DataObj_Wtr(DataWtr wtr) {
wtr.InitWtr(DsvStoreLayout.Key_const, layout);
wtr.WriteTableBgn(StoreTableName, FldList);
for (Object tblObj : this) {
TdbTable tbl = (TdbTable)tblObj;
wtr.WriteLeafBgn("tbl");
wtr.WriteData(Fld_id, tbl.Id());
wtr.WriteData(Fld_name, tbl.Name());
wtr.WriteData(Fld_file_id, tbl.File().Id());
wtr.WriteLeafEnd();
}
wtr.WriteNodeEnd();
}
@gplx.Internal protected void DataObj_Rdr(DataRdr rdr, TdbFileList files) {
layout = TdbStores.FetchLayout(rdr);
DataRdr subRdr = rdr.Subs();
this.Clear();
while (subRdr.MoveNextPeer()) {
int id = subRdr.ReadInt(Fld_id);
String name = subRdr.ReadStr(Fld_name);
int file_id = subRdr.ReadInt(Fld_file_id);
TdbFile file = files.Get_by_or_fail(file_id);
TdbTable table = TdbTable.load_(id, name, file);
this.Add(table);
}
}
DsvStoreLayout layout;
public static final String StoreTableName = "_tables";
static final String Fld_id = "id"; static final String Fld_name = "name"; static final String Fld_file_id = "file_id";
static final GfoFldList FldList = GfoFldList_.new_().Add(Fld_id, IntClassXtn._).Add(Fld_name, StringClassXtn._).Add(Fld_file_id, IntClassXtn._);
}

View File

@@ -0,0 +1,46 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.criterias.*; import gplx.lists.*; /*GfoNde*/
import gplx.dbs.qrys.*;
class TdbUpdateWkr implements Db_qryWkr {
public Object Exec(Db_engine engineObj, Db_qry cmdObj) {
TdbEngine engine = TdbEngine.cast_(engineObj); Db_qry_update cmd = (Db_qry_update)cmdObj;
int rv = 0;
TdbTable tbl = engine.FetchTbl(cmd.Base_table());
Criteria crt = cmd.Where();
for (int i = 0; i < tbl.Rows().Count(); i++) {
GfoNde row = (GfoNde)tbl.Rows().FetchAt_asGfoNde(i);
if (crt.Matches(row)) {
UpdateRow(cmd, row);
rv++;
}
}
if (rv > 0) tbl.IsDirty_set(true);
return rv;
}
void UpdateRow(Db_qry_update cmd, GfoNde row) {
for (int i = 0; i < cmd.Args().Count(); i++) {
KeyVal p = (KeyVal)cmd.Args().Get_at(i);
Db_arg prm = (Db_arg)p.Val();
row.Write(p.Key(), prm.Val());
}
}
public static TdbUpdateWkr new_() {TdbUpdateWkr rv = new TdbUpdateWkr(); return rv;}
}

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.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Tdb_conn_info extends Db_conn_info__base {
public Io_url Url() {return url;} Io_url url;
@Override public String Tid() {return Tid_const;} public static final String Tid_const = "tdb";
public static Db_conn_info new_(Io_url url) {
return Db_conn_info_.parse_(Bld_raw
( "gplx_key", Tid_const
, "url", url.Raw()
));
} Tdb_conn_info() {}
@Override public Db_conn_info New_self(String raw, GfoMsg m) {
Tdb_conn_info rv = new Tdb_conn_info();
String urlStr = m.ReadStr("url");
Io_url url = Io_url_.new_any_(urlStr);
rv.Ctor(urlStr, url.NameOnly(), raw, BldApi(m));
rv.url = url;
return rv;
}
public static final Tdb_conn_info _ = new Tdb_conn_info();
}

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

View File

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

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.metas; import gplx.*; import gplx.dbs.*;
public class Meta_idx_itm {
public Meta_idx_itm(String name, String sql) {this.name = name; this.sql = sql;}
public String Name() {return name;} private final String name;
public String Sql() {return sql;} private final String sql;
}

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.metas; import gplx.*; import gplx.dbs.*;
public class Meta_idx_mgr {
private final Ordered_hash hash = Ordered_hash_.new_();
public void Add(Meta_idx_itm itm) {hash.Add(itm.Name(), itm);}
public boolean Has(String name) {return hash.Has(name);}
public Meta_idx_itm Get(String name) {return (Meta_idx_itm)hash.Get_by(name);}
}

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.metas; import gplx.*; import gplx.dbs.*;
public class Meta_itm_tid {
public static final int Tid_unknown = 0, Tid_table = 1, Tid_index = 2;
public static final String Key_table = "table", Key_index = "index";
public static int Xto_int(String s) {
s = String_.Lower(s);
if (String_.Eq(s, Key_table)) return Tid_table;
else if (String_.Eq(s, Key_index)) return Tid_index;
else return Tid_unknown;
}
}

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.metas; import gplx.*; import gplx.dbs.*;
public class Meta_tbl_itm {
public Meta_tbl_itm(String name, String sql) {this.name = name; this.sql = sql;}
public Meta_fld_mgr Flds() {return flds;} private final Meta_fld_mgr flds = new Meta_fld_mgr();
public String Name() {return name;} private final String name;
public String Sql() {return sql;} private final String sql;
}

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.metas; import gplx.*; import gplx.dbs.*;
public class Meta_tbl_mgr {
private final Ordered_hash hash = Ordered_hash_.new_();
public void Add(Meta_tbl_itm itm) {hash.Add(itm.Name(), itm);}
public boolean Has(String name) {return hash.Has(name);}
public Meta_tbl_itm Get_by(String name) {return (Meta_tbl_itm)hash.Get_by(name);}
}

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

View File

@@ -0,0 +1,117 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*; import gplx.core.btries.*;
abstract class Meta_fld_wkr__base {
private byte[] hook;
private byte[][] words_ary; private int words_len;
@gplx.Virtual public int Tid() {return Tid_other;}
public void Ctor(byte[] hook, byte[]... words_ary) {
this.hook = hook;
this.words_ary = words_ary;
this.words_len = words_ary.length;
}
public void Reg(Btrie_slim_mgr trie) {
trie.Add_obj(hook, this);
}
@gplx.Virtual public void Match(Bry_rdr rdr, Meta_fld_itm fld) {
for (int i = 0; i < words_len; ++i) {
rdr.Skip_ws();
byte[] word = words_ary[i];
rdr.Chk_bry_or_fail(word);
}
When_match(fld);
}
protected abstract void When_match(Meta_fld_itm fld);
public static final int Tid_end_comma = 1, Tid_end_paren = 2, Tid_other = 3;
}
class Meta_fld_wkr__end_comma extends Meta_fld_wkr__base {
public Meta_fld_wkr__end_comma() {this.Ctor(Hook);}
@Override public int Tid() {return Tid_end_comma;}
@Override protected void When_match(Meta_fld_itm fld) {}
private static final byte[] Hook = Bry_.new_a7(",");
public static final Meta_fld_wkr__end_comma I = new Meta_fld_wkr__end_comma();
}
class Meta_fld_wkr__end_paren extends Meta_fld_wkr__base {
public Meta_fld_wkr__end_paren() {this.Ctor(Hook);}
@Override public int Tid() {return Tid_end_paren;}
@Override protected void When_match(Meta_fld_itm fld) {}
private static final byte[] Hook = Bry_.new_a7(")");
public static final Meta_fld_wkr__end_paren I = new Meta_fld_wkr__end_paren();
}
class Meta_fld_wkr__nullable_null extends Meta_fld_wkr__base {
public Meta_fld_wkr__nullable_null() {this.Ctor(Hook);}
@Override protected void When_match(Meta_fld_itm fld) {
fld.Nullable_tid_(Meta_fld_itm.Nullable_null);
}
private static final byte[] Hook = Bry_.new_a7("null");
public static final Meta_fld_wkr__nullable_null I = new Meta_fld_wkr__nullable_null();
}
class Meta_fld_wkr__nullable_not extends Meta_fld_wkr__base {
public Meta_fld_wkr__nullable_not() {this.Ctor(Hook, Bry_null);}
@Override protected void When_match(Meta_fld_itm fld) {
fld.Nullable_tid_(Meta_fld_itm.Nullable_not_null);
}
private static final byte[] Hook = Bry_.new_a7("not"), Bry_null = Bry_.new_a7("null");
public static final Meta_fld_wkr__nullable_not I = new Meta_fld_wkr__nullable_not();
}
class Meta_fld_wkr__primary_key extends Meta_fld_wkr__base {
public Meta_fld_wkr__primary_key() {this.Ctor(Hook, Bry_key);}
@Override protected void When_match(Meta_fld_itm fld) {
fld.Primary_key_y_();
}
private static final byte[] Hook = Bry_.new_a7("primary"), Bry_key = Bry_.new_a7("key");
public static final Meta_fld_wkr__primary_key I = new Meta_fld_wkr__primary_key();
}
class Meta_fld_wkr__autonumber extends Meta_fld_wkr__base {
public Meta_fld_wkr__autonumber() {this.Ctor(Hook);}
@Override protected void When_match(Meta_fld_itm fld) {
fld.Autonumber_y_();
}
private static final byte[] Hook = Bry_.new_a7("autoincrement");
public static final Meta_fld_wkr__autonumber I = new Meta_fld_wkr__autonumber();
}
class Meta_fld_wkr__default extends Meta_fld_wkr__base {
public Meta_fld_wkr__default() {this.Ctor(Hook);}
@Override public void Match(Bry_rdr rdr, Meta_fld_itm fld) {
Object default_val = null;
rdr.Skip_ws();
byte[] src = rdr.Src();
byte b = src[rdr.Pos()];
switch (b) {
case Byte_ascii.Quote:
case Byte_ascii.Apos:
int bgn_pos = rdr.Pos() + 1;
int end_pos = Bry_finder.Find_fwd(src, b, bgn_pos); if (end_pos == Bry_finder.Not_found) throw Exc_.new_("unclosed quote", "snip", rdr.Mid_by_len_safe(40));
default_val = Bry_.Mid(src, bgn_pos, end_pos);
rdr.Pos_(end_pos + 1);
break;
case Byte_ascii.Dash:
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
default_val = rdr.Read_int_to_non_num();
break;
default:
throw Exc_.new_("invalid field_default", "snip", rdr.Mid_by_len_safe(40));
}
fld.Default_val_(default_val);
}
@Override protected void When_match(Meta_fld_itm fld) {}
private static final byte[] Hook = Bry_.new_a7("default");
public static final Meta_fld_wkr__default I = new Meta_fld_wkr__default();
}

View File

@@ -0,0 +1,118 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*; import gplx.core.btries.*;
public class Meta_parser__fld {
public Meta_type_itm Parse_type(Bry_rdr rdr) {
rdr.Skip_ws();
Object type_obj = type_trie.Match_bgn(rdr.Src(), rdr.Pos(), rdr.Src_len());
if (type_obj == null) throw Exc_.new_("invalid fld type", "snip", rdr.Mid_by_len_safe(40));
Meta_parser__fld_itm type_itm = (Meta_parser__fld_itm)type_obj;
rdr.Pos_add(type_itm.Word().length);
int paren_itms_count = type_itm.Paren_itms_count();
int len_1 = Int_.MinValue, len_2 = Int_.MinValue;
if (paren_itms_count > 0) {
rdr.Skip_ws().Chk_byte_or_fail(Byte_ascii.Paren_bgn);
len_1 = rdr.Skip_ws().Read_int_to_non_num(); if (len_1 == Int_.MinValue) throw Exc_.new_("invalid fld len_1", "snip", rdr.Mid_by_len_safe(40));
if (paren_itms_count == 2) {
rdr.Skip_ws().Chk_byte_or_fail(Byte_ascii.Comma);
len_2 = rdr.Skip_ws().Read_int_to_non_num(); if (len_2 == Int_.MinValue) throw Exc_.new_("invalid fld len_2", "snip", rdr.Mid_by_len_safe(40));
}
rdr.Skip_ws().Chk_byte_or_fail(Byte_ascii.Paren_end);
}
return new Meta_type_itm(type_itm.Tid_ansi(), type_itm.Tid_sqlite(), type_itm.Word(), len_1, len_2);
}
public Meta_fld_itm Parse_fld(Sql_bry_rdr rdr) { // starts after "(" or ","; EX: "(fld1 int", ", fld2 int"; ends at ")"
byte[] name = rdr.Read_sql_identifier();
Meta_type_itm type = this.Parse_type(rdr);
Meta_fld_itm fld = new Meta_fld_itm(String_.new_u8(name), type);
byte[] src = rdr.Src(); int src_len = rdr.Src_len();
while (true) {
rdr.Skip_ws();
if (rdr.Pos() == src_len) return fld; // eos
switch (src[rdr.Pos()]) {
case Byte_ascii.Comma: return fld;
case Byte_ascii.Paren_end: return fld;
}
Object type_obj = fld_trie.Match_bgn(src, rdr.Pos(), src_len); if (type_obj == null) throw Exc_.new_("invalid", "snip", rdr.Mid_by_len_safe(40));
Meta_fld_wkr__base type_wkr = (Meta_fld_wkr__base)type_obj;
switch (type_wkr.Tid()) {
case Meta_fld_wkr__base.Tid_end_comma:
case Meta_fld_wkr__base.Tid_end_paren: return fld;
default:
rdr.Pos_(fld_trie.Match_pos());
type_wkr.Match(rdr, fld);
break;
}
}
// return fld; // NOTE: will happen for tests; EX: "fld_1 int" vs "fld_1 int,"
}
private static final Btrie_slim_mgr fld_trie = fld_trie_init
( Meta_fld_wkr__nullable_null.I
, Meta_fld_wkr__nullable_not.I
, Meta_fld_wkr__autonumber.I
, Meta_fld_wkr__primary_key.I
, Meta_fld_wkr__default.I
);
private static Btrie_slim_mgr fld_trie_init(Meta_fld_wkr__base... wkrs) {
Btrie_slim_mgr rv = Btrie_slim_mgr.ci_ascii_();
for (Meta_fld_wkr__base wkr : wkrs)
wkr.Reg(rv);
return rv;
}
private static final Btrie_slim_mgr type_trie = type_trie_init();
private static Btrie_slim_mgr type_trie_init() {
Btrie_slim_mgr rv = Btrie_slim_mgr.ci_ascii_();
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_byte , Sqlite_tid.Tid_int , 0, "tinyint", "int2");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_short , Sqlite_tid.Tid_int , 0, "smallint");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_int , Sqlite_tid.Tid_int , 0, "int", "integer", "mediumint");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_long , Sqlite_tid.Tid_int , 0, "bigint", "int8"); // "UNSIGNED BIG INT"
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_str , Sqlite_tid.Tid_text , 1, "character", "varchar", "nchar"); // "varying character", "native character"
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_text , Sqlite_tid.Tid_text , 0, "text", "clob");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_bry , Sqlite_tid.Tid_none , 0, "blob");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_float , Sqlite_tid.Tid_real , 0, "float");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_double , Sqlite_tid.Tid_real , 0, "real", "double"); // "double precision"
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_decimal , Sqlite_tid.Tid_numeric , 0, "numeric");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_decimal , Sqlite_tid.Tid_numeric , 2, "decimal");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_decimal , Sqlite_tid.Tid_numeric , 2, "decimal");
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_bool , Sqlite_tid.Tid_numeric , 0, "boolean", "bit"); // "bit" is not SQLITE
Meta_parser__fld_itm.reg_many(rv, Db_meta_fld.Tid_date , Sqlite_tid.Tid_numeric , 0, "date", "datetime");
return rv;
}
}
class Meta_parser__fld_itm {
public Meta_parser__fld_itm(int tid_ansi, int tid_sqlite, byte[] word, int paren_itms_count) {
this.tid_ansi = tid_ansi; this.tid_sqlite = tid_sqlite;
this.word = word; this.paren_itms_count = paren_itms_count;
}
public int Tid_ansi() {return tid_ansi;} private final int tid_ansi;
public int Tid_sqlite() {return tid_sqlite;} private final int tid_sqlite;
public byte[] Word() {return word;} private final byte[] word;
public int Paren_itms_count() {return paren_itms_count;} private final int paren_itms_count;
public static void reg_many(Btrie_slim_mgr trie, int tid_ansi, int tid_sqlite, int paren_itms_count, String... names_str) {
int len = names_str.length;
for (int i = 0; i < len; ++i) {
byte[] name_bry = Bry_.new_a7(names_str[i]);
Meta_parser__fld_itm itm = new Meta_parser__fld_itm(tid_ansi, tid_sqlite, name_bry, paren_itms_count);
trie.Add_obj(name_bry, itm);
}
}
}
class Sqlite_tid {
public static final int Tid_int = 1, Tid_text = 2, Tid_none = 3, Tid_real = 4, Tid_numeric = 5;
}

View File

@@ -0,0 +1,71 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import org.junit.*;
public class Meta_parser__fld_tst {
@Before public void init() {fxt.Clear();} private Meta_parser__fld_fxt fxt = new Meta_parser__fld_fxt();
@Test public void Parse_type() {
fxt.Test_parse_type("int" , fxt.Make_type(Db_meta_fld.Tid_int));
fxt.Test_parse_type("varchar(255)" , fxt.Make_type(Db_meta_fld.Tid_str, 255));
fxt.Test_parse_type("decimal(12,10)" , fxt.Make_type(Db_meta_fld.Tid_decimal, 12, 10));
fxt.Test_parse_type(" int" , fxt.Make_type(Db_meta_fld.Tid_int));
fxt.Test_parse_type(" decimal ( 12 , 10 )" , fxt.Make_type(Db_meta_fld.Tid_decimal, 12, 10));
}
@Test public void Parse_fld() {
fxt.Test_parse_fld("name_1 int" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_unknown));
fxt.Test_parse_fld("name_1 int null" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_null));
fxt.Test_parse_fld("name_1 int not null" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null));
fxt.Test_parse_fld("name_1 int not null autoincrement" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null, Bool_.N, Bool_.Y));
fxt.Test_parse_fld("name_1 int not null primary key" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null, Bool_.Y, Bool_.N));
fxt.Test_parse_fld("name_1 int not null default -1" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null, Bool_.Y, Bool_.N, -1));
fxt.Test_parse_fld("name_1 int not null default 'abc'" , fxt.Make_fld("name_1", Db_meta_fld.Tid_int, Meta_fld_itm.Nullable_not_null, Bool_.Y, Bool_.N, "abc"));
}
}
class Meta_parser__fld_fxt {
private final Meta_parser__fld fld_parser = new Meta_parser__fld();
private final Sql_bry_rdr rdr = new Sql_bry_rdr();
public void Clear() {}
public Meta_type_itm Make_type(int tid_ansi) {return new Meta_type_itm(tid_ansi, -1, null, Int_.MinValue, Int_.MinValue);}
public Meta_type_itm Make_type(int tid_ansi, int len_1) {return new Meta_type_itm(tid_ansi, -1, null, len_1, Int_.MinValue);}
public Meta_type_itm Make_type(int tid_ansi, int len_1, int len_2) {return new Meta_type_itm(tid_ansi, -1, null, len_1, len_2);}
public Meta_fld_itm Make_fld(String name, int tid_ansi, int nullable) {return Make_fld(name, tid_ansi, nullable, false, false, null);}
public Meta_fld_itm Make_fld(String name, int tid_ansi, int nullable, boolean autonumber, boolean primary_key) {return Make_fld(name, tid_ansi, nullable, false, false, null);}
public Meta_fld_itm Make_fld(String name, int tid_ansi, int nullable, boolean autonumber, boolean primary_key, Object default_val) {
Meta_fld_itm rv = new Meta_fld_itm(name, Make_type(tid_ansi));
rv.Nullable_tid_(nullable);
if (autonumber) rv.Autonumber_y_();
if (primary_key) rv.Primary_key_y_();
rv.Default_val_(default_val);
return rv;
}
public void Test_parse_type(String src, Meta_type_itm expd_type) {
rdr.Init(Bry_.new_u8(src));
Meta_type_itm actl_type = fld_parser.Parse_type(rdr);
Tfds.Eq(expd_type.Tid_ansi() , actl_type.Tid_ansi());
Tfds.Eq(expd_type.Len_1() , actl_type.Len_1());
Tfds.Eq(expd_type.Len_2() , actl_type.Len_2());
}
public void Test_parse_fld(String src, Meta_fld_itm expd_fld) {
rdr.Init(Bry_.new_u8(src));
Meta_fld_itm actl_fld = fld_parser.Parse_fld(rdr);
Tfds.Eq(expd_fld.Name() , actl_fld.Name());
Tfds.Eq(expd_fld.Type().Tid_ansi() , actl_fld.Type().Tid_ansi());
Tfds.Eq(expd_fld.Nullable_tid() , actl_fld.Nullable_tid());
Tfds.Eq(Object_.Xto_str_strict_or_empty(expd_fld.Default_val()), Object_.Xto_str_strict_or_empty(actl_fld.Default_val()));
}
}

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

View File

@@ -0,0 +1,66 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import org.junit.*;
public class Meta_parser__tbl_tst {
@Before public void init() {fxt.Clear();} private Meta_parser__tbl_fxt fxt = new Meta_parser__tbl_fxt();
@Test public void Test_parse() {
fxt.Test_parse("CREATE TABLE tbl_1 (fld_1 int, fld_2 int)", fxt.Make_tbl("tbl_1", "fld_1", "fld_2"));
}
@Test public void Test_smoke() {
fxt.Test_parse(String_.Concat_lines_nl_skip_last
( "CREATE TABLE page"
, "( page_id integer NOT NULL PRIMARY KEY"
, ", page_namespace integer NOT NULL"
, ", page_title varchar(255) NOT NULL"
, ", page_is_redirect integer NOT NULL"
, ", page_touched varchar(14) NOT NULL"
, ", page_len integer NOT NULL"
, ", page_random_int integer NOT NULL"
, ", page_text_db_id integer NOT NULL"
, ", page_html_db_id integer NOT NULL DEFAULT -1"
, ", page_redirect_id integer NOT NULL DEFAULT -1"
, ");"
), fxt.Make_tbl("page", "page_id", "page_namespace", "page_title", "page_is_redirect", "page_touched", "page_len", "page_random_int", "page_text_db_id", "page_html_db_id", "page_redirect_id"));
}
}
class Meta_parser__tbl_fxt {
private final Meta_parser__tbl tbl_parser = new Meta_parser__tbl();
public void Clear() {}
public Meta_tbl_itm Make_tbl(String tbl_name, String... fld_names) {
Meta_tbl_itm rv = new Meta_tbl_itm(tbl_name, "NONE");
int len = fld_names.length;
for (int i = 0; i < len; ++i) {
rv.Flds().Add(new Meta_fld_itm(fld_names[i], new Meta_type_itm(Db_meta_fld.Tid_int, Sqlite_tid.Tid_int, Bry_.new_a7("int"), Int_.MinValue, Int_.MinValue)));
}
return rv;
}
public void Test_parse(String src, Meta_tbl_itm expd_tbl) {
Meta_tbl_itm actl_tbl = tbl_parser.Parse(Bry_.new_u8(src));
Tfds.Eq(expd_tbl.Name(), actl_tbl.Name());
Tfds.Eq_ary_str(To_str_ary(expd_tbl.Flds()), To_str_ary(actl_tbl.Flds()));
}
private static String[] To_str_ary(Meta_fld_mgr fld_mgr) {
int len = fld_mgr.Len();
String[] rv = new String[len];
for (int i = 0; i < len; ++i) {
rv[i] = fld_mgr.Get_at(i).Name();
}
return rv;
}
}

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.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import gplx.core.brys.*;
public class Sql_bry_rdr extends Bry_rdr { public byte[] Read_sql_identifier() {
this.Skip_ws();
int bgn = pos, end = -1;
if (pos == src_len) return null;
if (src[pos] == Byte_ascii.Brack_bgn) { // EX: [name with space]
bgn = ++pos; // set bgn after [
end = this.Find_fwd(Byte_ascii.Brack_end);
pos = end + 1; // set pos after ]
}
else {
this.Skip_alpha_num_under(); // ASSUME: identifier is ASCII and alpha / num / underscore
if (pos == bgn) return null; // String is not identifier; EX: "!@#"
end = pos;
}
return Bry_.Mid(src, bgn, end);
}
@Override public Bry_rdr Skip_ws() {
byte b_0 = pos < src_len ? src[pos] : Byte_ascii.Nil;
byte bgn_1 = Byte_ascii.Nil;
byte[] end_bry = null;
switch (b_0) {
case Byte_ascii.Dash: bgn_1 = Byte_ascii.Dash; end_bry = Comm_end_line; break;
case Byte_ascii.Slash: bgn_1 = Byte_ascii.Star; end_bry = Comm_end_multi; break;
case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr: case Byte_ascii.Space:
++pos;
return super.Skip_ws();
default:
return this;
}
byte b_1 = pos + 1 < src_len ? src[pos + 1] : Byte_ascii.Nil;
if (b_1 != bgn_1) return this;
int end_pos = Bry_finder.Find_fwd(src, end_bry, pos + 2, src_len);
if (end_pos == Bry_finder.Not_found) return this;
pos = end_pos + end_bry.length;
return this.Skip_ws();
}
private static final byte[] Comm_end_line = Byte_ascii.Nl_bry, Comm_end_multi = Bry_.new_a7("*/");
}

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.metas.parsers; import gplx.*; import gplx.dbs.*; import gplx.dbs.metas.*;
import org.junit.*;
public class Sql_bry_rdr_tst {
@Before public void init() {fxt.Clear();} private Sql_bry_rdr_fxt fxt = new Sql_bry_rdr_fxt();
@Test public void Skip_ws() {
fxt.Test_skip_ws("a", 0); // char
fxt.Test_skip_ws("\ta", 1); // tab
fxt.Test_skip_ws("\na", 1); // \n
fxt.Test_skip_ws("\ra", 1); // \r
fxt.Test_skip_ws(" a", 1); // space
fxt.Test_skip_ws("\t\n\r a", 4); // multi
fxt.Test_skip_ws("", 0); // eos
}
@Test public void Read_sql_identifier() {
fxt.Test_read_sql_identifier("a", "a"); // one
fxt.Test_read_sql_identifier("abc_1", "abc_1"); // many
fxt.Test_read_sql_identifier("[abc_1]", "abc_1"); // bracket
fxt.Test_read_sql_identifier(" a ", "a"); // ws
fxt.Test_read_sql_identifier("", null); // eos
fxt.Test_read_sql_identifier("!@#", null); // sym
}
}
class Sql_bry_rdr_fxt {
private final Sql_bry_rdr rdr = new Sql_bry_rdr();
public void Clear() {}
public void Test_skip_ws(String src, int expd_pos) {
rdr.Init(Bry_.new_u8(src));
rdr.Skip_ws();
Tfds.Eq(expd_pos, rdr.Pos());
}
public void Test_read_sql_identifier(String src, String expd) {
rdr.Init(Bry_.new_u8(src));
Tfds.Eq(expd, String_.new_u8(rdr.Read_sql_identifier()));
}
}

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.qrys; import gplx.*; import gplx.dbs.*;
public class Db_arg {
public Db_arg(String key, Object val) {this.key = key; this.val = val;}
public String Key() {return key;} private String key;
public Object Val() {return val;} public void Val_(Object v) {this.val = v;} private Object val;
public byte Val_tid() {return val_tid;} public Db_arg Val_tid_(byte v) {val_tid = v; return this;} private byte val_tid = Db_val_type.Tid_null;
}

View File

@@ -0,0 +1,131 @@
/*
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.qrys; import gplx.*; import gplx.dbs.*;
import gplx.core.criterias.*; import gplx.dbs.sqls.*;
public class Db_qry__select_cmd implements Db_qry {
public int Tid() {return Db_qry_.Tid_select;}
public boolean Exec_is_rdr() {return true;}
public String Base_table() {return from.BaseTable().TblName();}
public String Xto_sql() {return Sql_qry_wtr_.I.Xto_str(this, false);}
public String Xto_sql_prepare() {return Sql_qry_wtr_.I.Xto_str(this, true);}
public DataRdr Exec_qry_as_rdr(Db_conn conn) {return conn.Exec_qry_as_rdr(this);}
public GfoNde ExecRdr_nde(Db_conn conn) {
DataRdr rdr = DataRdr_.Null;
try {return GfoNde_.rdr_(Exec_qry_as_rdr(conn));} finally {rdr.Rls();}
}
public Object ExecRdr_val(Db_conn conn) {
DataRdr rdr = Exec_qry_as_rdr(conn);
try {
Object rv = null;
if (rdr.MoveNextPeer()) {
rv = rdr.Read(cols.Flds().Get_at(0).Fld()); // NOTE: need to access from flds for tdb
}
return rv;
} finally {rdr.Rls();}
}
public static Object Rdr_to_val(DataRdr rdr) {
try {
Object rv = null;
if (rdr.MoveNextPeer()) {
rv = rdr.ReadAt(0);
}
return rv;
} finally {rdr.Rls();}
}
public Sql_from From() {return from;} Sql_from from;
public Db_qry__select_cmd From_(String tblName) {return From_(tblName, null);}
public Db_qry__select_cmd From_(String tblName, String alias) {
if (from != null) throw Exc_.new_("super table already defined", "from", from.Tbls().Count());
from = Sql_from.new_(Sql_tbl_src.new_().JoinType_(Sql_join_itmType.From).TblName_(tblName).Alias_(alias));
return this;
}
public Db_qry__select_cmd Join_(String name, String alias, Sql_join_itm... ary) {
if (from == null) throw Exc_.new_("super table is not defined");
Sql_tbl_src tbl = Sql_tbl_src.new_().JoinType_(Sql_join_itmType.Inner).TblName_(name).Alias_(alias);
for (Sql_join_itm itm : ary)
tbl.JoinLinks().Add(itm);
from.Tbls().Add(tbl);
return this;
}
public Sql_select Cols() {return cols;} Sql_select cols = Sql_select.All;
public String[] Cols_ary() {return cols.Flds().To_str_ary();}
public Db_qry__select_cmd Cols_all_() {return this;}
public Db_qry__select_cmd Cols_alias_(String expr, String alias) {
if (cols == Sql_select.All) cols = Sql_select.new_();
cols.Add(expr, alias);
return this;
}
public Db_qry__select_cmd Cols_(String... ary) {
if (cols == Sql_select.All) cols = Sql_select.new_();
for (String itm : ary)
cols.Add(itm);
return this;
}
public Db_qry__select_cmd Cols_groupBy_max(String fld) {return Cols_groupBy_max(fld, fld);}
public Db_qry__select_cmd Cols_groupBy_max(String fld, String alias) {
if (cols == Sql_select.All) cols = Sql_select.new_();
cols.Add(Sql_select_fld_.new_max(Sql_select_fld_base.Tbl_null, fld, alias));
return this;
}
public Db_qry__select_cmd Cols_groupBy_min(String fld, String alias) {
if (cols == Sql_select.All) cols = Sql_select.new_();
cols.Add(Sql_select_fld_.new_min(Sql_select_fld_base.Tbl_null, fld, alias));
return this;
}
public Db_qry__select_cmd Cols_groupBy_count(String fld, String alias) {
if (cols == Sql_select.All) cols = Sql_select.new_();
cols.Add(Sql_select_fld_.new_count(Sql_select_fld_base.Tbl_null, fld, alias));
return this;
}
public Db_qry__select_cmd Cols_groupBy_sum(String fld) {return Cols_groupBy_sum(fld, fld);}
public Db_qry__select_cmd Cols_groupBy_sum(String fld, String alias) {
if (cols == Sql_select.All) cols = Sql_select.new_();
cols.Add(Sql_select_fld_.new_sum(Sql_select_fld_base.Tbl_null, fld, alias));
return this;
}
public Criteria Where() {return where;} public Db_qry__select_cmd Where_(Criteria crt) {where = crt; return this;} Criteria where;
public Sql_order_by OrderBy() {return orderBy;} Sql_order_by orderBy = null;
public Db_qry__select_cmd OrderBy_(String fieldName, boolean ascending) {
Sql_order_by_itm item = Sql_order_by_itm.new_(fieldName, ascending);
orderBy = Sql_order_by.new_(item);
return this;
}
public Db_qry__select_cmd OrderBy_asc_(String fieldName) {return OrderBy_(fieldName, true);}
public Db_qry__select_cmd OrderBy_many_(String... fldNames) {
Sql_order_by_itm[] ary = new Sql_order_by_itm[fldNames.length];
for (int i = 0; i < fldNames.length; i++)
ary[i] = Sql_order_by_itm.new_(fldNames[i], true);
orderBy = Sql_order_by.new_(ary);
return this;
}
public Sql_group_by GroupBy() {return groupBy;} Sql_group_by groupBy = null;
public Db_qry__select_cmd GroupBy_(String... flds) {
if (groupBy != null) throw Exc_.new_("group by already defined", "group", groupBy);
groupBy = Sql_group_by.new_(flds);
return this;
}
public String Indexed_by() {return indexed_by;} public Db_qry__select_cmd Indexed_by_(String v) {indexed_by = v; return this;} private String indexed_by;
public Db_qry__select_cmd Distinct_() {cols.Distinct_set(true); return this;}
public int Limit() {return limit;} int limit = -1; public static final int Limit_disabled = -1;
public Db_qry__select_cmd Limit_(int v) {this.limit = v; return this;}
public static Db_qry__select_cmd new_() {return new Db_qry__select_cmd();} Db_qry__select_cmd() {}
}

View File

@@ -0,0 +1,87 @@
/*
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.qrys; import gplx.*; import gplx.dbs.*;
import gplx.core.strings.*; import gplx.core.criterias.*;
public class Db_qry__select_in_tbl implements Db_qry {
public Db_qry__select_in_tbl(String base_table, String[] select_flds, String[] where_flds, String group_by_sql, String having_sql, String order_by_sql, String limit_sql) {
this.base_table = base_table; this.select_flds = select_flds; this.where_flds = where_flds; this.group_by_sql = group_by_sql; this.having_sql = having_sql; this.order_by_sql = order_by_sql; this.limit_sql = limit_sql;
}
public int Tid() {return Db_qry_.Tid_select_in_tbl;}
public boolean Exec_is_rdr() {return true;}
public String Base_table() {return base_table;} private final String base_table;
public Criteria Where() {return where;} private Criteria where;
public String[] Select_flds() {return select_flds;} private final String[] select_flds;
private final String[] where_flds;
public void Where_sql(String_bldr sb) {
if (where_flds == null) return;
int where_flds_len = where_flds.length;
if (where_flds_len == 0) return;
for (int i = 0; i < where_flds_len; ++i) {
if (i != 0) sb.Add("AND ");
sb.Add(where_flds[i]).Add(" = ? ");
}
}
public String Group_by_sql() {return group_by_sql;} private final String group_by_sql;
public String Having_sql() {return having_sql;} private final String having_sql;
public String Order_by_sql() {return order_by_sql;} public Db_qry__select_in_tbl Order_by_sql_(String v) {order_by_sql = v; return this;} private String order_by_sql;
public String Limit_sql() {return limit_sql;} private final String limit_sql;
public String XtoSql() {return Xto_sql();}
public String Xto_sql() {
synchronized (this) {
String_bldr sb = String_bldr_.new_();
sb.Add("SELECT ");
int select_flds_len = select_flds.length;
for (int i = 0; i < select_flds_len; ++i) {
if (i != 0) sb.Add(",");
sb.Add(select_flds[i]);
}
sb.Add(" FROM ").Add(base_table);
if (where_flds != null && where_flds.length != 0) {sb.Add(" WHERE "); Where_sql(sb);}
if (group_by_sql != null) sb.Add(group_by_sql);
if (having_sql != null) sb.Add(having_sql);
if (order_by_sql != null) {sb.Add(" ORDER BY "); sb.Add(order_by_sql);}
if (limit_sql != null) sb.Add(limit_sql);
return sb.XtoStr();
}
}
public static Db_qry__select_in_tbl new_(String base_table, String[] where_flds, String[] select_flds, String[] order_flds) {
String order_by_sql = null;
if (order_flds != Order_by_null) {
int len = order_flds.length;
switch (len) {
case 0: break;
case 1: order_by_sql = order_flds[0]; break;
default:
Bry_bfr bfr = Bry_bfr.new_();
for (int i = 0; i < len; ++i) {
String order_fld = order_flds[i];
if (i != 0) bfr.Add_byte_comma();
bfr.Add_str_a7(order_fld);
}
order_by_sql = bfr.Xto_str_and_clear();
break;
}
}
Db_qry__select_in_tbl rv = new Db_qry__select_in_tbl(base_table, select_flds, where_flds, null, null, order_by_sql, null);
rv.where = where_flds.length == 0 ? Db_crt_.Wildcard : Db_crt_.eq_many_(where_flds);
return rv;
}
public static Db_qry__select_in_tbl as_(Object obj) {return obj instanceof Db_qry__select_in_tbl ? (Db_qry__select_in_tbl)obj : null;}
public static final String[] Where_flds__all = String_.Ary_empty;
public static final String[] Order_by_null = null;
}

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.qrys; import gplx.*; import gplx.dbs.*;
public interface Db_qry_arg_owner extends Db_qry {
Db_qry_arg_owner From_(String tbl);
Db_qry_arg_owner Key_arg_(String k, int v);
Db_qry_arg_owner Key_arg_(String k, String v);
Db_qry_arg_owner Arg_(String k, int v);
Db_qry_arg_owner Arg_(String k, long v);
Db_qry_arg_owner Arg_(String k, String v);
Db_qry_arg_owner Arg_(String k, byte[] v);
Db_qry_arg_owner Arg_(String k, DateAdp v);
Db_qry_arg_owner Arg_(String k, DecimalAdp v);
Db_qry_arg_owner Arg_byte_(String k, byte v);
Db_qry_arg_owner Arg_bry_(String k, byte[] v);
Db_qry_arg_owner Arg_obj_(String key, Object val);
Db_qry_arg_owner Arg_obj_type_(String key, Object val, byte val_tid);
}

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.qrys; import gplx.*; import gplx.dbs.*;
import gplx.core.criterias.*; import gplx.dbs.sqls.*;
public class Db_qry_delete implements Db_qry {
Db_qry_delete(String base_table, Criteria where) {this.base_table = base_table; this.where = where;}
public int Tid() {return Db_qry_.Tid_delete;}
public boolean Exec_is_rdr() {return false;}
public String Base_table() {return base_table;} private final String base_table;
public String Xto_sql() {return Sql_qry_wtr_.I.Xto_str(this, false);}
public Criteria Where() {return where;} private final Criteria where;
public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);}
public static Db_qry_delete new_all_(String tbl) {return new Db_qry_delete(tbl, Criteria_.All);}
public static Db_qry_delete new_(String tbl, String... where) {return new Db_qry_delete(tbl, Db_crt_.eq_many_(where));}
public static Db_qry_delete new_(String tbl, Criteria where) {return new Db_qry_delete(tbl, where);}
}

View File

@@ -0,0 +1,44 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.qrys; import gplx.*; import gplx.dbs.*;
import org.junit.*;
import gplx.core.criterias.*;
public class Db_qry_dml_tst {
@Test public void Delete_basic() {
tst_XtoSql(Db_qry_delete.new_("tbl0", Db_crt_.eq_("fld0", "val0"))
, "DELETE FROM tbl0 WHERE fld0='val0'");
}
@Test public void Insert_basic() {
tst_XtoSql(new Db_qry_insert("tbl0").Arg_("id", 0).Arg_("name", "me").Arg_("time", DateAdp_.parse_gplx("2007-12-23"))
, "INSERT INTO tbl0 (id, name, time) VALUES (0, 'me', '2007-12-23 00:00:00.000')");
}
@Test public void Update_basic() {
Db_qry_update qry = Db_qry_update.new_();
qry.From_("tbl0");
qry.Where_(Db_crt_.eq_("id", 0)).Arg_("name", "me");
tst_XtoSql(qry, "UPDATE tbl0 SET name='me' WHERE id=0");
}
@Test public void Update_all() {
Db_qry_update qry = Db_qry_update.new_();
qry.From_("tbl0");
qry.Arg_("id", 1).Arg_("name", "me").Arg_("startTime", DateAdp_.parse_gplx("2007-12-23"));
qry.Where_(Criteria_.And(Db_crt_.eq_("id", 0), Db_crt_.mt_("startTime", DateAdp_.parse_gplx("2005-01-01"))));
tst_XtoSql(qry, "UPDATE tbl0 SET id=1, name='me', startTime='2007-12-23 00:00:00.000' WHERE (id=0 AND startTime>'2005-01-01 00:00:00.000')");
}
void tst_XtoSql(Db_qry qry, String expd) {Tfds.Eq(expd, qry.Xto_sql());}
}

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.qrys; import gplx.*; import gplx.dbs.*;
import gplx.dbs.sqls.*;
public class Db_qry_flush implements Db_qry {
public int Tid() {return Db_qry_.Tid_flush;}
public boolean Exec_is_rdr() {return false;}
public String Base_table() {return tableNames[0];}
public String Xto_sql() {return Sql_qry_wtr_.I.Xto_str(this, false);}
public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);}
public String[] TableNames() {return tableNames;} private String[] tableNames;
public static Db_qry_flush as_(Object obj) {return obj instanceof Db_qry_flush ? (Db_qry_flush)obj : null;}
public static Db_qry_flush cast_(Object obj) {try {return (Db_qry_flush)obj;} catch(Exception exc) {throw Exc_.new_type_mismatch_w_exc(exc, Db_qry_flush.class, obj);}}
public static Db_qry_flush new_(String... ary) {
Db_qry_flush rv = new Db_qry_flush();
rv.tableNames = ary;
return rv;
} Db_qry_flush() {}
}

View File

@@ -0,0 +1,67 @@
/*
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.qrys; import gplx.*; import gplx.dbs.*;
import gplx.dbs.sqls.*;
public class Db_qry_insert implements Db_qry_arg_owner {
public Db_qry_insert(String base_table) {this.base_table = base_table;}
public int Tid() {return Db_qry_.Tid_insert;}
public boolean Exec_is_rdr() {return false;}
public String Xto_sql() {return Sql_qry_wtr_.I.Xto_str(this, false);}
public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);}
public String Base_table() {return base_table;} private String base_table;
public String[] Cols_for_insert() {return cols_for_insert;} private String[] cols_for_insert;
public Db_qry_arg_owner From_(String tbl) {base_table = tbl; return this;}
public KeyValHash Args() {return args;} private final KeyValHash args = KeyValHash.new_();
public Db_qry_arg_owner Arg_(String k, DecimalAdp v) {return Arg_obj_type_(k, v.Xto_decimal(), Db_val_type.Tid_decimal);}
public Db_qry_arg_owner Arg_(String k, DateAdp v) {return Arg_obj_type_(k, v, Db_val_type.Tid_date);}
public Db_qry_arg_owner Arg_byte_(String k, byte v) {return Arg_obj_type_(k, v, Db_val_type.Tid_byte);}
public Db_qry_arg_owner Arg_(String k, int v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int32);}
public Db_qry_arg_owner Arg_(String k, long v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int64);}
public Db_qry_arg_owner Arg_(String k, String v) {return Arg_obj_type_(k, v, Db_val_type.Tid_varchar);}
public Db_qry_arg_owner Arg_bry_(String k, byte[] v) {return Arg_obj_type_(k, v, Db_val_type.Tid_bry);}
public Db_qry_arg_owner Arg_(String k, byte[] v) {return Arg_obj_type_(k, String_.new_u8(v), Db_val_type.Tid_varchar);}
public Db_qry_arg_owner Arg_obj_(String k, Object v) {return Arg_obj_type_(k, v, Db_val_type.Tid_null);}
public Db_qry_arg_owner Arg_obj_type_(String key, Object val, byte val_tid) {
if (key == Db_meta_fld.Key_null) return this;
Db_arg arg = new Db_arg(key, val).Val_tid_(val_tid);
args.Add(arg.Key(), arg);
return this;
}
public Db_qry_arg_owner Key_arg_(String k, int v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int32);}
public Db_qry_arg_owner Key_arg_(String k, String v) {return Arg_obj_type_(k, v, Db_val_type.Tid_varchar);}
public Db_qry__select_cmd Select() {return select;} Db_qry__select_cmd select;
public Db_qry_insert Select_(Db_qry__select_cmd qry) {this.select = qry; return this;}
public Db_qry_insert Cols_(String... ary) {
if (cols == null) cols = Sql_select_fld_list.new_();
for (String fld : ary)
cols.Add(Sql_select_fld_.new_fld(Sql_select_fld_base.Tbl_null, fld, fld));
return this;
}
public Sql_select_fld_list Cols() {return cols;} private Sql_select_fld_list cols;
public static Db_qry_insert new_() {return new Db_qry_insert();} Db_qry_insert() {}
public static Db_qry_insert new_(String tbl, String... keys) {
Db_qry_insert rv = Db_qry_insert.new_();
rv.base_table = tbl;
rv.cols_for_insert = keys;
int len = keys.length;
for (int i = 0; i < len; ++i)
rv.Arg_obj_(keys[i], null);
return rv;
}
}

View File

@@ -0,0 +1,89 @@
/*
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.qrys; import gplx.*; import gplx.dbs.*;
import org.junit.*; import gplx.dbs.sqls.*;
public class Db_qry_select_tst {
@Before public void setup() {
cmd = Db_qry__select_cmd.new_();
} Db_qry__select_cmd cmd; String expd;
@Test public void Basic() {
cmd.Cols_("fld0", "fld1").From_("tbl0");
expd = "SELECT fld0, fld1 FROM tbl0";
tst_XtoStr(cmd, expd);
}
@Test public void OrderDoesNotMatter() {
cmd.From_("tbl0").Cols_("fld0", "fld1");
expd = "SELECT fld0, fld1 FROM tbl0";
tst_XtoStr(cmd, expd);
}
@Test public void DefaultAllFields() {
cmd.From_("tbl0");
expd = "SELECT * FROM tbl0";
tst_XtoStr(cmd, expd);
}
@Test public void Where() {
cmd.From_("tbl0").Where_(Db_crt_.eq_("fld0", 0));
expd = "SELECT * FROM tbl0 WHERE fld0=0";
tst_XtoStr(cmd, expd);
}
@Test public void Join() {
cmd.From_("tbl0").Join_("tbl1", "t1", Sql_join_itm.new_("fld1", "tbl0", "fld0"));
expd = "SELECT * FROM tbl0 INNER JOIN tbl1 t1 ON tbl0.fld0=t1.fld1";
tst_XtoStr(cmd, expd);
}
@Test public void OrderBy() {
cmd.From_("tbl0").OrderBy_("fld0", true);
expd = "SELECT * FROM tbl0 ORDER BY fld0";
tst_XtoStr(cmd, expd);
}
@Test public void OrderByMany() {
cmd.From_("tbl0").OrderBy_many_("fld0", "fld1");
expd = "SELECT * FROM tbl0 ORDER BY fld0, fld1";
tst_XtoStr(cmd, expd);
}
@Test public void Limit() {
cmd.From_("tbl0").Limit_(10);
expd = "SELECT * FROM tbl0 LIMIT 10";
tst_XtoStr(cmd, expd);
}
// @Test public void GroupBy() {
// cmd.From_("tbl0").groupBy_("fld0", "fld1");
// expd = "SELECT fld0, fld1 FROM tbl0 GROUP BY fld0, fld1";
// Tfds.Eq(cmd.XtoStr(), expd);
// }
// @Test public void Union() {
// cmd.From_("tbl0").select("fld0").union_(qry2.from("tbl1").select("fld0"));
// cmd.From_("tbl0").select("fld0").union_().from("tbl1").select("fld0"); // feasible, but will be bad later when trying to access Db_qry__select_cmd props
// expd = "SELECT fld0 FROM tbl0 UNION SELECT fld0 FROM tbl1";
// Tfds.Eq(cmd.XtoStr(), expd);
// }
// @Test public void Having() {
// cmd.From_("tbl0").groupBy_("fld0", "fld1");
// expd = "SELECT fld0, fld1 FROM tbl0 GROUP BY fld0, fld1 HAVING Count(fld0) > 1";
// Tfds.Eq(cmd.XtoStr(), expd);
// }
void tst_XtoStr(Db_qry qry, String expd) {Tfds.Eq(expd, cmd.Xto_sql());}
}

View File

@@ -0,0 +1,82 @@
/*
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.qrys; import gplx.*; import gplx.dbs.*;
import gplx.dbs.sqls.*;
public class Db_qry_sql implements Db_qry {
public int Tid() {return Db_qry_.Tid_sql;}
public boolean Exec_is_rdr() {return isReader;} private boolean isReader;
public String Base_table() {throw Exc_.new_unimplemented();}
public String Xto_sql() {return sql;} private String sql;
public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);}
public static Db_qry_sql dml_(String sql) {return sql_(sql);}
public static Db_qry_sql ddl_(String sql) {return sql_(sql);}
public static Db_qry_sql xtn_(String sql) {return sql_(sql);}
static Db_qry_sql sql_(String sql) {
Db_qry_sql rv = new Db_qry_sql();
rv.sql = sql; rv.isReader = false;
return rv;
}
public static Db_qry_sql rdr_(String sql) {
Db_qry_sql rv = new Db_qry_sql();
rv.sql = sql; rv.isReader = true;
return rv;
}
public static Db_qry_sql as_(Object obj) {return obj instanceof Db_qry_sql ? (Db_qry_sql)obj : null;}
public static Db_qry_sql cast_(Object obj) {try {return (Db_qry_sql)obj;} catch(Exception exc) {throw Exc_.new_type_mismatch_w_exc(exc, Db_qry_sql.class, obj);}}
public static String Gen_sql(Db_qry qry, Object... args) {
byte[] src = Bry_.new_u8(Sql_qry_wtr_.Gen_placeholder_parameters(qry));
int src_len = src.length;
int args_idx = 0, args_len = args.length, pos = 0;
Bry_bfr bfr = Bry_bfr.new_(src_len);
while (pos < src_len) {
int question_pos = Bry_finder.Find_fwd(src, Byte_ascii.Question, pos);
if (question_pos == Bry_.NotFound)
question_pos = src_len;
bfr.Add_mid(src, pos, question_pos);
if (args_idx < args_len)
Gen_sql_arg(bfr, args[args_idx++]);
pos = question_pos + 1;
}
return bfr.Xto_str_and_clear();
}
private static void Gen_sql_arg(Bry_bfr bfr, Object val) {
if (val == null) {bfr.Add(Bry_null); return;}
Class<?> val_type = val.getClass();
if (ClassAdp_.Eq(val_type, Int_.Cls_ref_type))
bfr.Add_int_variable(Int_.cast_(val));
else if (ClassAdp_.Eq(val_type, Bool_.Cls_ref_type))
bfr.Add_int_fixed(1, 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 (ClassAdp_.Eq(val_type, Double_.Cls_ref_type))
bfr.Add_double(Double_.cast_(val));
else if (ClassAdp_.Eq(val_type, Long_.Cls_ref_type))
bfr.Add_long_variable(Long_.cast_(val));
else if (ClassAdp_.Eq(val_type, Float_.Cls_ref_type))
bfr.Add_float(Float_.cast_(val));
else if (ClassAdp_.Eq(val_type, Byte_.Cls_ref_type))
bfr.Add_byte(Byte_.cast_(val));
else if (ClassAdp_.Eq(val_type, DateAdp_.Cls_ref_type))
bfr.Add_byte_apos().Add_str(DateAdp_.cast_(val).XtoStr_gplx_long()).Add_byte_apos();
else if (ClassAdp_.Eq(val_type, DecimalAdp_.Cls_ref_type))
bfr.Add_str(DecimalAdp_.cast_(val).Xto_str());
else {
byte[] val_bry = Bry_.new_u8(Object_.Xto_str_strict_or_null(val));
val_bry = Bry_.Replace(val_bry, Byte_ascii.Apos_bry, Bry_escape_apos);
bfr.Add_byte_apos().Add(val_bry).Add_byte_apos();
}
} private static final byte[] Bry_null = Bry_.new_u8("NULL"), Bry_escape_apos = Bry_.new_a7("''");
}

View File

@@ -0,0 +1,47 @@
/*
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.qrys; import gplx.*; import gplx.dbs.*;
import org.junit.*;
public class Db_qry_sql_tst {
@Before public void init() {fxt.Clear();} private Db_qry_sql_fxt fxt = new Db_qry_sql_fxt();
@Test public void Insert() {
fxt.Test_qry
( Db_qry_insert.new_("tbl", "k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9")
, Object_.Ary(123, Bool_.Y, 1.23d, 123L, 123f, Byte_ascii.Num_1, "123", DateAdp_.parse_iso8561("1981-04-05T14:30:30"), DecimalAdp_.parse_("1.23"))
, "INSERT INTO tbl (k1, k2, k3, k4, k5, k6, k7, k8, k9) VALUES (123, 1, 1.23, 123, 123, 1, '123', '1981-04-05 14:30:30.000', 1.23)"
);
}
@Test public void Update() {
fxt.Test_qry
( Db_qry_update.new_("tbl", String_.Ary("k1", "k2"), "k3", "k4")
, Object_.Ary("v3", "v4", "v1", "v2")
, "UPDATE tbl SET k3='v3', k4='v4' WHERE (k1='v1' AND k2='v2')"
);
}
@Test public void Delete() {
fxt.Test_qry
( Db_qry_delete.new_("tbl", String_.Ary("k1", "k2"))
, Object_.Ary("v1", "v2")
, "DELETE FROM tbl WHERE (k1='v1' AND k2='v2')"
);
}
}
class Db_qry_sql_fxt {
public void Clear() {}
public void Test_qry(Db_qry qry, Object[] vals, String expd) {Tfds.Eq(expd, Db_qry_sql.Gen_sql(qry, vals));}
}

View File

@@ -0,0 +1,61 @@
/*
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.qrys; import gplx.*; import gplx.dbs.*;
import gplx.core.criterias.*; import gplx.dbs.sqls.*;
public class Db_qry_update implements Db_qry_arg_owner {
public int Tid() {return Db_qry_.Tid_update;}
public boolean Exec_is_rdr() {return false;}
public String Xto_sql() {return Sql_qry_wtr_.I.Xto_str(this, false);}
public int Exec_qry(Db_conn conn) {return conn.Exec_qry(this);}
public String Base_table() {return base_table;} private String base_table;
public String[] Cols_for_update() {return cols_for_update;} private String[] cols_for_update;
public Criteria Where() {return where;} public Db_qry_update Where_(Criteria crt) {where = crt; return this;} private Criteria where;
public Db_qry_arg_owner From_(String tbl) {base_table = tbl; return this;}
public KeyValHash Args() {return args;} private final KeyValHash args = KeyValHash.new_();
public Db_qry_arg_owner Arg_(String k, DecimalAdp v) {return Arg_obj_type_(k, v.Xto_decimal(), Db_val_type.Tid_decimal);}
public Db_qry_arg_owner Arg_(String k, DateAdp v) {return Arg_obj_type_(k, v, Db_val_type.Tid_date);}
public Db_qry_arg_owner Arg_byte_(String k, byte v) {return Arg_obj_type_(k, v, Db_val_type.Tid_byte);}
public Db_qry_arg_owner Arg_(String k, int v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int32);}
public Db_qry_arg_owner Arg_(String k, long v) {return Arg_obj_type_(k, v, Db_val_type.Tid_int64);}
public Db_qry_arg_owner Arg_(String k, String v) {return Arg_obj_type_(k, v, Db_val_type.Tid_varchar);}
public Db_qry_arg_owner Arg_bry_(String k, byte[] v) {return Arg_obj_type_(k, v, Db_val_type.Tid_bry);}
public Db_qry_arg_owner Arg_(String k, byte[] v) {return Arg_obj_type_(k, String_.new_u8(v), Db_val_type.Tid_varchar);}
public Db_qry_arg_owner Arg_obj_(String k, Object v) {return Arg_obj_type_(k, v, Db_val_type.Tid_null);}
public Db_qry_arg_owner Arg_obj_type_(String key, Object val, byte val_tid) {
if (key == Db_meta_fld.Key_null) return this;
Db_arg arg = new Db_arg(key, val).Val_tid_(val_tid);
args.Add(arg.Key(), arg);
return this;
}
public Db_qry_arg_owner Key_arg_(String k, int v) {return Key_arg_obj_(k, v);}
public Db_qry_arg_owner Key_arg_(String k, String v) {return Key_arg_obj_(k, v);}
private Db_qry_arg_owner Key_arg_obj_(String k, Object v) {
Criteria crt = Db_crt_.eq_(k, v);
where = where == null ? crt : Criteria_.And(where, crt);
return this;
}
public static Db_qry_update new_() {return new Db_qry_update();} Db_qry_update() {}
public static Db_qry_update new_(String tbl, String[] where, String... update) {
Db_qry_update rv = Db_qry_.update_(tbl, Db_crt_.eq_many_(where));
rv.cols_for_update = update;
int len = update.length;
for (int i = 0; i < len; i++)
rv.Arg_obj_(update[i], null);
return rv;
}
}

View File

@@ -0,0 +1,163 @@
/*
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.qrys; import gplx.*; import gplx.dbs.*;
import java.sql.*;
import gplx.dbs.engines.*; import gplx.dbs.sqls.*;
public class Db_stmt_cmd implements Db_stmt {
private static final String Key_na = ""; // key is not_available; only called by procs with signature of Val(<type> v);
private Db_engine engine;
private PreparedStatement stmt = null;
private String sql; private int val_idx = 0;
public Db_stmt_cmd(Db_engine engine, Db_qry qry) {Ctor_stmt(engine, qry);}
public void Ctor_stmt(Db_engine engine, Db_qry qry) {
this.engine = engine;
sql = qry.Tid() == Db_qry_.Tid_select_in_tbl ? ((Db_qry__select_in_tbl)qry).Xto_sql() : Sql_qry_wtr_.I.Xto_str(qry, true);
Reset_stmt();
}
public Db_stmt Reset_stmt() {
stmt = (PreparedStatement)engine.New_stmt_prep_as_obj(sql);
return this;
}
public Db_stmt Crt_bool_as_byte(String k, boolean v) {return Add_byte_by_bool(Bool_.Y, k, v);}
public Db_stmt Val_bool_as_byte(String k, boolean v) {return Add_byte_by_bool(Bool_.N, k, v);}
public Db_stmt Val_bool_as_byte(boolean v) {return Add_byte_by_bool(Bool_.N, Key_na, v);}
private Db_stmt Add_byte_by_bool(boolean where, String k, boolean v) {return Add_byte(where, k, v ? Bool_.Y_byte : Bool_.N_byte);}
public Db_stmt Crt_byte(String k, byte v) {return Add_byte(Bool_.Y, k, v);}
public Db_stmt Val_byte(String k, byte v) {return Add_byte(Bool_.N, k, v);}
public Db_stmt Val_byte(byte v) {return Add_byte(Bool_.N, Key_na, v);}
private Db_stmt Add_byte(boolean where, String k, byte v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setByte(++val_idx, v);} catch (Exception e) {this.Rls(); throw Exc_.new_exc(e, "db", "failed to add value", "type", "byte", "val", v, "sql", sql);}
return this;
}
public Db_stmt Crt_int(String k, int v) {return Add_int(Bool_.Y, k, v);}
public Db_stmt Val_int(String k, int v) {return Add_int(Bool_.N, k, v);}
public Db_stmt Val_int(int v) {return Add_int(Bool_.N, Key_na, v);}
private Db_stmt Add_int(boolean where, String k, int v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setInt(++val_idx, v);} catch (Exception e) {this.Rls(); throw Exc_.new_exc(e, "db", "failed to add value", "type", "int", "val", v, "sql", sql);}
return this;
}
public Db_stmt Crt_long(String k, long v) {return Add_long(Bool_.Y, k, v);}
public Db_stmt Val_long(String k, long v) {return Add_long(Bool_.N, k, v);}
public Db_stmt Val_long(long v) {return Add_long(Bool_.N, Key_na, v);}
private Db_stmt Add_long(boolean where, String k, long v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setLong(++val_idx, v);} catch (Exception e) {this.Rls(); throw Exc_.new_exc(e, "db", "failed to add value", "type", "long", "val", v, "sql", sql);}
return this;
}
public Db_stmt Crt_float(String k, float v) {return Add_float(Bool_.Y, k, v);}
public Db_stmt Val_float(String k, float v) {return Add_float(Bool_.N, k, v);}
public Db_stmt Val_float(float v) {return Add_float(Bool_.N, Key_na, v);}
private Db_stmt Add_float(boolean where, String k, float v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setFloat(++val_idx, v);} catch (Exception e) {this.Rls(); throw Exc_.new_exc(e, "db", "failed to add value", "type", "float", "val", v, "sql", sql);}
return this;
}
public Db_stmt Crt_double(String k, double v) {return Add_double(Bool_.Y, k, v);}
public Db_stmt Val_double(String k, double v) {return Add_double(Bool_.N, k, v);}
public Db_stmt Val_double(double v) {return Add_double(Bool_.N, Key_na, v);}
private Db_stmt Add_double(boolean where, String k, double v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setDouble(++val_idx, v);} catch (Exception e) {this.Rls(); throw Exc_.new_exc(e, "db", "failed to add value", "type", "double", "val", v, "sql", sql);}
return this;
}
public Db_stmt Crt_decimal(String k, DecimalAdp v) {return Add_decimal(Bool_.Y, k, v);}
public Db_stmt Val_decimal(String k, DecimalAdp v) {return Add_decimal(Bool_.N, k, v);}
public Db_stmt Val_decimal(DecimalAdp v) {return Add_decimal(Bool_.N, Key_na, v);}
private Db_stmt Add_decimal(boolean where, String k, DecimalAdp v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setBigDecimal(++val_idx, v.Xto_decimal());} catch (Exception e) {this.Rls(); throw Exc_.new_exc(e, "db", "failed to add value", "type", "decimal", "val", v, "sql", sql);}
return this;
}
public Db_stmt Crt_bry(String k, byte[] v) {return Add_bry(Bool_.Y, k, v);}
public Db_stmt Val_bry(String k, byte[] v) {return Add_bry(Bool_.N, k, v);}
public Db_stmt Val_bry(byte[] v) {return Add_bry(Bool_.N, Key_na, v);}
private Db_stmt Add_bry(boolean where, String k, byte[] v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setBytes(++val_idx, v);} catch (Exception e) {this.Rls(); throw Exc_.new_exc(e, "db", "failed to add value", "type", "byte[]", v.length, sql);}
return this;
}
public Db_stmt Crt_bry_as_str(String k, byte[] v) {return Add_bry_as_str(Bool_.Y, k, v);}
public Db_stmt Val_bry_as_str(String k, byte[] v) {return Add_bry_as_str(Bool_.N, k, v);}
public Db_stmt Val_bry_as_str(byte[] v) {return Add_bry_as_str(Bool_.N, Key_na, v);}
private Db_stmt Add_bry_as_str(boolean where, String k, byte[] v) {return Add_str(where, k, String_.new_u8(v));}
public Db_stmt Crt_str(String k, String v) {return Add_str(Bool_.Y, k, v);}
public Db_stmt Val_str(String k, String v) {return Add_str(Bool_.N, k, v);}
public Db_stmt Val_str(String v) {return Add_str(Bool_.N, Key_na, v);}
private Db_stmt Add_str(boolean where, String k, String v) {
if (k == Db_meta_fld.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
try {stmt.setString(++val_idx, v);} catch (Exception e) {this.Rls(); throw Exc_.new_exc(e, "db", "failed to add value", "type", "String", "val", v, "sql", sql);}
return this;
}
public Db_stmt Val_rdr_(gplx.ios.Io_stream_rdr v, long rdr_len) {
try {stmt.setBinaryStream(++val_idx, (java.io.InputStream)v.Under(), (int)rdr_len);} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "rdr", "val", v);}
return this;
}
public boolean Exec_insert() {
try {boolean rv = stmt.execute(); return rv;}
catch (Exception e) {
this.Rls();
Reset_stmt();
throw Exc_.new_exc(e, "db_stmt", "insert failed", "url", engine.Conn_info().Xto_api(), "sql", sql);
}
}
public int Exec_update() {
try {int rv = stmt.executeUpdate(); return rv;}
catch (Exception e) {
this.Rls();
Reset_stmt();
throw Exc_.new_exc(e, "db_stmt", "update failed", "url", engine.Conn_info().Xto_api(), "sql", sql);
}
}
public int Exec_delete() {
try {int rv = stmt.executeUpdate(); return rv;}
catch (Exception e) {
this.Rls();
Reset_stmt();
throw Exc_.new_exc(e, "db_stmt", "delete failed", "url", engine.Conn_info().Xto_api(), "sql", sql);
}
}
public DataRdr Exec_select() {
try {DataRdr rv = engine.New_rdr(stmt.executeQuery(), sql); return rv;} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql);}
}
public Db_rdr Exec_select__rls_auto() {
try {return engine.New_rdr__rls_auto(this, stmt.executeQuery(), sql);} catch (Exception e) {throw Exc_.new_exc(e, "db", "select failed", "sql", sql);}
}
public Db_rdr Exec_select__rls_manual() {
try {return engine.New_rdr__rls_manual(stmt.executeQuery(), sql);} catch (Exception e) {throw Exc_.new_exc(e, "db", "select failed", "sql", sql);}
}
public Object Exec_select_val() {
try {Object rv = Db_qry__select_cmd.Rdr_to_val(engine.New_rdr(stmt.executeQuery(), sql)); return rv;} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql);}
}
public Db_stmt Clear() {
val_idx = 0;
try {stmt.clearBatch();}
catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to clear parameters", "sql", sql);}
return this;
}
public void Rls() {
if (stmt == null) return; // Null instance
try {
if (stmt.getConnection().isClosed()) return; // do not close stmt if connection is already closed; throws null error; DATE:2015-02-11
stmt.close();
stmt = null;
}
catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to close command", "sql", sql);}
}
}

View File

@@ -0,0 +1,177 @@
/*
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.qrys; import gplx.*; import gplx.dbs.*;
import gplx.dbs.engines.*;
public class Db_stmt_sql implements Db_stmt {// used for formatting SQL statements; not used for actual insert into database
private static final String Key_na = ""; // key is not_available; only called by procs with signature of Val(<type> v);
private final List_adp args = List_adp_.new_();
private final Bry_bfr tmp_bfr = Bry_bfr.new_();
private final Bry_fmtr tmp_fmtr = Bry_fmtr.new_();
public void Ctor_stmt(Db_engine engine, Db_qry qry) {}
public Db_conn Conn() {return conn;} public void Conn_(Db_conn v) {this.conn = v;} Db_conn conn;
public Db_stmt Reset_stmt() {return this;}
public Db_stmt Crt_bool_as_byte(String k, boolean v) {return Add_byte_by_bool(Bool_.Y, k, v);}
public Db_stmt Val_bool_as_byte(String k, boolean v) {return Add_byte_by_bool(Bool_.N, k, v);}
public Db_stmt Val_bool_as_byte(boolean v) {return Add_byte_by_bool(Bool_.N, Key_na, v);}
private Db_stmt Add_byte_by_bool(boolean where, String k, boolean v) {return Add_byte(where, k, v ? Bool_.Y_byte : Bool_.N_byte);}
public Db_stmt Crt_byte(String k, byte v) {return Add_byte(Bool_.Y, k, v);}
public Db_stmt Val_byte(String k, byte v) {return Add_byte(Bool_.N, k, v);}
public Db_stmt Val_byte(byte v) {return Add_byte(Bool_.N, Key_na, v);}
private Db_stmt Add_byte(boolean where, String k, byte v) {
try {Add(k, Byte_.Xto_str(v));} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "byte", "val", v);}
return this;
}
public Db_stmt Crt_int(String k, int v) {return Add_int(Bool_.Y, k, v);}
public Db_stmt Val_int(String k, int v) {return Add_int(Bool_.N, k, v);}
public Db_stmt Val_int(int v) {return Add_int(Bool_.N, Key_na, v);}
private Db_stmt Add_int(boolean where, String k, int v) {
try {Add(k, Int_.Xto_str(v));} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "int", "val", v);}
return this;
}
public Db_stmt Crt_long(String k, long v) {return Add_long(Bool_.Y, k, v);}
public Db_stmt Val_long(String k, long v) {return Add_long(Bool_.N, k, v);}
public Db_stmt Val_long(long v) {return Add_long(Bool_.N, Key_na, v);}
private Db_stmt Add_long(boolean where, String k, long v) {
try {Add(k, Long_.Xto_str(v));} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "long", "val", v);}
return this;
}
public Db_stmt Crt_float(String k, float v) {return Add_float(Bool_.Y, k, v);}
public Db_stmt Val_float(String k, float v) {return Add_float(Bool_.N, k, v);}
public Db_stmt Val_float(float v) {return Add_float(Bool_.N, Key_na, v);}
private Db_stmt Add_float(boolean where, String k, float v) {
try {Add(k, Float_.Xto_str(v));} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "float", "val", v);}
return this;
}
public Db_stmt Crt_double(String k, double v) {return Add_double(Bool_.Y, k, v);}
public Db_stmt Val_double(String k, double v) {return Add_double(Bool_.N, k, v);}
public Db_stmt Val_double(double v) {return Add_double(Bool_.N, Key_na, v);}
private Db_stmt Add_double(boolean where, String k, double v) {
try {Add(k, Double_.Xto_str(v));} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "double", "val", v);}
return this;
}
public Db_stmt Crt_decimal(String k, DecimalAdp v) {return Add_decimal(Bool_.Y, k, v);}
public Db_stmt Val_decimal(String k, DecimalAdp v) {return Add_decimal(Bool_.N, k, v);}
public Db_stmt Val_decimal(DecimalAdp v) {return Add_decimal(Bool_.N, Key_na, v);}
private Db_stmt Add_decimal(boolean where, String k, DecimalAdp v) {
try {Add(k, v.Xto_str());} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "decimal", "val", v);}
return this;
}
public Db_stmt Crt_bry(String k, byte[] v) {return Add_bry(Bool_.Y, k, v);}
public Db_stmt Val_bry(String k, byte[] v) {return Add_bry(Bool_.N, k, v);}
public Db_stmt Val_bry(byte[] v) {return Add_bry(Bool_.N, Key_na, v);}
private Db_stmt Add_bry(boolean where, String k, byte[] v) {// HACK: convert to String b/c tdb does not support byte[]
try {Add(k, Val_str_wrap(String_.new_u8(v)));} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "byte[]", "val", v.length);}
return this;
}
public Db_stmt Crt_bry_as_str(String k, byte[] v) {return Add_bry_as_str(Bool_.Y, k, v);}
public Db_stmt Val_bry_as_str(String k, byte[] v) {return Add_bry_as_str(Bool_.N, k, v);}
public Db_stmt Val_bry_as_str(byte[] v) {return Add_bry_as_str(Bool_.N, Key_na, v);}
private Db_stmt Add_bry_as_str(boolean where, String k, byte[] v) {return Add_str(where, k, String_.new_u8(v));}
public Db_stmt Crt_str(String k, String v) {return Add_str(Bool_.Y, k, v);}
public Db_stmt Val_str(String k, String v) {return Add_str(Bool_.N, k, v);}
public Db_stmt Val_str(String v) {return Add_str(Bool_.N, Key_na, v);}
private Db_stmt Add_str(boolean where, String k, String v) {
try {Add(k, Val_str_wrap(v));} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "String", "val", v);}
return this;
}
public Db_stmt Val_rdr_(gplx.ios.Io_stream_rdr v, long rdr_len) {
try {
Bry_bfr bfr = Bry_bfr.new_();
gplx.ios.Io_stream_rdr_.Load_all_to_bfr(bfr, v);
Add(Key_na, bfr.Xto_str_and_clear());
} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to add value", "type", "rdr", "val", v);}
return this;
}
private String Val_str_wrap(String v) {
return "'" + String_.Replace(v, "'", "\\'") + "'";
}
public boolean Exec_insert() {
try {boolean rv = conn.Exec_qry(Db_qry_sql.dml_(this.Xto_sql())) != 0; return rv;} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);}
}
public int Exec_update() {
try {int rv = conn.Exec_qry(Db_qry_sql.dml_(this.Xto_sql())); return rv;} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);}
}
public int Exec_delete() {
try {int rv = conn.Exec_qry(Db_qry_sql.dml_(this.Xto_sql())); return rv;} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);}
}
public DataRdr Exec_select() {
try {DataRdr rv = conn.Exec_qry_as_rdr(Db_qry_sql.rdr_(this.Xto_sql())); return rv;} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);}
}
public Db_rdr Exec_select__rls_auto() {return Db_rdr_.Empty;}
public Db_rdr Exec_select__rls_manual() {return Db_rdr_.Empty;}
public Object Exec_select_val() {
try {Object rv = Db_qry__select_cmd.Rdr_to_val(this.Exec_select()); return rv;} catch (Exception e) {throw Exc_.new_exc(e, "db", "failed to exec prepared statement", "sql", sql_orig);}
}
public Db_stmt Clear() {
args.Clear();
return this;
}
public void Rls() {this.Clear();}
public void Add(String k, String v) {
if (k == Db_meta_fld.Key_null) return; // key is explicitly null; ignore; allows version_2+ type definitions
args.Add(v);
}
public String Xto_sql() {
tmp_fmtr.Bld_bfr_many(tmp_bfr, (Object[])args.To_ary_and_clear(Object.class));
return tmp_bfr.Xto_str_and_clear();
}
public int Args_len() {return args.Count();}
public String Args_get_at(int i) {return (String)args.Get_at(i);}
private String sql_orig;
public Db_qry Qry() {return qry;} private Db_qry qry;
public Db_stmt Parse(Db_qry qry, String sql_str) {
this.qry = qry;
this.sql_orig = sql_str;
Init_fmtr(tmp_bfr, tmp_fmtr, sql_str);
return this;
}
private static void Init_fmtr(Bry_bfr tmp_bfr, Bry_fmtr tmp_fmtr, String sql_str) {
byte[] sql_bry = Bry_.new_u8(sql_str);
int arg_idx = 0; int pos_prv = 0;
tmp_bfr.Clear();
while (true) {
int pos_cur = Bry_finder.Find_fwd(sql_bry, Byte_ascii.Question, pos_prv); if (pos_cur == Bry_.NotFound) break;
tmp_bfr.Add_mid(sql_bry, pos_prv, pos_cur);
tmp_bfr.Add_byte(Byte_ascii.Tilde).Add_byte(Byte_ascii.Curly_bgn);
tmp_bfr.Add_int_variable(arg_idx++);
tmp_bfr.Add_byte(Byte_ascii.Curly_end);
pos_prv = pos_cur + 1;
}
tmp_bfr.Add_mid(sql_bry, pos_prv, sql_bry.length);
tmp_fmtr.Fmt_(tmp_bfr.Xto_bry_and_clear());
}
public static String Xto_str(Bry_bfr tmp_bfr, Bry_fmtr tmp_fmtr, String sql_str, List_adp args) {
Init_fmtr(tmp_bfr, tmp_fmtr, sql_str);
Object[] ary = args.To_obj_ary();
int len = ary.length;
for (int i = 0; i < len; ++i) {
Object obj = ary[i];
String str = "";
if (obj == null)
str = "NULL";
else {
str = Object_.Xto_str_strict_or_null(obj);
if (ClassAdp_.Eq(obj.getClass(), String_.Cls_ref_type))
str = "'" + String_.Replace(str, "'", "''") + "'";
}
ary[i] = str;
}
tmp_fmtr.Bld_bfr_many(tmp_bfr, ary);
return tmp_bfr.Xto_str_and_clear();
}
}

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.qrys; import gplx.*; import gplx.dbs.*;
import org.junit.*;
public class Db_stmt_sql_tst {
@Before public void init() {}
@Test public void Basic() {
Db_stmt_sql stmt = new Db_stmt_sql();
stmt.Parse(null, "UPDATE tbl_0 SET col_0 = ? WHERE col_1 = ?");
stmt.Add("col_0", "1");
stmt.Add("col_1", "2");
Tfds.Eq("UPDATE tbl_0 SET col_0 = 1 WHERE col_1 = 2", stmt.Xto_sql());
}
}

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.qrys; import gplx.*; import gplx.dbs.*;
public class Db_val_type {
public static final byte // not serialized
Tid_null = 0
, Tid_bool = 1
, Tid_byte = 2
, Tid_int32 = 3
, Tid_int64 = 4
, Tid_date = 5
, Tid_decimal = 6
, Tid_float = 7
, Tid_double = 8
, Tid_bry = 9
, Tid_varchar = 10
, Tid_nvarchar = 11
, Tid_rdr = 12
;
}

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

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