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

Embeddable: Create core dbs in proper subdirectory

This commit is contained in:
gnosygnu
2017-10-23 20:50:50 -04:00
parent 1336d44f34
commit 66877212bf
4537 changed files with 311750 additions and 0 deletions

View File

@@ -13,3 +13,10 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.srls; import gplx.*; import gplx.core.*;
public class Dbmeta_dat_itm {
public Dbmeta_dat_itm(int tid, String key, Object val) {this.Tid = tid; this.Key = key; this.Val = val;}
public int Tid;
public String Key;
public Object Val;
}

View File

@@ -13,3 +13,16 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.srls; import gplx.*; import gplx.core.*;
import gplx.dbs.*; import gplx.dbs.metas.*;
public class Dbmeta_dat_mgr {
private final Ordered_hash hash = Ordered_hash_.New();
public Dbmeta_dat_mgr Clear() {hash.Clear(); return this;}
public int Len() {return hash.Count();}
public Dbmeta_dat_itm Get_at(int idx) {return (Dbmeta_dat_itm)hash.Get_at(idx);}
public Dbmeta_dat_mgr Add_int(String key, int val) {
Dbmeta_dat_itm itm = new Dbmeta_dat_itm(Dbmeta_fld_tid.Tid__int, key, val);
hash.Add(key, itm);
return this;
}
}

View File

@@ -13,3 +13,9 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.srls; import gplx.*; import gplx.core.*;
public interface Gfo_srl_ctx {
Gfo_srl_mgr_wtr Wtr_bgn(String key);
Gfo_srl_mgr_rdr Rdr_bgn(String key);
Dbmeta_dat_mgr Rdr_subs(String key);
}

View File

@@ -13,3 +13,9 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.srls; import gplx.*; import gplx.core.*;
public interface Gfo_srl_itm {
Gfo_srl_itm Make_new(Gfo_srl_ctx ctx);
void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_rdr rdr);
void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_wtr wtr);
}

View File

@@ -13,3 +13,12 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.srls; import gplx.*; import gplx.core.*;
public interface Gfo_srl_mgr_rdr {
void Itm_bgn(String key);
void Itm_end();
boolean Get_bool (String key);
int Get_int (String key);
String Get_str (String key);
Object Get_subs (Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_itm proto, Dbmeta_dat_mgr crt_mgr);
}

View File

@@ -13,3 +13,13 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.srls; import gplx.*; import gplx.core.*;
public interface Gfo_srl_mgr_wtr {
int Uid_next__as_int();
void Itm_bgn(String key);
void Itm_end();
void Set_bool (String key, boolean val);
void Set_int (String key, int val);
void Set_str (String key, String val);
Object Set_subs (Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_itm proto, Object subs, Dbmeta_dat_mgr crt_mgr);
}

View File

@@ -13,3 +13,13 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.stores; import gplx.*; import gplx.core.*;
public class DbMaprArg {
public String ObjProp() {return objProp;} private String objProp;
public String DbFld() {return dbFld;} private String dbFld;
public static DbMaprArg new_(String objProp, String dbFld) {
DbMaprArg rv = new DbMaprArg();
rv.objProp = objProp; rv.dbFld = dbFld;
return rv;
}
}

View File

@@ -13,3 +13,38 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.stores; import gplx.*; import gplx.core.*;
public class DbMaprItm {
public String TableName() {return tableName;} public DbMaprItm TableName_(String val) {tableName = val; return this;} private String tableName;
public Ordered_hash Flds() {return flds;} Ordered_hash flds = Ordered_hash_.New();
public Hash_adp ContextFlds() {return contextFlds;} Hash_adp contextFlds = Hash_adp_.New();
public Hash_adp ConstantFlds() {return constantFlds;} Hash_adp constantFlds = Hash_adp_.New();
public List_adp Subs() {return subs;}
public DbMaprItm Flds_add(String objProp, String dbFld) {flds.Add(objProp, DbMaprArg.new_(objProp, dbFld)); return this;}
public DbMaprItm ContextFlds_add(String s) {
DbMaprArg arg = (DbMaprArg)flds.Get_by(s);
contextFlds.Add(arg.ObjProp(), arg);
return this;
}
public DbMaprItm ConstantFlds_add(String dbFld, Object dbVal) {constantFlds.Add(dbFld, Keyval_.new_(dbFld, dbVal)); return this;}
public DbMaprItm Subs_add(DbMaprItm... ary) {
for (DbMaprItm itm : ary)
subs.Add(itm);
return this;
}
public DbMaprItm Subs_get(String find) {
for (Object itmObj : subs) {
DbMaprItm itm = (DbMaprItm)itmObj;
if (String_.Eq(find, itm.key)) return itm;
}
throw Err_.new_missing_key(find);
}
public DbMaprArg Flds_get(String key) {return (DbMaprArg)flds.Get_by(key);}
SrlObj proto; String key; List_adp subs = List_adp_.New();
public static DbMaprItm proto_(SrlObj proto, String key, String tableName) {
DbMaprItm rv = new DbMaprItm();
rv.proto = proto; rv.key = key; rv.tableName = tableName;
return rv;
} DbMaprItm() {}
}

View File

@@ -13,3 +13,34 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.stores; import gplx.*; import gplx.core.*;
public class DbMaprMgr {
public DbMaprArg[] RootIndexFlds() {return rootIndexFlds;} public DbMaprMgr RootIndexFlds_(DbMaprArg... val) {rootIndexFlds = val; return this;} DbMaprArg[] rootIndexFlds;
public DbMaprItm Root() {return root;} public DbMaprMgr Root_(DbMaprItm v) {root = v; return this;} DbMaprItm root;
public List_adp OwnerStack() {return ownerStack;} List_adp ownerStack = List_adp_.New();
public Ordered_hash ContextVars() {return contextVars;} Ordered_hash contextVars = Ordered_hash_.New();
public List_adp MaprStack() {return maprStack;} List_adp maprStack = List_adp_.New();
public void EnvStack_add(DbMaprItm mapr, SrlObj gobj) {
for (Object argObj : mapr.ContextFlds()) {
DbMaprArg arg = (DbMaprArg)argObj;
Object contextVal = Gfo_invk_.Invk_by_key((Gfo_invk)gobj, arg.ObjProp());
this.ContextVars().Add_if_dupe_use_nth(arg.DbFld(), contextVal);
}
this.OwnerStack().Add(gobj);
this.MaprStack().Add(mapr);
}
public void EnvStack_del(DbMaprItm mapr, SrlObj gobj) {
for (Object argObj : mapr.ContextFlds()) {
DbMaprArg arg = (DbMaprArg)argObj;
this.ContextVars().Del(arg.DbFld());
}
List_adp_.Del_at_last(this.OwnerStack());
List_adp_.Del_at_last(this.MaprStack());
}
public void Clear() {
ownerStack.Clear();
contextVars.Clear();
maprStack.Clear();
}
public static DbMaprMgr new_() {return new DbMaprMgr();} DbMaprMgr() {}
}

View File

@@ -13,3 +13,126 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.stores; import gplx.*; import gplx.core.*;
import org.junit.*;
import gplx.dbs.*; /*Db_conn_info*/
public class DbMaprMgr_tst {
@Before public void setup() {
mgr = DbMaprMgr.new_().RootIndexFlds_(DbMaprArg.new_("id", "disc_id"))
.Root_
( DbMaprItm.proto_(MockDisc.Instance, "discs", "mock_discs")
. Flds_add(MockDisc.id_idk, "disc_id").Flds_add(MockDisc.name_idk, "disc_name")
. ContextFlds_add(MockDisc.id_idk).Subs_add
( DbMaprItm.proto_(MockTitle.Instance, "titles", "mock_titles")
. Flds_add(MockTitle.id_idk, "title_id").Flds_add(MockTitle.name_idk, "title_name")
. ContextFlds_add(MockTitle.id_idk).Subs_add
( DbMaprItm.proto_(MockChapter.Instance, "chapters", "mock_chapters")
. Flds_add(MockChapter.id_idk, "chapter_id").Flds_add(MockChapter.name_idk, "chapter_name")
, DbMaprItm.proto_(MockStream.Instance, "audios", "mock_streams")
. Flds_add(MockStream.id_idk, "stream_id").Flds_add(MockStream.name_idk, "stream_name")
. ConstantFlds_add("stream_type", 0)
, DbMaprItm.proto_(MockStream.Instance, "subtitles", "mock_streams")
. Flds_add(MockStream.id_idk, "stream_id").Flds_add(MockStream.name_idk, "stream_name")
. ConstantFlds_add("stream_type", 1)
)));
wtr = DbMaprWtr.new_by_url_(Db_conn_info_.Test);
wtr.EnvVars().Add(DbMaprWtr.Key_Mgr, mgr);
conn = Db_conn_pool.Instance.Get_or_new(Db_conn_info_.Test);
Db_qry_fxt.DeleteAll(conn, "mock_discs", "mock_titles", "mock_chapters", "mock_streams");
} DbMaprMgr mgr; DbMaprWtr wtr; Db_conn conn; MockDisc disc; MockTitle title; MockChapter chapter; MockStream audio, subtitle; SrlMgr rdr;
@Test public void PurgeObjTree() {
disc = MockDisc.new_().Id_(1);
Db_qry_fxt.Insert_kvo(conn, "mock_discs", Keyval_list.New_with_one("disc_id", 1));
DbMaprWtrUtl.PurgeObjTree(disc, mgr, conn);
Tfds.Eq(0, Db_qry_fxt.SelectAll_count(conn, "mock_discs"));
}
@Test public void PurgeObjTree_deep() {
disc = MockDisc.new_().Id_(1);
Db_qry_fxt.Insert_kvo(conn, "mock_discs", Keyval_list.New_with_one("disc_id", 1));
Db_qry_fxt.Insert_kvo(conn, "mock_titles", Keyval_list.New_with_one("disc_id", 1).Add("title_id", 1));
Db_qry_fxt.Insert_kvo(conn, "mock_chapters", Keyval_list.New_with_one("disc_id", 1).Add("title_id", 2).Add("chapter_id", 3));
Db_qry_fxt.Insert_kvo(conn, "mock_chapters", Keyval_list.New_with_one("disc_id", 2).Add("title_id", 2).Add("chapter_id", 3));
DbMaprWtrUtl.PurgeObjTree(disc, mgr, conn);
Tfds.Eq(0, Db_qry_fxt.SelectAll_count(conn, "mock_discs"));
Tfds.Eq(0, Db_qry_fxt.SelectAll_count(conn, "mock_titles"));
Tfds.Eq(1, Db_qry_fxt.SelectAll_count(conn, "mock_chapters")); // ignore chapter with disc_id=2
}
@Test public void Save_root() {
disc = MockDisc.new_().Id_(1).Name_("disc");
wtr.StoreRoot(disc, "mock_discs");
Db_qry_fxt.tst_Select(conn, "mock_discs", Db_mock_row.vals_only_(1, "disc"));
}
@Test public void Save_subs() {
disc = MockDisc.new_().Id_(1).Name_("disc");
title = MockTitle.new_().Id_(2).Name_("title").Disc_(disc);
wtr.StoreRoot(disc, "mock_discs");
Db_qry_fxt.tst_Select(conn, "mock_discs", Db_mock_row.vals_only_(1, "disc"));
Db_qry_fxt.tst_Select(conn, "mock_titles", Db_mock_row.vals_only_(1, 2, "title"));
}
@Test public void Save_deep() {
disc = MockDisc.new_().Id_(1).Name_("disc");
title = MockTitle.new_().Id_(2).Name_("title").Disc_(disc);
chapter = MockChapter.new_().Id_(3).Name_("chap").Title_(title);
audio = MockStream.new_().Id_(4).Name_("audio").Title_(title.Audios());
subtitle = MockStream.new_().Id_(5).Name_("subtitle").Title_(title.Subtitles());
wtr.StoreRoot(disc, "mock_discs");
Db_qry_fxt.tst_Select(conn, "mock_discs", Db_mock_row.vals_only_(1, "disc"));
Db_qry_fxt.tst_Select(conn, "mock_titles", Db_mock_row.vals_only_(1, 2, "title"));
Db_qry_fxt.tst_Select(conn, "mock_chapters", Db_mock_row.vals_only_(1, 2, 3, "chap"));
Db_qry_fxt.tst_Select(conn, "mock_streams"
, Db_mock_row.vals_only_(1, 2, null, 4, "audio")
, Db_mock_row.vals_only_(1, 2, null, 5, "subtitle")
);
}
@Test public void Load_root() {
rdr = rdr_();
Db_qry_fxt.Insert_kvo(conn, "mock_discs", Keyval_list.New_with_one("disc_id", 1).Add("disc_name", "name"));
disc = (MockDisc)rdr.StoreRoot(MockDisc.Instance, null);
Tfds.Eq(1, disc.Id());
Tfds.Eq("name", disc.Name());
Tfds.Eq(0, disc.Titles().Count());
}
@Test public void Load_subs() {
rdr = rdr_();
Db_qry_fxt.Insert_kvo(conn, "mock_discs", Keyval_list.New_with_one("disc_id", 1).Add("disc_name", "name"));
Db_qry_fxt.Insert_kvo(conn, "mock_titles", Keyval_list.New_with_one("disc_id", 1).Add("title_id", 1).Add("title_name", "title1"));
Db_qry_fxt.Insert_kvo(conn, "mock_titles", Keyval_list.New_with_one("disc_id", 1).Add("title_id", 2).Add("title_name", "title2"));
disc = (MockDisc)rdr.StoreRoot(MockDisc.Instance, null);
Tfds.Eq(1, disc.Id());
Tfds.Eq("name", disc.Name());
Tfds.Eq(2, disc.Titles().Count());
Tfds.Eq("title1", ((MockTitle)disc.Titles().Get_at(0)).Name());
Tfds.Eq("title2", ((MockTitle)disc.Titles().Get_at(1)).Name());
}
@Test public void Load_deep() {
rdr = rdr_();
Db_qry_fxt.Insert_kvo(conn, "mock_discs", Keyval_list.New_with_one("disc_id", 1).Add("disc_name", "name"));
Db_qry_fxt.Insert_kvo(conn, "mock_titles", Keyval_list.New_with_one("disc_id", 1).Add("title_id", 1).Add("title_name", "title1"));
Db_qry_fxt.Insert_kvo(conn, "mock_chapters", Keyval_list.New_with_one("disc_id", 1).Add("title_id", 1).Add("chapter_id", 3).Add("chapter_name", "chapter1"));
Db_qry_fxt.Insert_kvo(conn, "mock_streams", Keyval_list.New_with_one("disc_id", 1).Add("title_id", 1).Add("stream_id", 4).Add("stream_type", 0).Add("stream_name", "audio1"));
Db_qry_fxt.Insert_kvo(conn, "mock_streams", Keyval_list.New_with_one("disc_id", 1).Add("title_id", 1).Add("stream_id", 5).Add("stream_type", 1).Add("stream_name", "subtitle1"));
disc = (MockDisc)rdr.StoreRoot(MockDisc.Instance, null);
Tfds.Eq(1, disc.Id());
Tfds.Eq("name", disc.Name());
Tfds.Eq(1, disc.Titles().Count());
MockTitle t = ((MockTitle)disc.Titles().Get_at(0));
Tfds.Eq("title1", t.Name());
Tfds.Eq("chapter1", ((MockChapter)t.Chapters().Get_at(0)).Name());
Tfds.Eq(1, t.Audios().Count());
Tfds.Eq(1, t.Subtitles().Count());
Tfds.Eq("audio1", ((MockStream)t.Audios().Get_at(0)).Name());
Tfds.Eq("subtitle1", ((MockStream)t.Subtitles().Get_at(0)).Name());
}
DbMaprRdr rdr_() {
DbMaprRdr rv = DbMaprRdr.new_(Db_conn_info_.Test, Db_crt_.New_eq("disc_id", 1));
rv.EnvVars().Add(DbMaprWtr.Key_Mgr, mgr);
return rv;
}
}

View File

@@ -13,3 +13,108 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.stores; import gplx.*; import gplx.core.*;
import gplx.core.criterias.*; import gplx.dbs.*; import gplx.core.gfo_ndes.*;
public class DbMaprRdr extends DataRdr_base implements SrlMgr {
@Override public String NameOfNode() {return "DbMaprRdr";}
@Override public Object StoreRoot(SrlObj subProto, String key) {
mgr = (DbMaprMgr)this.EnvVars().Get_by_or_fail(DbMaprWtr.Key_Mgr);
DbMaprItm rootMapr = mgr.Root();
GfoNde tbl = GetTbl(rootMapr, rootCrt); int subsCount = tbl.Subs().Count(); if (subsCount == 0) return null; if (subsCount > 1) throw Err_.new_wo_type("criteria returned > 1 row", "criteria", rootCrt.To_str(), "subsCount", subsCount);
SrlObj root = subProto.SrlObj_New(null);
mgr.EnvStack_add(rootMapr, root); RowStack_add(tbl, 0);
root.SrlObj_Srl(this);
mgr.Clear(); rowStack.Clear();
return root;
}
@Override public void SrlList(String subPropKey, List_adp list, SrlObj subProto, String itmKey) {
DbMaprItm curMapr = (DbMaprItm)mgr.MaprStack().Get_at_last();
DbMaprItm subMapr = curMapr.Subs_get(subPropKey);
list.Clear();
Criteria crit = MakeCrt(mgr, subMapr);
GfoNde tbl = GetTbl(subMapr, crit);
int tblLen = tbl.Subs().Count();
for (int i = 0; i < tblLen; i++) {
SrlObj sub = (SrlObj)subProto.SrlObj_New(null);
GfoNde subRow = tbl.Subs().FetchAt_asGfoNde(i);
mgr.EnvStack_add(subMapr, sub); rowStack.Add(subRow);
sub.SrlObj_Srl(this); list.Add(sub);
mgr.EnvStack_del(subMapr, sub); List_adp_.Del_at_last(rowStack);
}
}
Criteria MakeCrt(DbMaprMgr mgr, DbMaprItm mapr) {
Criteria rv = null, cur = null;
List_adp list = GetIdxFlds(mgr, mapr);
for (Object kvObj : list) {
Keyval kv = (Keyval)kvObj;
cur = Db_crt_.New_eq(kv.Key(), kv.Val());
rv = (rv == null) ? cur : Criteria_.And(rv, cur);
}
return rv;
}
List_adp GetIdxFlds(DbMaprMgr mgr, DbMaprItm curMapr) {
List_adp rv = List_adp_.New();
int maprStackCount = mgr.MaprStack().Count() - 0; // -1 b/c current is added to stack
for (int i = 0; i < maprStackCount; i ++) {
DbMaprItm mapr = (DbMaprItm)mgr.MaprStack().Get_at(i);
SrlObj gobj = (SrlObj)mgr.OwnerStack().Get_at(i);
for (Object argObj : mapr.ContextFlds()) {
DbMaprArg arg = (DbMaprArg)argObj;
Object propVal = Gfo_invk_.Invk_by_key((Gfo_invk)gobj, arg.ObjProp());
rv.Add(Keyval_.new_(arg.DbFld(), propVal));
}
}
for (Object argObj : curMapr.ConstantFlds()) {
Keyval arg = (Keyval)argObj;
rv.Add(arg);
}
return rv;
}
GfoNde GetTbl(DbMaprItm mapr, Criteria crit) {
String key = mapr.TableName();
GfoNde tblByRootCrt = GfoNde_.as_(tables.Get_by(key));
if (tblByRootCrt == null) {
DataRdr dbRdr = null;
try {
dbRdr = conn.Exec_qry_as_old_rdr(Db_qry_.select_().From_(mapr.TableName()).Where_(rootCrt));
tblByRootCrt = GfoNde_.rdr_(dbRdr);
}
finally {dbRdr.Rls();}
tables.Add(key, tblByRootCrt);
}
GfoNde rv = GfoNde_.tbl_(mapr.TableName(), tblByRootCrt.Flds());
for (int i = 0; i < tblByRootCrt.Subs().Count(); i++) {
GfoNde row = tblByRootCrt.Subs().FetchAt_asGfoNde(i);
if (crit.Matches(row)) rv.Subs().Add(row);
}
return rv;
}
void RowStack_add(GfoNde tbl, int i) {
GfoNdeList ndeList = tbl.Subs(); if (i >= ndeList.Count()) throw Err_.new_missing_idx(i, ndeList.Count());
rowStack.Add(tbl.Subs().FetchAt_asGfoNde(i));
}
@Override public Object Read(String key) {
DbMaprItm mapr = (DbMaprItm)mgr.MaprStack().Get_at_last();
GfoNde row = (GfoNde)rowStack.Get_at_last();
DbMaprArg arg = mapr.Flds_get(key);
Object dbVal = null; try {dbVal = row.Read(arg.DbFld());} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to read dbVal from row", "key", key, "fld", arg.DbFld());}
return dbVal;
}
@Override public DataRdr Subs_byName_moveFirst(String name) {throw Err_.new_unimplemented();}
@Override public DataRdr Subs() {throw Err_.new_unimplemented();}
@Override public int FieldCount() {throw Err_.new_unimplemented();}
@Override public String KeyAt(int i) {throw Err_.new_unimplemented();}
@Override public Object ReadAt(int i) {throw Err_.new_unimplemented();}
@Override public Keyval KeyValAt(int i) {throw Err_.new_unimplemented();}
@Override public SrlMgr SrlMgr_new(Object o) {return new DbMaprRdr();}
Hash_adp tables = Hash_adp_.New();
Db_conn conn; Criteria rootCrt;
DbMaprMgr mgr; List_adp rowStack = List_adp_.New();
public static DbMaprRdr new_(Db_conn_info dbInfo, Criteria rootCrt) {
DbMaprRdr rv = new DbMaprRdr();
rv.conn = Db_conn_pool.Instance.Get_or_new(dbInfo); rv.rootCrt = rootCrt;
return rv;
} DbMaprRdr() {}
}

