1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

'v3.3.4.1'

This commit is contained in:
gnosygnu
2016-03-27 23:44:59 -04:00
parent de67253a9c
commit baaef32df2
903 changed files with 13339 additions and 8695 deletions

View File

@@ -38,8 +38,10 @@ public interface Db_engine {
void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary);
void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld);
void Ddl_delete_tbl(String tbl);
void Env_db_attach(String alias, Db_conn conn);
void Env_db_attach(String alias, Io_url db_url);
void Env_db_detach(String alias);
void Meta_reload();
boolean Meta_tbl_exists(String tbl);
boolean Meta_fld_exists(String tbl, String fld);
Dbmeta_tbl_mgr Meta_tbl_load_all();

View File

@@ -46,7 +46,7 @@ public abstract class Db_engine_sql_base implements Db_engine {
Statement cmd = New_stmt_exec(sql);
return cmd.executeUpdate(sql);
}
catch (Exception e) {throw Err_.new_exc(e, "db", "db.engine:exec failed", "url", conn_info.Xto_api(), "sql", sql);}
catch (Exception e) {throw Err_.new_exc(e, "db", "db.engine:exec failed", "url", conn_info.Db_api(), "sql", sql);}
}
private DataRdr Exec_as_rdr(String sql) {
try {
@@ -55,16 +55,17 @@ public abstract class Db_engine_sql_base implements Db_engine {
ResultSet rdr = cmd.getResultSet();
return New_rdr(rdr, sql);
}
catch (Exception e) {throw Err_.new_exc(e, "db", "db.engine:rdr failed", "url", conn_info.Xto_api(), "sql", sql);}
catch (Exception e) {throw Err_.new_exc(e, "db", "db.engine:rdr failed", "url", conn_info.Db_api(), "sql", sql);}
}
public void Ddl_create_tbl(Dbmeta_tbl_itm tbl) {Exec_as_int(tbl.To_sql_create(this.Sql_wtr()));}
public void Ddl_create_tbl(Dbmeta_tbl_itm tbl) {Exec_as_int(tbl.To_sql_create(this.Sql_wtr())); this.Meta_reload();}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {
int len = ary.length;
for (int i = 0; i < len; ++i) {
Dbmeta_idx_itm idx = ary[i];
usr_dlg.Plog_many("", "", "creating database index (please wait); db=~{0} idx=~{1}", conn_info.Database(), idx.Name());
usr_dlg.Plog_many("", "", "creating db index (please wait); db=~{0} idx=~{1}", conn_info.Database(), idx.Name());
Exec_as_int(idx.To_sql_create(Sql_wtr()));
}
this.Meta_reload();
}
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {
Gfo_usr_dlg_.Instance.Plog_many("", "", "adding column to table: db=~{0} tbl=~{1} fld=~{2}", conn_info.Database(), tbl, fld.Name());
@@ -75,10 +76,13 @@ public abstract class Db_engine_sql_base implements Db_engine {
catch (Exception e) { // catch error if column already added to table
Gfo_usr_dlg_.Instance.Warn_many("", "", "column not added to table: db=~{0} tbl=~{1} fld=~{2} err=~{3}", conn_info.Database(), tbl, fld.Name(), Err_.Message_gplx_full(e));
}
this.Meta_reload();
}
public void Ddl_delete_tbl(String tbl) {Exec_as_int(this.Sql_wtr().Schema_wtr().Bld_drop_tbl(tbl));}
public void Ddl_delete_tbl(String tbl) {Exec_as_int(this.Sql_wtr().Schema_wtr().Bld_drop_tbl(tbl)); this.Meta_reload();}
@gplx.Virtual public void Env_db_attach(String alias, Io_url db_url) {}
@gplx.Virtual public void Env_db_attach(String alias, Db_conn db_url) {}
@gplx.Virtual public void Env_db_detach(String alias) {}
@gplx.Virtual public void Meta_reload() {}
@gplx.Virtual public boolean Meta_tbl_exists(String tbl) {return false;}
@gplx.Virtual public boolean Meta_fld_exists(String tbl, String fld) {return false;}
public abstract Dbmeta_tbl_mgr Meta_tbl_load_all();
@@ -94,7 +98,7 @@ public abstract class Db_engine_sql_base implements Db_engine {
public void Conn_term() {
if (connection == null) return; // connection never opened; just exit
try {connection.close();}
catch (Exception e) {throw Err_.new_exc(e, "db", "Conn_term failed", "url", conn_info.Xto_raw());}
catch (Exception e) {throw Err_.new_exc(e, "db", "Conn_term failed", "url", conn_info.Raw());}
connection = null;
}
public Object New_stmt_prep_as_obj(String sql) {
@@ -109,6 +113,6 @@ public abstract class Db_engine_sql_base implements Db_engine {
}
protected Connection Conn_make_by_url(String url, String uid, String pwd) {
try {return DriverManager.getConnection(url, uid, pwd);}
catch (SQLException e) {throw Err_.new_exc(e, "db", "connection open failed", "info", Conn_info().Xto_raw());}
catch (SQLException e) {throw Err_.new_exc(e, "db", "connection open failed", "info", Conn_info().Raw());}
}
}

View File

@@ -16,12 +16,11 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.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 class Mem_conn_info extends Db_conn_info__base {
public Mem_conn_info(String raw, String db_api, String database) {super(raw, db_api, database);}
@Override public String Key() {return Tid_const;} public static final String Tid_const = "mem";
@Override public Db_conn_info New_self(String raw, Keyval_hash hash) {
return new Mem_conn_info(raw, raw, hash.Get_val_as_str_or_fail("database"));
}
public static Db_conn_info new_(String database) {
return Db_conn_info_.parse(Bld_raw
@@ -29,5 +28,5 @@ public class Db_conn_info__mem extends Db_conn_info__base {
, "database", database
));
}
public static final Db_conn_info__mem Instance = new Db_conn_info__mem(); Db_conn_info__mem() {}
public static final Mem_conn_info Instance = new Mem_conn_info("", "", "");
}

View File

@@ -0,0 +1,74 @@
/*
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.*;
class Mem_db_fxt {
public Mem_db_fxt() {
Io_mgr.Instance.InitEngine_mem();
Db_conn_bldr.Instance.Reg_default_mem();
}
public Db_conn Make_conn(String url) {return Db_conn_bldr.Instance.Get_or_autocreate(Bool_.Y, Io_url_.mem_fil_(url));}
public Dbmeta_tbl_itm Exec__create_tbl(Db_conn conn, String tbl, String... fld_names) {
Dbmeta_fld_list flds = Dbmeta_fld_list.new_();
int len = fld_names.length;
for (int i = 0; i < len; ++i)
flds.Add_str(fld_names[i], 255);
Dbmeta_tbl_itm rv = Dbmeta_tbl_itm.New(tbl, flds);
conn.Meta_tbl_create(rv);
return rv;
}
public void Exec__insert(Db_conn conn, String tbl_name, String[]... rows) {
Mem_engine engine = (Mem_engine)conn.Engine();
int rows_len = rows.length;
Mem_tbl tbl = engine.Tbls__get(tbl_name);
Dbmeta_fld_list flds_list = tbl.Meta().Flds().To_fld_list();
int flds_len = flds_list.Len();
Db_stmt stmt = conn.Stmt_insert(tbl_name, flds_list);
for (int i = 0; i < rows_len; ++i) {
stmt.Clear();
String[] row = rows[i];
for (int j = 0; j < flds_len; ++j)
stmt.Val_str(flds_list.Get_at(j).Name(), row[j]);
stmt.Exec_insert();
}
}
public void Test__select(Db_conn conn, Db_qry qry, String[]... expd) {
Db_stmt stmt = conn.Stmt_new(qry);
Db_rdr rdr = new Mem_exec_select((Mem_engine)conn.Engine()).Select((Mem_stmt)stmt);
List_adp actl_list = List_adp_.new_();
Bry_bfr tmp_bfr = Bry_bfr.new_();
int expd_len = expd.length;
String[] expd_rows = new String[expd_len];
for (int i = 0; i < expd_len; ++i) {
String[] expd_row = expd[i];
for (int j = 0; j < expd_row.length; ++j) {
if (j != 0) tmp_bfr.Add_byte_pipe();
tmp_bfr.Add_str_u8(expd_row[j]);
}
expd_rows[i] = tmp_bfr.To_str_and_clear();
}
while (rdr.Move_next()) {
int fld_len = rdr.Fld_len();
for (int i = 0; i < fld_len; ++i) {
if (i != 0) tmp_bfr.Add_byte_pipe();
tmp_bfr.Add_obj_strict(rdr.Read_at(i));
}
actl_list.Add(tmp_bfr.To_str_and_clear());
}
Tfds.Eq_ary(expd_rows, (String[])actl_list.To_ary_and_clear(String.class));
}
}

View File

@@ -17,15 +17,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*;
public class Db_engine__mem implements Db_engine {
public class Mem_engine 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;}
Mem_engine(Db_conn_info conn_info) {
this.conn_info = conn_info;
this.qry_runner = new Mem_exec_select(this);
}
public String Tid() {return Mem_conn_info.Tid_const;}
public Db_conn_info Conn_info() {return conn_info;} private Db_conn_info conn_info;
public Mem_exec_select Qry_runner() {return qry_runner;} private Mem_exec_select qry_runner;
public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.Basic;
public Db_engine New_clone(Db_conn_info conn_info) {return new Db_engine__mem(conn_info);}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt__mem(this, qry);}
public Mem_tbl Tbls_get(String name) {return (Mem_tbl)tbl_hash.Get_by(name);}
public Db_engine New_clone(Db_conn_info conn_info) {return new Mem_engine(conn_info);}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Mem_stmt(this, qry);}
public Mem_tbl Tbls__get(String name) {return (Mem_tbl)tbl_hash.Get_by(name);}
public void Tbls__del(String name) {tbl_hash.Del(name);}
public void Txn_bgn(String name) {++txn_count;} private int txn_count = 0;
public String Txn_end() {--txn_count; return "";}
public void Txn_cxl() {--txn_count;}
@@ -46,14 +51,19 @@ public class Db_engine__mem implements Db_engine {
}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {} // TODO: implement unique index
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {}
public void Ddl_delete_tbl(String tbl) {}
public void Ddl_delete_tbl(String tbl_key) {
Mem_tbl tbl = (Mem_tbl)tbl_hash.Get_by(tbl_key);
if (tbl != null) tbl.rows.Clear();
}
public void Env_db_attach(String alias, Db_conn conn) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public void Meta_reload() {}
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 Dbmeta_tbl_mgr Meta_tbl_load_all() {return meta_tbl_mgr;} private final Dbmeta_tbl_mgr meta_tbl_mgr = new Dbmeta_tbl_mgr();
public static final Db_engine__mem Instance = new Db_engine__mem(); Db_engine__mem() {}
public static final Mem_engine Instance = new Mem_engine(); Mem_engine() {}
}

View File

@@ -0,0 +1,211 @@
/*
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.criterias.*;
import gplx.dbs.qrys.*; import gplx.dbs.sqls.itms.*;
public class Mem_exec_select {
private final Mem_engine engine;
private final List_adp tmp_where_rows = List_adp_.new_();
public Mem_exec_select(Mem_engine engine) {this.engine = engine;}
public Db_rdr Select(Mem_stmt stmt) {
Db_qry stmt_qry = stmt.Qry();
Mem_tbl tbl = engine.Tbls__get(stmt_qry.Base_table());
String[] select = null; Criteria where = null;
Db_qry__select_in_tbl qry = Db_qry__select_in_tbl.as_(stmt_qry);
Db_qry__select_cmd qry2 = null;
if (qry == null) {
qry2 = (Db_qry__select_cmd)stmt_qry;
select = Mem_exec_.Flds__to_str_ary(qry2.Cols().Flds);
where = qry2.Where_itm().Root;
}
else {
select = qry.Select_flds();
where = qry.Where();
}
Mem_stmt_args_.Fill(stmt.Stmt_args(), where);
Mem_row[] tbl_rows = (Mem_row[])tbl.rows.To_ary(Mem_row.class);
if (qry2 != null) {
tbl_rows = Mem_exec_.Rows__alias(tbl_rows, qry2.From().Base_tbl.Alias);
List_adp join_tbls = qry2.From().Tbls;
int join_tbls_len = join_tbls.Len();
for (int i = 1; i < join_tbls_len; ++i) {
Sql_tbl_itm join_tbl = (Sql_tbl_itm)join_tbls.Get_at(i);
Mem_row[] join_rows = (Mem_row[])engine.Tbls__get(join_tbl.Name).rows.To_ary(Mem_row.class);
join_rows = Mem_exec_.Rows__alias(join_rows, join_tbl.Alias);
tbl_rows = Mem_exec_.Rows__join(join_tbl.Join_tid, tbl_rows, join_rows, join_tbl.Alias, join_tbl.Join_flds);
}
}
Mem_exec_.Where__filter(tmp_where_rows, tbl_rows, stmt, where);
Mem_row[] rslt_rows = (Mem_row[])tmp_where_rows.To_ary_and_clear(Mem_row.class);
if (qry2 != null) {
if (qry2.Order() != null && qry2.Order().Flds().length > 0)
Array_.Sort(rslt_rows, new Mem_sorter(qry2.Order().Flds()));
int offset = qry2.Offset();
if (offset != Db_qry__select_cmd.Offset__disabled) {
Mem_row[] trg_rows = new Mem_row[rslt_rows.length - offset];
Array_.Copy_to(rslt_rows, offset, trg_rows, 0, trg_rows.length);
rslt_rows = trg_rows;
}
int limit = qry2.Limit();
if (limit != Db_qry__select_cmd.Limit__disabled) {
Mem_row[] trg_rows = new Mem_row[limit];
Array_.Copy_to(rslt_rows, 0, trg_rows, 0, limit);
rslt_rows = trg_rows;
}
rslt_rows = Mem_exec_.Rows__select_flds(rslt_rows, qry2.Cols());
}
return new Mem_rdr(select, rslt_rows);
}
}
class Mem_sorter implements gplx.core.lists.ComparerAble {
private final Sql_order_fld[] flds;
public Mem_sorter(Sql_order_fld[] flds) {
this.flds = flds;
}
public int compare(Object lhsObj, Object rhsObj) {
Mem_row lhs = (Mem_row)lhsObj;
Mem_row rhs = (Mem_row)rhsObj;
int flds_len = flds.length;
for (int i = 0; i < flds_len; ++i) {
Sql_order_fld fld = flds[i];
Object lhs_val = lhs.Get_by(fld.Name);
Object rhs_val = rhs.Get_by(fld.Name);
int comp = CompareAble_.Compare_obj(lhs_val, rhs_val);
if (comp != CompareAble_.Same) return comp * (fld.Sort == Sql_order_fld.Sort__dsc ? -1 : 1);
}
return CompareAble_.Same;
}
}
class Mem_exec_ {
public static Mem_row[] Rows__join(int join_tid, Mem_row[] lhs_rows, Mem_row[] rhs_rows, String tbl_alias, Sql_join_fld[] join_flds) {
int join_flds_len = join_flds.length;
Bry_bfr bfr = Bry_bfr.new_();
Hash_adp_bry rhs_hash = Hash_adp_bry.cs();
int rhs_rows_len = rhs_rows.length;
for (int i = 0; i < rhs_rows_len; ++i) {
Mem_row rhs_row = rhs_rows[i];
byte[] rhs_key = Rows__bld_key(bfr, Bool_.N, tbl_alias, rhs_row, join_flds, join_flds_len);
List_adp rhs_list = (List_adp)rhs_hash.Get_by_bry(rhs_key);
if (rhs_list == null) {
rhs_list = List_adp_.new_();
rhs_hash.Add(rhs_key, rhs_list);
}
rhs_list.Add(rhs_row);
}
List_adp rv = List_adp_.new_();
int lhs_len = lhs_rows.length;
for (int i = 0; i < lhs_len; ++i) {
Mem_row lhs_row = lhs_rows[i];
byte[] lhs_key = Rows__bld_key(bfr, Bool_.Y, tbl_alias, lhs_row, join_flds, join_flds_len);
List_adp rhs_list = (List_adp)rhs_hash.Get_by_bry(lhs_key);
if (rhs_list == null) {
switch (join_tid) {
case Sql_tbl_itm.Tid__inner: continue;
case Sql_tbl_itm.Tid__left: break;
default: throw Err_.new_unhandled_default(join_tid);
}
}
int rhs_list_len = rhs_list == null ? 1 : rhs_list.Len();
for (int j = 0; j < rhs_list_len; ++j) {
Mem_row rhs_row = rhs_list == null ? Mem_row.Null_row : (Mem_row)rhs_list.Get_at(j);
Mem_row merged = Rows__merge(lhs_row, rhs_row);
rv.Add(merged);
}
}
return (Mem_row[])rv.To_ary_and_clear(Mem_row.class);
}
public static Mem_row[] Rows__alias(Mem_row[] src_rows, String tbl_alias) {
int src_rows_len = src_rows.length;
Mem_row[] rv = new Mem_row[src_rows_len];
for (int i = 0; i < src_rows_len; ++i) {
Mem_row src_row = src_rows[i];
Mem_row trg_row = new Mem_row(); rv[i] = trg_row;
int src_flds_len = src_row.Len();
for (int j = 0; j < src_flds_len; ++j) {
String fld = src_row.Fld_at(j);
Object val = src_row.Get_at(j);
trg_row.Add(Sql_select_fld.Bld_tbl_w_fld(tbl_alias, fld), val);
}
}
return rv;
}
private static byte[] Rows__bld_key(Bry_bfr bfr, boolean join_is_src, String trg_tbl, Mem_row row, Sql_join_fld[] join_flds, int join_flds_len) {
for (int i = 0; i < join_flds_len; ++i) {
if (i != 0) bfr.Add_byte_pipe();
Sql_join_fld join_fld = join_flds[i];
Object val = row.Get_by(join_fld.To_fld_sql(join_is_src, trg_tbl));
bfr.Add_obj(val);
}
return bfr.To_bry_and_clear();
}
private static Mem_row Rows__merge(Mem_row lhs, Mem_row rhs) {
Mem_row rv = new Mem_row();
Rows__copy_to(lhs, rv);
Rows__copy_to(rhs, rv);
return rv;
}
private static void Rows__copy_to(Mem_row src, Mem_row trg) {
int src_len = src.Len();
for (int i = 0; i < src_len; ++i) {
String fld = src.Fld_at(i);
Object val = src.Get_by_or_dbnull(fld);
trg.Add(fld, val);
}
}
public static Mem_row[] Rows__select_flds(Mem_row[] src_rows, Sql_select_clause cols) {
Sql_select_fld_list select_flds = cols.Flds; int select_flds_len = select_flds.Len();
int src_rows_len = src_rows.length;
Mem_row[] rv = new Mem_row[src_rows_len];
for (int i = 0; i < src_rows_len; ++i) { // loop over each row
Mem_row src_row = src_rows[i];
Mem_row trg_row = new Mem_row(); rv[i] = trg_row;
for (int j = 0; j < select_flds_len; ++j) { // loop over each fld
Sql_select_fld fld = select_flds.Get_at(j);
if (String_.Eq(fld.Alias, Sql_select_fld.Fld__wildcard)) { // wildcard; add all cols
for (int k = 0; k < src_row.Len(); ++k) {
String key = src_row.Fld_at(k);
Object val = src_row.Get_by_or_dbnull(key);
trg_row.Add(key, val);
}
}
else { // regular field; add it only
String key = fld.To_fld_key();
Object val = src_row.Get_by_or_dbnull(key);
trg_row.Add(fld.To_fld_alias(), val);
}
}
}
return rv;
}
public static String[] Flds__to_str_ary(Sql_select_fld_list flds) {
int len = flds.Len();
String[] rv = new String[len];
for (int i = 0; i < len; ++i)
rv[i] = flds.Get_at(i).Fld;
return rv;
}
public static void Where__filter(List_adp rv, Mem_row[] rows, Mem_stmt stmt, Criteria crt) {
rv.Clear();
int rows_len = rows.length;
for (int i = 0; i < rows_len; ++i) {
Mem_row itm = rows[i];
if (crt.Matches(itm))
rv.Add(itm);
}
}
}

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.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import org.junit.*; import gplx.dbs.sqls.itms.*;
public class Mem_exec_select_tst {
private final Mem_db_fxt__single fxt = new Mem_db_fxt__single();
@Test public void Basic() {
fxt.Exec__create_tbl("tbl_1", "fld_1");
fxt.Exec__insert("tbl_1"
, String_.Ary("a_1")
, String_.Ary("a_2")
, String_.Ary("a_0")
);
// select all
fxt.Test__select(Db_qry_.select_().From_("tbl_1").Cols_all_()
, String_.Ary("a_1")
, String_.Ary("a_2")
, String_.Ary("a_0")
);
// order by
fxt.Test__select(Db_qry_.select_().From_("tbl_1").Cols_all_().Order_("fld_1", Bool_.N)
, String_.Ary("a_2")
, String_.Ary("a_1")
, String_.Ary("a_0")
);
// offset
fxt.Test__select(Db_qry_.select_().From_("tbl_1").Cols_all_().Offset_(1)
, String_.Ary("a_2")
, String_.Ary("a_0")
);
// limit
fxt.Test__select(Db_qry_.select_().From_("tbl_1").Cols_all_().Limit_(2)
, String_.Ary("a_1")
, String_.Ary("a_2")
);
}
@Test public void Join__single() {
fxt.Exec__create_tbl("tbl_1", "fld_a", "fld_1a");
fxt.Exec__create_tbl("tbl_2", "fld_a", "fld_2a");
fxt.Exec__insert("tbl_1"
, String_.Ary("a_0", "1a_0")
, String_.Ary("a_1", "1a_1")
, String_.Ary("a_2", "1a_2")
);
fxt.Exec__insert("tbl_2"
, String_.Ary("a_0", "2a_0")
, String_.Ary("a_2", "2a_2")
);
// inner join
fxt.Test__select(Db_qry_.select_()
.Cols_w_tbl_("t1", "fld_a", "fld_1a").Cols_w_tbl_("t2", "fld_2a")
.From_("tbl_1", "t1")
. Join_("tbl_2", "t2", Db_qry_.New_join__join("fld_a", "t1", "fld_a"))
, String_.Ary("a_0", "1a_0", "2a_0")
, String_.Ary("a_2", "1a_2", "2a_2")
);
// left join
fxt.Test__select(Db_qry_.select_()
.Cols_w_tbl_("t1", "fld_a", "fld_1a").Cols_w_tbl_("t2", "fld_2a")
.From_("tbl_1", "t1")
. Join_(Sql_tbl_itm.Tid__left, Sql_tbl_itm.Db__null, "tbl_2", "t2", Db_qry_.New_join__join("fld_a", "t1", "fld_a"))
, String_.Ary("a_0", "1a_0", "2a_0")
, String_.Ary("a_1", "1a_1", Db_null.Null_str)
, String_.Ary("a_2", "1a_2", "2a_2")
);
}
@Test public void Join__many() {
fxt.Exec__create_tbl("tbl_1", "fld_a", "fld_1a");
fxt.Exec__create_tbl("tbl_2", "fld_a", "fld_2a");
fxt.Exec__insert("tbl_1"
, String_.Ary("a_0", "1a_0")
, String_.Ary("a_1", "1a_1")
);
fxt.Exec__insert("tbl_2"
, String_.Ary("a_0", "2a_0")
, String_.Ary("a_0", "2a_1")
);
// inner join
fxt.Test__select(Db_qry_.select_()
.Cols_w_tbl_("t1", "fld_a", "fld_1a").Cols_w_tbl_("t2", "fld_2a")
.From_("tbl_1", "t1")
. Join_("tbl_2", "t2", Db_qry_.New_join__join("fld_a", "t1", "fld_a"))
, String_.Ary("a_0", "1a_0", "2a_0")
, String_.Ary("a_0", "1a_0", "2a_1")
);
// left join
fxt.Test__select(Db_qry_.select_()
.Cols_w_tbl_("t1", "fld_a", "fld_1a").Cols_w_tbl_("t2", "fld_2a")
.From_("tbl_1", "t1")
. Join_(Sql_tbl_itm.Tid__left, Sql_tbl_itm.Db__null, "tbl_2", "t2", Db_qry_.New_join__join("fld_a", "t1", "fld_a"))
, String_.Ary("a_0", "1a_0", "2a_0")
, String_.Ary("a_0", "1a_0", "2a_1")
, String_.Ary("a_1", "1a_1", Db_null.Null_str)
);
}
}
class Mem_db_fxt__single {
private final Mem_db_fxt mem_fxt;
private final Db_conn conn;
public Mem_db_fxt__single() {
this.mem_fxt = new Mem_db_fxt();
this.conn = mem_fxt.Make_conn("mem/test.db");
}
public void Exec__create_tbl (String tbl, String... fld_names) {mem_fxt.Exec__create_tbl(conn, tbl, fld_names);}
public void Exec__insert (String tbl, String[]... rows) {mem_fxt.Exec__insert(conn, tbl, rows);}
public void Test__select (Db_qry qry, String[]... expd) {mem_fxt.Test__select(conn, qry, expd);}
}

View File

@@ -16,10 +16,10 @@ 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 {
public class Mem_rdr 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) {
public Mem_rdr(String[] cols, Mem_row[] rows) {
this.rows = rows; this.rows_len = rows.length;
}
public boolean Move_next() {
@@ -39,6 +39,7 @@ public class Db_rdr__mem implements Db_rdr {
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 int Fld_len() {return row.Len();}
public Object Read_obj(String k) {return row.Get_by(k);}
public Object Read_at(int i) {return row.Get_at(i);}
public void Rls() {}

View File

@@ -18,13 +18,22 @@ 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);}
private final Ordered_hash flds = Ordered_hash_.New();
public int Len() {return hash.Len();}
public String Fld_at(int i) {return (String)flds.Get_at(i);}
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 Get_by(String key) {return hash.Get_by(key);}
public Object Get_by_or_dbnull(String key) {
Object rv = hash.Get_by(key);
return rv == null ? Db_null.Instance : rv;
}
public void Set_by(String key, Object val) {hash.Add_if_dupe_use_nth(key, val); flds.Add_if_dupe_use_1st(key, key);}
public void Add(String key, Object val) {hash.Add(key, val); flds.Add_if_dupe_use_1st(key, key);}
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;
}
public static final Mem_row[] Ary_empty = new Mem_row[0];
public static final Mem_row Null_row = new Mem_row();
}

View File

@@ -17,12 +17,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*;
public class Db_stmt__mem implements Db_stmt {
public class Mem_stmt 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 Mem_stmt(Mem_engine engine, Db_qry qry) {Ctor_stmt(engine, qry);} private Mem_engine engine;
public void Ctor_stmt(Db_engine engine, Db_qry qry) {this.engine = (Mem_engine)engine; this.qry = qry;}
public Mem_stmt_args Stmt_args() {return stmt_args;} private final Mem_stmt_args stmt_args = new Mem_stmt_args();
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);}
@@ -30,7 +30,7 @@ public class Db_stmt__mem implements Db_stmt {
public Db_stmt Reset_stmt() {return this;}
public Db_stmt Clear() {
val_list.Clear();
crt_hash.Clear();
stmt_args.Clear();
return this;
}
public void Rls() {this.Clear();}
@@ -120,35 +120,29 @@ public class Db_stmt__mem implements Db_stmt {
return this;
}
public boolean Exec_insert() {
Mem_tbl tbl = engine.Tbls_get(qry.Base_table());
Mem_tbl tbl = engine.Tbls__get(qry.Base_table());
if (tbl == null) throw Err_.new_wo_type("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());
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());
Mem_tbl tbl = engine.Tbls__get(qry.Base_table());
return tbl.Delete(this);
}
public DataRdr Exec_select() {throw Err_.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);
// Mem_tbl tbl = engine.Tbls_get(qry.Base_table());
// return tbl.Select(this);
return engine.Qry_runner().Select(this);
}
public Object Exec_select_val() {throw Err_.new_unimplemented();}
private void Add(String k, boolean where, Object v) {
if (k == Dbmeta_fld_itm.Key_null) return; // key is explicitly null; ignore; allows schema_2+ type definitions
if (k == Dbmeta_fld_itm.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);
}
if (where) stmt_args.Add(k, v);
}
}

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.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.criterias.*;
public class Mem_stmt_args {
private final List_adp list = List_adp_.new_();
private int cur_idx = -1;
public void Clear() {list.Clear(); cur_idx = -1;}
public void Add(String k, Object v) {list.Add(Keyval_.new_(k, v));}
public Keyval Get_next() {
int idx = ++cur_idx;
return idx == list.Count() ? null: (Keyval)list.Get_at(idx);
}
}
class Mem_stmt_args_ {
public static void Fill(Mem_stmt_args args, Criteria crt) {
int tid = crt.Tid();
if (tid == Criteria_.Tid_wrapper) {
Criteria_fld fld = (Criteria_fld)crt;
Criteria sub = fld.Crt();
String fld_key = fld.Key();
switch (sub.Tid()) {
case Criteria_.Tid_eq:
case Criteria_.Tid_comp:
case Criteria_.Tid_like:
case Criteria_.Tid_iomatch:
Keyval kvp = args.Get_next();
if (!String_.Eq(kvp.Key(), fld.Key())) throw Err_.new_("db", "fld_crt.key mismatch", "fld.key", fld_key, "kvp.key", kvp.Key());
sub.Val_as_obj_(kvp.Val());
break;
case Criteria_.Tid_in:
Criteria_in crt_in = (Criteria_in)sub;
Object[] ary = crt_in.Ary(); int ary_len = crt_in.Ary_len();
for (int i = 0; i < ary_len; ++i)
ary[i] = args.Get_next().Val();
break;
case Criteria_.Tid_between:
Criteria_between crt_between = (Criteria_between)sub;
crt_between.Lo_((Comparable)(args.Get_next()).Val());
crt_between.Hi_((Comparable)(args.Get_next()).Val());
break;
default: throw Err_.new_unhandled(sub.Tid());
}
}
else {
switch (tid) {
case Criteria_.Tid_const: break; // true / false; nothing to fill
case Criteria_.Tid_and:
case Criteria_.Tid_or:
Criteria_bool_base crt_dual = (Criteria_bool_base)crt;
Fill(args, crt_dual.Lhs());
Fill(args, crt_dual.Rhs());
break;
case Criteria_.Tid_not:
Criteria_not crt_not = (Criteria_not)crt;
Fill(args, crt_not.Crt());
break;
default: throw Err_.new_unhandled(tid);
}
}
}
}

View File

@@ -19,11 +19,12 @@ package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs
import gplx.core.primitives.*; import gplx.core.criterias.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.itms.*;
import gplx.dbs.metas.*;
public class Mem_tbl {
private final List_adp rows = List_adp_.new_(); private final List_adp where_rows = List_adp_.new_();
private final List_adp where_rows = List_adp_.new_();
private final Hash_adp autonum_hash = Hash_adp_.new_();
public Mem_tbl(Dbmeta_tbl_itm meta) {this.meta = meta;}
public Dbmeta_tbl_itm Meta() {return meta;} private final Dbmeta_tbl_itm meta;
public int Insert(Db_stmt__mem stmt) {
public final List_adp rows = List_adp_.new_();
public int Insert(Mem_stmt stmt) {
Mem_row itm = new Mem_row();
Dbmeta_fld_mgr flds = meta.Flds();
int len = flds.Len();
@@ -31,6 +32,7 @@ public class Mem_tbl {
Dbmeta_fld_itm fld = flds.Get_at(i);
String fld_name = fld.Name();
Object val = fld.Autonum() ? Autonum_calc(fld_name) : stmt.Args_get_by(fld_name);
if (val == null) continue; // NOTE: allow Bulk_insert from test to skip filds
itm.Set_by(fld_name, val);
}
rows.Add(itm);
@@ -44,10 +46,11 @@ public class Mem_tbl {
}
return autonum_itm.Val_add();
}
public int Update(Db_stmt__mem stmt) {
public int Update(Mem_stmt 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());
Criteria where_crt = qry.Where(); if (where_crt == null) where_crt = Criteria_.All;
Mem_stmt_args_.Fill(stmt.Stmt_args(), where_crt);
Select_rows_where(where_rows, stmt, where_crt);
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) {
@@ -57,9 +60,9 @@ public class Mem_tbl {
}
return where_rows_len;
}
public int Delete(Db_stmt__mem stmt) {
public int Delete(Mem_stmt stmt) {
Db_qry_delete qry = (Db_qry_delete)stmt.Qry();
qry.Where().Val_from_args(stmt.Crts());
Mem_stmt_args_.Fill(stmt.Stmt_args(), qry.Where());
Select_rows_where(where_rows, stmt, qry.Where());
int where_rows_len = where_rows.Count();
for (int i = 0; i < where_rows_len; ++i) {
@@ -68,7 +71,7 @@ public class Mem_tbl {
}
return where_rows_len;
}
public Db_rdr Select(Db_stmt__mem stmt) {
public Db_rdr Select(Mem_stmt stmt) {
String[] select = null; Criteria where = null;
Db_qry__select_in_tbl qry = Db_qry__select_in_tbl.as_(stmt.Qry());
if (qry == null) {
@@ -80,9 +83,9 @@ public class Mem_tbl {
select = qry.Select_flds();
where = qry.Where();
}
where.Val_from_args(stmt.Crts());
Mem_stmt_args_.Fill(stmt.Stmt_args(), where);
Select_rows_where(where_rows, stmt, where);
return new Db_rdr__mem(select, (Mem_row[])where_rows.To_ary_and_clear(Mem_row.class));
return new Mem_rdr(select, (Mem_row[])where_rows.To_ary_and_clear(Mem_row.class));
}
private String[] To_str_ary(Sql_select_fld_list flds) {
int len = flds.Len();
@@ -91,7 +94,7 @@ public class Mem_tbl {
rv[i] = flds.Get_at(i).Fld;
return rv;
}
private void Select_rows_where(List_adp rv, Db_stmt__mem stmt, Criteria crt) {
private void Select_rows_where(List_adp rv, Mem_stmt stmt, Criteria crt) {
rv.Clear();
int rows_len = rows.Count();
for (int i = 0; i < rows_len; ++i) {

View File

@@ -17,9 +17,15 @@ 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 Mysql_conn_info(String raw, String db_api, String database, String server, String uid, String pwd) {super(raw, db_api, database);
this.server = server;
this.uid = uid;
this.pwd = pwd;
}
@Override public String Key() {return Tid_const;} public static final String Tid_const = "mysql";
public String Server() {return server;} private final String server;
public String Uid() {return uid;} private final String uid;
public String Pwd() {return pwd;} private final 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
@@ -30,12 +36,10 @@ public class Mysql_conn_info extends Db_conn_info__base {
, "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;
@Override public Db_conn_info New_self(String raw, Keyval_hash hash) {
return new Mysql_conn_info
( raw, Bld_api(hash, Keyval_.new_("charset", "utf8")), hash.Get_val_as_str_or_fail("database")
, hash.Get_val_as_str_or_fail("server"), hash.Get_val_as_str_or_fail("uid"), hash.Get_val_as_str_or_fail("pwd"));
}
public static final Mysql_conn_info Instance = new Mysql_conn_info(); Mysql_conn_info() {}
public static final Mysql_conn_info Instance = new Mysql_conn_info("", "", "", "", "", "");
}

View File

@@ -30,7 +30,8 @@ public class Mysql_engine extends Db_engine_sql_base {
@Override public Dbmeta_tbl_mgr Meta_tbl_load_all() {throw Err_.new_unimplemented();}
@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());
Connection rv = Conn_make_by_url("jdbc:mysql://localhost/" + conn_info_as_mysql.Database() + "?characterEncoding=UTF8&useSSL=false", conn_info_as_mysql.Uid(), conn_info_as_mysql.Pwd());
return rv;
}
public static final Mysql_engine Instance = new Mysql_engine(); Mysql_engine() {}
}

View File

@@ -17,7 +17,8 @@ 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 Instance = new Noop_conn_info(); Noop_conn_info() {this.Ctor("", "", "gplx_key=null_db", "");}
public Noop_conn_info(String raw, String db_api, String database) {super(raw, db_api, database);}
@Override public String Key() {return Tid_const;} public static final String Tid_const = "null_db";
@Override public Db_conn_info New_self(String raw, Keyval_hash hash) {return this;}
public static final Noop_conn_info Instance = new Noop_conn_info("gplx_key=null_db", "", "");
}

View File

@@ -38,8 +38,10 @@ public class Noop_engine implements Db_engine {
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {}
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {}
public void Ddl_delete_tbl(String tbl) {}
public void Env_db_attach(String alias, Db_conn conn) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public void Meta_reload() {}
public boolean Meta_tbl_exists(String tbl) {return false;}
public boolean Meta_fld_exists(String tbl, String fld) {return false;}
public Dbmeta_tbl_mgr Meta_tbl_load_all() {return meta_tbl_mgr;} private final Dbmeta_tbl_mgr meta_tbl_mgr = new Dbmeta_tbl_mgr();

View File

@@ -17,9 +17,15 @@ 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 Postgres_conn_info(String raw, String db_api, String database, String server, String uid, String pwd) {super(raw, db_api, database);
this.server = server;
this.uid = uid;
this.pwd = pwd;
}
@Override public String Key() {return Tid_const;} public static final String Tid_const = "postgresql";
public String Server() {return server;} private final String server;
public String Uid() {return uid;} private final String uid;
public String Pwd() {return pwd;} private final 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
@@ -31,12 +37,10 @@ public class Postgres_conn_info extends Db_conn_info__base {
, "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;
@Override public Db_conn_info New_self(String raw, Keyval_hash hash) {
return new Postgres_conn_info
( raw, Bld_api(hash, Keyval_.new_("encoding", "unicode")), hash.Get_val_as_str_or_fail("database")
, hash.Get_val_as_str_or_fail("server"), hash.Get_val_as_str_or_fail("user id"), hash.Get_val_as_str_or_fail("password"));
}
public static final Postgres_conn_info Instance = new Postgres_conn_info(); Postgres_conn_info() {}
public static final Postgres_conn_info Instance = new Postgres_conn_info("", "", "", "", "", "");
}

View File

@@ -29,8 +29,8 @@ public class Postgres_engine extends Db_engine_sql_base {
@Override public DataRdr New_rdr(ResultSet rdr, String commandText) {return Db_data_rdr_.new_(rdr, commandText);}
@Override public Dbmeta_tbl_mgr Meta_tbl_load_all() {throw Err_.new_unimplemented();}
@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());
Postgres_conn_info conn_info_as_postgres = (Postgres_conn_info)conn_info;
return Conn_make_by_url("jdbc:" + conn_info_as_postgres.Key() + "://localhost/" + conn_info_as_postgres.Database(), conn_info_as_postgres.Uid(), conn_info_as_postgres.Pwd());
}
public static final Postgres_engine Instance = new Postgres_engine(); Postgres_engine() {}
}

View File

@@ -17,19 +17,20 @@ 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 Sqlite_conn_info(String raw, String db_api, String database, Io_url url) {super(raw, db_api, database);this.url = url;}
@Override public String Key() {return Key_const;} public static final String Key_const = "sqlite";
public Io_url Url() {return url;} private final Io_url url;
@Override public Db_conn_info New_self(String raw, Keyval_hash hash) {
Io_url url = Io_url_.new_any_(hash.Get_val_as_str_or_fail("data source"));
String db = url.NameOnly();
String api = Bld_api(hash, Keyval_.new_("version", "3"));
return new Sqlite_conn_info(raw, api, db, url);
}
public static final Sqlite_conn_info Instance = new Sqlite_conn_info("", "", "", Io_url_.Empty);
public static Db_conn_info load_(Io_url url) {
return Db_conn_info_.parse(Bld_raw
( "gplx_key" , Tid_const
( "gplx_key" , Key_const
, Cs__data_source , url.Xto_api()
, Cs__version , Cs__version__3
));
@@ -37,12 +38,12 @@ public class Sqlite_conn_info extends Db_conn_info__base {
public static Db_conn_info make_(Io_url url) {
Io_mgr.Instance.CreateDirIfAbsent(url.OwnerDir());
return Db_conn_info_.parse(Bld_raw
( "gplx_key" , Tid_const
( "gplx_key" , Key_const
, Cs__data_source , url.Xto_api()
, Cs__version , Cs__version__3
));
}
public static final Sqlite_conn_info Instance = new Sqlite_conn_info(); Sqlite_conn_info() {}
public static final String Cs__data_source = "data source", Cs__version = "version", Cs__version__3 = "3";
public static Io_url To_url(Db_conn conn) {return ((Sqlite_conn_info)conn.Conn_info()).url;}
}

View File

@@ -19,13 +19,14 @@ package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.d
import java.sql.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.engines.sqlite.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*;
import gplx.dbs.qrys.*;
import org.sqlite.SQLiteConnection;
public class Sqlite_engine extends Db_engine_sql_base {
private final Sqlite_txn_mgr txn_mgr; private final Sqlite_schema_mgr schema_mgr;
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 String Tid() {return Sqlite_conn_info.Key_const;}
@Override public gplx.dbs.sqls.Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.Sqlite;}
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
Sqlite_engine rv = new Sqlite_engine();
@@ -34,12 +35,18 @@ public class Sqlite_engine extends Db_engine_sql_base {
}
@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, Db_conn conn) {
Db_conn_info cs_obj = conn.Conn_info(); if (!String_.Eq(cs_obj.Key(), Sqlite_conn_info.Key_const)) throw Err_.new_("dbs", "must attach to sqlite databases", "conn", cs_obj.Raw());
Sqlite_conn_info cs = (Sqlite_conn_info)cs_obj;
Env_db_attach(alias, cs.Url());
}
@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 String Txn_end() {return txn_mgr.Txn_end();}
@Override public void Txn_cxl() {txn_mgr.Txn_cxl();}
@Override public void Txn_sav() {txn_mgr.Txn_sav();}
@Override public void Meta_reload() {schema_mgr.Tbl_load_all();}
@Override public boolean Meta_tbl_exists(String tbl) {return schema_mgr.Tbl_exists(tbl);}
@Override public boolean Meta_fld_exists(String tbl, String fld) {return schema_mgr.Fld_exists(tbl, fld);}
@Override public Dbmeta_tbl_mgr Meta_tbl_load_all() {return schema_mgr.Tbl_load_all();}
@@ -56,9 +63,12 @@ public class Sqlite_engine extends Db_engine_sql_base {
}
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(), "\\", "/"), "", "");
SQLiteConnection rv_as_sqlite = (org.sqlite.SQLiteConnection)rv;
try {rv_as_sqlite.setBusyTimeout(10000);}
catch (SQLException e) {Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to set busy timeout; err=~{0}", Err_.Message_gplx_log(e));}
return rv;
}
public static final Sqlite_engine Instance = new Sqlite_engine();
public static final Sqlite_engine Instance = 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 Err_.new_exc(e, "db", "read failed", "k", k, "type", Byte_.Cls_val_name);}}
@Override public boolean Read_bool_by_byte(String k) {

View File

@@ -74,15 +74,6 @@ public class Sqlite_engine_ {
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.Instance.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.Instance.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;

View File

@@ -38,7 +38,7 @@ public class Sqlite_schema_mgr {
}
private void Init(Db_engine engine) {
init = false;
Gfo_usr_dlg_.Instance.Log_many("", "", "db.schema.load.bgn: conn=~{0}", engine.Conn_info().Xto_api());
Gfo_usr_dlg_.Instance.Log_many("", "", "db.schema.load.bgn: conn=~{0}", engine.Conn_info().Db_api());
tbl_mgr.Clear(); idx_mgr.Clear();
Dbmeta_parser__tbl tbl_parser = new Dbmeta_parser__tbl();
Dbmeta_parser__idx idx_parser = new Dbmeta_parser__idx();
@@ -52,14 +52,15 @@ public class Sqlite_schema_mgr {
int type_int = Dbmeta_itm_tid.Xto_int(type_str);
switch (type_int) {
case Dbmeta_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)";
if (String_.Has_at_bgn(name, "sqlite_")) continue; // ignore b/c of non-orthodox syntax; EX: "CREATE TABLE sqlite_sequence(name, seq)"; also "CREATE TABLE sqlite_stat(tbl,idx,stat)";
tbl_mgr.Add(tbl_parser.Parse(Bry_.new_u8(sql)));
break;
case Dbmeta_itm_tid.Tid_index:
if (sql == null) continue; // ignore "autoindex"; EX: sqlite_autoindex_temp_page_len_avg_1
idx_mgr.Add(idx_parser.Parse(Bry_.new_u8(sql)));
break;
default:
Gfo_usr_dlg_.Instance.Log_many("", "", "db.schema.unknown type: conn=~{0} type=~{1} name=~{2} sql=~{3}", engine.Conn_info().Xto_api(), type_str, name, sql);
Gfo_usr_dlg_.Instance.Log_many("", "", "db.schema.unknown type: conn=~{0} type=~{1} name=~{2} sql=~{3}", engine.Conn_info().Db_api(), type_str, name, sql);
break;
}
}

View File

@@ -63,8 +63,10 @@ public class TdbEngine implements Db_engine {
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {throw Err_.new_unimplemented();}
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {throw Err_.new_unimplemented();}
public void Ddl_delete_tbl(String tbl) {}
public void Env_db_attach(String alias, Db_conn conn) {}
public void Env_db_attach(String alias, Io_url db_url) {}
public void Env_db_detach(String alias) {}
public void Meta_reload() {}
public boolean Meta_tbl_exists(String name) {return false;}
public boolean Meta_fld_exists(String tbl, String fld) {return false;}
public Dbmeta_tbl_mgr Meta_tbl_load_all() {return meta_tbl_mgr;} private final Dbmeta_tbl_mgr meta_tbl_mgr = new Dbmeta_tbl_mgr();

View File

@@ -49,7 +49,7 @@ class TdbInsertWkr implements Db_qryWkr {
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);
Keyval kv = insert.Args().Get_at(i);
Db_arg arg = (Db_arg)kv.Val();
row.Write(kv.Key(), arg.Val);
}

View File

@@ -24,11 +24,11 @@ class TdbSelectWkr implements Db_qryWkr {
if (cmd.From().Tbls.Count() > 1) throw Err_.new_("gplx.tdbs", "joins not supported for tdbs", "sql", cmd.To_sql__exec(engineObj.Sql_wtr()));
TdbTable tbl = engine.FetchTbl(cmd.From().Base_tbl.Name);
GfoNdeList rv = (cmd.Where_itm() == Sql_where_itm.Where__null && cmd.Limit() == Db_qry__select_cmd.Limit__disabled) ? rv = tbl.Rows() : FilterRecords(tbl, cmd.Where_itm().Root, cmd.Limit());
GfoNdeList rv = (cmd.Where_itm() == Sql_where_clause.Where__null && cmd.Limit() == Db_qry__select_cmd.Limit__disabled) ? rv = tbl.Rows() : FilterRecords(tbl, cmd.Where_itm().Root, cmd.Limit());
if (cmd.GroupBy() != null)
rv = TdbGroupByWkr.GroupByExec(cmd, rv, tbl);
if (cmd.Order() != null) { // don't use null pattern here; if null ORDER BY, then don't call .Sort on GfoNdeList
ComparerAble comparer = Sql_order_fld_sorter.new_(cmd.Order().Flds);
ComparerAble comparer = Sql_order_fld_sorter.new_(cmd.Order().Flds());
rv.Sort_by(comparer);
}
return GfoNdeRdr_.peers_(rv, false);

View File

@@ -37,7 +37,7 @@ class TdbUpdateWkr implements Db_qryWkr {
}
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);
Keyval p = (Keyval)cmd.Args().Get_at(i);
Db_arg prm = (Db_arg)p.Val();
row.Write(p.Key(), prm.Val);
}

View File

@@ -17,21 +17,21 @@ 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) {
public Tdb_conn_info(String raw, String db_api, String database, Io_url url) {super(raw, db_api, database);this.url = url; this.server = url.Raw(); }
@Override public String Key() {return Tid_const;} public static final String Tid_const = "tdb";
public Io_url Url() {return url;} private final Io_url url;
public String Server() {return server;} private final String server;
@Override public Db_conn_info New_self(String raw, Keyval_hash hash) {
Io_url url = Io_url_.new_any_(hash.Get_val_as_str_or_fail("url"));
String db = url.NameOnly();
String api = Bld_api(hash, Keyval_.new_("version", "3"));
return new Tdb_conn_info(raw, api, db, url);
}
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 Instance = new Tdb_conn_info();
public static final Tdb_conn_info Instance = new Tdb_conn_info("", "", "", Io_url_.Empty);
}