use of io.github.ihongs.HongsException in project HongsCORE by ihongs.
the class Link method prepareStatement.
/**
* 查询辅助 *
*/
/**
* 预编译Statement并设置查询选项
* <p>可使用cacheStatement开启缓存</p>
* @param sql
* @param params
* @return PreparedStatement对象
* @throws HongsException
*/
public PreparedStatement prepareStatement(String sql, Object... params) throws HongsException {
/**
* 检查SQL语句及Params
* 以发现里面的Set对象
*/
List paramz = new ArrayList(Arrays.asList(params));
StringBuilder sb = new StringBuilder(sql);
checkSQLParams(sb, paramz);
sql = sb.toString();
PreparedStatement ps = this.prepareStatement(sql);
/**
* 遍历params以执行PreparedStatement.setObject
* 如果开启字符串模式, 则参数均以字符串形式绑定
*/
try {
int i = 0;
for (Object x : paramz) {
ps.setObject(++i, x);
}
} catch (SQLException ex) {
throw new HongsException(1042, ex);
}
return ps;
}
use of io.github.ihongs.HongsException 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.HongsException 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.HongsException 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.HongsException in project HongsCORE by ihongs.
the class FetchCase method toString.
// ** 对象 **/
/**
* 转换为字符串
* @return 合并了SQL/参数
*/
@Override
public String toString() {
StringBuilder sb = this.getSQLStrs();
List paramz = this.getParamsList();
try {
Link.checkSQLParams(sb, paramz);
Link.mergeSQLParams(sb, paramz);
} catch (HongsException ex) {
throw new Error(ex);
}
return sb.toString();
}
Aggregations