1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2014-06-30 00:04:32 -04:00
parent 85594d3cdd
commit bae88e739c
2482 changed files with 198730 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
class TdbDbSaveMgr {
public void SaveDb(TdbDatabase db) {
for (Object filObj : db.Files()) {
TdbFile fil = (TdbFile)filObj;
SaveFile(db, fil);
}
}
public void SaveFile(TdbDatabase db, TdbFile fil) {
ListAdp tbls = FetchTablesWithSamePath(db, fil.Path());
boolean isSaveNeeded = db.IsNew();
for (Object tblObj : tbls) {
TdbTable tbl = (TdbTable)tblObj;
if (tbl.IsDirty()) {
isSaveNeeded = true;
break;
}
}
if (isSaveNeeded) {
SaveTblsToFile(db, fil, tbls);
db.IsNew_set(false);
}
}
void SaveTblsToFile(TdbDatabase db, TdbFile fil, ListAdp tbls) {
DataWtr wtr = TdbStores.wtr_();
if (fil.Id() == TdbFile.MainFileId) { // if MainFile, save critical Files and Tables data
db.Files().DataObj_Wtr(wtr);
db.Tables().DataObj_Wtr(wtr);
}
for (Object tblObj : tbls) {
TdbTable tbl = (TdbTable)tblObj;
tbl.DataObj_Wtr(wtr);
}
Io_mgr._.SaveFilStr(fil.Path(), wtr.XtoStr());
}
ListAdp FetchTablesWithSamePath(TdbDatabase db, Io_url filPath) {
ListAdp list = ListAdp_.new_();
for (Object tblObj : db.Tables()) {
TdbTable tbl = (TdbTable)tblObj;
if (tbl.File().Path().Eq (filPath))
list.Add(tbl);
}
return list;
}
public static TdbDbSaveMgr new_() {return new TdbDbSaveMgr();} TdbDbSaveMgr() {}
}

View File

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

View File

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

View File

@@ -0,0 +1,67 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
class TdbEngine implements Db_engine {
public String Key() {return KeyDef;} public static final String KeyDef = "tdb";
public Db_connect ConnectInfo() {return connectInfo;} Db_connect connectInfo;
public TdbDatabase Db() {return db;} TdbDatabase db;
public Db_engine MakeEngine(Db_connect connectInfo) {
TdbEngine rv = new TdbEngine();
rv.CtorTdbEngine(connectInfo);
return rv;
}
public void Connect() {
String urlStr = (String)connectInfo.Server();
db = loadMgr.LoadTbls(Io_url_.new_any_(urlStr));
}
public Object Execute(Db_qry cmd) {
Db_qryWkr wkr = (Db_qryWkr)wkrs.FetchOrFail(cmd.KeyOfDb_qry());
return wkr.Exec(this, cmd);
}
public DataRdr NewDataRdr(java.sql.ResultSet rdr, String sql) {return DataRdr_.Null;}
public Db_stmt New_db_stmt(Db_provider provider, Db_qry qry) {return new Db_stmt_sql().Parse(Sql_cmd_wtr_.Ansi.XtoSqlQry(qry, true));}
public Object New_db_cmd(String sql) {throw Err_.not_implemented_();}
public void Txn_bgn() {}
public void Txn_end() {}
public TdbTable FetchTbl(String name) {
TdbTable tbl = db.Tables().FetchOrFail(name);
if (!tbl.IsLoaded()) loadMgr.LoadTbl(db, tbl);
return tbl;
}
public void FlushAll() {
saveMgr.SaveDb(db);
}
public void FlushTbl(TdbTable tbl) {
saveMgr.SaveFile(db, tbl.File());
}
public void Rls() {}
HashAdp wkrs = HashAdp_.new_(); TdbDbLoadMgr loadMgr = TdbDbLoadMgr.new_(); TdbDbSaveMgr saveMgr = TdbDbSaveMgr.new_();
@gplx.Internal protected static final TdbEngine _ = new TdbEngine();
//TdbEngine() {this.connectInfo = TdbConnectUrl._;}
void CtorTdbEngine(Db_connect connectInfo) {
this.connectInfo = connectInfo;
wkrs.Add(Db_qry_select.KeyConst, TdbSelectWkr._);
wkrs.Add(Db_qry_insert.KeyConst, TdbInsertWkr.new_());
wkrs.Add(Db_qry_update.KeyConst, TdbUpdateWkr.new_());
wkrs.Add(Db_qry_delete.KeyConst, TdbDeleteWkr.new_());
wkrs.Add(Db_qry_flush.KeyConst, TdbFlushWkr.new_());
}
public static TdbEngine as_(Object obj) {return obj instanceof TdbEngine ? (TdbEngine)obj : null;}
public static TdbEngine cast_(Object obj) {try {return (TdbEngine)obj;} catch(Exception exc) {throw Err_.type_mismatch_exc_(exc, TdbEngine.class, obj);}}
}

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
public class TdbFile {
public int Id() {return id;} int id;
public Io_url Path() {return url;} Io_url url;
public static TdbFile new_(int id, Io_url url) {
TdbFile rv = new TdbFile();
rv.id = id; rv.url = url;
return rv;
}
public static final int MainFileId = 1;
public static TdbFile as_(Object obj) {return obj instanceof TdbFile ? (TdbFile)obj : null;}
public static TdbFile cast_(Object obj) {try {return (TdbFile)obj;} catch(Exception exc) {throw Err_.type_mismatch_exc_(exc, TdbFile.class, obj);}}
}

