io.odysz.semantic.syn.Docheck Maven / Gradle / Ivy
package io.odysz.semantic.syn;
import static io.odysz.common.LangExt.compoundVal;
import static io.odysz.common.LangExt.ifnull;
import static io.odysz.common.LangExt.indexOf;
import static io.odysz.common.LangExt.isblank;
import static io.odysz.common.LangExt.isNull;
import static io.odysz.common.LangExt.repeat;
import static io.odysz.common.LangExt.strcenter;
import static io.odysz.transact.sql.parts.condition.Funcall.compound;
import static io.odysz.transact.sql.parts.condition.Funcall.concat;
import static io.odysz.transact.sql.parts.condition.Funcall.count;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import io.odysz.common.Utils;
import io.odysz.module.rs.AnResultset;
import io.odysz.semantic.DA.Connects;
import io.odysz.semantic.meta.ExpDocTableMeta;
import io.odysz.semantic.meta.PeersMeta;
import io.odysz.semantic.meta.SynChangeMeta;
import io.odysz.semantic.meta.SynSessionMeta;
import io.odysz.semantic.meta.SynSubsMeta;
import io.odysz.semantic.meta.SynchangeBuffMeta;
import io.odysz.semantic.meta.SyntityMeta;
import io.odysz.semantic.util.DAHelper;
import io.odysz.semantics.IUser;
import io.odysz.transact.sql.Query;
import io.odysz.transact.sql.parts.Logic.op;
import io.odysz.transact.sql.parts.condition.Predicate;
import io.odysz.transact.x.TransException;
/**
* Checker of each Synode.
*
* @author Ody
*/
public class Docheck {
public static IAssert azert;
public static final String org = "URA";
public static Docheck[] ck = new Docheck[4];
public ExpDocTableMeta docm;
public final DBSyntableBuilder trb;
final String domain;
static SynChangeMeta chm = new SynChangeMeta();
static SynSubsMeta sbm = new SynSubsMeta(chm);
static SynchangeBuffMeta xbm = new SynchangeBuffMeta(chm);
static SynSessionMeta ssm = new SynSessionMeta();
static PeersMeta prm = new PeersMeta();
public IUser robot() { return trb.synrobot(); }
public int docs() throws SQLException, TransException {
return trb.entities(docm);
}
String connId() { return trb.basictx().connId(); }
public Docheck(IAssert assertImpl, String domain, String conn,
String synid, SynodeMode mod, ExpDocTableMeta m)
throws Exception {
this(assertImpl, m, domain, conn, mod, synid, "rob-" + synid);
}
/**
* Verify all synodes information here are as expected.
*
* @param nx ck index
* @throws TransException
* @throws SQLException
*/
public void synodes(int ... nx) throws TransException, SQLException {
ArrayList nodes = new ArrayList();
int cnt = 0;
for (int x = 0; x < nx.length; x++) {
if (nx[x] >= 0) {
nodes.add(ck[x].trb.synode());
cnt++;
}
}
AnResultset rs = (AnResultset) trb.select(trb.synm.tbl)
.col(trb.synm.synoder)
.distinct(true)
.whereIn(trb.synm.synoder, nodes)
.rs(trb.instancontxt(trb.basictx().connId(), trb.synrobot()))
.rs(0);
azert.equali(cnt, rs.getRowCount());
}
public Docheck(IAssert assertImpl, ExpDocTableMeta docm, String domain, String conn,
SynodeMode mode, String synid, String usrid)
throws Exception {
trb = new DBSyntableBuilder(domain, conn, synid, mode)
; // .loadNyquvect(conn);
azert = assertImpl == null ? azert : assertImpl;
this.docm = docm;
this.domain = trb.domain();
this.tops = null;
}
private Docheck(boolean[] debugs) {
this.trb = null;
this.tops = debugs;
this.domain = null;
}
public void doc(int count, String... synids) throws TransException, SQLException {
Query q = trb.select(docm.tbl).col(count(), "c");
if (!isNull(synids))
q.whereIn(docm.synuid, synids);
azert.equali(count, ((AnResultset) q
.rs(trb.instancontxt(trb.synconn(), trb.synrobot()))
.rs(0))
.nxt()
.getInt("c"));
}
/**
* Verify change flag, crud, where tabl = entm.tbl, entity-id = eid.
*
* @param count
* @param crud flag to be verified
* @param eid entity id
* @param entm entity table meta
* @return nyquence.n
* @throws TransException
* @throws SQLException
*/
public long buf_change(int count, String crud, String eid, SyntityMeta entm)
throws TransException, SQLException {
return buf_change(count, crud, trb.synode(), eid, entm);
}
public long buf_change_p(int count, String crud, String eid)
throws TransException, SQLException {
return buf_change(count, crud, trb.synode(), eid, docm);
}
public long change_doclog(int count, String crud, String eid) throws TransException, SQLException {
return change_log(count, crud, trb.synode(), eid, docm);
}
public long change_doclog(int count, String crud, String synoder, String eid) throws TransException, SQLException {
return change_log(count, crud, synoder, eid, docm);
}
public long change_log(int count, String crud, String synoder, String eid, SyntityMeta entm)
throws TransException, SQLException {
Query q = trb
.select(trb.chgm.tbl, "ch")
.cols((Object[])trb.chgm.insertCols())
.whereEq(trb.chgm.domain, domain)
.whereEq(trb.chgm.entbl, entm.tbl);
if (synoder != null)
q.whereEq(trb.chgm.synoder, synoder);
if (eid != null)
q.whereEq(trb.chgm.uids, SynChangeMeta.uids(synoder, eid));
AnResultset chg = (AnResultset) q
.rs(trb.instancontxt(connId(), robot()))
.rs(0);
if (!chg.next() && count > 0)
azert.fail(String.format("Expecting count == %d, but is actual 0", count));
azert.equali(count, chg.getRowCount());
if (count > 0) {
azert.equals(crud, chg.getString(trb.chgm.crud));
azert.equals(entm.tbl, chg.getString(trb.chgm.entbl));
azert.equals(synoder, chg.getString(trb.chgm.synoder));
return chg.getLong(trb.chgm.nyquence);
}
return 0;
}
public long buf_change(int count, String crud, String synoder, String eid, SyntityMeta entm)
throws TransException, SQLException {
Query q = trb
.select(trb.chgm.tbl, "ch")
.je_(trb.exbm.tbl, "xb", trb.chgm.pk, trb.exbm.changeId, trb.chgm.synoder, trb.exbm.peer)
.cols((Object[])trb.chgm.insertCols())
.whereEq(trb.chgm.domain, domain)
.whereEq(trb.chgm.entbl, entm.tbl);
if (synoder != null)
q.whereEq(trb.chgm.synoder, synoder);
if (eid != null)
q.whereEq(trb.chgm.uids, SynChangeMeta.uids(synoder, eid));
AnResultset chg = (AnResultset) q
.rs(trb.instancontxt(connId(), robot()))
.rs(0);
if (!chg.next() && count > 0)
azert.fail(String.format("Expecting count == %d, but is actual 0", count));
azert.equali(count, chg.getRowCount());
if (count > 0) {
azert.equals(crud, chg.getString(trb.chgm.crud));
azert.equals(entm.tbl, chg.getString(trb.chgm.entbl));
azert.equals(synoder, chg.getString(trb.chgm.synoder));
return chg.getLong(trb.chgm.nyquence);
}
return 0;
}
public long changelog(int count, String crud, String eid, SyntityMeta entm)
throws TransException, SQLException {
return changelog(count, crud, trb.synode(), eid, entm);
}
public long changelog(int count, String crud, String synoder, String eid, SyntityMeta entm)
throws TransException, SQLException {
Query q = trb
.select(trb.chgm.tbl, "ch")
.cols((Object[])trb.chgm.insertCols())
.whereEq(trb.chgm.domain, domain)
.whereEq(trb.chgm.entbl, entm.tbl);
if (synoder != null)
q.whereEq(trb.chgm.synoder, synoder);
if (eid != null)
q.whereEq(trb.chgm.uids, SynChangeMeta.uids(synoder, eid));
AnResultset chg = (AnResultset) q
.rs(trb.instancontxt(connId(), robot()))
.rs(0);
if (!chg.next() && count > 0)
azert.fail(String.format("Expecting count == %d, but is actual 0", count));
azert.equali(count, chg.getRowCount());
if (count > 0) {
azert.equals(crud, chg.getString(trb.chgm.crud));
azert.equals(entm.tbl, chg.getString(trb.chgm.entbl));
azert.equals(synoder, chg.getString(trb.chgm.synoder));
return chg.getLong(trb.chgm.nyquence);
}
return 0;
}
/**
* verify h_photos' subscription.
* @param chgid
* @param sub subscriptions for X/Y/Z/W, -1 if not exists
* @throws SQLException
* @throws TransException
*/
public void psubs(int subcount, String chgid, int ... sub) throws SQLException, TransException {
ArrayList toIds = new ArrayList();
for (int n : sub)
if (n >= 0)
toIds.add(ck[n].trb.synode());
subsCount(docm, subcount, chgid, toIds.toArray(new String[0]));
}
public void synsubs(int subcount, String uids, int ... sub) throws SQLException, TransException {
ArrayList toIds = new ArrayList();
for (int n : sub)
if (n >= 0)
toIds.add(ck[n].trb.synode());
int cnt = 0;
AnResultset subs = (AnResultset) trb
.select(trb.chgm.tbl, "ch")
.je_(trb.subm.tbl, "sb", trb.chgm.pk, trb.subm.changeId)
.cols_byAlias("sb", (Object[])trb.subm.cols())
.whereEq(trb.chgm.uids, uids)
.rs(trb.instancontxt(connId(), robot()))
.rs(0);
;
subs.beforeFirst();
while (subs.next()) {
if (indexOf(toIds.toArray(new String[0]), subs.getString(trb.subm.synodee)) >= 0)
cnt++;
}
azert.equali(subcount, cnt);
azert.equali(subcount, subs.getRowCount());
}
public void subsCount(SyntityMeta entm, int subcount, String chgId, String ... toIds)
throws SQLException, TransException {
if (isNull(toIds)) {
AnResultset subs = subscribes(connId(), chgId, entm, robot());
azert.equali(subcount, subs.getRowCount());
}
else {
int cnt = 0;
AnResultset subs = subscribes(connId(), chgId, entm, robot());
subs.beforeFirst();
while (subs.next()) {
if (indexOf(toIds, subs.getString(trb.subm.synodee)) >= 0)
cnt++;
}
azert.equali(subcount, cnt);
azert.equali(subcount, subs.getRowCount());
}
}
/**
* Verify subscribes
* @param connId
* @param chgId
* @param entm
* @param robot
* @return results
*/
private AnResultset subscribes(String connId, String chgId, SyntityMeta entm, IUser robot)
throws TransException, SQLException {
Query q = trb.select(trb.subm.tbl, "ch")
.cols((Object[])trb.subm.cols())
;
if (!isblank(chgId))
q.whereEq(trb.subm.changeId, chgId) ;
return (AnResultset) q
.rs(trb.instancontxt(connId, robot))
.rs(0);
}
/**
* Verify if and only if one instance exists on this node.
*
* @param synoder
* @param clientpath
*/
public void verifile(String synoder, String clientpath, ExpDocTableMeta docm) {
trb.select(docm.tbl)
.col(count(docm.pk), "c")
.where(new Predicate(op.eq, compound(trb.chgm.uids), compoundVal(synoder, clientpath)))
;
}
@SuppressWarnings("unchecked")
public static HashMap[] printNyquv(Docheck[] ck) throws SQLException, TransException {
Utils.logi(Stream.of(ck)
.filter(c -> c != null)
.map(c -> { return c.trb.synode();})
.collect(Collectors.joining(" ", " ", "")));
final HashMap, ?>[] nv2 = new HashMap[ck.length];
for (int cx = 0; cx < ck.length && ck[cx] instanceof Docheck; cx++) {
DBSyntableBuilder t = ck[cx].trb;
boolean top = Connects.getDebug(t.synconn());
Connects.setDebug(t.synconn(), false);
try { HashMap nyquvect = ExessionPersist.loadNyquvect(t);
nv2[cx] = Nyquence.clone(nyquvect);
Utils.logi(
t.synode() + " [ " +
Stream.of(ck)
.filter(c -> c != null)
.map((c) -> {
String n = c.trb.synode();
return String.format("%3s",
nyquvect.containsKey(n) ?
nyquvect.get(n).n : "");
})
.collect(Collectors.joining(", ")) +
" ]");
}
finally { Connects.setDebug(t.synconn(), top); }
}
return (HashMap[]) nv2;
}
static String changeLine(AnResultset r) throws SQLException {
String seq = r.getString(xbm.pagex, " ");
return String.format("%1$1s %2$9s %3$9s %4$2s %5$2s [%6$4s]",
r.getString(chm.crud),
r.getString(chm.pk),
r.getString(chm.uids),
r.getString(chm.nyquence),
r.getString(sbm.synodee),
seq == null ? " " : seq
);
}
public static void printChangeLines(Docheck[] ck)
throws TransException, SQLException {
HashMap uidss = new HashMap();
for (int cx = 0; cx < ck.length && ck[cx] instanceof Docheck; cx++) {
DBSyntableBuilder b = ck[cx].trb;
boolean top = Connects.getDebug(b.synconn());
Connects.setDebug(b.synconn(), false);
try {
HashMap idmap = ((AnResultset) b
.select(chm.tbl, "ch")
.cols("ch.*", sbm.synodee).col(concat(ifnull(xbm.peer, " "), "':'", xbm.pagex), xbm.pagex)
// .je("ch", sbm.tbl, "sub", chm.entbl, sbm.entbl, chm.domain, sbm.domain, chm.uids, sbm.uids)
.je_(sbm.tbl, "sub", chm.pk, sbm.changeId)
.l_(xbm.tbl, "xb", chm.pk, xbm.changeId)
.orderby(xbm.pagex, chm.entbl, chm.uids)
// .rs(b.instancontxt(b.basictx().connId(), b.synrobot()))
.rs(b.instancontxt(b.synconn(), b.synrobot()))
.rs(0))
.map(new String[] {chm.pk, sbm.synodee}, (r) -> changeLine(r));
for(String cid : idmap.keySet()) {
if (!uidss.containsKey(cid))
uidss.put(cid, new String[ck.length]);
uidss.get(cid)[cx] = idmap.get(cid);
}
}
finally {
Connects.setDebug(b.synconn(), top);
}
}
Utils.logi(Stream.of(ck)
.filter(c -> c != null)
.map(c -> strcenter(c.trb.synode(), 36))
.collect(Collectors.joining("|")));
Utils.logi(Stream.of(ck)
.filter(c -> c != null)
.map(c -> repeat("-", 36))
.collect(Collectors.joining("+")));
Utils.logi(uidss.keySet().stream().map(
(String linekey) -> {
return Stream.of(uidss.get(linekey))
.map(c -> c == null ? String.format("%34s", " ") : c)
.collect(Collectors.joining(" | ", " ", " "));
})
.collect(Collectors.joining("\n")));
}
static String buffChangeLine(AnResultset r) throws SQLException {
return String.format("%1$1s %2$9s %3$9s %4$4s %5$2s",
r.getString(chm.crud),
r.getString(chm.pk),
r.getString(chm.uids),
r.getString(chm.nyquence),
r.getString(sbm.synodee)
);
}
/**
* Assert ai = bi, where ai, bi in nvs [a0, a1, ..., b0, b1, ...].
* @param nvs
*/
public static void assertnv(long... nvs) {
if (nvs == null || nvs.length == 0 || nvs.length % 2 != 0)
azert.fail("Invalid arguments to assert.");
for (int i = 0; i < nvs.length/2; i++) {
azert.equall(nvs[i], nvs[i + nvs.length/2],
String.format("nv[%d] %d : %d", i, nvs[i], nvs[i + nvs.length/2]));
}
}
public static void assertI(Docheck[] ck, HashMap, ?>[] nvs) throws SQLException, TransException {
for (int i = 0; i < nvs.length; i++) {
if (nvs[i] != null && nvs[i].size() > 0)
azert.equall(ck[i].n0().n, ((Nyquence)nvs[i].get(ck[i].trb.synode())).n);
else break;
}
}
public Nyquence n0() throws SQLException, TransException {
return DAHelper.getNyquence(trb, trb.synconn(), trb.synm, trb.synm.nyquence, trb.synm.synoder, trb.synode());
}
public static void assertnv(HashMap nv0,
HashMap nv1, int ... delta) {
if (nv0 == null || nv1 == null || nv0.size() != nv1.size() || nv1.size() != delta.length)
azert.fail("Invalid arguments to assert.");
for (int i = 0; i < nv0.size(); i++) {
azert.equall(nv0.get(ck[i].trb.synode()).n + delta[i], nv1.get(ck[i].trb.synode()).n,
String.format("nv[%d] %d : %d + %d",
i, nv0.get(ck[i].trb.synode()).n,
nv1.get(ck[i].trb.synode()).n,
delta[i]));
}
}
public long stamp() throws SQLException, TransException {
boolean dbg = Connects.getDebug(trb.synconn());
try { return DAHelper.getNstamp(trb).n; }
finally { Connects.setDebug(trb.synconn(), dbg); }
}
final boolean[] tops;
/**
* Push connect' debug flags and return a checker instance.
* Example:
* pushDebug()
* .assertl(
* expect1, loadNyquvect(actual1), // logging suppressed
* expect2, loadNyquvect(actual2), // logging suppressed
* ...)
* .popDebug(); // logging restored
*/
public static Docheck pushDebug() {
if (ck != null) {
final boolean[] tops = new boolean[ck.length];
for (int cx = 0; cx < ck.length; cx++) {
if (ck[cx] != null) {
tops[cx] = Connects.getDebug(ck[cx].connId());
Connects.setDebug(ck[cx].connId(), tops[cx]);
}
}
return new Docheck(tops);
}
return new Docheck(new boolean[0]);
}
public Docheck assertl(long ... n) {
if (!isNull(n))
for (int x = 0; x < n.length; x+=2)
azert.equall(n[x], n[x+1]);
return this;
}
public void popDebug() {
if (tops != null)
for (int cx = 0; cx < ck.length; cx++)
if (ck[cx] != null)
Connects.setDebug(ck[cx].connId(), tops[cx]);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy