use of io.github.ihongs.db.Table in project HongsCORE by ihongs.
the class AssocMore method fetchMore.
private static void fetchMore(Table table, FetchCase caze, Map assocs, List lnks2, String pn) throws HongsException {
Set tns = (Set) caze.getOption("ASSOCS");
Set tps = (Set) caze.getOption("ASSOC_TYPES");
Set jns = (Set) caze.getOption("ASSOC_JOINS");
Set jis = new HashSet(Arrays.asList("MERGE", ""));
String tn = caze.name;
if (tn == null || tn.length() == 0)
tn = caze.tableName;
for (Map.Entry et : (Set<Map.Entry>) assocs.entrySet()) {
Map assoc = (Map) et.getValue();
String tp = (String) assoc.get("type");
String jn = (String) assoc.get("join");
String an = (String) assoc.get("name");
String rn = (String) assoc.get("tableName");
if (rn == null || rn.length() == 0)
rn = an;
if (rn == null || rn.length() == 0)
continue;
// 检查是否许可关联
if (tns != null && !tns.contains(rn) && !tns.contains(an)) {
continue;
}
if (tps != null && !tps.contains(tp)) {
continue;
}
if (jn != null && !jis.contains(jn)) {
if (jns != null && !jns.contains(jn)) {
continue;
}
} else {
// 非JOIN表先放到一边
assoc.put("assocName", tn);
lnks2.add(assoc);
continue;
}
Map assocs2 = (Map) assoc.get("assocs");
String fk = (String) assoc.get("foreignKey");
String pk = (String) assoc.get("primaryKey");
Table table2 = table.db.getTable(rn);
FetchCase caze2 = caze.gotJoin(an).from(table2.tableName);
// 建立关联关系
if ("BLS_TO".equals(tp)) {
// 上级外键连接下级主键
if (pk == null)
pk = table2.primaryKey;
fk = "`" + tn + "`.`" + fk + "`";
pk = "`" + an + "`.`" + pk + "`";
} else if ("HAS_ONE".equals(tp)) {
// 上级主键连接下级外键
if (pk == null)
pk = table.primaryKey;
pk = "`" + tn + "`.`" + pk + "`";
fk = "`" + an + "`.`" + fk + "`";
} else if ("HAS_MANY".equals(tp) || "HAS_MORE".equals(tp)) {
throw new HongsException(1171, "Unsupported assoc type '" + tp + "'");
} else {
throw new HongsException(1171, "Unrecognized assoc type '" + tp + "'");
}
caze2.on(pk + "=" + fk);
// 转化关联类型
byte ji;
if ("LEFT".equals(jn)) {
ji = FetchCase.LEFT;
} else if ("RIGHT".equals(jn)) {
ji = FetchCase.RIGHT;
} else if ("FULL".equals(jn)) {
ji = FetchCase.FULL;
} else if ("INNER".equals(jn)) {
ji = FetchCase.INNER;
} else if ("CROSS".equals(jn)) {
throw new HongsException(1172, "Unsupported assoc join '" + jn + "'");
} else {
throw new HongsException(1172, "Unrecognized assoc join '" + jn + "'");
}
caze2.by(ji);
// 添加关联层级名, 如果不是 CLEVER_MODE 则没作用
String pu = null != pn ? pn + "." + an : an;
caze2.in(pu);
if (assocs2 != null) {
fetchMore(table2, caze2, assocs2, lnks2, pu);
}
checkCase(caze2, (Map) assoc.get("params"), pu, an, table2);
}
}
use of io.github.ihongs.db.Table in project HongsCORE by ihongs.
the class AssocMore method fetchMore.
private static void fetchMore(Table table, FetchCase caze, List rows2, List lnks2) throws HongsException {
Set tns = (Set) caze.getOption("ASSOCS");
Set tps = (Set) caze.getOption("ASSOC_TYPES");
FetchMore join = new FetchMore(rows2);
while (!lnks2.isEmpty()) {
List lnkz2 = new ArrayList();
for (Map assoc : (List<Map>) lnks2) {
String tp = (String) assoc.get("type");
String jn = (String) assoc.get("join");
String an = (String) assoc.get("name");
String rn = (String) assoc.get("tableName");
String pn = (String) assoc.get("assocName");
if (rn == null || rn.length() == 0)
rn = an;
if (rn == null || rn.length() == 0)
continue;
// 检查是否许可关联
if (tns != null && !tns.contains(rn) && !tns.contains(an)) {
continue;
}
if (tps != null && !tps.contains(tp)) {
continue;
}
Map assocs2 = (Map) assoc.get("assocs");
String fk = (String) assoc.get("foreignKey");
String pk = (String) assoc.get("primaryKey");
Table table2 = table.db.getTable(rn);
FetchCase caze2 = caze.gotJoin(an).from(table2.tableName);
// 准备关联关系
if ("BLS_TO".equals(tp)) {
// 上级外键连接下级主键, 交换主外键
String xk = fk;
fk = pk;
pk = xk;
if (fk == null)
fk = table2.primaryKey;
caze2.setOption("ASSOC_MULTI", false);
} else if ("HAS_ONE".equals(tp)) {
// 上级主键连接下级外键
if (pk == null)
pk = table.primaryKey;
caze2.setOption("ASSOC_MULTI", false);
} else if ("HAS_MANY".equals(tp)) {
// 上级主键连接下级外键
if (pk == null)
pk = table.primaryKey;
caze2.setOption("ASSOC_MULTI", true);
} else if ("HAS_MORE".equals(tp)) {
// 上级主键连接下级外键
if (pk == null)
pk = table.primaryKey;
caze2.setOption("ASSOC_MULTI", true);
// 将下层数据合并到本层
if (assocs2 != null) {
for (Map ass : (Collection<Map>) assocs2.values()) {
if (ass.containsKey("join") != true) {
ass.put("join", "MERGE");
}
}
}
} else {
throw new HongsException(1171, "Unrecognized assoc type '" + tp + "'");
}
caze2.setOption("ASSOC_MERGE", "MERGE".equals(jn));
if (assocs2 != null) {
fetchMore(table2, caze2, assocs2, lnkz2, null);
}
checkCase(caze2, (Map) assoc.get("params"), null, null, null);
if (pn != null && !pn.equals("") && !pn.equals(caze.getName())) {
pk = pn + "." + pk;
}
join.join(table2, caze2, pk, fk);
}
lnks2 = lnkz2;
}
}
use of io.github.ihongs.db.Table in project HongsCORE by ihongs.
the class AssocMore method insertMore.
/**
* 关联插入
*
* 关联配置中有指定 unique 键的话, 会调用 updateMore 进行更新
*
* @param table 主表
* @param assocs 关联配置
* @param values 要插入的数据
* @throws io.github.ihongs.HongsException
*/
public static void insertMore(Table table, Map assocs, Map values) throws HongsException {
if (assocs == null || assocs.isEmpty())
return;
String id = (String) values.get(table.primaryKey);
Iterator it = assocs.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Map config = (Map) entry.getValue();
String type = (String) config.get("type");
String name = (String) config.get("name");
String tableName = (String) config.get("tableName");
String foreignKey = (String) config.get("foreignKey");
if (!values.containsKey(name)) {
continue;
}
if (!type.equals("HAS_ONE") && !type.equals("HAS_MANY") && !type.equals("HAS_MORE")) {
continue;
}
if (tableName == null || tableName.length() == 0) {
tableName = name;
}
Table tb = table.db.getTable(tableName);
// 都整理成List方便处理
Object subValues = values.get(name);
List subValues2 = new ArrayList();
if ("HAS_ONE".equals(type)) {
if (subValues instanceof Map) {
subValues2.add(subValues);
} else {
throw new HongsException(1175, "Sub data type for table '" + tb.name + "' must be Map");
}
} else {
if (subValues instanceof Map) {
subValues2.addAll(((Map) subValues).values());
} else if (subValues instanceof Collection) {
subValues2.addAll((Collection) subValues);
} else {
throw new HongsException(1176, "Sub data type for table '" + tb.name + "' must be Map or List");
}
}
/**
* Add by Hongs on 2016/4/13
* 当存在 filter 条件时, 可以解析 filter 条件里的值作为要插入的限制值
*/
String wh = (String) config.get("filter");
if (wh != null && wh.length() != 0) {
Pattern pat = Pattern.compile("(?:`(.*?)`|(\\w+))\\s*=\\s*(?:'(.*?)'|(\\d+(?:\\.\\d+)?))");
Matcher mat = pat.matcher(wh);
Map map = new HashMap();
while (mat.find()) {
String n = mat.group(1);
if (null == n) {
n = mat.group(2);
}
String v = mat.group(3);
if (null == v) {
v = mat.group(4);
}
map.put(n, v);
}
// 填充约束
Iterator it2 = subValues2.iterator();
while (it2.hasNext()) {
Map subValues3 = (Map) it2.next();
subValues3.putAll(map);
}
// 附加条件
wh = "`" + foreignKey + "`=? AND " + wh;
} else {
wh = "`" + foreignKey + "`=?";
}
/**
* Add by Hongs on 2016/4/13
* 当存在 convey 字段时, 可以根据 convey 从上层提取需要同步传递的数据
*/
String cs = (String) config.get("convey");
if (cs != null && cs.length() != 0) {
String[] cz = cs.split("\\s*,\\s*");
// 提取数据
Map cd = new HashMap();
for (String cn : cz) {
cd.put(cn, values.get(cn));
}
// 传递数据
Iterator it2 = subValues2.iterator();
while (it2.hasNext()) {
Map subValues3 = (Map) it2.next();
subValues3.putAll(cd);
}
}
/**
* Add by Hongs on 2013/6/6
* 有时候子数据会被其他数据引用, 如果更新子数据, 子数据的ID就会改变;
* 通常这种情况存在以下规则: 如果某些字段值没发生改变则不要重新插入;
* 所以当有指定 unique 时, 可使用 updateMore 方法更新数据, 其原理为:
* 找出没改变的数据并更新, 然后插入新增数据, 最后删除更新和新增之外的数据.
*/
String ks = (String) config.get("unique");
// 2016/4/15, 也可以读取表自身的唯一键
if (ks == null || ks.length() == 0) {
ks = Synt.declare(tb.getParams().get("unique"), "");
}
if (ks != null && ks.length() != 0) {
String[] kz = ks.split("\\s*,\\s*");
// 填充外键
Iterator it2 = subValues2.iterator();
while (it2.hasNext()) {
Map subValues3 = (Map) it2.next();
subValues3.put(foreignKey, id);
}
updateMore(tb, subValues2, kz, wh, id);
} else {
// 先删除旧数据
tb.remove("`" + foreignKey + "`=?", id);
// 再插入新数据
Iterator it2 = subValues2.iterator();
while (it2.hasNext()) {
Map subValues3 = (Map) it2.next();
subValues3.put(foreignKey, id);
// 如果存在主键而没给定主键值,则帮其添加上唯一ID
if (tb.primaryKey != null && tb.primaryKey.length() != 0 && !subValues3.containsKey(tb.primaryKey)) {
subValues3.put(tb.primaryKey, Core.newIdentity());
}
tb.insert(subValues3);
}
}
}
}
use of io.github.ihongs.db.Table in project HongsCORE by ihongs.
the class Cmdrun method exec.
@Cmdlet("__main__")
public static void exec(String[] args) throws HongsException {
Map opts = CmdletHelper.getOpts(args, "from=s", "to=s", "sync:b", "del-tables:b", "del-fields:b");
String fr = (String) opts.get("from");
String to = (String) opts.get("to");
boolean sc = (boolean) opts.get("sync");
boolean dt = (boolean) opts.get("del-tables");
boolean df = (boolean) opts.get("del-fields");
Pattern patt = Pattern.compile("\\.\\w+$");
Matcher frMt = patt.matcher(fr);
Matcher toMt = patt.matcher(to);
if (frMt.find() && toMt.find()) {
DB frDb = DB.getInstance(fr.substring(0, frMt.start()));
Table frTb = frDb.getTable(fr.substring(frMt.start() + 1));
DB toDb = DB.getInstance(to.substring(0, toMt.start()));
Table toTb = toDb.getTable(to.substring(toMt.start() + 1));
if (sc) {
new TableDeff(frTb).syncSlaver(toTb, df);
} else {
new TableDeff(frTb).deffSlaver(toTb, df);
}
} else {
DB frDb = DB.getInstance(fr);
DB toDb = DB.getInstance(fr);
if (sc) {
new DBDeff(frDb).syncSlaver(toDb, null, null, dt, df);
} else {
new DBDeff(frDb).deffSlaver(toDb, null, null, dt, df);
}
}
}
use of io.github.ihongs.db.Table in project HongsCORE by ihongs.
the class DBDeff method deffSlaver.
public List<String> deffSlaver(DB slaver, String tablePrefix, String tableSuffix, boolean delExtraTables, boolean delExtraFields) throws HongsException {
List<String> sqls = new ArrayList();
List<String> sqlz;
String sql;
Set tables = new HashSet();
if (delExtraTables) {
List rows = slaver.fetchAll("SHOW TABLES");
Iterator it = rows.iterator();
while (it.hasNext()) {
Map.Entry et = (Map.Entry) ((Map) it.next()).entrySet().iterator().next();
String table = (String) et.getValue();
tables.add(table);
}
}
Set<String> tns = this.db.getTableNames();
for (String tab : tns) {
Table table = this.db.getTable(tab);
Map config = new HashMap();
config.put("name", table.name);
if (tablePrefix != null)
config.put("tablePrefix", tablePrefix);
if (tableSuffix != null)
config.put("tableSuffix", tableSuffix);
Table tablz = new Table(slaver, config);
TableDeff sync = new TableDeff(table);
sqlz = sync.deffSlaver(tablz, delExtraFields);
sqls.addAll(sqlz);
if (delExtraTables) {
tables.remove(tablz.tableName);
}
}
if (delExtraTables) {
Iterator it2 = tables.iterator();
while (it2.hasNext()) {
String table = (String) it2.next();
sql = "DROP TABLE '" + table + "'";
sqls.add(sql);
}
}
return sqls;
}
Aggregations