View File

@@ -13,3 +13,101 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.stores; import gplx.*; import gplx.core.*;
import gplx.core.criterias.*; import gplx.core.gfo_ndes.*;
import gplx.dbs.*; import gplx.dbs.qrys.*;
public class DbMaprWtr extends DataWtr_base implements DataWtr {
public void InitWtr(String key, Object val) {}
@Override public Object StoreRoot(SrlObj root, String key) {
mgr = (DbMaprMgr)this.EnvVars().Get_by_or_fail(DbMaprWtr.Key_Mgr);
DbMaprWtrUtl.PurgeObjTree(root, mgr, conn);
WriteGfoObj(root, mgr.Root());
mgr.Clear();
return null;
}
@Override public void SrlList(String subPropKey, List_adp list, SrlObj subProto, String itmKey) {
DbMaprItm ownerMapr = (DbMaprItm)mgr.MaprStack().Get_at_last();
DbMaprItm subMapr = ownerMapr.Subs_get(subPropKey);
for (Object subObj : list) {
SrlObj sub = (SrlObj)subObj;
WriteGfoObj(sub, subMapr);
}
}
void WriteGfoObj(SrlObj gobj, DbMaprItm mapr) {
mgr.EnvStack_add(mapr, gobj);
this.WriteNodeBgn(mapr.TableName());
this.WriteContextFlds();
gobj.SrlObj_Srl(this);
this.WriteNodeEnd();
mgr.EnvStack_del(mapr, gobj);
}
void WriteContextFlds() {
int maprStackCount = mgr.MaprStack().Count() - 1; // -1 b/c current is added to stack
for (int i = 0; i < maprStackCount; i ++) {
DbMaprItm mapr = (DbMaprItm)mgr.MaprStack().Get_at(i);
SrlObj gobj = (SrlObj)mgr.OwnerStack().Get_at(i);
for (Object argObj : mapr.ContextFlds()) {
DbMaprArg arg = (DbMaprArg)argObj;
Object argVal = Gfo_invk_.Invk_by_key((Gfo_invk)gobj, arg.ObjProp());
this.WriteDataVal(arg.DbFld(), argVal);
}
}
}
@Override public void WriteNodeBgn(String v) {
if (insertCmd != null) insertCmd.Exec_qry(conn); // occurs for nodes; ex: new title starts; commit changes for own disc
curTableName = v;
insertCmd = null;
}
@Override public void WriteData(String name, Object val) {
DbMaprItm ownerMapr = (DbMaprItm)mgr.MaprStack().Get_at_last();
String fld = ""; try {fld = ownerMapr.Flds_get(name).DbFld();} catch (Exception e) {throw Err_.new_exc(e, "db", "failed to fetch fld from mapr", "key", name);}
WriteDataVal(fld, val);
}
void WriteDataVal(String fld, Object val) {
if (insertCmd == null) insertCmd = Db_qry_.insert_(curTableName);
if (Type_.Eq_by_obj(val, String.class))
insertCmd.Val_obj_type(fld, val, Db_val_type.Tid_varchar);
else
insertCmd.Val_obj(fld, val);
}
@Override public void WriteNodeEnd() {
if (insertCmd != null) insertCmd.Exec_qry(conn); // occurs for nodes and leaves; for nodes, insertCmd will be null (committed by last leaf)
insertCmd = null;
}
public void WriteTableBgn(String name, GfoFldList fields) {}
public void WriteLeafBgn(String leafName) {}
public void WriteLeafEnd() {}
public void Clear() {}
public String To_str() {return "";}
@Override public SrlMgr SrlMgr_new(Object o) {return new DbMaprWtr();}
DbMaprMgr mgr; Db_conn conn; String curTableName; Db_qry_insert insertCmd;
public static DbMaprWtr new_by_url_(Db_conn_info url) {
DbMaprWtr rv = new DbMaprWtr();
rv.conn = Db_conn_pool.Instance.Get_or_new(url);
return rv;
} DbMaprWtr() {}
public static final String Key_Mgr = "DbMapr.mgr";
}
class DbMaprWtrUtl {
public static void PurgeObjTree(SrlObj root, DbMaprMgr mgr, Db_conn conn) {
Criteria crt = MakeCriteria(root, mgr.RootIndexFlds());
PurgeObj(mgr.Root(), crt, conn);
}
static Criteria MakeCriteria(SrlObj root, DbMaprArg[] objRootIdxFlds) {
Criteria rv = null;
for (DbMaprArg arg : objRootIdxFlds) {
Object argVal = Gfo_invk_.Invk_by_key((Gfo_invk)root, arg.ObjProp());
Criteria cur = Db_crt_.New_eq(arg.DbFld(), argVal);
rv = (rv == null) ? cur : Criteria_.And(rv, cur);
}
return rv;
}
static void PurgeObj(DbMaprItm mapr, Criteria crt, Db_conn conn) {
Db_qry_.delete_(mapr.TableName(), crt).Exec_qry(conn);
for (Object subObj : mapr.Subs()) {
DbMaprItm sub = (DbMaprItm)subObj;
PurgeObj(sub, crt, conn);
}
}
}

View File

@@ -13,3 +13,67 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.stores; import gplx.*; import gplx.core.*;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.GregorianCalendar;
import gplx.dbs.*;
public class Db_data_rdr extends DataRdr_base implements DataRdr {
@Override public String NameOfNode() {return commandText;} public String To_str() {return commandText;} private String commandText;
private ResultSet rdr;
private int fieldCount;
@Override public int FieldCount() {return fieldCount;}
@Override public String KeyAt(int i) {
String rv = null;
try {rv = rdr.getMetaData().getColumnLabel(i + List_adp_.Base1);}
catch (SQLException e) {throw Err_.new_exc(e, "db", "get columnName failed", "i", i, "commandText", commandText);}
return rv;
}
@Override public Object ReadAt(int i) {
Object rv;
try {rv = rdr.getObject(i + List_adp_.Base1);} catch(Exception exc) {throw Err_.new_wo_type("could not read val from dataReader; idx not found or rdr not open", "idx", i, "sql", commandText);}
return rv;
}
@Override public Object Read(String key) {
Object rv;
try {rv = rdr.getObject(key);} catch(Exception exc) {throw Err_.new_wo_type("could not read val from dataReader; key not found or rdr may not be open", "key", key, "sql", commandText);}
return rv;
}
@Override public DateAdp ReadDate(String key) {
Object o = this.Read(key);
Timestamp ts = (Timestamp)o;
GregorianCalendar g = new GregorianCalendar();
g.setTime(ts);
return DateAdp_.dateTime_(g);
}
@Override public Decimal_adp ReadDecimal(String key) {return Decimal_adp_.db_(this.Read(key));}
@Override public gplx.core.ios.streams.Io_stream_rdr ReadRdr(String key) {
try {
java.io.InputStream input_stream = rdr.getBinaryStream(key);
return gplx.core.ios.streams.Io_stream_rdr_.New__raw(input_stream);
}
catch (SQLException e) {return gplx.core.ios.streams.Io_stream_rdr_.Noop;}
}
public boolean MoveNextPeer() {
try {return rdr.next();}
catch (Exception e) {throw Err_.new_exc(e, "db", "could not move next; check column casting error in SQL", "sql", commandText);}
}
@Override public DataRdr Subs() {throw Err_.new_unimplemented();}
public DataRdr Subs_byName(String fld) {throw Err_.new_unimplemented();}
@Override public DataRdr Subs_byName_moveFirst(String fld) {throw Err_.new_unimplemented();}
public void Rls() {
try {rdr.close();}
catch (SQLException e) {throw Err_.new_exc(e, "db", "reader dispose failed", "commandText", commandText);}
this.EnvVars().Clear();
}
@gplx.Internal protected Db_data_rdr ctor_db_data_rdr(ResultSet rdr, String commandText) {
this.rdr = rdr; this.commandText = commandText; this.Parse_set(false);
try {fieldCount = this.rdr.getMetaData().getColumnCount();}
catch (SQLException e) {Err_.new_exc(e, "xo", "get columnCount failed", "commandText", commandText);}
return this;
}
@Override public SrlMgr SrlMgr_new(Object o) {return new Db_data_rdr();}
}

View File

@@ -13,3 +13,8 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.stores; import gplx.*; import gplx.core.*;
import java.sql.ResultSet;
public class Db_data_rdr_ {
public static Db_data_rdr new_(ResultSet rdr, String commandText) {return new Db_data_rdr().ctor_db_data_rdr(rdr, commandText);}
}

View File

@@ -13,3 +13,116 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.stores; import gplx.*; import gplx.core.*;
class MockDisc implements SrlObj, Gfo_invk {
public int Id() {return id;} public MockDisc Id_(int val) {id = val; return this;} int id; public static final String id_idk = "id";
public String Name() {return name;} public MockDisc Name_(String val) {name = val; return this;} private String name; public static final String name_idk = "name";
public List_adp Titles() {return titles;} List_adp titles = List_adp_.New(); public static final String titles_idk = "titles";
public static final MockDisc Instance = new MockDisc(); MockDisc() {}
public SrlObj SrlObj_New(Object o) {return new MockDisc();}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, id_idk)) return Id();
else if (ctx.Match(k, name_idk)) return Name();
else if (ctx.Match(k, titles_idk)) return Titles();
else return Gfo_invk_.Rv_unhandled;
}
// public Object Srl_new(GfsCtx ctx) {return new MockDisc();}
// public void Srl(GfsCtx ctx, int ikey, String k, GfoMsg m) {
// id = m.ReadIntOr(id_idk, id);
// name = m.ReadStrOr(name_idk, name);
// for (int i = 0; i < m.Subs_count(); i++) {
// GfoMsg subMsg = m.Subs_getAt(i);
// if (String_.Eq(subMsg.Key(), titles_idk)) DoIt(ctx, ikey, k, subMsg, titles, MockTitle.Instance, "title");
// }
// }
// public static void DoIt(GfsCtx ctx, int ikey, String k, GfoMsg m, List_adp list, Object o, String subKey) {
// }
public void SrlObj_Srl(SrlMgr mgr) {
id = mgr.SrlIntOr(id_idk, id);
name = mgr.SrlStrOr(name_idk, name);
mgr.SrlList(titles_idk, titles, MockTitle.Instance, "title");
}
public static MockDisc new_() {
MockDisc rv = new MockDisc();
return rv;
}
}
class MockTitle implements SrlObj, Gfo_invk {
public int Id() {return id;} public MockTitle Id_(int val) {id = val; return this;} int id; public static final String id_idk = "id";
public String Name() {return name;} public MockTitle Name_(String val) {name = val; return this;} private String name; public static final String name_idk = "name";
public List_adp Chapters() {return chapters;} List_adp chapters = List_adp_.New(); public static final String chapters_idk = "chapters";
public List_adp Audios() {return audios;} List_adp audios = List_adp_.New(); public static final String audios_idk = "audios";
public List_adp Subtitles() {return subtitles;} List_adp subtitles = List_adp_.New(); public static final String subtitles_idk = "subtitles";
public MockTitle Disc_(MockDisc disc) {disc.Titles().Add(this); return this;}
public static MockTitle new_() {
MockTitle rv = new MockTitle();
return rv;
}
public static final MockTitle Instance = new MockTitle(); MockTitle() {}
public SrlObj SrlObj_New(Object o) {return new MockTitle();}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, id_idk)) return Id();
else if (ctx.Match(k, name_idk)) return Name();
else if (ctx.Match(k, chapters_idk)) return Chapters();
else if (ctx.Match(k, audios_idk)) return Audios();
else if (ctx.Match(k, subtitles_idk)) return Subtitles();
else return Gfo_invk_.Rv_unhandled;
}
// public void Srl(GfsCtx ctx, int ikey, String k, GfoMsg m) {
// id = m.ReadIntOr(id_idk, id);
// name = m.ReadStrOr(name_idk, name);
// for (int i = 0; i < m.Subs_count(); i++) {
// GfoMsg subMsg = m.Subs_getAt(i);
// if (String_.Eq(subMsg.Key(), chapters_idk)) MockDisc.DoIt(ctx, ikey, k, subMsg, chapters, MockChapter.Instance, "chapter");
// else if (String_.Eq(subMsg.Key(), audios_idk)) MockDisc.DoIt(ctx, ikey, k, subMsg, audios, MockStream.Instance, "audio");
// else if (String_.Eq(subMsg.Key(), subtitles_idk)) MockDisc.DoIt(ctx, ikey, k, subMsg, subtitles, MockStream.Instance, "subtitle");
// }
// }
public void SrlObj_Srl(SrlMgr mgr) {
id = mgr.SrlIntOr(id_idk, id);
name = mgr.SrlStrOr(name_idk, name);
mgr.SrlList(chapters_idk, chapters, MockChapter.Instance, "chapter");
mgr.SrlList(audios_idk, audios, MockStream.Instance, "audio");
mgr.SrlList(subtitles_idk, subtitles, MockStream.Instance, "subtitle");
}
}
class MockChapter implements SrlObj, Gfo_invk {
public int Id() {return id;} public MockChapter Id_(int val) {id = val; return this;} int id; public static final String id_idk = "id";
public String Name() {return name;} public MockChapter Name_(String val) {name = val; return this;} private String name; public static final String name_idk = "name";
public MockChapter Title_(MockTitle title) {title.Chapters().Add(this); return this;}
public static final MockChapter Instance = new MockChapter(); MockChapter() {}
public static MockChapter new_() {
MockChapter rv = new MockChapter();
return rv;
}
public SrlObj SrlObj_New(Object o) {return new MockChapter();}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, id_idk)) return Id();
else if (ctx.Match(k, name_idk)) return Name();
else return Gfo_invk_.Rv_unhandled;
}
public void SrlObj_Srl(SrlMgr mgr) {
id = mgr.SrlIntOr(id_idk, id);
name = mgr.SrlStrOr(name_idk, name);
}
}
class MockStream implements SrlObj, Gfo_invk {
public int Id() {return id;} public MockStream Id_(int val) {id = val; return this;} int id; public static final String id_idk = "id";
public String Name() {return name;} public MockStream Name_(String val) {name = val; return this;} private String name; public static final String name_idk = "name";
public MockStream Title_(List_adp list) {list.Add(this); return this;}
public static final MockStream Instance = new MockStream(); MockStream() {}
public static MockStream new_() {
MockStream rv = new MockStream();
return rv;
}
public SrlObj SrlObj_New(Object o) {return new MockStream();}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, id_idk)) return Id();
else if (ctx.Match(k, name_idk)) return Name();
else return Gfo_invk_.Rv_unhandled;
}
public void SrlObj_Srl(SrlMgr mgr) {
id = mgr.SrlIntOr(id_idk, id);
name = mgr.SrlStrOr(name_idk, name);
}
}

View File

@@ -0,0 +1,26 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public class Db_attach_itm {
public Db_attach_itm(String key, Io_url url) {
this.Key = key; this.Url = url;
}
public Db_attach_itm(String key, Db_conn conn) {
this.Key = key; this.Url = gplx.dbs.engines.sqlite.Sqlite_conn_info.To_url(conn);
}
public final String Key;
public final Io_url Url;
}

View File

@@ -0,0 +1,120 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.sqls.*; import gplx.dbs.sqls.itms.*;
public class Db_attach_mgr {
private Db_conn main_conn; private Io_url main_conn_url;
private final Ordered_hash links_hash = Ordered_hash_.New();
private final List_adp attach_list = List_adp_.New();
public Db_attach_mgr() {}
public Db_attach_mgr(Db_conn main_conn, Db_attach_itm... links_ary) {
this.Conn_main_(main_conn);
this.Conn_links_(links_ary);
}
public Db_conn Conn_main() {return main_conn;}
public Db_attach_mgr Conn_main_(Db_conn conn) {
this.main_conn = conn; this.main_conn_url = Db_conn_info_.To_url(conn.Conn_info());
return this;
}
public Db_attach_mgr Conn_links_(Db_attach_itm... itms_ary) {
links_hash.Clear();
int len = itms_ary.length;
for (int i = 0; i < len; ++i) {
Db_attach_itm itm = itms_ary[i];
links_hash.Add(itm.Key, itm);
}
return this;
}
public void Attach() {
int len = attach_list.Len();
for (int i = 0; i < len; ++i) {
Db_attach_itm itm = (Db_attach_itm)attach_list.Get_at(i);
main_conn.Env_db_attach(itm.Key, itm.Url);
}
}
public void Detach() {
int len = attach_list.Len();
for (int i = 0; i < len; ++i) {
Db_attach_itm itm = (Db_attach_itm)attach_list.Get_at(i);
main_conn.Env_db_detach(itm.Key);
}
attach_list.Clear(); // clear list so multiple detachs don't fail
}
public String Resolve_sql(String sql) {
attach_list.Clear();
int hash_len = links_hash.Count();
for (int i = 0; i < hash_len; ++i) {
Db_attach_itm attach_itm = (Db_attach_itm)links_hash.Get_at(i);
String tkn = "<" + attach_itm.Key + ">";
if (String_.Has(sql, tkn)) {
Io_url attach_url = attach_itm.Url;
String repl = "";
if (!attach_url.Eq(main_conn_url)) {
repl = attach_itm.Key + ".";
attach_list.Add(attach_itm);
}
sql = String_.Replace(sql, tkn, repl);
}
}
attached_sql = sql;
return sql;
}
public Db_attach_mgr Exec_sql_w_msg(String msg, String sql, Object... args) {
Gfo_usr_dlg_.Instance.Plog_many("", "", msg);
Exec_sql(sql, args);
return this;
}
public Db_attach_mgr Exec_sql(String sql, Object... args) {
String attach_sql = String_.Format(Resolve_sql(sql), args);
this.Attach();
try {main_conn.Exec_sql(attach_sql);}
finally {this.Detach();}
return this;
}
public String Test__attach_sql() {return attached_sql;} private String attached_sql;
public String[] Test__attach_list_keys() {
int rv_len = attach_list.Count();
String[] rv = new String[rv_len];
for (int i = 0; i < rv_len; ++i) {
Db_attach_itm itm = (Db_attach_itm)attach_list.Get_at(i);
rv[i] = itm.Key;
}
return rv;
}
public Db_stmt Test__make_stmt_and_attach(Db_qry qry, gplx.dbs.sqls.itms.Sql_from_clause from_itm) { // NOTE: tries to do attach via DOM not SQL
attach_list.Clear();
Sql_qry_wtr sql_wtr = main_conn.Engine().Sql_wtr();
List_adp from_tbls = from_itm.Tbls;
int from_tbls_len = from_tbls.Count();
for (int i = 0; i < from_tbls_len; ++i) {
Sql_tbl_itm from_tbl = (Sql_tbl_itm)from_tbls.Get_at(i);
String from_tbl_db = from_tbl.Db;
if (String_.Eq(Sql_tbl_itm.Db__null, from_tbl_db)) continue; // tbl does not have db defined; only "tbl" not "db.tbl"; skip
Db_attach_itm attach_itm = (Db_attach_itm)links_hash.Get_by(from_tbl_db); if (attach_itm == null) throw Err_.new_("dbs", "qry defines an unknown database for attach_wkr", "from_tbl_db", from_tbl_db, "sql", qry.To_sql__exec(sql_wtr));
if (attach_itm.Url.Eq(main_conn_url)) // attach_db same as conn; blank db, so "tbl", not "db.tbl"
from_tbl.Db_enabled = false;
else
attach_list.Add(attach_itm);
}
attached_sql = sql_wtr.To_sql_str(qry, true);
this.Attach();
for (int i = 0; i < from_tbls_len; ++i) { // reverse blanking from above
Sql_tbl_itm from_tbl = (Sql_tbl_itm)from_tbls.Get_at(i);
from_tbl.Db_enabled = true;
}
return main_conn.Stmt_sql(attached_sql);
}
}

View File

@@ -0,0 +1,57 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import org.junit.*; import gplx.core.tests.*; import gplx.dbs.qrys.*;
public class Db_attach_mgr__tst {
private final Db_attach_mgr__fxt fxt = new Db_attach_mgr__fxt();
@Test public void Basic() {
Db_qry__select_cmd qry = Db_qry_.select_()
.Cols_w_tbl_("t1", "fld_1")
.Cols_w_tbl_("t2", "fld_2")
.Cols_w_tbl_("t3", "fld_3")
.From_("db_1", "tbl_1", "t1")
.Join_("db_2", "tbl_2", "t2", Db_qry_.New_join__same("t1", "fld_2"))
.Join_("db_3", "tbl_3", "t3", Db_qry_.New_join__same("t1", "fld_3"))
.Join_( "tbl_4", "t4", Db_qry_.New_join__same("t1", "fld_4"))
;
fxt.Init("db_2", fxt.Make__other("db_1"), fxt.Make__other("db_2"), fxt.Make__other("db_3"));
fxt.Test__make_stmt_and_attach(qry
, "SELECT t1.fld_1, t2.fld_2, t3.fld_3 "
+ "FROM db_1.tbl_1 t1 "
+ "INNER JOIN tbl_2 t2 ON t1.fld_2 = t2.fld_2 " // NOTE: curr is db_2 so do not prefix tbl_2 with db_2; fails if "db_2.tbl_2"
+ "INNER JOIN db_3.tbl_3 t3 ON t1.fld_3 = t3.fld_3 "
+ "INNER JOIN tbl_4 t4 ON t1.fld_4 = t4.fld_4"
, String_.Ary("db_1", "db_3") // NOTE: no "db_2"
);
}
}
class Db_attach_mgr__fxt {
private Db_attach_mgr mgr;
public Db_attach_mgr__fxt() {
Db_conn_bldr.Instance.Reg_default_mem();
}
public Db_conn Make__conn(String key) {return Db_conn_bldr.Instance.New(Io_url_.mem_fil_(key));}
public Db_attach_itm Make__other(String key) {return new Db_attach_itm(key, Io_url_.mem_fil_("mem/" + key));}
public void Init(String conn_key, Db_attach_itm... ary) {
Db_conn conn = Make__conn(conn_key);
mgr = new Db_attach_mgr(conn, ary);
}
public void Test__make_stmt_and_attach(Db_qry__select_cmd qry, String expd_sql, String[] expd_dbs) {
mgr.Test__make_stmt_and_attach(qry, qry.From());
Gftest.Eq__str(expd_sql, mgr.Test__attach_sql());
Gftest.Eq__ary(expd_dbs, mgr.Test__attach_list_keys());
}
}