View File

@@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.lists.*; /*OrderedHash_base*/ import gplx.stores.dsvs.*; /*DsvStoreLayout*/
public class TdbFileList extends OrderedHash_base {
public TdbFile FetchOrFail(int id) {return TdbFile.as_(FetchOrFail_base(id));}
public void Add(TdbFile src) {Add_base(src.Id(), src);}
Io_url dbInfo;
public static TdbFileList new_(Io_url dbInfo, TdbFile mainFile) {
TdbFileList rv = new TdbFileList();
rv.dbInfo = dbInfo;
rv.Add(mainFile);
rv.layout = DsvStoreLayout.dsv_full_();
return rv;
} TdbFileList() {}
@gplx.Internal protected void DataObj_Wtr(DataWtr wtr) {
wtr.InitWtr(DsvStoreLayout.Key_const, layout);
wtr.WriteTableBgn(StoreTblName, FldList);
for (Object filObj : this) {
TdbFile fil = (TdbFile)filObj;
wtr.WriteLeafBgn("fil");
wtr.WriteData(Fld_id, fil.Id());
wtr.WriteData(Fld_path, fil.Path());
wtr.WriteData("format", "dsv");
wtr.WriteLeafEnd();
}
wtr.WriteNodeEnd();
}
@gplx.Internal protected void DataObj_Rdr(DataRdr rdr) {
layout = TdbStores.FetchLayout(rdr);
this.Clear();
DataRdr subRdr = rdr.Subs();
while (subRdr.MoveNextPeer()) {
int id = subRdr.ReadInt(Fld_id);
String url = subRdr.ReadStrOr(Fld_path, dbInfo.Raw());
TdbFile file = (id == TdbFile.MainFileId)
? TdbFile.new_(TdbFile.MainFileId, dbInfo) // not redundant; prevents error of MainFile in different url/format than connectInfo
: TdbFile.new_(id, Io_url_.new_any_(url));
this.Add(file);
}
}
DsvStoreLayout layout;
public static final String StoreTblName = "_files";
static final String Fld_id = "id"; static final String Fld_path = "url";
static final GfoFldList FldList = GfoFldList_.new_().Add(Fld_id, IntClassXtn._).Add(Fld_path, StringClassXtn._).Add("format", StringClassXtn._);
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,99 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.criterias.*;
import gplx.lists.*; /*ComparerAble*/ import gplx.stores.*; /*GfoNdeRdr*/
class TdbSelectWkr implements Db_qryWkr {
public Object Exec(Db_engine engineObj, Db_qry cmdObj) {
TdbEngine engine = TdbEngine.cast_(engineObj); Db_qry_select cmd = (Db_qry_select)cmdObj;
if (cmd.From().Tbls().Count() > 1) throw Err_.new_key_("gplx.tdbs", "joins not supported for tdbs").Add("sql", cmd.XtoSql());
TdbTable tbl = engine.FetchTbl(cmd.From().BaseTable().TblName());
GfoNdeList rv = (cmd.Where() == Db_qry_.WhereAll && cmd.Limit() == Db_qry_select.Limit_disabled) ? rv = tbl.Rows() : FilterRecords(tbl, cmd.Where().Crt(), cmd.Limit());
if (cmd.GroupBy() != null)
rv = TdbGroupByWkr.GroupByExec(cmd, rv, tbl);
if (cmd.OrderBy() != null) { // don't use null pattern here; if null ORDER BY, then don't call .Sort on GfoNdeList
ComparerAble comparer = Sql_order_by_sorter.new_((Sql_order_by_itm[])cmd.OrderBy().Flds().XtoAry(Sql_order_by_itm.class));
rv.SortBy(comparer);
}
return GfoNdeRdr_.peers_(rv, false);
}
GfoNdeList FilterRecords(TdbTable tbl, Criteria crt, int limit) {
GfoNdeList rv = GfoNdeList_.new_();
int count = 0;
for (int i = 0; i < tbl.Rows().Count(); i++) {
GfoNde row = (GfoNde)tbl.Rows().FetchAt_asGfoNde(i);
if (crt.Matches(row)) rv.Add(row);
++count;
if (count == limit) break;
}
return rv;
}
public static final TdbSelectWkr _ = new TdbSelectWkr(); TdbSelectWkr() {}
}
class TdbGroupByWkr {
public static GfoNdeList GroupByExec(Db_qry_select select, GfoNdeList selectRows, TdbTable tbl) {
GfoNdeList rv = GfoNdeList_.new_();
OrderedHash groupByHash = OrderedHash_.new_();
ListAdp groupByFlds = select.GroupBy().Flds();
GfoFldList selectFldsForNewRow = select.Cols().Flds().XtoGfoFldLst(tbl);
Sql_select_fld_list selectFlds = select.Cols().Flds();
for (int rowIdx = 0; rowIdx < selectRows.Count(); rowIdx++) {
GfoNde selectRow = selectRows.FetchAt_asGfoNde(rowIdx);
GfoNde groupByRow = FindOrNew(selectFldsForNewRow, groupByFlds, selectRow, groupByHash, rv);
for (int i = 0; i < selectFlds.Count(); i++) {
Sql_select_fld_base selectFld = selectFlds.FetchAt(i);
Object val = groupByRow.Read(selectFld.Alias()); // groupByRow is keyed by Alias; EX: Count(Id) AS CountOf
groupByRow.WriteAt(i, selectFld.GroupBy_eval(val, selectRow.Read(selectFld.Fld()), selectFld.ValType()));
}
}
return rv;
}
static GfoNde FindOrNew(GfoFldList selectFldsForNewRow, ListAdp groupByFlds, GfoNde selectRow, OrderedHash groupByRows, GfoNdeList rslt) {
int len = groupByFlds.Count();
OrderedHash curHash = groupByRows;
GfoNde rv = null;
for (int i = 0; i < len; i++) {
String fld = (String)groupByFlds.FetchAt(i);
boolean last = i == len - 1;
Object val = selectRow.Read(fld);
Object o = curHash.Fetch(val);
if (last) {
if (o == null) {
Object[] valAry = new Object[selectFldsForNewRow.Count()];
rv = GfoNde_.vals_(selectFldsForNewRow, valAry);
curHash.Add(val, rv);
rslt.Add(rv);
}
else
rv = GfoNde_.as_(o);
}
else {
if (o == null) {
OrderedHash nextHash = OrderedHash_.new_();
curHash.Add(val, nextHash);
curHash = nextHash;
}
else {
curHash = (OrderedHash)o;
}
}
}
return rv;
}
}

View File

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

View File

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

View File

@@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.dbs; import gplx.*;
import gplx.lists.*; /*OrderedHash_base*/ import gplx.stores.dsvs.*; /*DsvStoreLayout*/
public class TdbTableList extends OrderedHash_base {
public TdbTable Fetch(String name) {return TdbTable.as_(Fetch_base(name));}
public TdbTable FetchOrFail(String name) {
TdbTable rv = TdbTable.as_(Fetch(name)); if (rv == null) throw Err_.new_("could not find table; database file may not exist").Add("table", name);
return rv;
}
public void Add(TdbTable dataTable) {Add_base(dataTable.Name(), dataTable);}
public static TdbTableList new_(Io_url dbInfo) {
TdbTableList rv = new TdbTableList();
rv.layout = DsvStoreLayout.dsv_full_();
return rv;
}
@gplx.Internal protected void DataObj_Wtr(DataWtr wtr) {
wtr.InitWtr(DsvStoreLayout.Key_const, layout);
wtr.WriteTableBgn(StoreTableName, FldList);
for (Object tblObj : this) {
TdbTable tbl = (TdbTable)tblObj;
wtr.WriteLeafBgn("tbl");
wtr.WriteData(Fld_id, tbl.Id());
wtr.WriteData(Fld_name, tbl.Name());
wtr.WriteData(Fld_file_id, tbl.File().Id());
wtr.WriteLeafEnd();
}
wtr.WriteNodeEnd();
}
@gplx.Internal protected void DataObj_Rdr(DataRdr rdr, TdbFileList files) {
layout = TdbStores.FetchLayout(rdr);
DataRdr subRdr = rdr.Subs();
this.Clear();
while (subRdr.MoveNextPeer()) {
int id = subRdr.ReadInt(Fld_id);
String name = subRdr.ReadStr(Fld_name);
int file_id = subRdr.ReadInt(Fld_file_id);
TdbFile file = files.FetchOrFail(file_id);
TdbTable table = TdbTable.load_(id, name, file);
this.Add(table);
}
}
DsvStoreLayout layout;
public static final String StoreTableName = "_tables";
static final String Fld_id = "id"; static final String Fld_name = "name"; static final String Fld_file_id = "file_id";
static final GfoFldList FldList = GfoFldList_.new_().Add(Fld_id, IntClassXtn._).Add(Fld_name, StringClassXtn._).Add(Fld_file_id, IntClassXtn._);
}

View File

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