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

View File

@@ -16,10 +16,11 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines; import gplx.*; import gplx.dbs.*;
import gplx.core.stores.*; import gplx.dbs.metas.*;
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*;
public interface Db_engine {
String Tid();
Db_conn_info Conn_info();
Sql_qry_wtr Sql_wtr();
Db_engine New_clone(Db_conn_info url);
Db_rdr New_rdr__rls_manual (Object rdr_obj, String sql); // Object o:ResultSet if desktop; Cursor if android
Db_rdr New_rdr__rls_auto (Db_stmt stmt, Object rdr_obj, String sql); // Object o:ResultSet if desktop; Cursor if android

View File

@@ -18,26 +18,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.dbs.engines; import gplx.*; import gplx.dbs.*;
import java.sql.*;
import gplx.core.stores.*;
import gplx.dbs.engines.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.metas.*;
import gplx.dbs.engines.*; import gplx.dbs.metas.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*;
public abstract class Db_engine_sql_base implements Db_engine {
@gplx.Internal protected void Ctor(Db_conn_info conn_info) {this.conn_info = conn_info;}
public abstract String Tid();
public Db_conn_info Conn_info() {return conn_info;} protected Db_conn_info conn_info;
public abstract Db_engine New_clone(Db_conn_info conn_info);
public Db_rdr New_rdr__rls_manual(Object rdr_obj, String sql) {return New_rdr(null, rdr_obj, sql);}
public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {return New_rdr(stmt, rdr_obj, sql);}
@gplx.Virtual public Db_rdr New_rdr_clone() {return new Db_rdr__basic();}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_cmd(this, qry);}
@gplx.Virtual public void Txn_bgn(String name) {Exec_as_obj(Db_qry_sql.xtn_("BEGIN TRANSACTION;"));}
@gplx.Virtual public String Txn_end() {Exec_as_obj(Db_qry_sql.xtn_("COMMIT TRANSACTION;")); return "";}
@gplx.Virtual public void Txn_cxl() {Exec_as_obj(Db_qry_sql.xtn_("ROLLBACK TRANSACTION;"));}
@gplx.Virtual public void Txn_sav() {
public abstract String Tid();
public Db_conn_info Conn_info() {return conn_info;} protected Db_conn_info conn_info;
public abstract Sql_qry_wtr Sql_wtr();
public abstract Db_engine New_clone(Db_conn_info conn_info);
public Db_rdr New_rdr__rls_manual(Object rdr_obj, String sql) {return New_rdr(null, rdr_obj, sql);}
public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {return New_rdr(stmt, rdr_obj, sql);}
@gplx.Virtual public Db_rdr New_rdr_clone() {return new Db_rdr__basic();}
@gplx.Virtual public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_cmd(this, qry);}
@gplx.Virtual public void Txn_bgn(String name) {Exec_as_obj(Db_qry_sql.xtn_("BEGIN TRANSACTION;"));}
@gplx.Virtual public String Txn_end() {Exec_as_obj(Db_qry_sql.xtn_("COMMIT TRANSACTION;")); return "";}
@gplx.Virtual public void Txn_cxl() {Exec_as_obj(Db_qry_sql.xtn_("ROLLBACK TRANSACTION;"));}
@gplx.Virtual public void Txn_sav() {
String txn_name = this.Txn_end();
this.Txn_bgn(txn_name);
}
public Object Exec_as_obj(Db_qry qry) {
if (qry.Tid() == Db_qry_.Tid_flush) return null; // ignore flush (delete-db) statements
String sql = this.SqlWtr().Xto_str(qry, false); // DBG: Tfds.Write(sql);
String sql = this.Sql_wtr().To_sql_str(qry, false); // DBG: Tfds.Write(sql);
return qry.Exec_is_rdr() ? (Object)this.Exec_as_rdr(sql) : this.Exec_as_int(sql);
}
protected int Exec_as_int(String sql) {
@@ -56,33 +57,32 @@ public abstract class Db_engine_sql_base implements Db_engine {
}
catch (Exception e) {throw Err_.new_exc(e, "db", "db.engine:rdr failed", "url", conn_info.Xto_api(), "sql", sql);}
}
public void Ddl_create_tbl(Dbmeta_tbl_itm tbl) {Exec_as_int(tbl.To_sql_create());}
public void Ddl_create_tbl(Dbmeta_tbl_itm tbl) {Exec_as_int(tbl.To_sql_create(this.Sql_wtr()));}
public void Ddl_create_idx(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {
int len = ary.length;
for (int i = 0; i < len; ++i) {
Dbmeta_idx_itm idx = ary[i];
usr_dlg.Plog_many("", "", "creating database index (please wait); db=~{0} idx=~{1}", conn_info.Database(), idx.Name());
Exec_as_int(idx.To_sql_create());
Exec_as_int(idx.To_sql_create(Sql_wtr()));
}
}
public void Ddl_append_fld(String tbl, Dbmeta_fld_itm fld) {
Gfo_usr_dlg_.Instance.Plog_many("", "", "adding column to table: db=~{0} tbl=~{1} fld=~{2}", conn_info.Database(), tbl, fld.Name());
try {
Exec_as_int(Db_sqlbldr__sqlite.Instance.Bld_alter_tbl_add(tbl, fld));
Exec_as_int(this.Sql_wtr().Schema_wtr().Bld_alter_tbl_add(tbl, fld));
Gfo_usr_dlg_.Instance.Plog_many("", "", "column added to table: db=~{0} tbl=~{1} fld=~{2}", conn_info.Database(), tbl, fld.Name());
}
catch (Exception e) { // catch error if column already added to table
Gfo_usr_dlg_.Instance.Warn_many("", "", "column not added to table: db=~{0} tbl=~{1} fld=~{2} err=~{3}", conn_info.Database(), tbl, fld.Name(), Err_.Message_gplx_full(e));
}
}
public void Ddl_delete_tbl(String tbl) {Exec_as_int(Db_sqlbldr__sqlite.Instance.Bld_drop_tbl(tbl));}
public void Ddl_delete_tbl(String tbl) {Exec_as_int(this.Sql_wtr().Schema_wtr().Bld_drop_tbl(tbl));}
@gplx.Virtual public void Env_db_attach(String alias, Io_url db_url) {}
@gplx.Virtual public void Env_db_detach(String alias) {}
@gplx.Virtual public boolean Meta_tbl_exists(String tbl) {return false;}
@gplx.Virtual public boolean Meta_fld_exists(String tbl, String fld) {return false;}
public abstract Dbmeta_tbl_mgr Meta_tbl_load_all();
@gplx.Virtual public DataRdr New_rdr(ResultSet rdr, String sql) {return gplx.core.stores.Db_data_rdr_.new_(rdr, sql);}
@gplx.Virtual public Sql_qry_wtr SqlWtr() {return Sql_qry_wtr_.new_ansi();}
private Db_rdr New_rdr(Db_stmt stmt, Object rdr, String sql) {
Db_rdr__basic rv = (Db_rdr__basic)New_rdr_clone();
rv.Ctor(stmt, (ResultSet)rdr, sql);

View File

@@ -16,12 +16,13 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.dbs.metas.*;
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*;
public class Db_engine__mem implements Db_engine {
private final Hash_adp tbl_hash = Hash_adp_.new_();
Db_engine__mem(Db_conn_info conn_info) {this.conn_info = conn_info;}
public String Tid() {return Db_conn_info__mem.Tid_const;}
public Db_conn_info Conn_info() {return conn_info;} private Db_conn_info conn_info;
public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.Basic;
public Db_engine New_clone(Db_conn_info conn_info) {return new Db_engine__mem(conn_info);}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt__mem(this, qry);}
public Mem_tbl Tbls_get(String name) {return (Mem_tbl)tbl_hash.Get_by(name);}

View File

@@ -40,5 +40,6 @@ public class Db_rdr__mem implements Db_rdr {
public double Read_double(String k) {return Double_.cast(row.Get_by(k));}
public boolean Read_bool_by_byte(String k) {return Byte_.cast(row.Get_by(k)) == 1;}
public Object Read_obj(String k) {return row.Get_by(k);}
public Object Read_at(int i) {return row.Get_at(i);}
public void Rls() {}
}

View File

@@ -99,6 +99,18 @@ public class Db_stmt__mem implements Db_stmt {
try {Add(k, where, v);} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "String", "val", v);}
return this;
}
public Db_stmt Crt_date(String k, DateAdp v) {return Add_date(Bool_.Y, k, v);}
public Db_stmt Val_date(String k, DateAdp v) {return Add_date(Bool_.N, k, v);}
private Db_stmt Add_date(boolean where, String k, DateAdp v) {
try {Add(k, where, v);} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "date", "val", v);}
return this;
}
public Db_stmt Crt_text(String k, String v) {return Add_text(Bool_.Y, k, v);}
public Db_stmt Val_text(String k, String v) {return Add_text(Bool_.N, k, v);}
private Db_stmt Add_text(boolean where, String k, String v) {
try {Add(k, where, v);} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to add value", "type", "text", "val", v);}
return this;
}
public Db_stmt Val_rdr_(gplx.core.ios.Io_stream_rdr v, long rdr_len) {
try {
Bry_bfr bfr = Bry_bfr.new_();

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.primitives.*; import gplx.core.criterias.*; import gplx.dbs.qrys.*;
import gplx.core.primitives.*; import gplx.core.criterias.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.itms.*;
import gplx.dbs.metas.*;
public class Mem_tbl {
private final List_adp rows = List_adp_.new_(); private final List_adp where_rows = List_adp_.new_();
@@ -73,8 +73,8 @@ public class Mem_tbl {
Db_qry__select_in_tbl qry = Db_qry__select_in_tbl.as_(stmt.Qry());
if (qry == null) {
Db_qry__select_cmd qry2 = (Db_qry__select_cmd)stmt.Qry();
select = qry2.Cols_ary();
where = qry2.Where();
select = To_str_ary(qry2.Cols().Flds);
where = qry2.Where_itm().Root;
}
else {
select = qry.Select_flds();
@@ -84,6 +84,13 @@ public class Mem_tbl {
Select_rows_where(where_rows, stmt, where);
return new Db_rdr__mem(select, (Mem_row[])where_rows.To_ary_and_clear(Mem_row.class));
}
private String[] To_str_ary(Sql_select_fld_list flds) {
int len = flds.Len();
String[] rv = new String[len];
for (int i = 0; i < len; ++i)
rv[i] = flds.Get_at(i).Fld;
return rv;
}
private void Select_rows_where(List_adp rv, Db_stmt__mem stmt, Criteria crt) {
rv.Clear();
int rows_len = rows.Count();

View File

@@ -20,7 +20,7 @@ import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; im
import java.sql.*;
public class Mysql_engine extends Db_engine_sql_base {
@Override public String Tid() {return Mysql_conn_info.Tid_const;}
@Override public Sql_qry_wtr SqlWtr() {return Sql_qry_wtr_.new_escape_backslash();}
@Override public Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.Mysql;}
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
Mysql_engine rv = new Mysql_engine();
rv.Ctor(connectInfo);

View File

@@ -16,10 +16,11 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.nulls; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.dbs.metas.*;
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*;
public class Noop_engine implements Db_engine {
public String Tid() {return Noop_conn_info.Tid_const;}
public Db_conn_info Conn_info() {return Db_conn_info_.Null;}
public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.Basic;
public void Conn_open() {}
public void Conn_term() {}
public Db_engine New_clone(Db_conn_info url) {return this;}

View File

@@ -20,7 +20,7 @@ import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; im
import java.sql.*;
public class Postgres_engine extends Db_engine_sql_base {
@Override public String Tid() {return Postgres_conn_info.Tid_const;}
@Override public Sql_qry_wtr SqlWtr() {return Sql_qry_wtr_.new_escape_backslash();}
@Override public Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.Mysql;}
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
Postgres_engine rv = new Postgres_engine();
rv.Ctor(connectInfo);

View File

@@ -30,18 +30,19 @@ public class Sqlite_conn_info extends Db_conn_info__base {
public static Db_conn_info load_(Io_url url) {
return Db_conn_info_.parse(Bld_raw
( "gplx_key" , Tid_const
, "data source" , url.Xto_api()
, "version" , "3"
, Cs__data_source , url.Xto_api()
, Cs__version , Cs__version__3
));
}
public static Db_conn_info make_(Io_url url) {
Io_mgr.Instance.CreateDirIfAbsent(url.OwnerDir());
return Db_conn_info_.parse(Bld_raw
( "gplx_key" , Tid_const
, "data source" , url.Xto_api()
, "version" , "3"
, Cs__data_source , url.Xto_api()
, Cs__version , Cs__version__3
));
}
public static final Sqlite_conn_info Instance = new Sqlite_conn_info(); Sqlite_conn_info() {}
public static final String Cs__data_source = "data source", Cs__version = "version", Cs__version__3 = "3";
}

View File

@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import java.sql.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.engines.sqlite.*; import gplx.dbs.metas.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.engines.sqlite.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*;
import gplx.dbs.qrys.*;
public class Sqlite_engine extends Db_engine_sql_base {
private final Sqlite_txn_mgr txn_mgr; private final Sqlite_schema_mgr schema_mgr;
@@ -26,13 +26,14 @@ public class Sqlite_engine extends Db_engine_sql_base {
this.schema_mgr = new Sqlite_schema_mgr(this);
}
@Override public String Tid() {return Sqlite_conn_info.Tid_const;}
@Override public gplx.dbs.sqls.Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.Sqlite;}
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
Sqlite_engine rv = new Sqlite_engine();
rv.Ctor(connectInfo);
return rv;
}
@Override public DataRdr New_rdr(ResultSet rdr, String commandText) {return Sqlite_rdr.new_(rdr, commandText);}
@Override public Db_rdr New_rdr_clone() {return new Db_rdr__sqlite();}
@Override public Db_rdr New_rdr_clone() {return new Db_rdr__sqlite();}
@Override public void Env_db_attach(String alias, Io_url db_url) {Exec_as_int(String_.Format("ATTACH '{0}' AS {1};", db_url.Raw(), alias));}
@Override public void Env_db_detach(String alias) {Exec_as_int(String_.Format("DETACH {0};", alias));}
@Override public void Txn_bgn(String name) {txn_mgr.Txn_bgn(name);}
@@ -42,6 +43,7 @@ public class Sqlite_engine extends Db_engine_sql_base {
@Override public boolean Meta_tbl_exists(String tbl) {return schema_mgr.Tbl_exists(tbl);}
@Override public boolean Meta_fld_exists(String tbl, String fld) {return schema_mgr.Fld_exists(tbl, fld);}
@Override public Dbmeta_tbl_mgr Meta_tbl_load_all() {return schema_mgr.Tbl_load_all();}
@Override public Db_stmt New_stmt_prep(Db_qry qry) {return new Sqlite_stmt(this, qry);}
private static boolean loaded = false;
protected void Meta_tbl_gather_hook() {throw Err_.new_unimplemented();}
@gplx.Internal @Override protected Connection Conn_new() {
@@ -130,3 +132,9 @@ class Sqlite_rdr extends Db_data_rdr { @Override public float ReadFloat(String
return rv;
} Sqlite_rdr() {}
}
class Sqlite_stmt extends gplx.dbs.qrys.Db_stmt_cmd { public Sqlite_stmt(Db_engine engine, Db_qry qry) {super(engine, qry);}
@Override protected Db_stmt Add_date(boolean where, String k, DateAdp v) {
if (k == Dbmeta_fld_itm.Key_null) return this; // key is explicitly null; ignore; allows version_2+ type definitions
return super.Add_str(where, k, v.XtoStr_fmt_iso_8561());
}
}

View File

@@ -58,9 +58,9 @@ public class Sqlite_engine_ {
int len = idx_ary.length;
for (int i = 0; i < len; ++i) {
Dbmeta_idx_itm idx = idx_ary[i];
String idx_sql = idx.To_sql_create();
String idx_sql = idx.To_sql_create(conn.Engine().Sql_wtr());
usr_dlg.Plog_many("", "", "creating index: ~{0} ~{1}", tbl, idx_sql);
conn.Exec_qry(Db_qry_sql.ddl_(idx.To_sql_create()));
conn.Exec_qry(Db_qry_sql.ddl_(idx.To_sql_create(conn.Engine().Sql_wtr())));
usr_dlg.Log_many("", "", "index created: ~{0} ~{1}", tbl, idx_sql);
}
}

View File

@@ -23,7 +23,7 @@ class TdbDeleteWkr implements Db_qryWkr {
TdbTable tbl = engine.FetchTbl(cmd.Base_table());
List_adp deleted = List_adp_.new_();
int rv = 0;
if (cmd.Where() == Db_qry_.WhereAll) {
if (cmd.Where() == Db_qry_delete.Where__null) {
rv = tbl.Rows().Count();
tbl.Rows().Clear();
}

View File

@@ -21,6 +21,7 @@ import gplx.dbs.qrys.*; import gplx.dbs.sqls.*;
public class TdbEngine implements Db_engine {
public String Tid() {return Tdb_conn_info.Tid_const;}
public Db_conn_info Conn_info() {return conn_info;} private Db_conn_info conn_info;
public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.Basic;
public TdbDatabase Db() {return db;} TdbDatabase db;
public void Conn_open() {
Tdb_conn_info tdb_url = (Tdb_conn_info)conn_info;
@@ -42,7 +43,7 @@ public class TdbEngine implements Db_engine {
Db_qryWkr wkr = (Db_qryWkr)wkrs.Get_by_or_fail(qry.Tid());
return wkr.Exec(this, qry);
}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_sql().Parse(qry, Sql_qry_wtr_.Instance.Xto_str(qry, true));}
public Db_stmt New_stmt_prep(Db_qry qry) {return new Db_stmt_sql().Parse(qry, Sql_qry_wtr_.Basic.To_sql_str(qry, true));}
public Object New_stmt_prep_as_obj(String sql) {throw Err_.new_unimplemented();}
public Db_rdr New_rdr__rls_manual(Object rdr_obj, String sql) {return Db_rdr_.Empty;}
public Db_rdr New_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {return Db_rdr_.Empty;}

View File

@@ -94,7 +94,7 @@ class TdbEngineFxt {
}
public void run_InsertRow(TdbEngine engine, String tblName, int idVal) {
Db_qry_insert cmd = new Db_qry_insert(tblName);
cmd.Arg_("id", idVal);
cmd.Val_int("id", idVal);
engine.Exec_as_obj(cmd);
}

View File

@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.gfo_ndes.*; import gplx.core.stores.*;
import gplx.core.lists.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*;
import gplx.core.lists.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.itms.*;
class TdbInsertWkr implements Db_qryWkr {
public Object Exec(Db_engine engineObj, Db_qry cmdObj) {
TdbEngine engine = TdbEngine.cast(engineObj); Db_qry_insert cmd = (Db_qry_insert)cmdObj;
@@ -31,11 +31,11 @@ class TdbInsertWkr implements Db_qryWkr {
int InsertRowsBySelect(TdbEngine engine, TdbTable tbl, Db_qry_insert insert) {
int count = 0;
DataRdr rdr = (DataRdr)TdbSelectWkr.Instance.Exec(engine, insert.Select());
Sql_select_fld_list insertFlds = insert.Cols(); int insertFldsCount = insertFlds.Count();
Sql_select_fld_list insertFlds = insert.Cols(); int insertFldsCount = insertFlds.Len();
GfoFldList selectFldsForNewRow = null;
try {selectFldsForNewRow = insertFlds.XtoGfoFldLst(tbl);}
try {selectFldsForNewRow = TdbSelectWkr.To_GfoFldLst(tbl, insertFlds);}
catch (Exception e) {throw Err_.new_exc(e, "db", "failed to generate flds for new row");}
if (insertFldsCount > selectFldsForNewRow.Count()) throw Err_.new_wo_type("insert flds cannot exceed selectFlds", "insertFlds", insertFlds.To_str(), "selectFlds", selectFldsForNewRow.To_str());
if (insertFldsCount > selectFldsForNewRow.Count()) throw Err_.new_wo_type("insert flds cannot exceed selectFlds", "insertFlds", To_str(insertFlds), "selectFlds", selectFldsForNewRow.To_str());
while (rdr.MoveNextPeer()) {
count++;
GfoNde row = GfoNde_.vals_(selectFldsForNewRow, new Object[insertFldsCount]);
@@ -51,10 +51,18 @@ class TdbInsertWkr implements Db_qryWkr {
for (int i = 0; i < insert.Args().Count(); i++) {
KeyVal kv = insert.Args().Get_at(i);
Db_arg arg = (Db_arg)kv.Val();
row.Write(kv.Key(), arg.Val());
row.Write(kv.Key(), arg.Val);
}
tbl.Rows().Add(row);
return 1;
}
private String To_str(Sql_select_fld_list flds) {
Bry_bfr bfr = Bry_bfr.new_();
for (int i = 0; i < flds.Len(); i++) {
Sql_select_fld fld = flds.Get_at(i);
bfr.Add_str_u8(String_.Format("{0},{1}|", fld.Fld, fld.Alias));
}
return bfr.To_str();
}
public static TdbInsertWkr new_() {TdbInsertWkr rv = new TdbInsertWkr(); return rv;}
}

View File

@@ -16,19 +16,19 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.criterias.*; import gplx.core.gfo_ndes.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*;
import gplx.core.criterias.*; import gplx.core.gfo_ndes.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.itms.*;
import gplx.core.lists.*; /*ComparerAble*/ import gplx.core.stores.*; /*GfoNdeRdr*/
class TdbSelectWkr implements Db_qryWkr {
public Object Exec(Db_engine engineObj, Db_qry cmdObj) {
TdbEngine engine = TdbEngine.cast(engineObj); Db_qry__select_cmd cmd = (Db_qry__select_cmd)cmdObj;
if (cmd.From().Tbls().Count() > 1) throw Err_.new_("gplx.tdbs", "joins not supported for tdbs", "sql", cmd.Xto_sql());
if (cmd.From().Tbls.Count() > 1) throw Err_.new_("gplx.tdbs", "joins not supported for tdbs", "sql", cmd.To_sql__exec(engineObj.Sql_wtr()));
TdbTable tbl = engine.FetchTbl(cmd.From().BaseTable().TblName());
GfoNdeList rv = (cmd.Where() == Db_qry_.WhereAll && cmd.Limit() == Db_qry__select_cmd.Limit_disabled) ? rv = tbl.Rows() : FilterRecords(tbl, cmd.Where(), cmd.Limit());
TdbTable tbl = engine.FetchTbl(cmd.From().Base_tbl.Name);
GfoNdeList rv = (cmd.Where_itm() == Sql_where_itm.Where__null && cmd.Limit() == Db_qry__select_cmd.Limit__disabled) ? rv = tbl.Rows() : FilterRecords(tbl, cmd.Where_itm().Root, cmd.Limit());
if (cmd.GroupBy() != null)
rv = TdbGroupByWkr.GroupByExec(cmd, rv, tbl);
if (cmd.OrderBy() != null) { // don't use null pattern here; if null ORDER BY, then don't call .Sort on GfoNdeList
ComparerAble comparer = Sql_order_by_sorter.new_((Sql_order_by_itm[])cmd.OrderBy().Flds().To_ary(Sql_order_by_itm.class));
if (cmd.Order() != null) { // don't use null pattern here; if null ORDER BY, then don't call .Sort on GfoNdeList
ComparerAble comparer = Sql_order_fld_sorter.new_(cmd.Order().Flds);
rv.Sort_by(comparer);
}
return GfoNdeRdr_.peers_(rv, false);
@@ -44,6 +44,19 @@ class TdbSelectWkr implements Db_qryWkr {
}
return rv;
}
public static GfoFldList To_GfoFldLst(TdbTable tbl, Sql_select_fld_list flds) {
GfoFldList rv = GfoFldList_.new_();
int len = flds.Len();
for (int i = 0; i < len; ++i) {
Sql_select_fld selectFld = flds.Get_at(i);
GfoFld fld = tbl.Flds().FetchOrNull(selectFld.Fld);
if (fld == null) throw Err_.new_wo_type("fld not found in tbl", "fldName", selectFld.Fld, "tblName", tbl.Name(), "tblFlds", tbl.Flds().To_str());
if (rv.Has(selectFld.Alias)) throw Err_.new_wo_type("alias is not unique", "fldName", selectFld.Fld, "flds", rv.To_str());
selectFld.GroupBy_type(fld.Type());
rv.Add(selectFld.Alias, selectFld.Val_type());
}
return rv;
}
public static final TdbSelectWkr Instance = new TdbSelectWkr(); TdbSelectWkr() {}
}
class TdbGroupByWkr {
@@ -51,15 +64,16 @@ class TdbGroupByWkr {
GfoNdeList rv = GfoNdeList_.new_();
Ordered_hash groupByHash = Ordered_hash_.New();
List_adp groupByFlds = select.GroupBy().Flds();
GfoFldList selectFldsForNewRow = select.Cols().Flds().XtoGfoFldLst(tbl);
Sql_select_fld_list selectFlds = select.Cols().Flds();
GfoFldList selectFldsForNewRow = TdbSelectWkr.To_GfoFldLst(tbl, select.Cols().Flds);
Sql_select_fld_list selectFlds = select.Cols().Flds;
for (int rowIdx = 0; rowIdx < selectRows.Count(); rowIdx++) {
GfoNde selectRow = selectRows.FetchAt_asGfoNde(rowIdx);
GfoNde groupByRow = FindOrNew(selectFldsForNewRow, groupByFlds, selectRow, groupByHash, rv);
for (int i = 0; i < selectFlds.Count(); i++) {
Sql_select_fld_base selectFld = selectFlds.Get_at(i);
Object val = groupByRow.Read(selectFld.Alias()); // groupByRow is keyed by Alias; EX: Count(Id) AS CountOf
groupByRow.WriteAt(i, selectFld.GroupBy_eval(val, selectRow.Read(selectFld.Fld()), selectFld.ValType()));
int len = selectFlds.Len();
for (int i = 0; i < len; ++i) {
Sql_select_fld selectFld = selectFlds.Get_at(i);
Object val = groupByRow.Read(selectFld.Alias); // groupByRow is keyed by Alias; EX: Count(Id) AS CountOf
groupByRow.WriteAt(i, selectFld.GroupBy_eval(val, selectRow.Read(selectFld.Fld), selectFld.Val_type()));
}
}
return rv;

View File

@@ -39,7 +39,7 @@ class TdbUpdateWkr implements Db_qryWkr {
for (int i = 0; i < cmd.Args().Count(); i++) {
KeyVal p = (KeyVal)cmd.Args().Get_at(i);
Db_arg prm = (Db_arg)p.Val();
row.Write(p.Key(), prm.Val());
row.Write(p.Key(), prm.Val);
}
}
public static TdbUpdateWkr new_() {TdbUpdateWkr rv = new TdbUpdateWkr(); return rv;}