View File

@@ -0,0 +1,40 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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 Err_.new_unhandled(cur);
}
}
}

View File

@@ -0,0 +1,157 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.engines.*; import gplx.dbs.qrys.*; import gplx.dbs.sys.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.bats.*;
public class Db_conn {
private final List_adp rls_list = List_adp_.New();
public Db_conn(Db_engine engine) {
this.engine = engine;
this.sys_mgr = new Db_sys_mgr(this);
}
public Db_conn_info Conn_info() {return engine.Conn_info();}
public Db_conn_props_mgr Props() {return engine.Props();}
public Db_batch_mgr Batch_mgr() {return engine.Batch_mgr();}
public Db_engine Engine() {return engine;} private final Db_engine engine;
public Db_sys_mgr Sys_mgr() {return sys_mgr;} private final Db_sys_mgr sys_mgr; // autonum and other functions
public boolean Eq(Db_conn comp) {return String_.Eq(engine.Conn_info().Db_api(), comp.Conn_info().Db_api());}
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 void Env_db_attach(String alias, Db_conn conn) {engine.Env_db_attach(alias, conn);}
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().Db_api(), "VACUUM;");}
public void Meta_tbl_create(Dbmeta_tbl_itm meta) {engine.Meta_tbl_create(meta); engine.Meta_idx_create(Gfo_usr_dlg_.Noop, meta.Idxs().To_ary());}
public void Meta_tbl_delete(String tbl) {engine.Meta_tbl_delete(tbl);}
public void Meta_tbl_remake_many(Db_tbl... tbls) {for (Db_tbl tbl : tbls) Meta_tbl_remake(tbl);}
public void Meta_tbl_remake(Db_tbl tbl) {engine.Meta_tbl_delete(tbl.Tbl_name()); tbl.Create_tbl();}
public void Meta_tbl_remake(Dbmeta_tbl_itm meta) {engine.Meta_tbl_delete(meta.Name()); engine.Meta_tbl_create(meta);}
public void Meta_idx_assert(String tbl, String suffix, String... flds) {if (engine.Meta_idx_exists(tbl + "__" + suffix)) return; this.Meta_idx_create(tbl, suffix, flds);}
public void Meta_idx_assert(String tbl, String suffix, Dbmeta_idx_fld... flds) {if (engine.Meta_idx_exists(tbl + "__" + suffix)) return; this.Meta_idx_create(tbl, suffix, flds);}
public void Meta_idx_create(String tbl, String suffix, String... flds) {engine.Meta_idx_create(Gfo_usr_dlg_.Instance, Dbmeta_idx_itm.new_normal_by_tbl(tbl, suffix, flds));}
public void Meta_idx_create(String tbl, String suffix, Dbmeta_idx_fld... flds) {engine.Meta_idx_create(Gfo_usr_dlg_.Instance, Dbmeta_idx_itm.new_normal_by_tbl(tbl, suffix, flds));}
public void Meta_idx_create(Dbmeta_idx_itm... idxs) {engine.Meta_idx_create(Gfo_usr_dlg_.Instance, idxs);}
public void Meta_idx_create(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... idxs) {engine.Meta_idx_create(usr_dlg, idxs);}
public void Meta_idx_delete(String idx) {engine.Meta_idx_delete(idx);}
public void Meta_idx_delete(String tbl, String suffix) {engine.Meta_idx_delete(tbl + "__" + suffix);}
public void Meta_fld_append(String tbl, Dbmeta_fld_itm fld) {engine.Meta_fld_append(tbl, fld);}
public void Meta_fld_assert(String tbl, String fld, Dbmeta_fld_tid tid, Object dflt) {if (!Meta_fld_exists(tbl, fld)) this.Meta_fld_append(tbl, new Dbmeta_fld_itm(fld, tid).Default_(dflt));}
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 boolean Meta_idx_exists(String idx) {return engine.Meta_idx_exists(idx);}
public boolean Meta_idx_exists(String tbl, String suffix) {return engine.Meta_idx_exists(tbl + "__" + suffix);}
public void Meta_tbl_assert(Db_tbl... tbls) {
boolean dirty = false;
for (Db_tbl tbl : tbls) {
if (!Meta_tbl_exists(tbl.Tbl_name())) {
tbl.Create_tbl();
dirty = true;
}
}
if (dirty) this.Meta_mgr().Load_all();
}
public String Meta_fld_append_if_missing(String tbl_name, Dbmeta_fld_list flds, Dbmeta_fld_itm fld) {
String fld_name = fld.Name();
// if fld doesn't exist, add it; NOTE: need to check if tbl exists first else meta_fld not available
if ( this.Meta_tbl_exists(tbl_name)
&& !this.Meta_fld_exists(tbl_name, fld_name)) {
try {this.Meta_fld_append(tbl_name, fld);}
catch (Exception e) {
Gfo_log_.Instance.Warn("failed to append fld", "conn", this.Conn_info().Db_api(), "tbl", tbl_name, "fld", fld_name, "err", Err_.Message_gplx_log(e));
fld_name = Dbmeta_fld_itm.Key_null;
}
}
// if fld does exist, or tbl doesn't exist, just add fld to collection
else {
if (!flds.Has(fld.Name())) // NOTE: need to check if it already exists; DATE:2016-09-22
fld_name = flds.Add(fld);
}
return fld_name;
}
public Dbmeta_tbl_mgr Meta_mgr() {return engine.Meta_mgr();}
public Db_stmt Stmt_insert(String tbl, Dbmeta_fld_list flds) {return engine.Stmt_by_qry(Db_qry_insert.new_(tbl, flds.To_str_ary_wo_autonum()));}
public Db_stmt Stmt_insert(String tbl, String... cols) {return engine.Stmt_by_qry(Db_qry_insert.new_(tbl, cols));}
public Db_stmt Stmt_update(String tbl, String[] where, String... cols) {return engine.Stmt_by_qry(Db_qry_update.New(tbl, where, cols));}
public Db_stmt Stmt_update_exclude(String tbl, Dbmeta_fld_list flds, String... where) {return engine.Stmt_by_qry(Db_qry_update.New(tbl, where, flds.To_str_ary_exclude(where)));}
public Db_stmt Stmt_delete(String tbl, String... where) {return engine.Stmt_by_qry(Db_qry_delete.new_(tbl, where));}
public Db_stmt Stmt_select_all(String tbl, Dbmeta_fld_list flds) {return engine.Stmt_by_qry(Db_qry__select_in_tbl.new_(tbl, String_.Ary_empty, flds.To_str_ary(), null));}
public Db_stmt Stmt_select(String tbl, String[] cols, String... where) {return engine.Stmt_by_qry(Db_qry__select_in_tbl.new_(tbl, where, cols, null));}
public Db_stmt Stmt_select(String tbl, Dbmeta_fld_list flds, String... where) {return engine.Stmt_by_qry(Db_qry__select_in_tbl.new_(tbl, where, flds.To_str_ary(), null));}
public Db_stmt Stmt_select_order(String tbl, Dbmeta_fld_list flds, String[] where, String... orderbys) {return engine.Stmt_by_qry(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.Stmt_by_qry(Db_qry__select_in_tbl.new_(tbl, where, flds, orderbys));}
public Db_stmt Stmt_new(Db_qry qry) {return engine.Stmt_by_qry(qry);}
public Db_stmt Stmt_sql(String sql) {return engine.Stmt_by_qry(Db_qry_sql.sql_(sql));}
public int Exec_qry(Db_qry qry) {return Int_.Cast(engine.Exec_as_obj(qry));}
public int Exec_sql_concat(String... ary) {return this.Exec_qry(Db_qry_sql.dml_(String_.Concat_lines_nl_skip_last(ary)));}
public int Exec_sql_concat_w_msg(String msg, String... ary) {Gfo_usr_dlg_.Instance.Plog_many("", "", msg); return Exec_sql_concat(ary);}
public int Exec_sql(String sql) {return this.Exec_qry(Db_qry_sql.dml_(sql));}
public int Exec_sql(String msg, String sql) {Gfo_usr_dlg_.Instance.Plog_many("", "", msg); return this.Exec_sql(sql);}
public Db_rdr Exec_rdr(String sql) {return this.Stmt_sql(sql).Exec_select__rls_auto();}
public void Exec_delete_all(String tbl) {Stmt_delete(tbl).Exec_delete();}
public int Exec_sql_args(String sql, Object... args) {return this.Exec_qry(Db_qry_sql.dml_(String_.Format(sql, args)));}
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_.Instance.Plog_many("", "", msg);
if (txn) this.Txn_bgn(msg);
int rv = Exec_sql(sql);
if (txn) this.Txn_end();
Gfo_usr_dlg_.Instance.Plog_many("", "", "done:" + msg);
return rv;
}
public int Exec_select_max_as_int (String tbl_name, String fld_name, int or) {
Object rv = Exec_select_as_obj(String_.Format("SELECT Max({0}) FROM {1}", fld_name, tbl_name));
return rv == null ? or : Int_.Cast(rv);
}
public int Exec_select_count_as_int(String tbl_name, int or) {
Object rv = Exec_select_as_obj(String_.Format("SELECT Count(*) FROM {0}", tbl_name));
return rv == null ? or : Int_.Cast(rv);
}
public int Exec_select_as_int (String sql, int or) {Object rv = Exec_select_as_obj(sql); return rv == null ? or : Int_.Cast(rv);}
public double Exec_select_as_double (String sql, double or) {Object rv = Exec_select_as_obj(sql); return rv == null ? or : Double_.cast(rv);}
private Object Exec_select_as_obj(String sql) {
Db_rdr rdr = Exec_rdr(sql);
try {return rdr.Move_next() ? rdr.Read_at(0) : null;}
finally {rdr.Rls();}
}
public void Rls_reg(Rls_able rls) {
if (this == Db_conn_.Noop) return; // ignore Db_conn_.Noop, else memory leak
rls_list.Add(rls);
}
public void Rls_conn() {
int len = rls_list.Count();
for (int i = 0; i < len; ++i) {
Rls_able itm = (Rls_able)rls_list.Get_at(i);
itm.Rls();
}
// rls_list.Clear(); // TOMBSTONE: do not clear rls_list, else tables which self-registered won't get called again; DATE:2016-07-06
engine.Conn_term();
Db_conn_pool.Instance.Del(engine.Conn_info());
}
public void Reopen_conn() {
engine.Conn_open();
Db_conn_pool.Instance.Add_existing(this);
}
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);
qry.Where_(where.length == 0 ? Db_crt_.Wildcard : Db_crt_.eq_many_(where));
return engine.Stmt_by_qry(qry);
}
public DataRdr Exec_sql_as_old_rdr(String sql) {return DataRdr_.cast(engine.Exec_as_obj(Db_qry_sql.rdr_(sql)));}
public DataRdr Exec_qry_as_old_rdr(Db_qry qry) {return DataRdr_.cast(engine.Exec_as_obj(qry));}
}

View File

@@ -0,0 +1,19 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public class Db_conn_ {
public static final Db_conn Noop = new Db_conn(gplx.dbs.engines.noops.Noop_engine.Instance);
}

View File

@@ -0,0 +1,52 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public class Db_conn_bldr {
private final Object thread_lock = new Object(); // LOCK:synchronized else random failures in Schema_mgr due to diff conn pointing to same db; DATE:2016-07-12
private Db_conn_bldr_wkr wkr;
public void Reg_default_sqlite() {wkr = Db_conn_bldr_wkr__sqlite.Instance; wkr.Clear_for_tests();}
public void Reg_default_mem() {wkr = Db_conn_bldr_wkr__mem.Instance; wkr.Clear_for_tests();}
public boolean Exists(Io_url url) {synchronized (thread_lock) {return wkr.Exists(url);}}
public Db_conn Get(Io_url url) {synchronized (thread_lock) {return wkr.Get(url);}}
public Db_conn New(Io_url url) {synchronized (thread_lock) {return wkr.New(url);}}
public Db_conn_bldr_data Get_or_new(Io_url url) {
synchronized (thread_lock) {
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) {
synchronized (thread_lock) {
Db_conn rv = wkr.Get(url);
return rv == null ? Db_conn_.Noop : rv;
}
}
public Db_conn Get_or_autocreate(boolean autocreate, Io_url url) {
synchronized (thread_lock) {
boolean exists = wkr.Exists(url);
if (exists) return Get(url);
if (autocreate) return New(url);
else throw Err_.new_("dbs", "db does not exist", "url", url.Raw());
}
}
public Db_conn Get_or_fail(Io_url url) {
Db_conn rv = Get(url);
if (rv == Db_conn_.Noop) throw Err_.new_wo_type("connection is null; file does not exist: file={0}", "file", url.Raw());
return rv;
}
public static final Db_conn_bldr Instance = new Db_conn_bldr(); Db_conn_bldr() {}
}

View File

@@ -0,0 +1,22 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.engines.sqlite.*; import gplx.dbs.qrys.bats.*;
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 Db_batch_mgr Batch_mgr() {return batch_mgr;} private final Db_batch_mgr batch_mgr = new Db_batch_mgr();
public boolean Exists(Io_url url) {return Io_mgr.Instance.ExistsFil(url);}
public Db_conn Get(Io_url url) {
if (!Io_mgr.Instance.ExistsFil(url)) return null;
Db_conn_info db_url = Db_conn_info_.sqlite_(url);
return Db_conn_pool.Instance.Get_or_new(db_url);
}
public Db_conn New(Io_url url) {
Io_mgr.Instance.CreateDirIfAbsent(url.OwnerDir()); // must assert that dir exists
Db_conn_info db_url = Sqlite_conn_info.make_(url);
Db_conn conn = Db_conn_pool.Instance.Get_or_new(db_url);
conn.Exec_qry(Sqlite_pragma.New__page_size(4096));
return conn;
}
public static final Db_conn_bldr_wkr__sqlite Instance = 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.Instance.Rls_all();}
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 Get_or_new(url);
}
public Db_conn New(Io_url url) {
String io_url_str = url.Xto_api();
hash.Add_if_dupe_use_nth(io_url_str, io_url_str); // NOTE: tests can call New multiple times; don't fail if exists; just overwrite existing entry; DATE:2016-04-21
return Get_or_new(url);
}
private Db_conn Get_or_new(Io_url url) {
return Db_conn_pool.Instance.Get_or_new(gplx.dbs.engines.mems.Mem_conn_info.new_(url.Xto_api()));
}
public static final Db_conn_bldr_wkr__mem Instance = new Db_conn_bldr_wkr__mem(); Db_conn_bldr_wkr__mem() {}
}

View File

@@ -0,0 +1,23 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public interface Db_conn_info {
String Key(); // EX: "sqlite"
String Raw(); // EX: "gplx_key=sqlite;data source=/db.sqlite3;version=3"
String Db_api(); // EX: "data source=/db.sqlite3;version=3"
String Database(); // EX: /db.sqlite3 -> "db" ; xowa -> "xowa"
Db_conn_info New_self(String raw, Keyval_hash hash);
}

View File

@@ -0,0 +1,86 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.engines.noops.*; 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.Instance;
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.Instance.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 Mem_conn_info.new_(db);}
public static final String Key_tdb = Tdb_conn_info.Tid_const;
public static Io_url To_url(Db_conn_info cs) {
if (String_.Eq(cs.Key(), Sqlite_conn_info.Key_const)) return ((Sqlite_conn_info)cs).Url();
else if (String_.Eq(cs.Key(), Mem_conn_info.Instance.Key())) return Io_url_.mem_fil_("mem/" + ((Mem_conn_info)cs).Database());
else throw Err_.new_unhandled_default(cs.Key());
}
}
class Db_conn_info_pool {
private final Ordered_hash regy = Ordered_hash_.New();
public Db_conn_info_pool() {
this.Add(Noop_conn_info.Instance).Add(Tdb_conn_info.Instance).Add(Mysql_conn_info.Instance).Add(Postgres_conn_info.Instance).Add(Sqlite_conn_info.Instance);
this.Add(Mem_conn_info.Instance);
}
public Db_conn_info_pool Add(Db_conn_info itm) {regy.Add_if_dupe_use_nth(itm.Key(), itm); return this;}
public Db_conn_info Parse(String raw) {// assume each pair has format of: name=val;
try {
Keyval_hash hash = new Keyval_hash();
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
hash.Add(kv[0], kv[1]);
}
Db_conn_info prototype = (Db_conn_info)regy.Get_by(url_tid);
return prototype.New_self(raw, hash);
}
catch(Exception exc) {throw Err_.new_parse_exc(exc, Db_conn_info.class, raw);}
}
public Db_conn_info Parse_or_sqlite_or_fail(String raw) {// assume each pair has format of: name=val;
Keyval_hash hash = new Keyval_hash();
String[] kvps = String_.Split(raw, ";");
String cs_tid = null;
int kvps_len = kvps.length;
for (int i = 0; i < kvps_len; ++i) {
String kvp_str = kvps[i];
if (String_.Len(kvp_str) == 0) continue; // ignore empty; EX: "data source=/db.sqlite;;"
String[] kvp = String_.Split(kvp_str, "=");
String key = kvp[0], val = kvp[1];
if (String_.Eq(key, "gplx_key"))
cs_tid = val; // NOTE: do not add to GfoMsg; will not be part of ApiStr
else
hash.Add(key, val);
}
if (cs_tid == null) { // gplx_key not found; try url as sqlite; EX: "/db.sqlite"
Io_url sqlite_url = null;
try {sqlite_url = Io_url_.new_any_(raw);}
catch (Exception exc) {throw Err_.new_exc(exc, "dbs", "invalid connection String", "raw", raw);}
hash.Clear();
cs_tid = Sqlite_conn_info.Key_const;
hash.Add(Sqlite_conn_info.Cs__data_source, sqlite_url.Raw());
hash.Add(Sqlite_conn_info.Cs__version , Sqlite_conn_info.Cs__version__3);
}
Db_conn_info prototype = (Db_conn_info)regy.Get_by(cs_tid);
return prototype.New_self(raw, hash);
}
public static final Db_conn_info_pool Instance = new Db_conn_info_pool();
}

View File

@@ -0,0 +1,48 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public abstract class Db_conn_info__base implements Db_conn_info {
public Db_conn_info__base(String raw, String db_api, String database) {this.raw = raw; this.db_api = db_api; this.database = database;}
public abstract String Key();
public String Raw() {return raw;} private final String raw;
public String Db_api() {return db_api;} private final String db_api;
public String Database() {return database;} protected final String database;
public abstract Db_conn_info New_self(String raw, Keyval_hash hash);
protected static String Bld_raw(String... ary) {// "a", "b" -> "a=b;"
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.To_str_and_clear();
}
protected static String Bld_api(Keyval_hash hash, Keyval... xtn_ary) {
Bry_bfr bfr = Bry_bfr_.New();
int len = hash.Count();
for (int i = 0; i < len; ++i) {
Keyval kv = hash.Get_at(i);
bfr.Add_str_u8_fmt("{0}={1};", kv.Key(), kv.Val_to_str_or_empty());
}
for (Keyval xtn : xtn_ary) {
if (hash.Has(xtn.Key())) continue;
bfr.Add_str_u8_fmt("{0}={1};", xtn.Key(), xtn.Val_to_str_or_empty());
}
return bfr.To_str_and_clear();
}
}

View File

@@ -0,0 +1,46 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import org.junit.*;
public class Db_conn_info_tst {
@Before public void setup() {
regy.Add(Db_conn_info_mock.Instance);
} 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 Db_conn_info_mock(String raw, String db_api, String database) {super(raw, db_api, database);}
public Keyval[] Kvs() {return kvs;} Keyval[] kvs;
@Override public String Key() {return Tid_const;} public static final String Tid_const = "mock";
@Override public Db_conn_info New_self(String raw, Keyval_hash hash) {
Db_conn_info_mock rv = new Db_conn_info_mock("", "", "");
int len = hash.Count();
rv.kvs = new Keyval[len];
for (int i = 0; i < len; ++i)
rv.kvs[i] = hash.Get_at(i);
return rv;
}
public static final Db_conn_info_mock Instance = new Db_conn_info_mock("", "", "");
}

View File

@@ -0,0 +1,64 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.engines.*;
import gplx.dbs.qrys.bats.*;
public class Db_conn_pool { // PURPOSE: cache one connection per connection_string
private final Ordered_hash hash = Ordered_hash_.New();
public Db_batch_mgr Batch_mgr() {return batch_mgr;} private final Db_batch_mgr batch_mgr = new Db_batch_mgr();
public void Del(Db_conn_info url) {hash.Del(url.Db_api());}
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)hash.Get_by(url.Db_api());
if (rv == null) {
Db_engine prime = (Db_engine)prime_hash.Get_by(url.Key()); if (prime == null) Err_.new_wo_type("db engine prototype not found", "key", url.Key());
Db_engine clone = prime.New_clone(url);
rv = new Db_conn(clone);
clone.Batch_mgr().Copy(clone.Tid(), batch_mgr);
hash.Add(url.Db_api(), rv);
}
return rv;
}
public void Add_existing(Db_conn conn) {
hash.Add(conn.Conn_info().Db_api(), conn);
}
public void Rls_all() {
int len = hash.Len();
Db_conn[] rls_ary = new Db_conn[len];
for (int i = 0; i < len; ++i)
rls_ary[i] = (Db_conn)hash.Get_at(i);
for (int i = 0; i < len; ++i)
rls_ary[i].Rls_conn();
hash.Clear();
}
private final Hash_adp prime_hash = Hash_adp_.New();
public static final Db_conn_pool Instance = new Db_conn_pool(); Db_conn_pool() {this.Init();}
public void Primes__add(Db_engine... ary) { // PUBLIC.DRD:
for (Db_engine itm : ary)
prime_hash.Add(itm.Tid(), itm);
}
private void Init() {
this.Primes__add
( gplx.dbs.engines.noops .Noop_engine.Instance
, gplx.dbs.engines.mems .Mem_engine.Instance
, gplx.dbs.engines.sqlite .Sqlite_engine.Instance
, gplx.dbs.engines.mysql .Mysql_engine.Instance
, gplx.dbs.engines.postgres .Postgres_engine.Instance
, gplx.dbs.engines.tdbs .TdbEngine.Instance
);
}
}

View File

@@ -0,0 +1,75 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.metas.*;
public class Db_conn_utl {
public static Db_conn Conn__new(String url_rel) {
Db_conn_bldr.Instance.Reg_default_mem();
return Db_conn_bldr.Instance.Get_or_new(Io_url_.mem_fil_("mem/" + url_rel)).Conn();
}
public static void Tbl__new(Db_conn conn, String tbl, Dbmeta_fld_itm[] flds, Object[]... rows) {
conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl, flds));
int rows_len = rows.length;
Db_stmt stmt = conn.Stmt_insert(tbl, Dbmeta_fld_itm.To_str_ary(flds));
for (int i = 0; i < rows_len; ++i) {
Object[] row = rows[i];
int dat_len = row.length;
stmt.Clear();
for (int j = 0; j < dat_len; ++j) {
Dbmeta_fld_itm fld = flds[j];
String fld_name = fld.Name();
Object val = row[j];
switch (fld.Type().Tid_ansi()) {
case Dbmeta_fld_tid.Tid__bool: stmt.Val_bool_as_byte (fld_name, Bool_.Cast(val)); break;
case Dbmeta_fld_tid.Tid__byte: stmt.Val_byte (fld_name, Byte_.Cast(val)); break;
case Dbmeta_fld_tid.Tid__int: stmt.Val_int (fld_name, Int_.Cast(val)); break;
case Dbmeta_fld_tid.Tid__long: stmt.Val_long (fld_name, Long_.cast(val)); break;
case Dbmeta_fld_tid.Tid__float: stmt.Val_float (fld_name, Float_.cast(val)); break;
case Dbmeta_fld_tid.Tid__double: stmt.Val_double (fld_name, Double_.cast(val)); break;
case Dbmeta_fld_tid.Tid__str: stmt.Val_str (fld_name, String_.cast(val)); break;
case Dbmeta_fld_tid.Tid__bry: stmt.Val_bry (fld_name, Bry_.cast(val)); break;
}
}
stmt.Exec_insert();
}
}
public static void Insert(Db_conn conn, String tbl_name, String[] flds, Object[]... rows) {
Db_stmt stmt = Db_stmt_.new_insert_(conn, tbl_name, flds);
int flds_len = flds.length;
int rows_len = rows.length;
for (int i = 0; i < rows_len; ++i) {
Object[] row = rows[i];
stmt.Clear();
for (int j = 0; j < flds_len; ++j)
Db_stmt_.Val_by_obj(stmt, flds[j], row[j]);
stmt.Exec_insert();
}
}
public static Object[][] Select(Db_conn conn, Db_qry qry) {
List_adp rv = List_adp_.New();
Db_rdr rdr = conn.Stmt_new(qry).Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
int fld_len = rdr.Fld_len();
Object[] row = new Object[fld_len];
for (int i = 0; i < fld_len; ++i)
row[i] = rdr.Read_at(i);
rv.Add(row);
}
} finally {rdr.Rls();}
return (Object[][])rv.To_ary_and_clear(Object[].class);
}
}

View File

@@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.core.criterias.*;
public class Db_crt_ {
public static final Criteria Wildcard = Criteria_.All;
public static Criteria New_and (Criteria lhs, Criteria rhs) {return Criteria_.And(lhs, rhs);}
public static Criteria_fld New_eq (String key, Object val) {return Criteria_fld.new_(key, Criteria_.eq_(val));}
public static Criteria_fld New_eq (String pre, String key, Object val) {return Criteria_fld.new_(pre, key, Criteria_.eq_(val));}
public static Criteria_fld New_eq_not (String key, Object val) {return Criteria_fld.new_(key, Criteria_.eqn_(val));}
public static Criteria_fld New_lt (String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.lt_(val));}
public static Criteria_fld New_lte (String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.lte_(val));}
public static Criteria_fld New_mt (String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.mt_(val));}
public static Criteria_fld New_mte (String key, Comparable val) {return Criteria_fld.new_(key, Criteria_.mte_(val));}
public static Criteria_fld New_between (String key, Comparable lo, Comparable hi) {return Criteria_fld.new_(key, Criteria_.between_(lo, hi));}
public static Criteria_fld New_in (String key, Object... vals) {return Criteria_fld.new_(key, Criteria_.in_(vals));}
public static Criteria_fld New_like (String key, String pattern) {return Criteria_fld.new_(key, Criteria_.like_(pattern));}
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_.New_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 == Dbmeta_fld_itm.Key_null) continue;
Criteria crt = Db_crt_.New_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_.New_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,50 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import org.junit.*; import gplx.core.criterias.*; import gplx.core.gfo_ndes.*; import gplx.core.type_xtns.*;
public class Db_crt_tst {
@Before public void setup() {
row = GfoNde_.vals_(GfoFldList_.new_().Add("id", IntClassXtn.Instance).Add("name", StringClassXtn.Instance), Object_.Ary(1, "me"));
}
@Test public void EqualTest() {
crt = Db_crt_.New_eq("id", 1);
tst_Match(true, row, crt);
}
@Test public void EqualFalseTest() {
crt = Db_crt_.New_eq("id", 2);
tst_Match(false, row, crt);
}
@Test public void AndCompositeTest() {
crt = Criteria_.And(Db_crt_.New_eq("id", 1), Db_crt_.New_eq("name", "me"));
tst_Match(true, row, crt);
crt = Criteria_.And(Db_crt_.New_eq("id", 1), Db_crt_.New_eq("name", "you"));
tst_Match(false, row, crt);
}
@Test public void OrCompositeTest() {
crt = Criteria_.Or(Db_crt_.New_eq("id", 1), Db_crt_.New_eq("name", "you"));
tst_Match(true, row, crt);
crt = Criteria_.Or(Db_crt_.New_eq("id", 2), Db_crt_.New_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,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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,22 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public class Db_mock_cell {
public int Idx() {return idx;} public Db_mock_cell Idx_(int val) {idx = val; return this;} int idx = -1;
public String Fld() {return fld;} public Db_mock_cell Fld_(String v) {fld = v; return this;} private String fld = null;
public Object Val() {return val;} public Db_mock_cell Val_(Object v) {val = v; return this;} Object val = null;
public static Db_mock_cell new_() {return new Db_mock_cell();} Db_mock_cell() {}
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public class Db_mock_row {
public int Idx() {return idx;} public Db_mock_row Idx_(int val) {idx = val; return this;} int idx = -1;
public Db_mock_cell[] Dat() {return dat;} Db_mock_cell[] dat = null;
public static Db_mock_row vals_only_(Object... ary) {
Db_mock_row rv = new Db_mock_row();
int len = Array_.Len(ary);
rv.dat = new Db_mock_cell[len];
for (int i = 0; i < len; i++)
rv.dat[i] = Db_mock_cell.new_().Val_(ary[i]);
return rv;
}
public static Db_mock_row new_() {return new Db_mock_row();} Db_mock_row() {}
}

View File

@@ -0,0 +1,22 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public class Db_null implements gplx.core.brys.Bfr_arg {
public void Bfr_arg__add(Bry_bfr bfr) {bfr.Add_str_a7(Null_str);}
@Override public String toString() {return Null_str;}
public static final String Null_str = "NULL";
public static final Db_null Instance = new Db_null(); Db_null() {}
}

View File

@@ -0,0 +1,28 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public interface Db_qry {
int Tid();
boolean Exec_is_rdr();
String Base_table();
String To_sql__exec(gplx.dbs.sqls.Sql_qry_wtr wtr);
}
class Db_qry__noop implements Db_qry {
public int Tid() {return Db_qry_.Tid_noop;}
public boolean Exec_is_rdr() {return false;}
public String Base_table() {return "";}
public String To_sql__exec(gplx.dbs.sqls.Sql_qry_wtr wtr) {return "";}
}

View File

@@ -0,0 +1,61 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.core.criterias.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.itms.*;
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).Cols_all_();}
public static Db_qry__select_cmd select_() {return new Db_qry__select_cmd();}
public static Db_qry__select_cmd select_(String tbl, String... cols) {return new Db_qry__select_cmd().From_(tbl).Cols_(cols);}
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.Val_obj(pair.Key(), pair.Val());
return cmd;
}
public static Sql_join_fld New_join__join(String trg_fld, String src_tbl, String src_fld) {return new Sql_join_fld(trg_fld, src_tbl, src_fld);}
public static Sql_join_fld New_join__same(String tbl, String fld) {return new Sql_join_fld(fld, tbl, fld);}
public static Db_qry_update update_(String tbl, Criteria crt) {
Db_qry_update update = new Db_qry_update();
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 = new Db_qry_update();
cmd.From_(tbl); cmd.Where_(crt);
for (Keyval pair : pairs)
cmd.Val_obj(pair.Key(), pair.Val());
return cmd;
}
public static gplx.core.gfo_ndes.GfoNde Exec_as_nde(Db_conn conn, Db_qry qry) {return gplx.core.gfo_ndes.GfoNde_.rdr_(conn.Exec_qry_as_old_rdr(qry));}
public static Object Exec_as_obj(Db_conn conn, Db_qry__select_cmd qry) {
gplx.core.stores.DataRdr rdr = conn.Exec_qry_as_old_rdr(qry);
try {
return rdr.MoveNextPeer() ? rdr.Read(qry.Cols().Flds.Get_at(0).Fld) : null; // NOTE: need to access from flds for tdb
} finally {rdr.Rls();}
}
public static Db_qry as_(Object obj) {return obj instanceof Db_qry ? (Db_qry)obj : null;}
public static final Db_qry Noop = new Db_qry__noop();
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, Tid_noop = 7, Tid_pragma = 8;
}

View File

@@ -0,0 +1,65 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.qrys.*; import gplx.core.gfo_ndes.*;
public class Db_qry_fxt {
public static void Insert_kvo(Db_conn conn, String tblName, Keyval_list kvList) {
Db_qry_insert qry = Db_qry_.insert_(tblName);
for (int i = 0; i < kvList.Count(); i++) {
Keyval kv = kvList.Get_at(i);
qry.Val_obj(kv.Key(), kv.Val());
}
qry.Exec_qry(conn);
}
public static GfoNde SelectAll(Db_conn conn, String tblName) {
return Db_qry_.Exec_as_nde(conn, Db_qry_.select_tbl_(tblName));
}
public static int SelectAll_count(Db_conn conn, String tblName) {
GfoNde nde = Db_qry_fxt.SelectAll(conn, tblName);
return nde.Subs().Count();
}
public static void DeleteAll(Db_conn conn, String... ary) {
for (String s : ary)
Db_qry_.delete_tbl_(s).Exec_qry(conn);
}
public static void tst_Select(Db_conn conn, String tblName, Db_mock_row... expdAry) {
GfoNde nde = Db_qry_fxt.SelectAll(conn, tblName);
int len = Array_.Len(expdAry);
for (int i = 0; i < len; i++) {
Db_mock_row expdRow = expdAry[i];
int actlIdx = (expdRow.Idx() == -1) ? i : expdRow.Idx();
GfoNde actlNde = nde.Subs().FetchAt_asGfoNde(actlIdx);
int fldLen = Array_.Len(expdRow.Dat());
for (int j = 0; j < fldLen; j++) {
Db_mock_cell expdDat = expdRow.Dat()[j];
Object actlVal = expdDat.Fld() == null ? actlNde.ReadAt(j) : actlNde.Read(expdDat.Fld());
Tfds.Eq(expdDat.Val(), actlVal);
}
}
}
public static String Db__print_tbl_as_str(Bry_bfr bfr, Db_conn conn, String tbl, String... cols) {
int cols_len = cols.length;
Db_rdr rdr = conn.Stmt_select(tbl, cols).Exec_select__rls_auto();
while (rdr.Move_next()) {
for (int i = 0; i < cols_len; ++i) {
bfr.Add_obj(rdr.Read_at(i));
bfr.Add_byte(i == cols_len - 1 ? Byte_ascii.Nl : Byte_ascii.Pipe);
}
}
rdr.Rls();
return bfr.To_str_and_clear();
}
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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);
int Fld_len();
Object Read_obj(String k);
Object Read_at(int i);
void Rls();
}

View File

@@ -0,0 +1,37 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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_.Min_value;}
public long Read_long(String k) {return Long_.Min_value;}
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 int Fld_len() {return 0;}
public Object Read_obj(String k) {return null;}
public Object Read_at(int i) {return null;}
public void Rls() {}
}

View File

@@ -0,0 +1,49 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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 Err_.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 Err_.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 Err_.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 Err_.new_unimplemented();}
@gplx.Virtual public String Read_str(String k) {try {return (String)rdr.getObject(k);} catch (Exception e) {throw Err_.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 Err_.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 Err_.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 Err_.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 Err_.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 Err_.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 Err_.new_exc(e, "db", "read failed", "key", k, "type", Bool_.Cls_val_name);}}
@gplx.Virtual public int Fld_len() {try {return rdr.getMetaData().getColumnCount();} catch (Exception e) {throw Err_.new_exc(e, "db", "field count failed", "sql", sql);}}
@gplx.Virtual public Object Read_obj(String k) {try {return rdr.getObject(k);} catch (Exception e) {throw Err_.new_exc(e, "db", "read failed", "key", k, "type", Object_.Cls_val_name);}}
@gplx.Virtual public Object Read_at(int i) {try {return rdr.getObject(i + 1);} catch (Exception e) {throw Err_.new_exc(e, "db", "read failed", "idx", i, "type", Object_.Cls_val_name);}}
@gplx.Virtual public void Rls() {
try {rdr.close();}
catch (Exception e) {throw Err_.new_exc(e, "db", "close failed");}
if (stmt != null) {
stmt.Rls();
stmt = null; // NOTE: must null reference else will throw SQLException during statements DATE:2016-04-10
}
}
}

View File

@@ -0,0 +1,60 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public class Db_sql_ {
public static String Make_by_fmt(String[] lines, Object... args) {
Bry_bfr bfr = Bry_bfr_.New();
int len = lines.length;
for (int i = 0; i < len; ++i) {
if (i != 0) bfr.Add_byte_nl();
bfr.Add_str_u8(lines[i]);
}
String fmt = bfr.To_str_and_clear();
return String_.Format(fmt, args);
}
public static byte[] Escape_arg(byte[] raw) {
int len = raw.length;
Bry_bfr bfr = null;
boolean dirty = false;
for (int i = 0; i < len; ++i) {
byte b = raw[i];
if (b == Byte_ascii.Apos) {
if (bfr == null) {
dirty = true;
bfr = Bry_bfr_.New();
bfr.Add_mid(raw, 0, i);
}
bfr.Add_byte_apos().Add_byte_apos();
}
else {
if (dirty) {
bfr.Add_byte(b);
}
}
}
return dirty ? bfr.To_bry_and_clear() : raw;
}
public static String Prep_in_from_ary(Object ary) {
Bry_bfr bfr = Bry_bfr_.New();
int len = Array_.Len(ary);
for (int i = 0; i < len; i++) {
if (i != 0) bfr.Add_byte(Byte_ascii.Comma);
bfr.Add_byte(Byte_ascii.Question);
}
return bfr.To_str_and_clear();
}
}

View File

@@ -0,0 +1,76 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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.Instance.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 == Dbmeta_fld_itm.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 Instance = 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,65 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.engines.*; import gplx.core.stores.*;
public interface Db_stmt extends Rls_able {
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_by_bool(String k, boolean 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, Decimal_adp v);
Db_stmt Val_decimal(String k, Decimal_adp v);
Db_stmt Val_decimal(Decimal_adp 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.core.ios.streams.Io_stream_rdr rdr, long rdr_len);
Db_stmt Crt_date(String k, DateAdp v);
Db_stmt Val_date(String k, DateAdp v);
Db_stmt Crt_text(String k, String v);
Db_stmt Val_text(String k, String v);
boolean Exec_insert();
int Exec_update();
int Exec_delete();
DataRdr Exec_select();
Db_rdr Exec_select__rls_auto(); // stmt is automatically released
Db_rdr Exec_select__rls_manual(); // stmt must be released manually; for "batch" insert
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,74 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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_.New_in(in_fld, in_vals), flds).Order_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 Db_stmt New_sql_lines(Db_conn conn, String... lines) {
Db_qry qry = Db_qry_sql.sql_(String_.Concat_with_str("\n", lines));
return conn.Stmt_new(qry);
}
public static Err err_(Exception e, Db_stmt stmt, String proc) {
throw Err_.new_exc(e, "db", "db stmt failed", "proc", proc);
}
public static Err err_(Exception e, String tbl, String proc) {
throw Err_.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;}
public static void Val_by_obj(Db_stmt stmt, String key, Object val) {
int tid = Type_ids_.To_id_by_obj(val);
switch (tid) {
case Type_ids_.Id__bool: stmt.Val_bool_as_byte (key, Bool_.Cast(val)); break;
case Type_ids_.Id__byte: stmt.Val_byte (key, Byte_.Cast(val)); break;
case Type_ids_.Id__int: stmt.Val_int (key, Int_.Cast(val)); break;
case Type_ids_.Id__long: stmt.Val_long (key, Long_.cast(val)); break;
case Type_ids_.Id__float: stmt.Val_float (key, Float_.cast(val)); break;
case Type_ids_.Id__double: stmt.Val_double (key, Double_.cast(val)); break;
case Type_ids_.Id__str: stmt.Val_str (key, String_.cast(val)); break;
case Type_ids_.Id__bry: stmt.Val_bry (key, Bry_.cast(val)); break;
default: throw Err_.new_unhandled_default(tid);
}
}
}

View File

@@ -0,0 +1,46 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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, Dbmeta_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 Err_.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,20 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public interface Db_tbl extends Rls_able {
String Tbl_name();
void Create_tbl();
}

View File

@@ -0,0 +1,28 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public class Db_tbl_ {
public static void Create_tbl(Db_tbl... ary) {
int len = ary.length;
for (int i = 0; i < len; ++i)
ary[i].Create_tbl();
}
public static void Rls(Db_tbl... ary) {
int len = ary.length;
for (int i = 0; i < len; ++i)
ary[i].Rls();
}
}

View File

@@ -0,0 +1,19 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public interface Db_tbl_owner {
Db_tbl Tbls__get_by_key(String key);
}

View File

@@ -0,0 +1,79 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.metas.*;
public class Dbmeta_fld_itm {
public Dbmeta_fld_itm(String name, Dbmeta_fld_tid type) {
this.name = name; this.type = type;
this.primary = false; this.autonum = false; this.default_val = Default_value_null;
}
public String Name() {return name;} private final String name;
public Dbmeta_fld_tid Type() {return type;} private final Dbmeta_fld_tid type;
public int Nullable_tid() {return nullable_tid;} public Dbmeta_fld_itm Nullable_tid_(int v) {nullable_tid = v; return this;} private int nullable_tid;
public Dbmeta_fld_itm Nullable_y_() {return Nullable_tid_(Nullable_null);}
public boolean Primary() {return primary;} public Dbmeta_fld_itm Primary_y_() {primary = true; return this;} private boolean primary; public Dbmeta_fld_itm Primary_n_() {primary = false; return this;}
public boolean Autonum() {return autonum;} public Dbmeta_fld_itm Autonum_y_() {autonum = true; return this;} private boolean autonum;
public Object Default() {return default_val;} public Dbmeta_fld_itm Default_(Object v) {default_val = v; return this;} private Object default_val;
public boolean Eq(Dbmeta_fld_itm comp) {
return String_.Eq(name, comp.name)
&& type.Eq(comp.type)
&& nullable_tid == comp.nullable_tid
&& primary == comp.primary
&& autonum == comp.autonum
&& Object_.Eq(default_val, comp.default_val);
}
public static final int Nullable_unknown = 0, Nullable_null = 1, Nullable_not_null = 2;
public static final Object Default_value_null = null;
public static final String Key_null = null;
public static final String[] Str_ary_empty = String_.Ary_empty;
public static final Dbmeta_fld_itm[] Ary_empty = new Dbmeta_fld_itm[0];
public static Dbmeta_fld_itm new_bool(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__bool);}
public static Dbmeta_fld_itm new_byte(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__byte);}
public static Dbmeta_fld_itm new_short(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__short);}
public static Dbmeta_fld_itm new_int(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__int);}
public static Dbmeta_fld_itm new_long(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__long);}
public static Dbmeta_fld_itm new_float(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__float);}
public static Dbmeta_fld_itm new_double(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__double);}
public static Dbmeta_fld_itm new_text(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__text);}
public static Dbmeta_fld_itm new_bry(String name) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__bry);}
public static Dbmeta_fld_itm new_str(String name, int len) {return new Dbmeta_fld_itm(name, Dbmeta_fld_tid.Itm__str(len));}
public static String[] To_str_ary(Dbmeta_fld_itm[] ary) {
int len = ary.length;
String[] rv = new String[len];
for (int i = 0; i < len; ++i)
rv[i] = ary[i].name;
return rv;
}
public static String Make_or_null(Db_conn conn, Dbmeta_fld_list flds, String tbl_name, int fld_type, Object fld_dflt, String fld_name) {
boolean tbl_exists = conn.Meta_tbl_exists(tbl_name);
boolean fld_exists = true;
if (tbl_exists) {
fld_exists = conn.Meta_fld_exists(tbl_name, fld_name);
if (!fld_exists) return Dbmeta_fld_itm.Key_null;
}
Dbmeta_fld_itm fld = null;
switch (fld_type) {
case Dbmeta_fld_tid.Tid__int: fld = Dbmeta_fld_itm.new_int(fld_name); break;
}
if (fld_dflt != null) fld.Default_(fld_dflt);
flds.Add(fld);
return fld.name;
}
public static String To_double_str_by_int(int v) {return Int_.To_str(v) + ".0";}
}

View File

@@ -0,0 +1,106 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
public class Dbmeta_fld_list {
private final Ordered_hash flds = Ordered_hash_.New();
public void Clear() {flds.Clear(); str_ary = null; fld_ary = null;}
public int Len() {return flds.Len();}
public boolean Has(String key) {return flds.Has(key);}
public Dbmeta_fld_itm Get_by(String name) {return (Dbmeta_fld_itm)flds.Get_by(name);}
public Dbmeta_fld_itm Get_at(int idx) {return (Dbmeta_fld_itm)flds.Get_at(idx);}
public String Add_bool(String name) {return Add(Dbmeta_fld_itm.new_bool(name));}
public String Add_byte(String name) {return Add(Dbmeta_fld_itm.new_byte(name));}
public String Add_short(String name) {return Add(Dbmeta_fld_itm.new_short(name));}
public String Add_int(String name) {return Add(Dbmeta_fld_itm.new_int(name));}
public String Add_int_pkey(String name) {return Add(Dbmeta_fld_itm.new_int(name).Primary_y_());}
public String Add_int_pkey_autonum(String name) {return Add(Dbmeta_fld_itm.new_int(name).Primary_y_().Autonum_y_());}
public String Add_int_autonum(String name) {return Add(Dbmeta_fld_itm.new_int(name).Autonum_y_());}
public String Add_int_dflt(String name, int dflt) {return Add(Dbmeta_fld_itm.new_int(name).Default_(dflt));}
public String Add_long(String name) {return Add(Dbmeta_fld_itm.new_long(name));}
public String Add_float(String name) {return Add(Dbmeta_fld_itm.new_float(name));}
public String Add_double(String name) {return Add(Dbmeta_fld_itm.new_double(name));}
public String Add_text(String name) {return Add(Dbmeta_fld_itm.new_text(name));}
public String Add_bry(String name) {return Add(Dbmeta_fld_itm.new_bry(name));}
public String Add_str(String name, int len) {return Add(Dbmeta_fld_itm.new_str(name, len));}
public String Add_date(String name) {return Add(Dbmeta_fld_itm.new_str(name, 32));}
public String Add_str_pkey(String name, int len) {return Add(Dbmeta_fld_itm.new_str(name, len).Primary_y_());}
public String Add_str_null(String name, int len) {return Add(Dbmeta_fld_itm.new_str(name, len).Nullable_y_());}
public String Add_str_dflt(String name, int len, String dflt)
{return Add(Dbmeta_fld_itm.new_str(name, len).Default_(dflt));}
public String Add(Dbmeta_fld_itm fld) {
fld_ary = null; str_ary = null;
String name = fld.Name();
flds.Add(name, fld);
return name;
}
public void Del(String key) {
fld_ary = null; str_ary = null;
flds.Del(key);
}
public void Insert(int pos, Dbmeta_fld_itm fld) {
fld_ary = null; str_ary = null;
flds.Add_at(pos, fld);
}
public Dbmeta_fld_list New_int(String name) {Add(Dbmeta_fld_itm.new_int(name)); return this;}
public Dbmeta_fld_list New_fld(Dbmeta_fld_itm fld) {Add(fld); return this;}
public Dbmeta_fld_list Clone() {
Dbmeta_fld_list rv = new Dbmeta_fld_list();
int len = this.Len();
for (int i = 0; i < len; ++i)
rv.Add(this.Get_at(i));
return rv;
}
public Dbmeta_fld_itm[] To_fld_ary() {if (fld_ary == null) fld_ary = (Dbmeta_fld_itm[])flds.To_ary(Dbmeta_fld_itm.class); return fld_ary;} private Dbmeta_fld_itm[] fld_ary;
public String[] To_str_ary() {
if (str_ary == null) {
int len = flds.Len();
this.str_ary = new String[len];
for (int i = 0; i < len; ++i) {
Dbmeta_fld_itm fld = (Dbmeta_fld_itm)flds.Get_at(i);
str_ary[i] = fld.Name();
}
}
return str_ary;
} private String[] str_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) {
Dbmeta_fld_itm fld = (Dbmeta_fld_itm)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) {
Dbmeta_fld_itm fld = (Dbmeta_fld_itm)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();
}
}

View File

@@ -0,0 +1,71 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.engines.sqlite.*; // for Tid_sqlite; note that Tid_sqlite is not used, and only exists for doc purposes
public class Dbmeta_fld_tid {
public Dbmeta_fld_tid(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;
public boolean Eq(Dbmeta_fld_tid comp) {
return tid_ansi == comp.tid_ansi
&& tid_sqlite == comp.tid_sqlite
&& Bry_.Eq(name, comp.name)
&& len_1 == comp.len_1
&& len_2 == comp.len_2;
}
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 Dbmeta_fld_tid
Itm__byte = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__byte , Sqlite_tid.Tid_int , Bry_.new_a7("tinyint") , -1, -1)
, Itm__short = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__short , Sqlite_tid.Tid_int , Bry_.new_a7("smallint") , -1, -1)
, Itm__int = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__int , Sqlite_tid.Tid_int , Bry_.new_a7("integer") , -1, -1)
, Itm__long = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__long , Sqlite_tid.Tid_int , Bry_.new_a7("bigint") , -1, -1)
, Itm__text = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__text , Sqlite_tid.Tid_text , Bry_.new_a7("text") , -1, -1)
, Itm__bry = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__bry , Sqlite_tid.Tid_none , Bry_.new_a7("blob") , -1, -1)
, Itm__float = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__float , Sqlite_tid.Tid_real , Bry_.new_a7("float") , -1, -1)
, Itm__double = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__double , Sqlite_tid.Tid_real , Bry_.new_a7("double") , -1, -1)
, Itm__numeric = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__decimal , Sqlite_tid.Tid_numeric , Bry_.new_a7("numeric") , -1, -1)
, Itm__bool = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__bool , Sqlite_tid.Tid_numeric , Bry_.new_a7("bit") , -1, -1) // "bit" is not SQLITE
, Itm__date = new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__date , Sqlite_tid.Tid_numeric , Bry_.new_a7("date") , -1, -1)
;
public static Dbmeta_fld_tid Itm__str (int len) {return new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__str , Sqlite_tid.Tid_text , Bry_.new_a7("varchar") , len, -1);}
public static Dbmeta_fld_tid Itm__decimal (int len_1, int len_2) {return new Dbmeta_fld_tid(Dbmeta_fld_tid.Tid__decimal , Sqlite_tid.Tid_numeric , Bry_.new_a7("decimal") , len_1, len_2);}
public static Dbmeta_fld_tid New(int tid, int len1) {
switch (tid) {
case Dbmeta_fld_tid.Tid__bool: return Itm__bool;
case Dbmeta_fld_tid.Tid__byte: return Itm__byte;
case Dbmeta_fld_tid.Tid__short: return Itm__short;
case Dbmeta_fld_tid.Tid__int: return Itm__int;
case Dbmeta_fld_tid.Tid__long: return Itm__long;
case Dbmeta_fld_tid.Tid__float: return Itm__float;
case Dbmeta_fld_tid.Tid__double: return Itm__double;
case Dbmeta_fld_tid.Tid__str: return Itm__str(len1);
case Dbmeta_fld_tid.Tid__text: return Itm__text;
case Dbmeta_fld_tid.Tid__bry: return Itm__bry;
case Dbmeta_fld_tid.Tid__date: return Itm__date;
case Dbmeta_fld_tid.Tid__decimal: // return Itm__decimal(len1);
default: throw Err_.new_unhandled(tid);
}
}
public static Dbmeta_fld_itm To_itm(String raw) {
return null;
}
}

View File

@@ -0,0 +1,52 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*;
public class Dbmeta_idx_itm {
public Dbmeta_idx_itm(boolean unique, String tbl, String name, Dbmeta_idx_fld[] 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 final Dbmeta_idx_fld[] Flds;
public String To_sql_create(Sql_qry_wtr sql_wtr) {return sql_wtr.Schema_wtr().Bld_create_idx(this);}
public boolean Eq(Dbmeta_idx_itm comp) {
return String_.Eq(name, comp.name)
&& unique == comp.unique
&& tbl == comp.tbl
&& Dbmeta_idx_fld.Ary_eq(Flds, comp.Flds);
}
public static Dbmeta_idx_itm new_unique_by_name (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.Y, tbl, name, To_fld_ary(flds));}
public static Dbmeta_idx_itm new_normal_by_name (String tbl, String name, Dbmeta_idx_fld... flds) {return new Dbmeta_idx_itm(Bool_.N, tbl, name, flds);}
public static Dbmeta_idx_itm new_normal_by_name (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.N, tbl, name, To_fld_ary(flds));}
public static Dbmeta_idx_itm new_unique_by_tbl (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.Y, tbl, Bld_idx_name(tbl, name), To_fld_ary(flds));}
public static Dbmeta_idx_itm new_normal_by_tbl (String tbl, String name, Dbmeta_idx_fld... flds) {return new Dbmeta_idx_itm(Bool_.N, tbl, Bld_idx_name(tbl, name), flds);}
public static Dbmeta_idx_itm new_normal_by_tbl (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.N, tbl, Bld_idx_name(tbl, name), To_fld_ary(flds));}
public static Dbmeta_idx_itm new_unique_by_tbl_wo_null (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.Y, tbl, Bld_idx_name(tbl, name), To_fld_ary(flds));}
public static Dbmeta_idx_itm new_normal_by_tbl_wo_null (String tbl, String name, String... flds) {return new Dbmeta_idx_itm(Bool_.N, tbl, Bld_idx_name(tbl, name), To_fld_ary(flds));}
public static String Bld_idx_name(String tbl, String suffix) {return String_.Concat(tbl, "__", suffix);}
public static final Dbmeta_idx_itm[] Ary_empty = new Dbmeta_idx_itm[0];
public static Dbmeta_idx_fld[] To_fld_ary(String[] ary) {
int len = ary.length;
Dbmeta_idx_fld[] rv = new Dbmeta_idx_fld[len];
for (int i = 0; i < len; ++i) {
String itm = ary[i]; if (itm == null) continue;
rv[i] = new Dbmeta_idx_fld(itm, Dbmeta_idx_fld.Sort_tid__none);
}
return rv;
}
}

View File

@@ -0,0 +1,41 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs; import gplx.*;
import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*;
public class Dbmeta_tbl_itm {
public String Name() {return name;} private String name;
public Dbmeta_idx_mgr Idxs() {return idxs;} private final Dbmeta_idx_mgr idxs = new Dbmeta_idx_mgr();
public Dbmeta_fld_mgr Flds() {return flds;} private final Dbmeta_fld_mgr flds = new Dbmeta_fld_mgr();
public String To_sql_create(Sql_qry_wtr sql_wtr) {return sql_wtr.Schema_wtr().Bld_create_tbl(this);}
public static Dbmeta_tbl_itm New(String name, Dbmeta_fld_list flds, Dbmeta_idx_itm... idxs) {return New(name, flds.To_fld_ary(), idxs);}
public static Dbmeta_tbl_itm New(String name, Dbmeta_fld_itm... flds) {return New(name, flds, Dbmeta_idx_itm.Ary_empty);}
public static Dbmeta_tbl_itm New(String name, Dbmeta_fld_itm[] flds, Dbmeta_idx_itm... idxs) {
Dbmeta_tbl_itm rv = new Dbmeta_tbl_itm();
rv.name = name;
if (flds != null) {
int flds_len = flds.length;
for (int i = 0; i < flds_len; ++i)
rv.flds.Add(flds[i]);
}
if (idxs != null) {
int idxs_len = idxs.length;
for (int i = 0; i < idxs_len; ++i)
rv.idxs.Add(idxs[i]);
}
return rv;
}
}

View File

@@ -13,3 +13,14 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.conn_props; import gplx.*; import gplx.dbs.*;
public class Db_conn_props_mgr {
private final Ordered_hash hash = Ordered_hash_.New();
public boolean Has(String key) {return hash.Has(key);}
public boolean Match(String key, String expd_val) {
String actl_val = (String)hash.Get_by(key);
return actl_val == null ? false : String_.Eq(expd_val,actl_val);
}
public void Add(String key, String val) {hash.Add(key, val);}
public void Del(String key) {hash.Del(key);}
}

View File

@@ -13,3 +13,32 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*;
import gplx.dbs.diffs.itms.*;
import gplx.dbs.diffs.builds.*;
public class Gdif_core {
private final Db_conn conn;
private final Gdif_job_tbl job_tbl;
private final Gdif_cmd_tbl cmd_tbl;
private final Gdif_txn_tbl txn_tbl;
public Gdif_core(Db_conn conn) {
this.conn = conn;
this.db = new Gdif_db(conn);
this.job_tbl = db.Job_tbl();
this.cmd_tbl = db.Cmd_tbl();
this.txn_tbl = db.Txn_tbl();
}
public Gdif_db Db() {return db;} private final Gdif_db db;
public Gdif_job_itm New_job(String name, String made_by) {
int job_id = conn.Sys_mgr().Autonum_next(job_tbl.Tbl_name(), job_tbl.Fld_job_id());
return job_tbl.Insert(job_id, name, made_by, Datetime_now.Get().XtoUtc(), "");
}
public Gdif_cmd_itm New_cmd(Gdif_bldr_ctx ctx, int tid) {
ctx.Cur_cmd_count++;
return cmd_tbl.Insert(ctx.Cur_job.Id, ctx.Cur_cmd_count, tid, "");
}
public Gdif_txn_itm New_txn(Gdif_bldr_ctx ctx, int cmd_id, int owner_txn) {
ctx.Cur_txn_count++;
return txn_tbl.Insert(ctx.Cur_job.Id, ctx.Cur_txn_count, cmd_id, owner_txn);
}
}

View File

@@ -13,3 +13,17 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*;
import gplx.dbs.diffs.itms.*;
public class Gdif_db {
public Gdif_db(Db_conn conn) {
this.conn = conn;
this.job_tbl = new Gdif_job_tbl(conn);
this.cmd_tbl = new Gdif_cmd_tbl(conn);
this.txn_tbl = new Gdif_txn_tbl(conn);
}
public Db_conn Conn() {return conn;} private final Db_conn conn;
public Gdif_job_tbl Job_tbl() {return job_tbl;} private final Gdif_job_tbl job_tbl;
public Gdif_cmd_tbl Cmd_tbl() {return cmd_tbl;} private final Gdif_cmd_tbl cmd_tbl;
public Gdif_txn_tbl Txn_tbl() {return txn_tbl;} private final Gdif_txn_tbl txn_tbl;
}

View File

@@ -13,3 +13,19 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*;
public class Gdif_db_ {
public static final String
Fld__dif_txn = "dif_txn" // 0+ where 0+ is defined in a tbl
, Fld__dif_uid = "dif_uid" // 0+
, Fld__dif_type = "dif_type" // I,U,D,M
, Fld__dif_db_trg = "dif_db_trg" // -1 for single-db tables; 0+ for multiple-db tables
, Fld__dif_db_src = "dif_db_src" // -1 for I,U,D; 0+ for M
;
public static final byte
Tid__insert = 0
, Tid__update = 1
, Tid__delete = 2
, Tid__move = 3
;
}

View File

@@ -13,3 +13,44 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*;
import gplx.dbs.metas.*; import gplx.dbs.diffs.builds.*;
class Gfdb_diff_cmd {
private final Gfdb_diff_wkr__db diff_bldr_wkr = new Gfdb_diff_wkr__db();
private final Gfdb_diff_bldr diff_bldr = new Gfdb_diff_bldr();
public Gfdb_diff_cmd() {
diff_bldr.Init(diff_bldr_wkr);
}
public Gfdb_diff_job New_job(Gdif_db db, String guid, String name, String made_by, String desc) {
return new Gfdb_diff_job(db);
}
public void Bld(Gfdb_diff_job job, Gfdb_diff_tbl_mgr lhs_mgr, Gfdb_diff_tbl_mgr rhs_mgr) {
diff_bldr_wkr.Init_conn(job.Db(), 1000);
int rhs_len = rhs_mgr.Len();
for (int i = 0; i < rhs_len; ++i) {
Gfdb_diff_tbl rhs_tbl = rhs_mgr.Get_at(i);
Gfdb_diff_tbl lhs_tbl = lhs_mgr.Get_by(rhs_tbl.Name);
if (lhs_tbl == null) {
// Add_cmd_tbl_create();
// Add_cmd_tbl_insert_all());
}
else {
// Compare_flds();
// Compare_idxs();
// diff_bldr.Compare(lhs_tbl, rhs_tbl);
}
}
int lhs_len = lhs_mgr.Len();
for (int i = 0; i < lhs_len; ++i) {
Gfdb_diff_tbl lhs_tbl = lhs_mgr.Get_at(i);
if (lhs_tbl == null) {
// Add_cmd_dat_delete_all());
// Add_cmd_tbl_delete();
}
}
}
}
class Gfdb_diff_job {
public Gfdb_diff_job(Gdif_db db) {this.db = db;}
public Gdif_db Db() {return db;} private Gdif_db db;
}

View File

@@ -13,3 +13,72 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*;
import gplx.dbs.metas.*;
public class Gfdb_diff_tbl {
public Gfdb_diff_tbl(String name, Dbmeta_fld_itm[] flds, Dbmeta_fld_itm[] keys, Dbmeta_fld_itm[] vals) {
this.Name = name; this.Flds = flds; this.Keys = keys; this.Vals = vals;
}
public final String Name;
public final Dbmeta_fld_itm[] Flds;
public final Dbmeta_fld_itm[] Keys;
public final Dbmeta_fld_itm[] Vals;
public Db_rdr Make_rdr(Db_conn conn) {
Db_stmt stmt = conn.Stmt_select_order(Name, Dbmeta_fld_itm.To_str_ary(Flds), Dbmeta_fld_itm.Str_ary_empty, Dbmeta_fld_itm.To_str_ary(Keys));
return stmt.Exec_select__rls_auto();
}
public static Gfdb_diff_tbl New(Dbmeta_tbl_itm tbl) {
Dbmeta_fld_mgr flds = tbl.Flds();
Dbmeta_fld_mgr keys = Calc_keys(tbl);
Dbmeta_fld_mgr vals = Calc_vals(tbl.Flds(), keys);
return new Gfdb_diff_tbl(tbl.Name(), flds.To_ary(), keys.To_ary(), vals.To_ary());
}
public static Dbmeta_fld_mgr Calc_keys(Dbmeta_tbl_itm tbl) {
Dbmeta_fld_mgr rv = new Dbmeta_fld_mgr();
// try to find primary
Dbmeta_fld_mgr flds = tbl.Flds();
int flds_len = flds.Len();
for (int i = 0; i < flds_len; ++i) {
Dbmeta_fld_itm fld = flds.Get_at(i);
if (fld.Primary()) {
rv.Add(fld);
return rv;
}
}
// try to find shortest unique index
Dbmeta_idx_itm unique_idx = null; int unique_idx_len = Int_.Max_value;
Dbmeta_idx_mgr idxs = tbl.Idxs();
int idxs_len = idxs.Len();
for (int i = 0; i < idxs_len; ++i) {
Dbmeta_idx_itm idx = idxs.Get_at(i);
if (idx.Unique() && idx.Flds.length < unique_idx_len) { // get first shortest unique index; note that "<" is "get first" whereas "<=" is "get last"
unique_idx = idx;
unique_idx_len = idx.Flds.length;
break;
}
}
if (unique_idx != null) {
Dbmeta_idx_fld[] idx_flds = unique_idx.Flds;
int idx_flds_len = idx_flds.length;
for (int i = 0; i < idx_flds_len; ++i)
rv.Add(flds.Get_by(idx_flds[i].Name));
return rv;
}
// just add all
for (int i = 0; i < flds_len; ++i) {
Dbmeta_fld_itm fld = flds.Get_at(i);
rv.Add(fld);
}
return rv;
}
private static Dbmeta_fld_mgr Calc_vals(Dbmeta_fld_mgr flds, Dbmeta_fld_mgr keys) {
Dbmeta_fld_mgr rv = new Dbmeta_fld_mgr();
int flds_len = flds.Len();
for (int i = 0; i < flds_len; ++i) {
Dbmeta_fld_itm fld = flds.Get_at(i);
if (!keys.Has(fld.Name())) rv.Add(fld);
}
return rv;
}
}

View File

@@ -13,3 +13,21 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*;
class Gfdb_diff_tbl_mgr {
private final Ordered_hash hash = Ordered_hash_.New();
public int Len() {return hash.Count();}
public Gfdb_diff_tbl Get_at(int idx) {return (Gfdb_diff_tbl)hash.Get_at(idx);}
public Gfdb_diff_tbl Get_by(String key) {return (Gfdb_diff_tbl)hash.Get_by(key);}
}
class Gfdb_diff_tbl_mgr__sqlite {
public void Fill(Gfdb_diff_tbl_mgr tbl_mgr, Db_conn conn) {
// String schema_str = ""; // conn.Get_schema();
}
public void Fill(Gfdb_diff_tbl_mgr tbl_mgr, String schema_str) {
/*
Db_conn conn = null;
conn.Meta_get_tbls(Gfdb_diff_tbl_mgr tbl_mgr, "");
*/
}
}

View File

@@ -13,3 +13,64 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs; import gplx.*; import gplx.dbs.*;
import gplx.dbs.metas.*;
public class Gfdb_rdr_utl_ {
public static int Compare(Dbmeta_fld_itm[] flds, int len, Db_rdr lhs_rdr, Db_rdr rhs_rdr) {
int comp = CompareAble_.Same;
for (int i = 0; i < len; ++i) {
Dbmeta_fld_itm fld = flds[i];
String fld_name = fld.Name();
int tid = fld.Type().Tid_ansi();
switch (tid) {
case Dbmeta_fld_tid.Tid__bool: comp = Bool_.Compare (lhs_rdr.Read_bool_by_byte(fld_name), rhs_rdr.Read_bool_by_byte(fld_name)); break;
case Dbmeta_fld_tid.Tid__byte: comp = Byte_.Compare (lhs_rdr.Read_byte(fld_name) , rhs_rdr.Read_byte(fld_name)); break;
case Dbmeta_fld_tid.Tid__int: comp = Int_.Compare (lhs_rdr.Read_int(fld_name) , rhs_rdr.Read_int(fld_name)); break;
case Dbmeta_fld_tid.Tid__long: comp = Long_.Compare (lhs_rdr.Read_long(fld_name) , rhs_rdr.Read_long(fld_name)); break;
case Dbmeta_fld_tid.Tid__float: comp = Float_.Compare (lhs_rdr.Read_float(fld_name) , rhs_rdr.Read_float(fld_name)); break;
case Dbmeta_fld_tid.Tid__double: comp = Double_.Compare (lhs_rdr.Read_double(fld_name) , rhs_rdr.Read_double(fld_name)); break;
case Dbmeta_fld_tid.Tid__str: comp = String_.Compare (lhs_rdr.Read_str(fld_name) , rhs_rdr.Read_str(fld_name)); break;
case Dbmeta_fld_tid.Tid__bry: comp = Bry_.Compare (lhs_rdr.Read_bry(fld_name) , rhs_rdr.Read_bry(fld_name)); break;
default: throw Err_.new_unhandled(tid);
}
if (comp != CompareAble_.Same) return comp;
}
return CompareAble_.Same;
}
public static void Stmt_args(Db_stmt stmt, Dbmeta_fld_itm[] flds, int bgn, int end, Db_rdr rdr) {
for (int i = bgn; i < end; ++i) {
Dbmeta_fld_itm fld = flds[i];
String fld_name = fld.Name();
int tid = fld.Type().Tid_ansi();
switch (tid) {
case Dbmeta_fld_tid.Tid__bool: stmt.Val_bool_as_byte (fld_name, rdr.Read_bool_by_byte(fld_name)); break;
case Dbmeta_fld_tid.Tid__byte: stmt.Val_byte (fld_name, rdr.Read_byte(fld_name)); break;
case Dbmeta_fld_tid.Tid__int: stmt.Val_int (fld_name, rdr.Read_int(fld_name)); break;
case Dbmeta_fld_tid.Tid__long: stmt.Val_long (fld_name, rdr.Read_long(fld_name)); break;
case Dbmeta_fld_tid.Tid__float: stmt.Val_float (fld_name, rdr.Read_float(fld_name)); break;
case Dbmeta_fld_tid.Tid__double: stmt.Val_double (fld_name, rdr.Read_double(fld_name)); break;
case Dbmeta_fld_tid.Tid__str: stmt.Val_str (fld_name, rdr.Read_str(fld_name)); break;
case Dbmeta_fld_tid.Tid__bry: stmt.Val_bry (fld_name, rdr.Read_bry(fld_name)); break;
default: throw Err_.new_unhandled(tid);
}
}
}
public static void Stmt_args(Db_stmt stmt, Dbmeta_fld_list flds, int bgn, int end, Db_rdr rdr) {
for (int i = bgn; i < end; ++i) {
Dbmeta_fld_itm fld = flds.Get_at(i);
String fld_name = fld.Name();
int tid = fld.Type().Tid_ansi();
switch (tid) {
case Dbmeta_fld_tid.Tid__bool: stmt.Val_bool_as_byte (fld_name, rdr.Read_bool_by_byte(fld_name)); break;
case Dbmeta_fld_tid.Tid__byte: stmt.Val_byte (fld_name, rdr.Read_byte(fld_name)); break;
case Dbmeta_fld_tid.Tid__int: stmt.Val_int (fld_name, rdr.Read_int(fld_name)); break;
case Dbmeta_fld_tid.Tid__long: stmt.Val_long (fld_name, rdr.Read_long(fld_name)); break;
case Dbmeta_fld_tid.Tid__float: stmt.Val_float (fld_name, rdr.Read_float(fld_name)); break;
case Dbmeta_fld_tid.Tid__double: stmt.Val_double (fld_name, rdr.Read_double(fld_name)); break;
case Dbmeta_fld_tid.Tid__str: stmt.Val_str (fld_name, rdr.Read_str(fld_name)); break;
case Dbmeta_fld_tid.Tid__bry: stmt.Val_bry (fld_name, rdr.Read_bry(fld_name)); break;
default: throw Err_.new_unhandled(tid);
}
}
}
}

View File

@@ -13,3 +13,24 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import gplx.dbs.diffs.itms.*;
public class Gdif_bldr_ctx {
public Gdif_bldr_ctx() {}
public Gdif_core Core;
public Gdif_job_itm Cur_job;
public Gdif_cmd_itm Cur_cmd;
public Gdif_txn_itm Cur_txn;
public int Cur_cmd_count;
public int Cur_txn_count;
public Gdif_bldr_ctx Init(Gdif_core core, Gdif_job_itm cur_job) {
this.Core = core; this.Cur_job = cur_job;
return this;
}
public void Clear() {
Cur_cmd_count = 0; Cur_txn_count = 0;
Cur_job = null;
Cur_cmd = null;
Cur_txn = null;
}
}

View File

@@ -13,3 +13,26 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import gplx.dbs.*;
public class Gfdb_diff_bldr {
private Gfdb_diff_rdr_comparer rdr_comparer = new Gfdb_diff_rdr_comparer();
private Gfdb_diff_wkr diff_wkr;
public void Init(Gfdb_diff_wkr diff_wkr) {this.diff_wkr = diff_wkr;}
public void Compare(Gdif_bldr_ctx ctx, Gfdb_diff_tbl tbl, Db_conn old_conn, Db_conn new_conn) {
Db_rdr old_rdr = tbl.Make_rdr(old_conn), new_rdr = tbl.Make_rdr(new_conn);
rdr_comparer.Init_rdrs(tbl, old_rdr, new_rdr);
diff_wkr.Init_rdrs(ctx, tbl, old_rdr, new_rdr);
boolean loop = true;
while (loop) {
int rslt = rdr_comparer.Compare();
switch (rslt) {
case Gfdb_diff_rdr_comparer.Rslt__same: diff_wkr.Handle_same(); break;
case Gfdb_diff_rdr_comparer.Rslt__old_missing: diff_wkr.Handle_old_missing(); break;
case Gfdb_diff_rdr_comparer.Rslt__new_missing: diff_wkr.Handle_new_missing(); break;
case Gfdb_diff_rdr_comparer.Rslt__done: loop = false; break;
}
}
diff_wkr.Term_tbls();
}
}

View File

@@ -13,3 +13,93 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import org.junit.*;
import gplx.dbs.*; import gplx.dbs.metas.*; import gplx.dbs.engines.mems.*;
public class Gfdb_diff_bldr_tst {
private final Gfdb_diff_bldr_fxt fxt = new Gfdb_diff_bldr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Same() {
fxt.Init__tbl__old(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Init__tbl__cur(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Test__bld();
}
@Test public void Update() {
fxt.Init__tbl__old(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Init__tbl__cur(Object_.Ary(1, "A1") , Object_.Ary(2, "B1"));
fxt.Test__bld("U|1|A1", "U|2|B1");
}
@Test public void Insert() {
fxt.Init__tbl__old(Object_.Ary(1, "A"));
fxt.Init__tbl__cur(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Test__bld("I|2|B");
}
@Test public void Delete() {
fxt.Init__tbl__old(Object_.Ary(1, "A") , Object_.Ary(2, "B"));
fxt.Init__tbl__cur(Object_.Ary(1, "A"));
fxt.Test__bld("D|2");
}
@Test public void Basic() {
fxt.Init__tbl__old
( Object_.Ary(1, "A")
, Object_.Ary(2, "B")
, Object_.Ary(3, "C")
);
fxt.Init__tbl__cur
( Object_.Ary(1, "A")
, Object_.Ary(2, "B1")
, Object_.Ary(4, "D")
);
fxt.Test__bld("U|2|B1", "D|3", "I|4|D");
}
}
class Gfdb_diff_bldr_fxt {
private final Gfdb_diff_bldr bldr = new Gfdb_diff_bldr();
private final Db_conn old_conn, new_conn;
private final Gfdb_diff_tbl tbl;
private final Gfdb_diff_wkr__test wkr = new Gfdb_diff_wkr__test();
private final Dbmeta_fld_itm[] flds_ary;
private final String tbl_name = "tbl";
private final Gdif_bldr_ctx ctx = new Gdif_bldr_ctx();
public Gfdb_diff_bldr_fxt() {
old_conn = Db_conn_utl.Conn__new("old_db");
new_conn = Db_conn_utl.Conn__new("new_db");
this.flds_ary = new Dbmeta_fld_itm[] {Dbmeta_fld_itm.new_int("id").Primary_y_(), Dbmeta_fld_itm.new_str("val", 255)};
tbl = Gfdb_diff_tbl.New(Dbmeta_tbl_itm.New(tbl_name, flds_ary));
bldr.Init(wkr);
}
public void Clear() {
ctx.Clear();
old_conn.Meta_tbl_delete("tbl");
new_conn.Meta_tbl_delete("tbl");
}
public void Init__tbl__old(Object[]... rows) {Db_conn_utl.Tbl__new(old_conn, "tbl", flds_ary, rows);}
public void Init__tbl__cur(Object[]... rows) {Db_conn_utl.Tbl__new(new_conn, "tbl", flds_ary, rows);}
public void Test__bld(String... expd) {
bldr.Compare(ctx, tbl, old_conn, new_conn);
Tfds.Eq_ary_str(expd, wkr.To_str_ary());
}
}
class Gfdb_diff_wkr__test implements Gfdb_diff_wkr {
private final List_adp list = List_adp_.New();
private final Bry_bfr bfr = Bry_bfr_.New();
private Db_rdr old_rdr, new_rdr;
public void Init_rdrs(Gdif_bldr_ctx ctx, Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr) {
this.old_rdr = old_rdr; this.new_rdr = new_rdr;
}
public void Term_tbls() {}
public void Handle_same() {
String old_val = old_rdr.Read_str("val");
String new_val = new_rdr.Read_str("val");
if (!String_.Eq(old_val, new_val))
list.Add(bfr.Add_str_a7("U").Add_byte_pipe().Add_obj(old_rdr.Read_obj("id")).Add_byte_pipe().Add_str_a7(new_val).To_str_and_clear());
}
public void Handle_old_missing() {
String new_val = new_rdr.Read_str("val");
list.Add(bfr.Add_str_a7("I").Add_byte_pipe().Add_obj(new_rdr.Read_obj("id")).Add_byte_pipe().Add_str_a7(new_val).To_str_and_clear());
}
public void Handle_new_missing() {
list.Add(bfr.Add_str_a7("D").Add_byte_pipe().Add_obj(old_rdr.Read_obj("id")).To_str_and_clear());
}
public String[] To_str_ary() {return list.To_str_ary_and_clear();}
}

View File

@@ -13,3 +13,52 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
class Gfdb_diff_rdr_comparer {
private Db_rdr old_rdr, new_rdr;
private boolean old_rdr_move, new_rdr_move;
private boolean old_rdr_done, new_rdr_done;
private Dbmeta_fld_itm[] key_flds; private int key_flds_len;
public void Init_rdrs(Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr) {
this.old_rdr = old_rdr; this.new_rdr = new_rdr;
this.old_rdr_move = new_rdr_move = Bool_.Y;
this.old_rdr_done = new_rdr_done = Bool_.N;
this.key_flds = tbl.Keys; key_flds_len = key_flds.length;
}
public int Compare() {
if (old_rdr_move) {
old_rdr_move = old_rdr.Move_next();
if (!old_rdr_move) old_rdr_done = true;
}
if (new_rdr_move) {
new_rdr_move = new_rdr.Move_next();
if (!new_rdr_move) new_rdr_done = true;
}
if (old_rdr_done && new_rdr_done) return Gfdb_diff_rdr_comparer.Rslt__done;
else if (old_rdr_done) {new_rdr_move = true; return Gfdb_diff_rdr_comparer.Rslt__old_missing;}
else if (new_rdr_done) {old_rdr_move = true; return Gfdb_diff_rdr_comparer.Rslt__new_missing;}
else {
int comp = Gfdb_rdr_utl_.Compare(key_flds, key_flds_len, old_rdr, new_rdr);
switch (comp) {
case CompareAble_.Same: // old == cur; move both
old_rdr_move = new_rdr_move = true;
return Gfdb_diff_rdr_comparer.Rslt__same;
case CompareAble_.Less: // old < cur; EX: old == 2; cur == 3
old_rdr_move = true;
new_rdr_move = false;
return Gfdb_diff_rdr_comparer.Rslt__new_missing;
case CompareAble_.More: // old > cur; EX: old == 4; cur == 3
old_rdr_move = false;
new_rdr_move = true;
return Gfdb_diff_rdr_comparer.Rslt__old_missing;
default: throw Err_.new_unhandled(comp);
}
}
}
public static final int
Rslt__same = 0
, Rslt__old_missing = 1
, Rslt__new_missing = 2
, Rslt__done = 3
;
}

View File

@@ -13,3 +13,11 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
public interface Gfdb_diff_wkr {
void Init_rdrs(Gdif_bldr_ctx ctx, Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr);
void Term_tbls();
void Handle_same();
void Handle_old_missing();
void Handle_new_missing();
}

View File

@@ -13,3 +13,75 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.builds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import gplx.dbs.metas.*; import gplx.dbs.diffs.itms.*;
public class Gfdb_diff_wkr__db implements Gfdb_diff_wkr {
private Dbmeta_fld_itm[] val_flds; private int val_flds_len;
private Gfdb_diff_tbl tbl; private Db_rdr old_rdr, new_rdr;
private Gdif_bldr_ctx ctx;
private Db_conn dif_conn; private Db_stmt stmt;
private int uid, prog_interval, prog_count;
private boolean cmd_create;
public void Init_conn(Gdif_db dif_db, int prog_interval) {this.dif_conn = dif_db.Conn(); this.prog_interval = prog_interval;}
public void Init_rdrs(Gdif_bldr_ctx ctx, Gfdb_diff_tbl tbl, Db_rdr old_rdr, Db_rdr new_rdr) {
this.ctx = ctx; this.tbl = tbl; this.old_rdr = old_rdr; this.new_rdr = new_rdr;
this.val_flds = tbl.Vals; val_flds_len = val_flds.length;
this.uid = 0; this.prog_count = 0;
String dif_tbl = tbl.Name; Dbmeta_fld_itm[] dif_flds = Gfdb_diff_wkr__db_.New_dif_flds(tbl.Flds);
if (!dif_conn.Meta_tbl_exists(dif_tbl)) dif_conn.Meta_tbl_create(Dbmeta_tbl_itm.New(dif_tbl, dif_flds));
this.stmt = dif_conn.Stmt_insert(dif_tbl, Gfdb_diff_wkr__db_.To_str_ary(dif_flds));
dif_conn.Txn_bgn("dif_db_tbl_" + dif_tbl);
cmd_create = true;
}
public void Term_tbls() {
dif_conn.Txn_end();
}
public void Handle_old_missing() {Insert(Gdif_db_.Tid__insert, ++uid, new_rdr, tbl.Flds);}
public void Handle_new_missing() {Insert(Gdif_db_.Tid__delete, ++uid, old_rdr, tbl.Flds);}
public void Handle_same() {
if (Gfdb_rdr_utl_.Compare(val_flds, val_flds_len, old_rdr, new_rdr) != CompareAble_.Same)
Insert(Gdif_db_.Tid__update, ++uid, new_rdr, tbl.Flds);
}
private void Insert(byte dif_type, int uid, Db_rdr rdr, Dbmeta_fld_itm[] flds) {
if (cmd_create) {
cmd_create = false;
ctx.Cur_cmd = ctx.Core.New_cmd(ctx, Gdif_cmd_itm.Tid__data);
ctx.Cur_txn = ctx.Core.New_txn(ctx, ctx.Cur_cmd.Cmd_id, Gdif_txn_itm.Owner_txn__null);
}
stmt.Clear();
stmt.Val_int (Gdif_db_.Fld__dif_txn , ctx.Cur_txn.Txn_id)
.Val_int (Gdif_db_.Fld__dif_uid , uid)
.Val_int (Gdif_db_.Fld__dif_type , dif_type)
.Val_int (Gdif_db_.Fld__dif_db_src , -1)
.Val_int (Gdif_db_.Fld__dif_db_trg , -1);
Gfdb_rdr_utl_.Stmt_args(stmt, flds, 0, flds.length, rdr);
stmt.Exec_insert();
if ((++prog_count % prog_interval) == 0) dif_conn.Txn_sav();
}
}
class Gfdb_diff_wkr__db_ {
public static Dbmeta_fld_itm[] New_dif_flds(Dbmeta_fld_itm[] cur_flds) {
int len = cur_flds.length;
int sys_flds = 5;
Dbmeta_fld_itm[] rv = new Dbmeta_fld_itm[len + sys_flds];
rv[0] = Dbmeta_fld_itm.new_int (Gdif_db_.Fld__dif_txn);
rv[1] = Dbmeta_fld_itm.new_int (Gdif_db_.Fld__dif_uid);
rv[2] = Dbmeta_fld_itm.new_byte (Gdif_db_.Fld__dif_type);
rv[3] = Dbmeta_fld_itm.new_int (Gdif_db_.Fld__dif_db_trg);
rv[4] = Dbmeta_fld_itm.new_int (Gdif_db_.Fld__dif_db_src);
for (int i = 0; i < len; ++i) {
Dbmeta_fld_itm cur_fld = cur_flds[i];
Dbmeta_fld_itm dif_fld = new Dbmeta_fld_itm(cur_fld.Name(), cur_fld.Type());
rv[i + sys_flds] = dif_fld;
}
return rv;
}
public static String[] To_str_ary(Dbmeta_fld_itm[] ary) {
int len = ary.length;
String[] rv = new String[len];
for (int i = 0; i < len; ++i)
rv[i] = ary[i].Name();
return rv;
}
}

View File

@@ -13,3 +13,291 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.cmds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import gplx.core.srls.*; import gplx.core.brys.fmtrs.*;
import gplx.dbs.metas.*;
interface Gfdb_diff_cmd {
void Merge_undo();
void Merge_exec();
}
class Gfdb_diff_ctx implements Gfo_srl_ctx {
public Gfo_srl_mgr_wtr Wtr_bgn(String key) {return null;}
public Gfo_srl_mgr_rdr Rdr_bgn(String key) {return null;}
public Dbmeta_dat_mgr Rdr_subs(String key) {return null;}
public Dbmeta_tbl_itm Tbls__get(String key) {return null;}
}
class Gfo_srl_mgr_rdr__defn {
public String Tbl = null;
public String[] Select_crt_cols = null;
public String[] Delete_crt_cols = null;
}
class Gfo_srl_mgr_rdr__db {
public Object Get_subs (Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_itm proto, String defn_key, Dbmeta_dat_mgr crt_mgr) {
List_adp list = List_adp_.New();
Gfo_srl_mgr_rdr__defn defn = new Gfo_srl_mgr_rdr__defn(); // Get(key)
Db_conn conn = Db_conn_.Noop;
Db_stmt select = conn.Stmt_select(defn.Tbl, Dbmeta_fld_itm.Str_ary_empty, defn.Select_crt_cols);
int crt_len = crt_mgr.Len();
for (int i = 0; i < crt_len; ++i) {
Dbmeta_dat_itm crt = crt_mgr.Get_at(i);
switch (crt.Tid) {
case Dbmeta_fld_tid.Tid__int: select.Crt_int(crt.Key, Int_.Cast(crt.Val)); break;
}
}
Db_rdr rdr = select.Exec_select__rls_manual();
while (rdr.Move_next()) {
Gfo_srl_itm sub = proto.Make_new(ctx);
list.Add(sub);
sub.Load(ctx, owner, null);
}
rdr.Rls();
return list.To_ary_and_clear(proto.getClass());
}
public void Set_subs (Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_itm proto, Gfo_srl_itm[] subs_ary, String defn_key, Dbmeta_dat_mgr crt_mgr) {
Gfo_srl_mgr_rdr__defn defn = new Gfo_srl_mgr_rdr__defn(); // Get(key)
Db_conn conn = Db_conn_.Noop;
Db_stmt delete = conn.Stmt_delete(defn.Tbl, defn.Delete_crt_cols);
int crt_len = crt_mgr.Len();
for (int i = 0; i < crt_len; ++i) {
Dbmeta_dat_itm crt = crt_mgr.Get_at(i);
switch (crt.Tid) {
case Dbmeta_fld_tid.Tid__int: delete.Crt_int(crt.Key, Int_.Cast(crt.Val)); break;
}
}
delete.Exec_delete();
int subs_len = subs_ary.length;
for (int i = 0; i < subs_len; ++i) {
Gfo_srl_itm itm = subs_ary[i];
itm.Save(ctx, owner, null);
}
}
}
class Gfdb_diff_cmd__idx__delete {
public Gfdb_diff_cmd__idx__delete(Dbmeta_idx_itm old) {this.Old = old;}
public final Dbmeta_idx_itm Old;
}
class Gfdb_diff_cmd__idx__modify {
public Gfdb_diff_cmd__idx__modify(Dbmeta_idx_itm old, Dbmeta_idx_itm cur) {this.Old = old; this.Cur = cur;}
public final Dbmeta_idx_itm Old;
public final Dbmeta_idx_itm Cur;
}
class Gfdb_diff_txn {
public int Id = 0;
}
class Gfdb_diff_cmd__fld__create {
public Gfdb_diff_cmd__fld__create(Dbmeta_fld_itm cur) {this.cur = cur;}
private Dbmeta_fld_itm cur;
public void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner) {
Gfo_srl_mgr_wtr wtr = ctx.Wtr_bgn("cmd.fld");
wtr.Set_int ("txn_id" , ((Gfdb_diff_txn)owner).Id);
wtr.Set_str ("name" , cur.Name());
wtr.Set_int ("type_tid" , cur.Type().Tid_ansi());
wtr.Set_int ("type_len_1" , cur.Type().Len_1());
wtr.Set_int ("type_len_2" , cur.Type().Len_2());
wtr.Set_bool ("primary" , cur.Primary());
wtr.Set_int ("nullable" , cur.Nullable_tid());
wtr.Set_str ("dflt" , Object_.Xto_str_or(cur.Default(), null));
wtr.Itm_end();
}
public void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner) {
Gfo_srl_mgr_rdr rdr = ctx.Rdr_bgn("cmd.fld");
String name = rdr.Get_str("name");
int type_tid = rdr.Get_int("type_tid");
int type_len_1 = rdr.Get_int("type_len_1");
// int type_len_2 = rdr.Get_int("type_len_2");
boolean primary = rdr.Get_bool("primary");
int nullable_tid = rdr.Get_int("nullable");
String dflt_str = rdr.Get_str("dflt");
cur = new Dbmeta_fld_itm(name, Dbmeta_fld_tid.New(type_tid, type_len_1));
cur.Nullable_tid_(nullable_tid);
if (primary) cur.Primary_y_();
if (dflt_str != null) cur.Default_(dflt_str);
rdr.Itm_end();
// Gfdb_diff_cmd__idx__create idx = ((Gfdb_diff_cmd__idx__create)owner);
// Dbmeta_tbl_itm tbl = ((Gfdb_diff_ctx)ctx).Tbls__get(idx.cur.Tbl());
// Dbmeta_fld_tid tid = tbl.Flds().Get_by(name).Type();
}
}
class Gfdb_diff_cmd__fld__delete {
public Gfdb_diff_cmd__fld__delete(Dbmeta_fld_itm old) {this.Old = old;}
public final Dbmeta_fld_itm Old;
}
class Gfdb_diff_cmd__fld__modify {
public Gfdb_diff_cmd__fld__modify(Dbmeta_fld_itm old, Dbmeta_fld_itm cur) {this.Old = old; this.Cur = cur;}
public final Dbmeta_fld_itm Old;
public final Dbmeta_fld_itm Cur;
}
class Gfdb_diff_cmd__tbl__create {
public Gfdb_diff_cmd__tbl__create(Dbmeta_tbl_itm cur) {this.Cur = cur;}
public final Dbmeta_tbl_itm Cur;
}
class Gfdb_diff_cmd__tbl__delete {
public Gfdb_diff_cmd__tbl__delete(Dbmeta_tbl_itm old) {this.Old = old;}
public final Dbmeta_tbl_itm Old;
}
class Gfdb_diff_cmd_bldr {
public void Chk_tbls(List_adp rv, Dbmeta_tbl_mgr old_tbls, Dbmeta_tbl_mgr cur_tbls) {
int cur_tbls_len = cur_tbls.Len();
for (int i = 0; i < cur_tbls_len; ++i) {
Dbmeta_tbl_itm cur_tbl = cur_tbls.Get_at(i);
Dbmeta_tbl_itm old_tbl = old_tbls.Get_by(cur_tbl.Name());
if (old_tbl == null)
rv.Add(new Gfdb_diff_cmd__tbl__create(cur_tbl));
else {
Chk_idxs(rv, old_tbl, cur_tbl);
Chk_flds(rv, old_tbl, cur_tbl);
// Chk_data?
}
}
int old_tbls_len = old_tbls.Len();
for (int i = 0; i < old_tbls_len; ++i) {
Dbmeta_tbl_itm old_tbl = old_tbls.Get_at(i);
Dbmeta_tbl_itm cur_tbl = cur_tbls.Get_by(old_tbl.Name());
if (cur_tbl == null)
rv.Add(new Gfdb_diff_cmd__tbl__delete(old_tbl));
}
}
public void Chk_idxs(List_adp rv, Dbmeta_tbl_itm old_tbl, Dbmeta_tbl_itm cur_tbl) {
Dbmeta_idx_mgr old_idxs = old_tbl.Idxs(), cur_idxs = cur_tbl.Idxs();
int cur_idxs_len = cur_idxs.Len();
for (int i = 0; i < cur_idxs_len; ++i) {
Dbmeta_idx_itm cur_idx = cur_idxs.Get_at(i);
Dbmeta_idx_itm old_idx = old_idxs.Get_by(cur_idx.Name());
if (old_idx == null)
rv.Add(new Gfdb_diff_cmd__idx__create(cur_idx));
else
if (!cur_idx.Eq(old_idx))
rv.Add(new Gfdb_diff_cmd__idx__modify(old_idx, cur_idx));
}
int old_idxs_len = old_idxs.Len();
for (int i = 0; i < old_idxs_len; ++i) {
Dbmeta_idx_itm old_idx = old_idxs.Get_at(i);
Dbmeta_idx_itm cur_idx = cur_idxs.Get_by(old_idx.Name());
if (cur_idx == null)
rv.Add(new Gfdb_diff_cmd__idx__delete(old_idx));
}
}
public void Chk_flds(List_adp rv, Dbmeta_tbl_itm old_tbl, Dbmeta_tbl_itm cur_tbl) {
Dbmeta_fld_mgr old_flds = old_tbl.Flds(), cur_flds = cur_tbl.Flds();
int cur_flds_len = cur_flds.Len();
for (int i = 0; i < cur_flds_len; ++i) {
Dbmeta_fld_itm cur_fld = cur_flds.Get_at(i);
Dbmeta_fld_itm old_fld = old_flds.Get_by(cur_fld.Name());
if (old_fld == null)
rv.Add(new Gfdb_diff_cmd__fld__create(cur_fld));
else
if (!cur_fld.Eq(old_fld))
rv.Add(new Gfdb_diff_cmd__fld__modify(old_fld, cur_fld));
}
int old_flds_len = old_flds.Len();
for (int i = 0; i < old_flds_len; ++i) {
Dbmeta_fld_itm old_fld = old_flds.Get_at(i);
Dbmeta_fld_itm cur_fld = cur_flds.Get_by(old_fld.Name());
if (cur_fld == null)
rv.Add(new Gfdb_diff_cmd__fld__delete(old_fld));
}
}
}
class Gfdb_diff_cmd__insert {
// else if I
// // txn_bgn
// // audit
// INSERT INTO db_temp.page (diff_type, diff, *)
// SELECT 'D', d.page_id, *
// FROM db_diff.page d
// JOIN db_main.page m ON d.page_id = m.page_id
// WHERE d.diff_type = 0
// AND d.diff_idx BETWEEN lo and hi
//
// // update
// INSERT INTO db_main.page
// SELECT d.page_title
// FROM db_diff.page d
// JOIN db_main.page m
// // txn_end
private Db_conn conn;
private String exec_sql;
public void Init(Db_conn main_conn, Db_conn diff_conn, Db_conn temp_conn, Gfdb_diff_tbl tbl) {
this.conn = temp_conn;
this.exec_sql = "";
// this.exec_sql = String_.Format(String_.Concat_lines_nl_skip_last
// ( "INSERT INTO db_curr.{tbl}"
// ), Gfdb_diff_cmd_ctx.Alias__curr);
}
public void Merge_exec() {
conn.Exec_sql(exec_sql);
}
}
class Gfdb_diff_cmd_sql_bldr {
private final Bry_fmtr fmtr = Bry_fmtr.new_();
private final Bry_bfr tmp_bfr = Bry_bfr_.New();
public void Bld_insert(Bry_bfr bfr, String tbl_name, String[] keys, String[] vals, int rng_bgn, int rng_end) {
fmtr.Fmt_(Insert__fmt).Keys_(Insert__keys);
fmtr.Bld_bfr_many(bfr, tbl_name, Bld_flds(tmp_bfr, ", ", "d.", keys, vals), Bld_join(keys), rng_bgn, rng_end);
}
public void Bld_update(Bry_bfr bfr, String tbl_name, String[] keys, String[] vals, int rng_bgn, int rng_end) {
fmtr.Fmt_(Update__fmt).Keys_(Update__keys);
fmtr.Bld_bfr_many(bfr, tbl_name, Bld_flds(tmp_bfr, ", ", "d.", keys, vals), Bld_join(keys), rng_bgn, rng_end);
}
public void Bld_delete(Bry_bfr bfr, String tbl_name, String[] keys, int rng_bgn, int rng_end) {
fmtr.Fmt_(Delete__fmt).Keys_(Delete__keys);
fmtr.Bld_bfr_many(bfr, tbl_name, Bld_flds(tmp_bfr, " || '|' || ", "", keys, String_.Ary_empty), Bld_flds(tmp_bfr, " || '|' || ", "k.", keys, String_.Ary_empty), Bld_join(keys), rng_bgn, rng_end);
}
private static String Bld_flds(Bry_bfr tmp_bfr, String dlm, String alias, String[] keys, String[] vals) {
int keys_len = keys.length;
for (int i = 0; i < keys_len; ++i) {
String key = keys[i];
if (i != 0) tmp_bfr.Add_str_a7(dlm);
tmp_bfr.Add_str_a7(alias).Add_str_a7(key);
}
int flds_len = vals.length;
for (int i = 0; i < flds_len; ++i) {
String val = vals[i];
tmp_bfr.Add_str_a7(dlm);
tmp_bfr.Add_str_a7(alias).Add_str_a7(val);
}
return tmp_bfr.To_str_and_clear();
}
private String Bld_join(String[] keys) {
int len = keys.length;
for (int i = 0; i < len; ++i) {
String key = keys[i];
tmp_bfr.Add_str_a7(i == 0 ? " ON " : " AND ");
tmp_bfr.Add_str_a7("k.").Add_str_a7(key).Add_str_a7(" = ");
tmp_bfr.Add_str_a7("d.").Add_str_a7(key);
}
return tmp_bfr.To_str_and_clear();
}
private static final String[] Insert__keys = String_.Ary("tbl", "flds", "join", "rng_bgn", "rng_end");
private static final String Insert__fmt = String_.Concat_lines_nl_skip_last
( "INSERT INTO db_curr.~{tbl}"
, "SELECT ~{flds}"
, "FROM db_temp.~{tbl}_pkey k"
, " JOIN db_diff.~{tbl} d~{join}"
, "WHERE k.diff_type = 1"
, "AND k.diff_uid BETWEEN ~{rng_bgn} AND ~{rng_end};"
);
private static final String[] Update__keys = String_.Ary("tbl", "flds", "join", "rng_bgn", "rng_end");
private static final String Update__fmt = String_.Concat_lines_nl_skip_last
( "REPLACE INTO db_curr.~{tbl}"
, "SELECT ~{flds}"
, "FROM db_temp.~{tbl}_pkey k"
, " JOIN db_diff.~{tbl} d~{join}"
, "WHERE k.diff_type = 2"
, "AND k.diff_uid BETWEEN ~{rng_bgn} AND ~{rng_end};"
);
private static final String[] Delete__keys = String_.Ary("tbl", "pkey_where", "pkey_select", "join", "rng_bgn", "rng_end");
private static final String Delete__fmt = String_.Concat_lines_nl_skip_last
( "DELETE db_curr.~{tbl}"
, "WHERE ~{pkey_where} IN"
, "( SELECT ~{pkey_select}"
, " FROM db_temp.~{tbl}_pkey k"
, " JOIN db_diff.~{tbl} d~{join}"
, " WHERE k.diff_type = 0"
, " AND k.diff_uid BETWEEN ~{rng_bgn} AND ~{rng_end}"
, ");"
);
}

View File

@@ -13,3 +13,103 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.cmds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import gplx.core.srls.*; import gplx.dbs.metas.*;
class Gfdb_diff_cmd__idx__create implements Gfo_srl_itm {
public Gfdb_diff_cmd__idx__create(Dbmeta_idx_itm cur) {this.cur = cur;}
public Dbmeta_idx_itm cur;
private Gfdb_diff_cmd__idx__fld[] flds = new Gfdb_diff_cmd__idx__fld[0];
public Gfo_srl_itm Make_new(Gfo_srl_ctx ctx) {return new Gfdb_diff_cmd__idx__create();} Gfdb_diff_cmd__idx__create() {}
private int idx_uid;
// *_sdif_ddl_idx : txn_uid,idx_uid,idx_tbl,idx_name,idx_unique
public void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_wtr wtr) {
wtr.Itm_bgn("idx");
wtr.Set_int ("idx_uid" , idx_uid);
wtr.Set_str ("idx_tbl" , cur.Tbl());
wtr.Set_str ("idx_name" , cur.Name());
wtr.Set_bool ("idx_unique" , cur.Unique());
wtr.Set_subs (ctx, this, Gfdb_diff_cmd__idx__fld.Instance, flds, ctx.Rdr_subs("idx_fld").Add_int("idx_uid", idx_uid));
wtr.Itm_end();
}
public void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_rdr rdr) {
rdr.Itm_bgn("idx");
this.idx_uid = rdr.Get_int ("idx_uid");
String tbl = rdr.Get_str ("idx_tbl");
String name = rdr.Get_str ("idx_name");
boolean unique = rdr.Get_bool ("idx_unique");
this.flds = (Gfdb_diff_cmd__idx__fld[])rdr.Get_subs(ctx, this, Gfdb_diff_cmd__idx__fld.Instance, ctx.Rdr_subs("idx_fld").Add_int("idx_uid", idx_uid));
cur = new Dbmeta_idx_itm(unique, tbl, name, Dbmeta_idx_fld.Ary_empty);
rdr.Itm_end();
}
public void Exec(Db_conn conn) {
conn.Meta_idx_create(cur);
}
}
class Gfdb_diff_cmd__idx__fld implements Gfo_srl_itm {
public Gfdb_diff_cmd__idx__fld(Dbmeta_idx_fld cur) {this.cur = cur;}
private Dbmeta_idx_fld cur;
public Gfo_srl_itm Make_new(Gfo_srl_ctx ctx) {return new Gfdb_diff_cmd__idx__fld();} Gfdb_diff_cmd__idx__fld() {}
// *_sdif_ddl_idx_fld : idx_uid,fld_order,fld_name,fld_asc
public void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_wtr wtr) {
wtr.Itm_bgn("idx_fld");
wtr.Set_str ("fld_name" , cur.Name);
wtr.Set_int ("fld_asc" , cur.Sort_tid);
wtr.Itm_end();
}
public void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_rdr rdr) {
rdr.Itm_bgn("idx_fld");
String name = rdr.Get_str ("fld_name");
int sort_tid = rdr.Get_int ("fld_sort");
cur = new Dbmeta_idx_fld(name, sort_tid);
rdr.Itm_end();
}
public static final Gfdb_diff_cmd__idx__fld Instance = new Gfdb_diff_cmd__idx__fld();
}
// class Gfdb_diff_cmd__tbl__fld : Gfo_srl_itm {
// public Gfdb_diff_cmd__tbl__fld(Dbmeta_fld_itm cur) {this.cur = cur;}
// private Dbmeta_fld_itm cur;
// public String Name;
// public int Type_tid;
// public int Len1;
// public int Len2;
// public int Nullable;
// public boolean Primary;
// public boolean Autonum;
//
// public Gfo_srl_itm Make_new(Gfo_srl_ctx ctx) {return new Gfdb_diff_cmd__tbl__fld();} Gfdb_diff_cmd__tbl__fld() {}
// // *_sdif_ddl_tbl_fld : tbl_uid,fld_idx,fld_name,fld_type,fld_len1, fld_len2, fld_nullable, fld_primary, fld_autonumber
// public void Save(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_wtr wtr) {
// wtr.Itm_bgn("tbl_fld");
// wtr.Set_str ("fld_name" , cur.Name());
// wtr.Set_int ("fld_type" , cur.Type().Tid_ansi());
// wtr.Set_int ("fld_len1" , cur.Type().Len_1());
// wtr.Set_int ("fld_len2" , cur.Type().Len_2());
// wtr.Set_int ("fld_nullable" , cur.Nullable_tid());
// wtr.Set_bool ("fld_primary" , cur.Primary());
// wtr.Set_bool ("fld_autonum" , cur.Autonum());
// wtr.Set_str ("fld_dflt" , Object_.Xto_str_or(cur.Default(), null));
//// wtr.Set_int ("fld_asc" , cur.Sort_tid);
// wtr.Itm_end();
// }
// public void Load(Gfo_srl_ctx ctx, Gfo_srl_itm owner, Gfo_srl_mgr_rdr rdr) {
// rdr.Itm_bgn("tbl_fld");
// String name = rdr.Get_str("name");
// int type_tid = rdr.Get_int("type_tid");
// int type_len_1 = rdr.Get_int("type_len_1");
// boolean primary = rdr.Get_bool("primary");
// int nullable_tid = rdr.Get_int("nullable");
// String dflt_str = rdr.Get_str("dflt");
// cur = new Dbmeta_fld_itm(name, Dbmeta_fld_tid.New(type_tid, type_len_1));
// cur.Nullable_tid_(nullable_tid);
// if (primary) cur.Primary_y_();
// if (dflt_str != null) cur.Default_(dflt_str);
// rdr.Itm_end();
//// Gfdb_diff_cmd__idx__create idx = ((Gfdb_diff_cmd__idx__create)owner);
//// Dbmeta_tbl_itm tbl = ((Gfdb_diff_ctx)ctx).Tbls__get(idx.cur.Tbl());
//// Dbmeta_fld_tid tid = tbl.Flds().Get_by(name).Type();
// }
//
// public static final Gfdb_diff_cmd__tbl__fld Instance = new Gfdb_diff_cmd__tbl__fld();
// }

View File

@@ -13,3 +13,57 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.cmds; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
import org.junit.*;
import gplx.dbs.*; import gplx.dbs.engines.mems.*;
public class Gfdb_diff_cmd_sql_bldr_tst {
private final Gfdb_diff_cmd_sql_bldr_fxt fxt = new Gfdb_diff_cmd_sql_bldr_fxt();
@Test public void Insert() {
fxt.Test__insert("tbl1", String_.Ary("key1", "key2"), String_.Ary("fld1", "fld2"), 0, 99, String_.Concat_lines_nl_skip_last
( "INSERT INTO db_curr.tbl1"
, "SELECT d.key1, d.key2, d.fld1, d.fld2"
, "FROM db_temp.tbl1_pkey k"
, " JOIN db_diff.tbl1 d ON k.key1 = d.key1 AND k.key2 = d.key2"
, "WHERE k.diff_type = 1"
, "AND k.diff_uid BETWEEN 0 AND 99;"
));
}
@Test public void Update() {
fxt.Test__update("tbl1", String_.Ary("key1", "key2"), String_.Ary("fld1", "fld2"), 0, 99, String_.Concat_lines_nl_skip_last
( "REPLACE INTO db_curr.tbl1"
, "SELECT d.key1, d.key2, d.fld1, d.fld2"
, "FROM db_temp.tbl1_pkey k"
, " JOIN db_diff.tbl1 d ON k.key1 = d.key1 AND k.key2 = d.key2"
, "WHERE k.diff_type = 2"
, "AND k.diff_uid BETWEEN 0 AND 99;"
));
}
@Test public void Delete() {
fxt.Test__delete("tbl1", String_.Ary("key1", "key2"), 0, 99, String_.Concat_lines_nl_skip_last
( "DELETE db_curr.tbl1"
, "WHERE key1 || '|' || key2 IN"
, "( SELECT k.key1 || '|' || k.key2"
, " FROM db_temp.tbl1_pkey k"
, " JOIN db_diff.tbl1 d ON k.key1 = d.key1 AND k.key2 = d.key2"
, " WHERE k.diff_type = 0"
, " AND k.diff_uid BETWEEN 0 AND 99"
, ");"
));
}
}
class Gfdb_diff_cmd_sql_bldr_fxt {
private Gfdb_diff_cmd_sql_bldr bldr = new Gfdb_diff_cmd_sql_bldr();
private final Bry_bfr bfr = Bry_bfr_.New();
public void Test__insert(String tbl_name, String[] keys, String[] flds, int rng_bgn, int rng_end, String expd) {
bldr.Bld_insert(bfr, tbl_name, keys, flds, 0, 99);
Tfds.Eq_str_lines(expd, bfr.To_str_and_clear());
}
public void Test__update(String tbl_name, String[] keys, String[] flds, int rng_bgn, int rng_end, String expd) {
bldr.Bld_update(bfr, tbl_name, keys, flds, 0, 99);
Tfds.Eq_str_lines(expd, bfr.To_str_and_clear());
}
public void Test__delete(String tbl_name, String[] keys, int rng_bgn, int rng_end, String expd) {
bldr.Bld_delete(bfr, tbl_name, keys, 0, 99);
Tfds.Eq_str_lines(expd, bfr.To_str_and_clear());
}
}

View File

@@ -13,3 +13,15 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
public class Gdif_cmd_itm {
public Gdif_cmd_itm(int grp_id, int cmd_id, int tid) {
this.Grp_id = grp_id; this.Cmd_id = cmd_id; this.Tid = tid;
}
public final int Grp_id;
public final int Cmd_id;
public final int Tid;
public String Data;
public static final int Tid__data = 1;
}

View File

@@ -13,3 +13,29 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
public class Gdif_cmd_tbl implements Rls_able {
private String tbl_name = "gdif_cmd";
private String fld_grp_id, fld_cmd_id, fld_tid, fld_data;
private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final Db_conn conn; private Db_stmt stmt_insert;
public Gdif_cmd_tbl(Db_conn conn) {
this.conn = conn;
fld_grp_id = flds.Add_int("grp_id"); fld_cmd_id = flds.Add_int("cmd_id"); fld_tid = flds.Add_int("tid"); fld_data = flds.Add_text("data");
conn.Rls_reg(this);
}
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds, Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "main", fld_grp_id, fld_cmd_id)));}
public Gdif_cmd_itm Insert(int grp_id, int cmd_id, int tid, String data) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_grp_id , grp_id)
.Val_int(fld_cmd_id , cmd_id)
.Val_int(fld_tid , tid)
.Val_str(fld_data , data)
.Exec_insert();
return new Gdif_cmd_itm(grp_id, cmd_id, tid);
}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
}
}

View File

@@ -13,3 +13,14 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
public class Gdif_job_itm {
public Gdif_job_itm(int id, String name, String made_by, DateAdp made_on) {
this.Id = id; this.Name = name; this.Made_by = made_by; this.Made_on = made_on;
}
public final int Id;
public final String Name;
public final String Made_by;
public final DateAdp Made_on;
public String Data;
}

View File

@@ -13,3 +13,32 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
public class Gdif_job_tbl implements Rls_able {
private String tbl_name = "gdif_job";
private String fld_job_id, fld_name, fld_made_by, fld_made_on, fld_data;
private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final Db_conn conn; private Db_stmt stmt_insert;
public Gdif_job_tbl(Db_conn conn) {
this.conn = conn;
fld_job_id = flds.Add_int_pkey("job_id"); fld_name = flds.Add_str("name", 255); fld_made_by = flds.Add_str("made_by", 255); fld_made_on = flds.Add_date("made_on"); fld_data = flds.Add_text("data");
conn.Rls_reg(this);
}
public String Tbl_name() {return tbl_name;}
public String Fld_job_id() {return fld_job_id;}
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds));}
public Gdif_job_itm Insert(int id, String name, String made_by, DateAdp made_on, String data) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_job_id , id)
.Val_str(fld_name , name)
.Val_str(fld_made_by , made_by)
.Val_date(fld_made_on , made_on)
.Val_str(fld_data , data)
.Exec_insert();
return new Gdif_job_itm(id, name, made_by, made_on);
}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
}
}

View File

@@ -13,3 +13,15 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
public class Gdif_txn_itm {
public Gdif_txn_itm(int job_id, int txn_id, int cmd_id, int owner_txn) {
this.Job_id = job_id; this.Txn_id = txn_id; this.Cmd_id = cmd_id; this.Owner_txn = owner_txn;
}
public final int Job_id;
public final int Txn_id;
public final int Cmd_id;
public final int Owner_txn;
public static final int Owner_txn__null = 0;
}

View File

@@ -13,3 +13,29 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.diffs.itms; import gplx.*; import gplx.dbs.*; import gplx.dbs.diffs.*;
public class Gdif_txn_tbl implements Rls_able {
private String tbl_name = "gdif_txn";
private String fld_job_id, fld_txn_id, fld_cmd_id, fld_owner_txn;
private final Dbmeta_fld_list flds = new Dbmeta_fld_list();
private final Db_conn conn; private Db_stmt stmt_insert;
public Gdif_txn_tbl(Db_conn conn) {
this.conn = conn;
fld_job_id = flds.Add_int("job_id"); fld_txn_id = flds.Add_int("txn_id"); fld_cmd_id = flds.Add_int("cmd_id"); fld_owner_txn = flds.Add_int("owner_txn");
conn.Rls_reg(this);
}
public void Create_tbl() {conn.Meta_tbl_create(Dbmeta_tbl_itm.New(tbl_name, flds, Dbmeta_idx_itm.new_unique_by_tbl(tbl_name, "main", fld_job_id, fld_txn_id)));}
public Gdif_txn_itm Insert(int job_id, int txn_id, int cmd_id, int owner_txn) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_job_id , job_id)
.Val_int(fld_txn_id , txn_id)
.Val_int(fld_cmd_id , cmd_id)
.Val_int(fld_owner_txn , owner_txn)
.Exec_insert();
return new Gdif_txn_itm(job_id, txn_id, cmd_id, owner_txn);
}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
}
}

View File

@@ -13,3 +13,37 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines; import gplx.*; import gplx.dbs.*;
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.bats.*;
public interface Db_engine {
String Tid();
Db_conn_info Conn_info();
Db_conn_props_mgr Props();
Db_batch_mgr Batch_mgr();
Sql_qry_wtr Sql_wtr();
Db_engine New_clone(Db_conn_info conn_info);
void Conn_open();
void Conn_term();
void Txn_bgn(String name); // NOTE: sqlite has different transaction semantics with SAVEPOINT
String Txn_end();
void Txn_cxl();
void Txn_sav();
void Meta_tbl_create(Dbmeta_tbl_itm meta);
void Meta_tbl_delete(String tbl);
void Meta_fld_append(String tbl, Dbmeta_fld_itm fld);
void Meta_idx_create(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary);
void Meta_idx_delete(String idx);
Dbmeta_tbl_mgr Meta_mgr();
boolean Meta_tbl_exists(String tbl);
boolean Meta_fld_exists(String tbl, String fld);
boolean Meta_idx_exists(String idx);
Object Exec_as_obj(Db_qry qry);
Db_rdr Exec_as_rdr__rls_manual (Object rdr_obj, String sql); // Object o:ResultSet if desktop; Cursor if android
Db_rdr Exec_as_rdr__rls_auto (Db_stmt stmt, Object rdr_obj, String sql); // Object o:ResultSet if desktop; Cursor if android
Db_stmt Stmt_by_qry(Db_qry qry);
Object Stmt_by_sql(String sql);
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);
DataRdr New_rdr(java.sql.ResultSet rdr, String sql);
}

View File

@@ -13,3 +13,127 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines; import gplx.*; import gplx.dbs.*;
import java.sql.*;
import gplx.core.stores.*;
import gplx.dbs.engines.*; import gplx.dbs.metas.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.sqls.wtrs.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.bats.*;
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 Db_conn_props_mgr Props() {return props;} private final Db_conn_props_mgr props = new Db_conn_props_mgr();
public Db_batch_mgr Batch_mgr() {return batch_mgr;} private final Db_batch_mgr batch_mgr = new Db_batch_mgr();
public abstract Sql_qry_wtr Sql_wtr();
public abstract Db_engine New_clone(Db_conn_info conn_info);
public Db_rdr Exec_as_rdr__rls_manual(Object rdr_obj, String sql) {return New_rdr(null, rdr_obj, sql);}
public Db_rdr Exec_as_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 Stmt_by_qry(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;")); batch_mgr.Txn_end().Run(this); 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.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) {
try {
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.Db_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 Err_.new_exc(e, "db", "db.engine:rdr failed", "url", conn_info.Db_api(), "sql", sql);}
}
public void Meta_tbl_create(Dbmeta_tbl_itm tbl) {Exec_as_int(tbl.To_sql_create(this.Sql_wtr())); this.Meta_mgr().Load_all();}
public void Meta_tbl_delete(String tbl) {Exec_as_int(this.Sql_wtr().Schema_wtr().Bld_drop_tbl(tbl)); this.Meta_mgr().Load_all();}
public void Meta_idx_create(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 db index (please wait); db=~{0} idx=~{1}", conn_info.Database(), idx.Name());
Exec_as_int(idx.To_sql_create(Sql_wtr()));
}
this.Meta_mgr().Load_all();
}
@gplx.Virtual public void Meta_idx_delete(String idx) {
if (Meta_idx_exists(idx)) Exec_as_int("DROP INDEX " + idx);
}
public void Meta_fld_append(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(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));
}
this.Meta_mgr().Load_all();
}
@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 boolean Meta_idx_exists(String idx) {return false;}
public abstract Dbmeta_tbl_mgr Meta_mgr();
@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 DataRdr New_rdr(ResultSet rdr, String sql) {return gplx.core.stores.Db_data_rdr_.new_(rdr, sql);}
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_make();
private void Batch_mgr__conn_bgn() {batch_mgr.Conn_bgn().Run(this);}
private void Batch_mgr__conn_end() {batch_mgr.Conn_end().Run(this);}
private void Conn_assert() {
this.connection = Conn_make(); // auto-open connection
Batch_mgr__conn_bgn();
}
protected Connection connection;
public void Conn_open() {connection = Conn_make();}
public void Conn_term() {
if (connection == null) return; // connection never opened; just exit
this.Batch_mgr__conn_end();
try {connection.close();}
catch (Exception e) {throw Err_.new_exc(e, "db", "Conn_term failed", "url", conn_info.Raw());}
connection = null;
}
@Override public Object Stmt_by_sql(String sql) {
if (connection == null) Conn_assert();
try {return connection.prepareStatement(sql);}
catch (Exception e) {
throw Err_.new_exc(e, "db", "New_stmt_prep failed", "sql", sql);
}
}
private Statement New_stmt_exec(String sql) {
if (connection == null) Conn_assert();
try {return connection.createStatement();}
catch (Exception e) {throw Err_.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 Err_.new_exc(e, "db", "connection open failed", "info", Conn_info().Raw());}
}
protected Connection Conn__new_by_url_and_props(String url, Keyval... props) {
try {
java.util.Properties properties = new java.util.Properties();
for (Keyval prop : props)
properties.setProperty(prop.Key(), prop.Val_to_str_or_empty());
return DriverManager.getConnection(url, properties);
}
catch (SQLException e) {throw Err_.new_exc(e, "db", "connection open failed", "info", Conn_info().Raw());}
}
}

View File

@@ -13,3 +13,18 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
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
( "gplx_key", Tid_const
, "database", database
));
}
public static final Mem_conn_info Instance = new Mem_conn_info("", "", "");
}

View File

@@ -13,3 +13,60 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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 = new Dbmeta_fld_list();
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

@@ -13,3 +13,58 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.bats.*;
public class Mem_engine implements Db_engine {
private final Hash_adp tbl_hash = Hash_adp_.New();
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 Db_conn_props_mgr Props() {return props;} private final Db_conn_props_mgr props = new Db_conn_props_mgr();
public Db_batch_mgr Batch_mgr() {return batch_mgr;} private final Db_batch_mgr batch_mgr = new Db_batch_mgr();
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_.New__basic();
public Db_engine New_clone(Db_conn_info conn_info) {return new Mem_engine(conn_info);}
public Db_stmt Stmt_by_qry(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() {return "";}// --txn_count; return "";}
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 Err_.new_unimplemented();}
public void Conn_open() {}
public void Conn_term() {
// if (txn_count != 0) throw Err_.new_wo_type("Conn_term.txns still open", "txn_count", txn_count); // IGNORE: causing test to fails; DATE:2016-03-30
}
public Db_rdr Exec_as_rdr__rls_manual(Object rdr_obj, String sql) {throw Err_.new_unimplemented();}
public Db_rdr Exec_as_rdr__rls_auto(Db_stmt stmt, Object rdr_obj, String sql) {throw Err_.new_unimplemented();}
public DataRdr New_rdr(java.sql.ResultSet rdr, String sql) {throw Err_.new_unimplemented();}
public Object Stmt_by_sql(String sql) {throw Err_.new_unimplemented();}
public void Meta_tbl_create(Dbmeta_tbl_itm meta) {
Mem_tbl mem_tbl = new Mem_tbl(meta);
tbl_hash.Add_if_dupe_use_nth(meta.Name(), mem_tbl);
meta_mgr.Add(meta);
}
public void Meta_tbl_delete(String tbl_key) {
Mem_tbl tbl = (Mem_tbl)tbl_hash.Get_by(tbl_key);
if (tbl != null) tbl.rows.Clear();
}
public void Meta_idx_create(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {} // TODO_OLD: implement unique index
public void Meta_idx_delete(String idx) {}
public void Meta_fld_append(String tbl, Dbmeta_fld_itm fld) {}
public Dbmeta_tbl_mgr Meta_mgr() {return meta_mgr;} private final Dbmeta_tbl_mgr meta_mgr = new Dbmeta_tbl_mgr(Dbmeta_reload_cmd_.Noop);
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_idx_exists(String idx) {return false;}
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 static final Mem_engine Instance = new Mem_engine(); Mem_engine() {}
}

View File

@@ -13,3 +13,197 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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

@@ -13,3 +13,116 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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

@@ -13,3 +13,10 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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

@@ -13,3 +13,32 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
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 Mem_rdr(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 Err_.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 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

@@ -13,3 +13,25 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Mem_row implements Gfo_invk {
private final Ordered_hash hash = Ordered_hash_.New();
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 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 Gfo_invk_.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

@@ -13,3 +13,134 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*;
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 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);}
public Db_qry Qry() {return qry;} private Db_qry qry;
public Db_stmt Reset_stmt() {return this;}
public Db_stmt Clear() {
val_list.Clear();
stmt_args.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 Err_.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_by_bool(String k, boolean v) {return Add_int(Bool_.N, k, v ? 1 : 0);}
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 Err_.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 Err_.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 Err_.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 Err_.new_exc(e, "db", "failed to add value", "type", "double", "val", v);}
return this;
}
public Db_stmt Crt_decimal(String k, Decimal_adp v) {return Add_decimal(Bool_.Y, k, v);}
public Db_stmt Val_decimal(String k, Decimal_adp v) {return Add_decimal(Bool_.N, k, v);}
public Db_stmt Val_decimal(Decimal_adp v) {return Add_decimal(Bool_.N, Key_na, v);}
private Db_stmt Add_decimal(boolean where, String k, Decimal_adp v) {
try {Add(k, where, v);} catch (Exception e) {throw Err_.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 Err_.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 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.streams.Io_stream_rdr v, long rdr_len) {
try {
Bry_bfr bfr = Bry_bfr_.New();
gplx.core.ios.streams.Io_stream_rdr_.Load_all_to_bfr(bfr, v);
Add("", Bool_.N, bfr.To_str_and_clear());
} catch (Exception e) {throw Err_.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 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());
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 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);
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
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) stmt_args.Add(k, v);
}
}

View File

@@ -13,3 +13,63 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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

@@ -13,3 +13,92 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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.dbs.sqls.itms.*;
import gplx.dbs.metas.*;
public class Mem_tbl {
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 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();
for (int i = 0; i < len; ++i) {
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);
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(Mem_stmt stmt) {
Db_qry_update qry = (Db_qry_update)stmt.Qry();
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) {
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(Mem_stmt stmt) {
Db_qry_delete qry = (Db_qry_delete)stmt.Qry();
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) {
Mem_row itm = (Mem_row)where_rows.Get_at(i);
rows.Del(itm);
}
return where_rows_len;
}
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) {
Db_qry__select_cmd qry2 = (Db_qry__select_cmd)stmt.Qry();
select = 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);
Select_rows_where(where_rows, stmt, where);
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();
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, Mem_stmt 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

@@ -13,3 +13,31 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.mysql; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Mysql_conn_info extends Db_conn_info__base {
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
, "server", server
, "database", database
, "uid", uid
, "pwd", pwd
, "charset", "utf8"
));
}
@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("", "", "", "", "", "");
}

View File

@@ -13,3 +13,36 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.mysql; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; import gplx.dbs.metas.*;
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 Sql_wtr() {return Sql_qry_wtr_.New__mysql();}
@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);}
@Override public Dbmeta_tbl_mgr Meta_mgr() {throw Err_.new_unimplemented();}
@gplx.Internal @Override protected Connection Conn_make() {
Mysql_conn_info conn_info_as_mysql = (Mysql_conn_info)conn_info;
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() {}
}
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

@@ -13,3 +13,10 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.noops; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Noop_conn_info extends Db_conn_info__base {
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

@@ -13,3 +13,38 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.noops; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.bats.*;
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 Db_conn_props_mgr Props() {return props;} private final Db_conn_props_mgr props = new Db_conn_props_mgr();
public Db_batch_mgr Batch_mgr() {return batch_mgr;} private final Db_batch_mgr batch_mgr = new Db_batch_mgr();
public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.New__basic();
public void Conn_open() {}
public void Conn_term() {}
public Db_engine New_clone(Db_conn_info url) {return this;}
public Db_rdr Exec_as_rdr__rls_manual (Object rdr_obj, String sql) {return Db_rdr_.Empty;}
public Db_rdr Exec_as_rdr__rls_auto (Db_stmt stmt, Object rdr_obj, String sql) {return Db_rdr_.Empty;}
public Db_stmt Stmt_by_qry(Db_qry qry) {return Db_stmt_.Null;}
public Object Stmt_by_sql(String sql) {throw Err_.new_unimplemented();}
public DataRdr New_rdr(java.sql.ResultSet rdr, String sql) {return DataRdr_.Null;}
public void Txn_bgn(String name) {}
public String Txn_end() {return "";}
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 Meta_tbl_create(Dbmeta_tbl_itm meta) {}
public void Meta_tbl_delete(String tbl) {}
public void Meta_idx_create(Gfo_usr_dlg usr_dlg, Dbmeta_idx_itm... ary) {}
public void Meta_idx_delete(String idx) {}
public void Meta_fld_append(String tbl, Dbmeta_fld_itm fld) {}
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 boolean Meta_tbl_exists(String tbl) {return false;}
public boolean Meta_fld_exists(String tbl, String fld) {return false;}
public boolean Meta_idx_exists(String idx) {return false;}
public Dbmeta_tbl_mgr Meta_mgr() {return meta_tbl_mgr;} private final Dbmeta_tbl_mgr meta_tbl_mgr = new Dbmeta_tbl_mgr(Dbmeta_reload_cmd_.Noop);
public static final Noop_engine Instance = new Noop_engine(); Noop_engine() {}
}

View File

@@ -13,3 +13,32 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.postgres; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Postgres_conn_info extends Db_conn_info__base {
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
, "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, 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("", "", "", "", "", "");
}

View File

@@ -13,3 +13,22 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.postgres; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; import gplx.dbs.metas.*;
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 Sql_wtr() {return Sql_qry_wtr_.New__mysql();}
@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);}
@Override public Dbmeta_tbl_mgr Meta_mgr() {throw Err_.new_unimplemented();}
@gplx.Internal @Override protected Connection Conn_make() {
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

@@ -13,3 +13,35 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.dbs.engines.sqlite; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
public class Sqlite_conn_info extends Db_conn_info__base {
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" , Key_const
, 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" , Key_const
, Cs__data_source , url.Xto_api()
, Cs__version , Cs__version__3
));
}
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

@@ -13,3 +13,151 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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.dbs.sqls.*;
import gplx.dbs.qrys.*;
import gplx.core.ios.IoItmFil;
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;
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.Key_const;}
@Override public gplx.dbs.sqls.Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.New__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 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 Dbmeta_tbl_mgr Meta_mgr() {return schema_mgr.Tbl_mgr();}
@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 boolean Meta_idx_exists(String idx) {return schema_mgr.Idx_exists(idx);}
@Override public Db_stmt Stmt_by_qry(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_make() {
if (!loaded) {
try {
Class.forName("org.sqlite.JDBC");
}
catch (ClassNotFoundException e) {throw Err_.new_exc(e, "db", "could not load sqlite jdbc driver");}
loaded = true;
}
// init vars for opening connection
Sqlite_conn_info conn_info_as_sqlite = (Sqlite_conn_info)conn_info;
Io_url sqlite_fs_url = conn_info_as_sqlite.Url();
String sqlite_db_url = "jdbc:sqlite://" + String_.Replace(sqlite_fs_url.Raw(), "\\", "/");
// set open_mode flag if conn is read-only; needed else all SELECT queries will be very slow; DATE:2016-09-03
IoItmFil sqlite_fs_itm = Io_mgr.Instance.QueryFil(sqlite_fs_url);
Keyval[] props = sqlite_fs_itm.Exists() && sqlite_fs_itm.ReadOnly() // NOTE: must check if it exists; else missing-file will be marked as readonly connection, and missing-file will sometimes be dynamically created as read-write; DATE:2016-09-04
? Keyval_.Ary(Keyval_.new_("open_mode", "1"))
: Keyval_.Ary_empty;
// open connection
Connection rv = Conn__new_by_url_and_props(sqlite_db_url, props);
// set busyTimeout; needed else multiple processes accessing same db can cause "database is locked" error; DATE:2016-09-03
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();
}
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) {
try {
int val = rdr.getInt(k);
return val == 1;
} catch (Exception e) {throw Err_.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 Err_.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 Err_.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 Err_.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 Decimal_adp ReadDecimal(String key) {return ReadDecimalOr(key, null);}
@Override public Decimal_adp ReadDecimalOr(String key, Decimal_adp or) {
Object val = Read(key);
Double d = ((Double)val);
return val == null ? or : Decimal_adp_.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_.Min_value);}
@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() {}
}
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

@@ -13,3 +13,65 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
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 Idx_create(Gfo_usr_dlg usr_dlg, Db_conn conn, String tbl, Dbmeta_idx_itm[] idx_ary) {
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(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.Engine().Sql_wtr())));
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 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;
}

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