This commit is contained in:
2019-03-07 10:24:29 +08:00
parent 6c8c683c31
commit e057d613b9
215 changed files with 70917 additions and 118 deletions

View File

@@ -0,0 +1,78 @@
package net.tccn.base;
import org.redkale.convert.json.JsonConvert;
/**
* Created by liangxianyou at 2018/7/30 16:51.
*/
public class JBean {
private int code;
private String message;
private Object body;
private long timestamp;
public static JBean by(int code, String message){
JBean jBean = new JBean();
jBean.code = code;
jBean.message = message;
jBean.timestamp = System.currentTimeMillis();
return jBean;
}
public static JBean by(int code, String message, Object result){
JBean jBean = new JBean();
jBean.code = code;
jBean.message = message;
jBean.body = result;
jBean.timestamp = System.currentTimeMillis();
return jBean;
}
public JBean set(int code, String message){
this.code = code;
this.message = message;
return this;
}
public JBean set(int code, String message, Object result){
this.code = code;
this.message = message;
this.body = result;
this.timestamp = System.currentTimeMillis();
return this;
}
public JBean setCode(int code) {
this.code = code;
return this;
}
public JBean setMessage(String message) {
this.message = message;
return this;
}
public JBean setBody(Object body) {
this.body = body;
return this;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public Object getBody() {
return body;
}
public long getTimestamp() {
return timestamp;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -0,0 +1,156 @@
package net.tccn.base;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* Created by liangxianyou@eversec.cn at 2018/3/12 14:17.
*/
public class Kv<K,V> extends LinkedHashMap {
public static Kv of(){
return new Kv();
}
public static Kv of(Object k, Object v){
return new Kv().set(k,v);
}
public Kv<K, V> set(K k, V v){
put(k, v);
return this;
}
public static Kv toKv(Object m) {
return toKv(m, Kv.of(), m.getClass());
}
private static Kv toKv(Object m, Kv kv, Class clazz) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
if (!kv.containsKey(field.getName())) {
kv.set(field.getName(), field.get(m));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
Class superclass = clazz.getSuperclass();
if (superclass != null) {
kv = toKv(m, kv, superclass);
}
return kv;
}
public <T> T toBean(Class<T> type) {
return (T) toBean(this, type);
}
// 首字母大写
private static Function<String, String> upFirst = (s) -> {
return s.substring(0, 1).toUpperCase() + s.substring(1);
};
private static Map<Class, Class[]> clazzMap = new HashMap<>();
static {
clazzMap.put(ArrayList.class, new Class[]{List.class, ArrayList.class, String.class});
clazzMap.put(HashMap.class, new Class[]{Map.class, HashMap.class, String.class});
clazzMap.put(Long.class, new Class[]{Long.class, Integer.class, long.class, int.class, short.class, String.class});
clazzMap.put(String.class, new Class[]{String.class, Integer.class, Date.class});
clazzMap.put(Double.class, new Class[]{Double.class, Long.class, Integer.class, long.class, int.class, short.class, String.class});
}
private static Predicate<Class> isNumber = (t) -> {
return t == Integer.class || t == int.class
|| t == Long.class || t == long.class
|| t == Double.class || t == double.class
;
};
public static <T> T toBean(Map<String, Object> m, Class<T> type) {
try {
Object obj = type.newInstance();
m.forEach((k, v) -> {
String methodName = "set" + upFirst.apply(k);
Method method = null;
Class[] clazzs = clazzMap.get(v == null ? null : v.getClass());
if (clazzs == null) {
//doc.set(k, v);
} else {
for (Class clazz : clazzs) {
try {
method = type.getDeclaredMethod(methodName, clazz);
} catch (NoSuchMethodException e) {
}
if (method != null) {
try {
if (v == null || "".equals(v)) {
} else if (v.getClass() == Long.class && clazz != Long.class) {//多种数值类型的处理
Object _v;
switch (clazz.getSimpleName()) {
case "int":
case "Long": _v = v; break;
case "Integer": _v = (int)((long) v); break;
case "short":
case "Short": _v = (short)((long) v); break;
default: _v = v;
}
method.invoke(obj, _v);
} else if (v.getClass() == Double.class) {
Object _v = null;
if (isNumber.test(clazz)) {
switch (clazz.getSimpleName()) {
case "long":
case "Long": _v = (long)(double) v; break;
case "int":
case "Integer": _v = (int)((double) v); break;
case "short":
case "Short": _v = (int)(double) v; break;
default: _v = v;
}
} else if (clazz == String.class){
_v = String.valueOf(v);
}
method.invoke(obj, _v);
} else if (v.getClass() == String.class && clazz == Date.class) {
Date _v = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) v);
method.invoke(obj, _v);
} else if (v.getClass() == String.class && clazz == Integer.class) {
Object _v = (int)Double.parseDouble((String) v);
method.invoke(obj, _v);
}
else {
method.invoke(obj, v);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
break;
}
}
}
});
return (T) obj;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,39 @@
package net.tccn.base;
import java.util.List;
/**
* Created by JUECHENG at 2018/5/7 11:20.
*/
public class PageBean<M> {
private List<M> rows;
private long total;
public static PageBean by(List rows, long total) {
return new PageBean(rows, total);
}
public PageBean() {
}
public PageBean(List<M> rows, long total) {
this.rows = rows;
this.total = total;
}
public List<M> getRows() {
return rows;
}
public void setRows(List<M> rows) {
this.rows = rows;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
}

View File

@@ -0,0 +1,290 @@
package net.tccn.base.arango;
import com.arangodb.*;
import com.arangodb.entity.DocumentCreateEntity;
import com.arangodb.entity.DocumentDeleteEntity;
import com.arangodb.entity.MultiDocumentEntity;
import javax.persistence.Table;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.Arrays.asList;
/**
* 管理 数据源连接对象
* @author: liangxianyou at 2018/12/15 11:35.
*/
public class ArangoSource {
public Logger logger = Logger.getLogger(this.getClass().getSimpleName());
private ArangoDB arangoDb;
private static Map<String, ArangoSource> sources = new HashMap();
static {
init();
}
public static void init() {
sources.put("main", new ArangoSource(new ArangoDB.Builder().host("120.24.230.60", 8529).user("root").password("abc123").build()));
sources.put("abc", new ArangoSource(new ArangoDB.Builder().host("192.168.199.135", 8529).user("root").password("root").build()));
}
public ArangoSource(ArangoDB arangoDb) {
this.arangoDb = arangoDb;
}
public static ArangoSource use() {
return use("main");
}
public static ArangoSource use(String unit) {
if (unit == null || unit.isEmpty()) {
unit = "main";
}
return sources.get(unit);
}
public ArangoDB arangoDB() {
return arangoDb;
}
public ArangoDatabase db(String db) {
return arangoDb.db(db);
}
public <T extends Doc> ArangoCollection collection(Doc<T> doc) {
return collection(doc.getClass());
}
public <T extends Doc> ArangoCollection collection(Class<T> type) {
Table table = type.getAnnotation(Table.class);
//createDb(table.catalog());
return arangoDb.db(table.catalog()).collection(table.name());
}
public boolean createDb(String db) {
ArangoDatabase database = arangoDb.db(db);
if (!database.exists()) {
return database.create();
}
logger.log(Level.INFO, "arango database exists");
return true;
}
public <T extends Doc> ArangoCollection createDocument(Doc<T> doc) {
Class<? extends Doc> type = doc.getClass();
Table table = type.getAnnotation(Table.class);
ArangoDatabase database = arangoDb.db(table.catalog());
if (!database.exists()) {
database.create();
}
ArangoCollection collection = database.collection(table.name());
if (!collection.exists()) {
collection.create();
}
return collection;
}
// 首字母大写
private static Function<String, String> upFirst = (s) -> {
return s.substring(0, 1).toUpperCase() + s.substring(1);
};
private static Map<Class, Class[]> clazzMap = new HashMap<>();
static {
clazzMap.put(ArrayList.class, new Class[]{List.class, ArrayList.class, String.class});
clazzMap.put(HashMap.class, new Class[]{Map.class, HashMap.class, String.class});
clazzMap.put(Long.class, new Class[]{Long.class, Integer.class, long.class, int.class, short.class, String.class});
clazzMap.put(String.class, new Class[]{String.class});
}
/**
* 还原 Doc对象
* @param map
* @param type
* @param <T>
* @return
*/
public <T extends Doc> T toDoc1(Map<String, Object> map, Class<T> type) {
try {
Doc doc = type.newInstance();
map.forEach((k, v) -> {
String methodName = "set" + upFirst.apply(k);
Method method = null;
Class[] clazzs = clazzMap.get(v == null ? null : v.getClass());
if (clazzs == null) {
doc.set(k, v);
} else {
for (Class clazz : clazzs) {
try {
method = type.getDeclaredMethod(methodName, clazz);
} catch (NoSuchMethodException e) {
}
if (method != null) {
try {
if (v.getClass() == Long.class && clazz != Long.class) {//多种数值类型的处理
Object _v;
switch (clazz.getSimpleName()) {
case "int":
case "Integer": _v = (int)((long) v); break;
case "short":
case "Short": _v = (short)((long) v); break;
default: _v = v;
}
System.out.println(clazz.getSimpleName());
method.invoke(doc, _v);
} else {
method.invoke(doc, v);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
doc.set(k, v);
} catch (InvocationTargetException e) {
e.printStackTrace();
doc.set(k, v);
}
break;
}
}
}
if (method == null) {
doc.set(k, v);
}
});
return (T) doc;
} catch (Exception e) {
}
return null;
}
private Predicate isEmpty = (x) -> {
if (x == null)
return true;
if (x instanceof List)
return ((List) x).isEmpty();
if (x instanceof String)
return ((String) x).isEmpty();
if (x instanceof Map)
return ((Map) x).isEmpty();
if (x instanceof Collection)
return ((Collection) x).isEmpty();
return false;
};
/**
* Doc 转为查询对象
* @param t
* @param <T>
* @return
*/
private Function<Doc, StringBuilder> filterBuilder = (t) -> {
Table table = t.getClass().getAnnotation(Table.class);
StringBuilder buf = new StringBuilder();
buf.append("for d in ").append(table.name());
buf.append(" filter 1==1");
t.toDoc().forEach((k, v) -> {
if (v != null && (v.getClass() == String.class || v instanceof Number)) {
buf.append(" and d.").append(k).append("==");
}
if (v.getClass() == String.class) {
buf.append("'").append(v).append("'");
} else if (v instanceof Number) {
buf.append(v);
}
});
return buf;
};
private Function<Doc, StringBuilder> orderBuilder = (t) -> {
StringBuilder buf = new StringBuilder();
Map<String, Integer> order = t.getOrder();
if (isEmpty.test(order)) {
return buf;
}
buf.append(" sort ");
order.forEach((k, v) -> {
buf.append("d.").append(k).append(v == 1 ? " desc," : " asc,");
});
buf.deleteCharAt(buf.length() - 1);
return buf;
};
private Function<Doc, StringBuilder> returnBuilder = (t) -> {
StringBuilder buf = new StringBuilder();
if (isEmpty.test(t.get_Shows())) {
return buf.append(" return d");
}
buf.append(" return {");
t.get_Shows().forEach(x -> {
buf.append(x).append(":d.").append(x).append(",");
});
buf.deleteCharAt(buf.length() - 1).append("}");
return buf;
};
public <T extends Doc> String parseAqlCount(T t) {
StringBuilder buf = new StringBuilder();
buf.append(filterBuilder.apply(t));
buf.append(" COLLECT WITH COUNT INTO total");
buf.append(" return total");
//logger.log(Level.INFO, buf.toString());
return buf.toString();
}
public <T extends Doc> String parseAql(T t, int offset, int ps) {
if (offset < 0) offset = 0;
if (ps <= 0) ps = 1000;
StringBuilder buf = new StringBuilder();
buf.append(filterBuilder.apply(t));
buf.append(orderBuilder.apply(t));
buf.append(" limit ").append(offset).append(",").append(ps);
buf.append(returnBuilder.apply(t));
//logger.log(Level.INFO, buf.toString());
return buf.toString();
}
//----------------------------------------
//ok
public <T extends Doc> T save(T doc) {
DocumentCreateEntity<Map> tmap = collection(doc).insertDocument(doc.toDoc());
doc.setKey(tmap.getKey());
doc.setId(tmap.getId());
return doc;
}
//ok
public <T extends Doc> void update(T doc) {
collection(doc).updateDocument(doc.getKey(), doc.toDoc());
}
//ok
public <T extends Doc> T getDoc(Object key, Class<T> type) {
return collection(type).getDocument(String.valueOf(key), type);
}
//ok
public <T extends Doc> DocumentDeleteEntity<Void> delete(String key, Class<T> type) {
return collection(type).deleteDocument(key);
}
//ok
public <T extends Doc> MultiDocumentEntity<DocumentDeleteEntity<Void>> deleteAll(Doc<T> ... docs) {
return collection(docs[0]).deleteDocuments(asList(docs));
}
public <T extends Doc> MultiDocumentEntity find(Collection keys, Class<T> type) {
return collection(type).getDocuments(keys, type);
}
}

View File

@@ -0,0 +1,251 @@
package net.tccn.base.arango;
import com.arangodb.ArangoCollection;
import com.arangodb.ArangoDBException;
import com.arangodb.ArangoDatabase;
import com.arangodb.entity.DocumentCreateEntity;
import javax.persistence.Table;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
/**
* @author: liangxianyou at 2018/12/1 22:59.
*/
public abstract class Doc<T extends Doc> {
private HashMap attr = new HashMap();
private String _id;
private String _key;
private Set<String> _shows;
private Map _order;
public String getId() {
return _id;
}
public void setId(String id) {
this._id = id;
}
public String getKey() {
return _key;
}
public void setKey(String key) {
this._key = key;
}
public Doc<T> set(String k, Object v) {
attr.put(k, v);
return this;
}
public <V> V get(String k) {
return (V)attr.get(k);
}
public T setShows(String... show) {
if (_shows == null) {
_shows = new HashSet<>();
}
for (String s : show) {
_shows.add(s);
}
return (T) this;
}
public Set<String> get_Shows() {
return _shows;
}
public void set_Shows(Set<String> shows) {
this._shows = shows;
}
public T setOrder(String col, int desc) {
if (_order == null) {
_order = new LinkedHashMap();
}
_order.put(col, desc);
return (T) this;
}
public Map<String, Integer> getOrder() {
return _order;
}
/*public void setOrder(Map order) {
this._order = order;
}*/
/*@Override
public String toString() {
//convert.
String doc = convert.convertTo(this);
if (attr.size() == 0) {
return doc;
}
StringBuilder builder = new StringBuilder();
if (attr.size() != 0) {
String attrStr = convert.convertTo(attr);
builder.append("{");
builder.append(attrStr, 1, attrStr.length() - 1);
builder.append(",");
builder.append(doc, 1, doc.length()); //builder.append(doc.substring(1));
}
return builder.toString();
}*/
private Function<String, String> fieldName = (s) -> {
return s.replace("get", "").substring(0, 1).toLowerCase() + s.substring(4);
};
/**
* 提取Doc 属性到 Map用于存贮到Arango中
* 提取规则:
* 1、将doc中自带非空 !=null 属性提取都map中
* 2、将attr中属性覆盖到map中如果attr中存在同名属性attr为主
* @return
*/
public Map toDoc() {
HashMap clone = (HashMap) attr.clone();
Class<? extends Doc> type = this.getClass();
Method[] methods = type.getDeclaredMethods();
for (Method method : methods) {
String name = method.getName();
if (name.startsWith("get") && method.getParameterCount() == 0) {
//Type mt = method.getAnnotatedReturnType().getType();
try {
//System.out.println(method.getName());
Object v = method.invoke(this);
if (v != null) {
clone.put(fieldName.apply(name), v);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return clone;
}
//---------------------------------------------------------------------------------------------------
private ArangoSource arangoSource;
private ArangoDatabase db;
private ArangoCollection collection;
private static ConcurrentHashMap<Class, Doc> daos = new ConcurrentHashMap();
public Doc() {
Table table = this.getClass().getAnnotation(Table.class);
String sourceName = null;
Source source = this.getClass().getAnnotation(Source.class);
if (source != null) {
sourceName = source.name();
}
arangoSource = ArangoSource.use(sourceName);
this.db = arangoSource.db(table.catalog());
this.collection = arangoSource.collection(this);
}
public final static <T extends Doc> T dao(Class<T> type) {
if (daos.get(type) == null) {
try {
daos.put(type, type.newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return (T) daos.get(type);
}
//ok
public T save() {
DocumentCreateEntity<Map> tmap = collection.insertDocument(this.toDoc());
this.setId(tmap.getId());
this.setKey(tmap.getKey());
return (T) this;
}
//ok
public void update() {
collection.updateDocument(this.getKey(), this.toDoc());
}
public T findFirst(T t) {
return findFirst(arangoSource.parseAql(t, 0, 1), (Class<T>) t.getClass());
}
public List<T> find() {
return find((T) this, 0, 1000);
}
public List<T> find(T t) {
return find(t, 0, 1000);
}
public <T extends Doc> List<T> find(T t, int offset, int pn) {
return find(arangoSource.parseAql(t, offset, pn), (Class<T>)this.getClass());
}
public <T> List<T> find(String aql, Class<T> clazz) {
try {
return db.query(aql, clazz).asListRemaining();
} catch (ArangoDBException e) {
System.out.println(aql);
e.printStackTrace();
ArangoSource.init();
}
return db.query(aql, clazz).asListRemaining();
}
public <T> T findFirst(String aql, Class<T> clazz) {
try {
return db.query(aql, clazz).first();
} catch (ArangoDBException e) {
System.out.println(aql);
e.printStackTrace();
ArangoSource.init();
}
return db.query(aql, clazz).first();
}
public long count() {
return count(this);
}
public <T extends Doc> long count(T t) {
return db.query(arangoSource.parseAqlCount(t), long.class).first();
}
//ok
public <T extends Doc> T findByKey(Object key) {
return (T) collection.getDocument(String.valueOf(key), this.getClass());
}
//ok
public void delete() {
collection.deleteDocument(getKey());
}
public void delete(Collection<String> key) {
collection.deleteDocuments(key);
}
}

View File

@@ -0,0 +1,15 @@
package net.tccn.base.arango;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author: liangxianyou at 2018/12/22 0:32.
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Source {
String name() default "";
}

View File

@@ -0,0 +1,98 @@
package net.tccn.dbq;
import net.tccn.base.arango.Doc;
import net.tccn.dbq.jdbc.JdbcAccount;
import org.redkale.convert.json.JsonConvert;
import javax.persistence.Table;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
* 数据库平台
* @author: liangxianyou at 2018/11/14 12:58.
*/
@Table(name = "db_plat", catalog = "db_dev")
public class DbPlat extends Doc<DbPlat> {
public static DbPlat dao = dao(DbPlat.class);
private String name; //名称
private String cate; //类型 mysql|ArangoDb
private String remark; //备注
private String url; //数据库连接地址
private String user; //账号
private String pwd; //密码
private List<String> catalogs; //库
private JdbcAccount jdbcAccount;
//------------- setter/getter ---------------
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCate() {
return cate;
}
public void setCate(String cate) {
this.cate = cate;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public List<String> getCatalogs() {
return catalogs;
}
public void setCatalogs(List<String> catalogs) {
this.catalogs = catalogs;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
//-------------------------------------------------------------------------
protected Connection connection() throws SQLException {
if (jdbcAccount == null) {
jdbcAccount = new JdbcAccount(url, user, pwd);
}
return jdbcAccount.getConnection();
}
}

View File

@@ -0,0 +1,99 @@
package net.tccn.dbq;
/**
* @author: liangxianyou at 2018/10/17 17:24.
*/
public class Field {
private String name;
private String label;
private String remark;
private String type;
private String inType;
private String inExt;
//============== getter/setter =============
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getInType() {
return inType;
}
public void setInType(String inType) {
this.inType = inType;
}
public String getInExt() {
return inExt;
}
public void setInExt(String inExt) {
this.inExt = inExt;
}
//------------------------------------
public enum InType {
SELECT_EXT("select_ext"),
INPUT_DT("input_dt");
String name;
InType(String name) {
this.name = name;
}
}
public enum QueryType {
}
public String showField() {
if (InType.SELECT_EXT.name.equalsIgnoreCase(inType)) {
return name + "|" + inExt;
} else if (InType.INPUT_DT.name.equalsIgnoreCase(inType)) {
return name + "=dt";
}
return name;
}
public boolean isDict() {
return InType.SELECT_EXT.name.equalsIgnoreCase(inType);
}
@Override
public boolean equals(Object name) {
return (this.name == null && name == null) || this.name.equals(name);
}
}

View File

@@ -0,0 +1,8 @@
package net.tccn.dbq.fbean;
/**
* Created by liangxianyou at 2018/12/14 15:34.
*/ //数据库类型
public enum DbType {
MYSQL, ARANGODB
}

View File

@@ -0,0 +1,73 @@
package net.tccn.dbq.fbean;
import java.util.List;
/**
* 查询用实体
* @author: liangxianyou at 2018/10/25 14:49.
*/
public class FBean {
private String name;
private List<Filter> filters;//[{f:xx, v: v, type:t}] -- t,
private List<Order> orders;//{f1: 1, f2: -1}
private Limit limit;//{pn: 1, ps: 10}
//---------- getter/setter ------------
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Filter> getFilters() {
return filters;
}
public void setFilters(List<Filter> filters) {
this.filters = filters;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
public Limit getLimit() {
return limit;
}
public void setLimit(Limit limit) {
this.limit = limit;
}
//-----------------------------------
//组装查询sql[list, count]
public String[] buildSqlFilter() {
//where 1=1 and x=1 and y=1 order by x,y limit 1,3;
String where = Filter.filter(filters);
String order = Order.order(orders, DbType.MYSQL);
if (limit == null) {
limit = new Limit();
}
String limit = this.limit.limit();
String list = where + order + limit;
String count = where;
return new String[]{list, count};
}
public void setLimit(int pn, int ps) {
limit.setPn(pn);
limit.setPs(ps);
}
}

View File

@@ -0,0 +1,89 @@
package net.tccn.dbq.fbean;
import java.util.List;
/**
* 查询条件实体
* Created by liangxianyou at 2018/12/14 15:34.
*/
public class Filter {
private String col;
private String value;
private String type;
public static Filter by(String col, Object value) {
return by(col, "==", value + "");//todo: == 不是mysql 语法,不具备通用性
}
public static Filter by(String col, String type, String value) {
Filter filter = new Filter();
filter.setCol(col);
filter.setType(type);
filter.setValue(value);
return filter;
}
//mysql 查询组装
public static String filter(List<Filter> filters) {
if (filters == null || filters.size() == 0) {
return "";
}
StringBuilder buf = new StringBuilder();
buf.append(" where 1=1");
filters.forEach(x -> {
buf.append(FilterType.buildSql(x));
});
return buf.toString();
}
public static String filter(List<Filter> filters, DbType dbType) {
if (DbType.MYSQL == dbType) {
return filter(filters);
} else if (DbType.ARANGODB == dbType) {
StringBuilder buf = new StringBuilder();
buf.append(" filter 1==1");
if (filters == null || filters.size() == 0) {
return "";
}
filters.forEach(x -> {
buf.append(" and d.").append(x.col).append(" " + (x.type == null ? "==" : x.type) + " ");
//处理数值型字段查询
if ("sysPlatId".equals(x.col) || "platId".equals(x.col) || "status".equals(x.col) || false) {
buf.append(x.value);
} else {
buf.append("'" + x.value + "'");
}
});
return buf.toString();
}
return "";
}
//---------- getter/setter ------------
public String getCol() {
return col;
}
public void setCol(String col) {
this.col = col;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@@ -0,0 +1,81 @@
package net.tccn.dbq.fbean;
import net.tccn.base.Kv;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/14 15:34.
*/
public enum FilterType {
EQUAL("=", "等于"),
NOTEQUAL("!=", "不等于"),
GREATERTHANOREQUALTO(">=", ">="),
LESSTHAN("<", "小于"),
LIKE("LIKE", "LIKE"),
IN("IN", "包含");
private String expre;
private String remark;
FilterType(String expre, String remark) {
this.expre = expre;
this.remark = remark;
}
//不同的条件构建过滤语句
public static String buildSql(Filter filter) {
if (filter.getValue() == null || filter.getValue().length() == 0) {
return "";
}
FilterType filterType = getFilterType(filter.getType());
if (filterType == null) {
return "";
}
String _sql;
switch (filterType) {
case IN:
_sql = String.format(" AND `%s` IN (%s)", filter.getCol(), filter.getValue());
break;
case LIKE:
_sql = String.format(" AND `%s` LIKE '%s'", filter.getCol(), "%" + filter.getValue() + "%");
break;
default:
_sql = String.format(" AND `%s` %s '%s'", filter.getCol(), filterType.expre, filter.getValue());
break;
}
return _sql;
}
public static FilterType getFilterType(String name) {
for (FilterType t : FilterType.values()) {
if (t.name().equalsIgnoreCase(name)) {
return t;
}
}
return null;
}
//获取所有的查询类型
public static List<Map> getAllTypes() {
List<Map> list = new ArrayList<>();
for (FilterType type : FilterType.values()) {
Kv kv = Kv.of("name", type.name())/*.set("expre", type.expre)*/.set("remark", type.remark);
list.add(kv);
}
return list;
}
public String getExpre() {
return expre;
}
public String getRemark() {
return remark;
}}

View File

@@ -0,0 +1,44 @@
package net.tccn.dbq.fbean;
/**
* Created by liangxianyou at 2018/12/14 15:36.
*/
public class Limit {
private int pn;
private int ps;
public Limit() {
}
public Limit(int pn, int ps) {
this.pn = pn;
this.ps = ps;
}
public String limit() {
if (pn < 1) {
pn = 1;
}
if (ps < 1) {
ps = 10;
}
return String.format(" LIMIT %s, %s", (pn - 1) * ps, ps);
}
//---- getter/setter -----
public int getPn() {
return pn;
}
public void setPn(int pn) {
this.pn = pn;
}
public int getPs() {
return ps;
}
public void setPs(int ps) {
this.ps = ps;
}
}

View File

@@ -0,0 +1,58 @@
package net.tccn.dbq.fbean;
import java.util.List;
/**
* Created by liangxianyou at 2018/12/14 15:36.
*/
public class Order {
private String col;
private int desc;//1 or -1
public Order() {
}
public Order(String col, int desc) {
this.col = col;
this.desc = desc;
}
public static String order(List<Order> orders, DbType dbType) {
if (orders == null || orders.size() == 0) {
return "";
}
StringBuilder buf = new StringBuilder();
switch (dbType) {
case MYSQL:
buf.append(" ORDER BY");
orders.forEach(x -> {
buf.append(String.format(" %s %s,", x.col, (x.desc == 1 ? "desc" : "asc")));
});
buf.deleteCharAt(buf.length() - 1);
break;
case ARANGODB:
// 待实现
break;
}
return buf.toString();
}
//--- getter/setter ---
public String getCol() {
return col;
}
public void setCol(String col) {
this.col = col;
}
public int getDesc() {
return desc;
}
public void setDesc(int desc) {
this.desc = desc;
}
}

View File

@@ -0,0 +1,29 @@
package net.tccn.dbq.fbean;
import net.tccn.meta.MetaService;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/24 15:49.
*/
public class ParseArango implements Parser {
@Override
public String parse(FBean fBean) {
return null;
}
@Override
public String parse(Filter filter) {
return null;
}
@Override
public String parseSave(MetaService ms, Map data) {
return "";
}
}

View File

@@ -0,0 +1,26 @@
package net.tccn.dbq.fbean;
import net.tccn.meta.MetaService;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/24 15:49.
*/
public class ParseEs implements Parser {
@Override
public String parse(FBean fBean) {
return null;
}
@Override
public String parse(Filter filter) {
return null;
}
@Override
public String parseSave(MetaService ms, Map data) {
return "";
}
}

View File

@@ -0,0 +1,118 @@
package net.tccn.dbq.fbean;
import net.tccn.meta.MetaKit;
import net.tccn.meta.MetaLink;
import net.tccn.meta.MetaService;
import net.tccn.meta.MetaTable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
/**
* Created by liangxianyou at 2018/12/24 15:49.
*/
public class ParseMysql implements Parser {
private Predicate isEmpty = (x) -> {
if (x == null)
return true;
if (x instanceof List)
return ((List) x).isEmpty();
if (x instanceof String)
return ((String) x).isEmpty();
if (x instanceof Map)
return ((Map) x).isEmpty();
if (x instanceof Collection)
return ((Collection) x).isEmpty();
return false;
};
@Override
public String parse(FBean fBean) {
MetaService metaService = MetaKit.metaService(fBean.getName());
//基础属性
MetaTable metaTable = metaService.getMetaTable();//基础元数据
List<MetaLink> linkTables = metaService.getMetaLinks();//表关联条件
Map<String, MetaTable> attachTable = metaService.getTables();//用到的关联表
List<String> shows = metaService.getShows();//查询的属性
//查询条件
List<Filter> filters = fBean.getFilters();
Limit limit = fBean.getLimit();
List<Order> orders = fBean.getOrders();
StringBuilder buf = new StringBuilder();
//select
buf.append("select ");
if (!isEmpty.test(shows)) {
shows.forEach(x -> {
//buf.append("`").append("x").append("`").append(",");
buf.append(x).append(",");
});
buf.deleteCharAt(buf.length() - 1);
} else {
buf.append("*");
}
//from
buf.append(" from ").append("`").append(metaTable.getName()).append("` ").append(metaTable.getAlias());
//left join
if (!isEmpty.test(linkTables)) {
linkTables.forEach(x -> {
MetaTable leftTable = attachTable.get(metaTable.getAlias().equals(x.getTables()[0]) ? x.getTables()[1] : x.getTables()[0]);
buf.append(" left join ").append(leftTable.getName()).append(" ").append(leftTable.getAlias()).append(" on ");
int tag = buf.length();
x.getLink().forEach((k,v) -> {
if (buf.length() > tag) {
buf.append(" and ");
}
buf.append(k).append("=").append(v);
});
});
}
//where
if (!isEmpty.test(filters)) {
buf.append(Filter.filter(filters, DbType.MYSQL));
}
//order by
if (!isEmpty.test(orders)) {
buf.append(" ").append(Order.order(orders, DbType.MYSQL));
}
//limit
buf.append(" ").append(limit.limit());
return buf.toString();
}
@Override
public String parse(Filter filter) {
return null;
}
@Override
public String parseSave(MetaService ms, Map data) {
String sqlTpl = "insert %s (%s) value (%s)";
StringBuilder bufK = new StringBuilder();
StringBuilder bufV = new StringBuilder();
data.forEach((k,v) -> {
if (v != null || !String.valueOf(v).isEmpty()) {
bufK.append("`").append(k).append("`,");
if (v instanceof Number) {
bufV.append(v).append(",");
} else {
bufV.append("'").append(v).append("',");
}
}
});
bufK.deleteCharAt(bufK.length() - 1);
bufV.deleteCharAt(bufV.length() - 1);
return String.format(sqlTpl, ms.getMetaTable().getName(), bufK.toString(), bufV.toString());
}
}

View File

@@ -0,0 +1,31 @@
package net.tccn.dbq.fbean;
import net.tccn.meta.MetaService;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/24 15:47.
*/
public interface Parser {
/**
* 组装完整的查询条件
* @param fBean
*/
String parse(FBean fBean);
/**
* 解析一个查询条件
* @param filter
*/
String parse(Filter filter);
/**
* 解析入库语句
* @param data
* @return
*/
String parseSave(MetaService ms, Map data);
}

View File

@@ -0,0 +1,55 @@
package net.tccn.dbq.jdbc;
/**
* 数据库表的列
* @author: liangxianyou at 2018/10/8 10:59.
*/
public class Column {
private String name; //列名称
private String type; //列类型
private boolean notNull; //不为null
private String comment; //列说明
public Column() {
}
public Column(String name, String type, boolean notNull, String comment) {
this.name = name;
this.type = type;
this.notNull = notNull;
this.comment = comment;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean getNotNull() {
return notNull;
}
public void setNotNull(boolean notNull) {
this.notNull = notNull;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}

View File

@@ -0,0 +1,72 @@
package net.tccn.dbq.jdbc;
import java.sql.Connection;
/**
* @author: liangxianyou at 2018/10/11 17:47.
*/
public class JdbcAccount {
private String url;
private String user;
private String pwd;
private Integer connectMax = 5;//默认最大连接数5
public JdbcAccount() {
}
public JdbcAccount(String url, String user, String pwd) {
this.url = url;
this.user = user;
this.pwd = pwd;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public Integer getConnectMax() {
return connectMax;
}
public void setConnectMax(Integer connectMax) {
this.connectMax = connectMax;
}
//-------------------------------------------------------
public String parse() {
int start = url.indexOf("//") + 2;
int end = url.indexOf("/", start);
int endDef = url.indexOf("?", end);
if (endDef == -1) {
endDef = url.length();
}
String host = url.substring(start, end == -1 ? url.length() : end);
return user + "@" + host;
}
public Connection getConnection() {
return null;
}
}

View File

@@ -0,0 +1,151 @@
package net.tccn.dbq.jdbc;
import org.redkale.util.Comment;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
/**
* JdbcService.
*
* @author: liangxianyou at 2018/10/8 10:39.
*/
public class JdbcService {
private JdbcAccount account;
private static ConcurrentHashMap<JdbcAccount, Connection> jdbcPool = new ConcurrentHashMap<>();
public JdbcService(JdbcAccount account) {
this.account = account;
}
//-------------- query -----------------
private <R> List<R> executeQuery(String sql, Map columns, BiFunction<ResultSet, Map, R> fun) throws SQLException {
try (
Connection connection = DriverManager.getConnection(account.getUrl(), account.getUser(), account.getPwd());
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery()) {
List list = new ArrayList();
while (resultSet.next()) {
list.add(fun.apply(resultSet, columns));
}
return list;
}
}
public static List<String> getCatalogs(Connection connection) throws SQLException {
List<String> catalogs = new ArrayList<>();
try (
PreparedStatement ps = connection.prepareStatement("show databases;");
ResultSet rs = ps.executeQuery()
) {
while (rs.next()) {
catalogs.add(rs.getString(1));
}
}
return catalogs;
}
public static Connection getConnection(JdbcAccount account) throws SQLException {
Connection connection = jdbcPool.get(account);
if (connection == null) {
connection = DriverManager.getConnection(account.getUrl(), account.getUser(), account.getPwd());
jdbcPool.put(account, connection);
}
return connection;
}
@Comment("列表数据查询")
public static List<Map> findList(Connection connection, String sql) throws SQLException {
try (
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
List list = new ArrayList();
while (rs.next()) {
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
Map row = new HashMap();
for (int i = 1; i <= count; i++) {
String columnTypeName = metaData.getColumnTypeName(i);
String columnName = metaData.getColumnName(i);
row.put(columnName, null);
if (rs.getObject(i) != null) {
switch (columnTypeName) {
case "DATETIME":
case "TIMESTAMP":
case "DATE":
row.put(columnName, rs.getTimestamp(i).getTime()); break;
default:
row.put(columnName, rs.getObject(i));
}
}
}
list.add(row);
}
return list;
}
}
@Comment("统计总数")
public static int findNumber(Connection connection, String sql) throws SQLException {
try (
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
rs.next();
return rs.getInt(1);
}
}
public static int update(Connection connection, String sql) throws SQLException {
try (
PreparedStatement ps = connection.prepareStatement(sql);
){
return ps.executeUpdate();
}
}
// ---------------- DDL ---------------------
public static boolean createTable(Connection connection, Table table) throws SQLException {
if (table.getCatalog() != null && table.getCatalog().length() > 0) {
connection.setCatalog(table.getCatalog());
}
String tableDdl = table.getTableDdl();
System.out.println(tableDdl);
try (PreparedStatement ps = connection.prepareStatement(tableDdl)) {
return ps.execute();
}
}
public static void main(String[] args) throws SQLException {
String url = "jdbc:mysql://192.168.202.11:3306/gxbii_dev";
String user = "root";
String pwd = "eversec123098";
JdbcAccount account = new JdbcAccount(url, user, pwd);
Connection connection = account.getConnection();
System.out.println(connection);
String sql = "select * from basic_concat";
}
}

View File

@@ -0,0 +1,209 @@
package net.tccn.dbq.jdbc;
import net.tccn.dbq.qtask.Qtask;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
/**
* Created by liangxianyou at 2018/12/21 17:42.
*/
public class JdbcSource {
private JdbcAccount account;
private Queue<Qtask> queue = new LinkedBlockingDeque();
private static ConcurrentHashMap<String, JdbcSource> sources = new ConcurrentHashMap<>();
private List<Connection> connections = new ArrayList<>();
private AtomicInteger connectNum = new AtomicInteger();
private JdbcSource() {
}
public JdbcSource(JdbcAccount account) {
String key = account.parse();
synchronized (sources) {
JdbcSource source = sources.get(key);
if (source == null) {
source = new JdbcSource();
}
source.account = account;
do {
try {
Connection connection = DriverManager.getConnection(account.getUrl(), account.getUser(), account.getPwd());
connections.add(connection);
} catch (SQLException e) {
e.printStackTrace();
break;
}
} while (connectNum.incrementAndGet() < 2);//默认初始化连接数 2
}
}
/**
* 获取连接
* @return
*/
private Connection getConnection() {
synchronized (connections) {
//有闲置连接,直接返回
if (connections.size() > 0) {
return connections.remove(0);
}
//没有闲置连接,总连接数小于最大连接数,创建新连接
if (connectNum.get() < account.getConnectMax()) {
try {
return DriverManager.getConnection(account.getUrl(), account.getUser(), account.getPwd());
} catch (SQLException e) {
e.printStackTrace();
}
}
//已达最大连接,且没有闲置,等待
}
return null;
}
/**
* 释放连接
* @param connection
*/
private void releaseConnection(Connection connection) {
connections.add(connection);
}
/**
* 通过Account 获取连接
* 同一个连接对象同一时刻只能被一个线程所使用,
* 两种方案:
* 1、多个连接对象每次线程得到对应的连接用完返还连接
* 2、一到多个连接每次数据库操作交给执行队列执行并返回执行结果
* @param account
* @return
*/
/*public Connection getConnection(JdbcAccount account) {
String key = account.parse();
List<Connection> conns = sources.get(key);
if (conns == null) {
conns = new ArrayList<>();
}
if (conns.size() == 0) {
try {
Connection connection = DriverManager.getConnection(account.getUrl(), account.getUser(), account.getPwd());
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}*/
private Function<ResultSet, Map> dataToMap = (rs) -> {
Map row = new HashMap();
try {
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
for (int i = 1; i <= count; i++) {
String columnTypeName = metaData.getColumnTypeName(i);
String columnName = metaData.getColumnName(i);
row.put(columnName, null);
if (rs.getObject(i) != null) {
switch (columnTypeName) {
case "DATETIME":
case "TIMESTAMP":
case "DATE":
row.put(columnName, rs.getTimestamp(i).getTime()); break;
default:
row.put(columnName, rs.getObject(i));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return row;
};
private Function<ResultSet, List<Map>> dataToList = (rs) -> {
List list = new ArrayList<>();
try {
while (rs.next()) {
list.add(dataToMap.apply(rs));
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
};
/**
* 通过sql查询 数据,
* 将每次查询任务加入到查询队列
* @param sql
* @return
*/
private Queue<String> finds = new LinkedBlockingQueue<>();
public CompletableFuture<List<Map>> find(String sql) {
return CompletableFuture.supplyAsync(() -> {
List<Map> list = null;
Connection connection = getConnection();
try (
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
) {
list = dataToList.apply(rs);
} catch (SQLException e) {
e.printStackTrace();
}
releaseConnection(connection);
return list;
});
/*
Connection connection = getConnection(null);
try (
PreparedStatement ps = connection.prepareStatement(sql);
) {
} catch (SQLException e) {
e.printStackTrace();
}
return null;
*/
}
private void find(String sql, int cate) {
}
}

View File

@@ -0,0 +1,72 @@
package net.tccn.dbq.jdbc;
import java.util.List;
/**
* 数据库表.
* @author: liangxianyou at 2018/10/8 10:58.
*/
public class Table {
private String catalog; //库名称
private String name; //表名称
private String comment; //表备注
private List<Column> columns; //表的字段列
public Table(String name, String comment) {
this.name = name;
this.comment = comment;
}
//------------ getter/setter -------------
public String getCatalog() {
return catalog;
}
public void setCatalog(String catalog) {
this.catalog = catalog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public List<Column> getColumns() {
return columns;
}
public void setColumns(List<Column> columns) {
this.columns = columns;
}
//------------------------------
//Dev
public String getTableDdl() {
StringBuilder buf = new StringBuilder();
buf.append("CREATE TABLE " + name + "(");
columns.forEach(x -> {
buf.append("\n " + x.getName() + " " + x.getType() + ",");
});
buf.deleteCharAt(buf.length() - 1);
buf.append("\n) COMMENT '" + comment + "';");
return buf.toString();
}
//----------
}

View File

@@ -0,0 +1,105 @@
package net.tccn.dbq.qtask;
import net.tccn.base.arango.Doc;
import javax.persistence.Table;
/**
* @author: liangxianyou at 2018/11/13 14:59.
*/
@Table(name = "qtask", catalog = "db_dev")
public class Qtask extends Doc<Qtask> {
public static Qtask dao = dao(Qtask.class);
private String queryId; //查询id
private String name; //业务名称
private String remark; //说明
private String sql; //SQL
private String para; //默认查询参数
private String cate; //任务类型 find|update
private Integer sysPlatId; //数据平台id
private Integer platId; //数据平台id
private String catalog; //数据库名
private Integer status; //状态 1启用|0未启用|-1删除
//------------- setter/getter ------------------------
public String getQueryId() {
return queryId;
}
public void setQueryId(String queryId) {
this.queryId = queryId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public String getPara() {
return para;
}
public void setPara(String para) {
this.para = para;
}
public String getCate() {
return cate;
}
public void setCate(String cate) {
this.cate = cate;
}
public Integer getSysPlatId() {
return sysPlatId;
}
public void setSysPlatId(Integer sysPlatId) {
this.sysPlatId = sysPlatId;
}
public Integer getPlatId() {
return platId;
}
public void setPlatId(Integer platId) {
this.platId = platId;
}
public String getCatalog() {
return catalog;
}
public void setCatalog(String catalog) {
this.catalog = catalog;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}

View File

@@ -0,0 +1,39 @@
package net.tccn.dbq.qtask;
import net.tccn.base.arango.Doc;
import javax.persistence.Table;
/**
* @author: liangxianyou at 2018/11/26 17:46.
*/
@Table(name = "sys_plat", catalog = "db_dev")
public class SysPlat extends Doc<SysPlat> {
public static SysPlat dao = dao(SysPlat.class);
private String name;
private String token;
public SysPlat() {
}
public SysPlat(String token) {
this.token = token;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}

View File

@@ -0,0 +1,236 @@
package net.tccn.meta;
import net.tccn.base.Kv;
import net.tccn.dbq.DbPlat;
import net.tccn.dbq.Field;
import net.tccn.dbq.fbean.FilterType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
* Created by liangxianyou at 2019/1/7 13:31.
*/
public class MetaKit {
//基础数据缓存
private static List<MetaTable> metaTables;
private static List<MetaLink> metaLinks;
private static List<MetaService> metaServices;
private static List<DbPlat> dbPlats;
static {
metaTables = MetaTable.dao.find();
metaLinks = MetaLink.dao.find();
metaServices = MetaService.dao.find();
dbPlats = DbPlat.dao.find();
}
//----- get/set ----
public static List<MetaTable> getMetaTables() {
return metaTables;
}
public static void setMetaTables(List<MetaTable> metaTables) {
MetaKit.metaTables = metaTables;
}
public static List<MetaLink> getMetaLinks() {
return metaLinks;
}
public static void setMetaLinks(List<MetaLink> metaLinks) {
MetaKit.metaLinks = metaLinks;
}
public static List<MetaService> getMetaServices() {
return metaServices;
}
public static List<DbPlat> getDbPlats() {
return dbPlats;
}
public static void setDbPlats(List<DbPlat> dbPlats) {
MetaKit.dbPlats = dbPlats;
}
//-----------------------------------
public static void setMetaServices(List<MetaService> metaServices) {
MetaKit.metaServices = metaServices;
}
/**
* 通过 别名 查询 MetaTable
* @param alias
* @return
*/
private static MetaTable metaTableByAlias(String alias) {
Optional<MetaTable> table = metaTables.stream().filter(x -> x.getAlias().equals(alias)).findAny();
return table.orElse(null);
}
/**
* 通过 MetaLink[] 得到 MetaTable{}
* @param links
* @return {alias:table}
*/
private static Map<String, MetaTable> metaTables(List<MetaLink> links) {
Map map = new HashMap();
List<String> tables = links.stream().map(MetaLink::getTables).flatMap(Arrays::stream).distinct().collect(Collectors.toList());//tables
metaTables.stream().filter(x -> tables.contains(x.getAlias())).forEach(x -> {
map.put(x.getAlias(), x);
});
return map;
}
/**
* 通过 link._key 得到 MetaLink[]
* @param links
* @return
*/
private static List<MetaLink> metaLinks(List<String> links) {
if (links == null) {
return new ArrayList<>();
}
return metaLinks.stream().filter(x -> links.contains(x.getKey())).collect(Collectors.toList());
}
/**
* 构建完整的 MetaService
* @param name
* @return
*/
public static MetaService metaService(String name) {
Optional<MetaService> service = metaServices.stream().filter(x -> x.getName().equals(name)).findAny();
//处理业务逻辑
service.ifPresent(x -> {
x.setMetaTable(metaTableByAlias(x.getTable()));
x.setMetaLinks(metaLinks(x.getLinks()));
x.setTables(metaTables(x.getMetaLinks()));
});
return service.orElse(null);
}
//字段特征排序
public static BiFunction<MetaTable, String[], MetaTable> sortItem = (t, arr) -> {
List<Field> items = t.getItems();
//x 是跨越值
a:for (int i = 0, x = 0; i < arr.length; i++) {
int inx = i - x;
if (!items.get(inx).equals(arr[i])) {
Field tmp = items.get(inx);
for (int j = inx + 1; j < items.size(); j++) {
if (items.get(j).equals(arr[i])) {
items.set(inx, items.get(j));
items.set(j, tmp);
continue a;
}
}
//运行到这里,说明在 list 中找不到排序标识对应的数据, 让排序角标差值+1
x ++;
}
}
t.setItems(items);
return t;
};
public static Function<String, Field> getField = (n) -> {
String[] arr = n.split("[.]");
MetaTable metaTable = metaTableByAlias(arr[0]);
return metaTable.getItems().stream().filter(x -> x.getName().equals(arr[1])).findAny().orElse(null);
};
//listcfg
public static Function<MetaService, Kv> builderCfg = (m) -> {
List<String> shows = m.getShows();
List<Map> filters = m.getFilters();
List<Map> _filters = new ArrayList<>();
List<Map> _cols = new ArrayList<>();
//todo: 优化,批量操作
//build shows
shows.forEach(x -> {
Field field = getField.apply(x);
if (field != null) {
Kv col = Kv.of();
col.set("col", x.split("[.]]")[0] + field.showField());//a.createtime=dt
col.set("label", field.getLabel());
col.set("order", 1);//dev 是否支持排序
_cols.add(col);
}
});
//build filters
filters.forEach(x -> {
Kv filter = Kv.of();
Field filed = getField.apply(x.get("name") + "");
if (filed != null) {
filter.set("name", x.get("name"));
filter.set("label", filed.getLabel());
}
filter.set("inType", filed.getInType());
filter.set("inExt", filed.getInExt());
List<Kv> types = new ArrayList<>();
List<String> list = (List) x.get("filterType");
list.forEach(t -> {
FilterType type = FilterType.getFilterType(t);
if (type != null) {
types.add(Kv.of("name", t).set("remark", type.getRemark()));
}
});
filter.set("filterType", types);
Object checked = x.getOrDefault("checked", false);
filter.set("checked", checked instanceof Boolean ? checked : false);
_filters.add(filter);
});
/*shows.forEach(x -> {
_shows.add(Kv.of("name", x).set("label", getFieldLabel(x)));
});*/
Kv cfg = Kv.of();
cfg.set("title", m.getName())//业务名称
//.set("url", getUrl())
.set("cols", _cols)//展示的数据列
//.set("conditionLabel", "")
.set("filters", _filters);//查询过滤条件
return cfg;
};
//itemUpdate
public static BiFunction<MetaTable, List<Field>, MetaTable> itemUpdate = (t, fields) -> {
List<Field> items = t.getItems();
for (int i = 0; i < fields.size(); i++) {
for (int j = 0; j < items.size(); j++) {
if (items.get(j).equals(fields.get(i).getName())) {
items.set(j, fields.get(i));
}
}
}
return t;
};
public static MetaTable getMetaTableByKey(String key) {
return metaTables.stream().filter(x -> x.getKey().equals(key)).findAny().orElse(null);
};
}

View File

@@ -0,0 +1,35 @@
package net.tccn.meta;
import net.tccn.base.arango.Doc;
import javax.persistence.Table;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/25 16:22.
*/
@Table(name = "MetaLink", catalog = "db_demo")
public class MetaLink extends Doc<MetaLink> {
public static MetaLink dao = Doc.dao(MetaLink.class);
private String[] tables;
private Map link;
//-------------------------------------------
public String[] getTables() {
return tables;
}
public void setTables(String[] tables) {
this.tables = tables;
}
public Map getLink() {
return link;
}
public void setLink(Map link) {
this.link = link;
}
}

View File

@@ -0,0 +1,103 @@
package net.tccn.meta;
import net.tccn.base.arango.Doc;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/24 16:15.
*/
@Table(name = "MetaService", catalog = "db_demo")
public class MetaService extends Doc<MetaService> {
public static MetaService dao = Doc.dao(MetaService.class);
private String name; //业务标识
private String table; //主体表别名
private List<String> links; //["link._key1","link._key2"]
private List<String> shows = new ArrayList<>();
private List<String> edits = new ArrayList<>();
private List<Map> filters = new ArrayList<>();
//待组装数据
private MetaTable metaTable;
private List<MetaLink> metaLinks;//[{alias:"b", table:"dept", link:[mk,lk]}, xxxx]
private Map<String, MetaTable> tables;
//-------------------------------------------
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTable() {
return table;
}
public void setTable(String table) {
this.table = table;
}
public List<String> getLinks() {
return links;
}
public void setLinks(List<String> links) {
this.links = links;
}
public List<String> getShows() {
return shows;
}
public void setShows(List<String> shows) {
this.shows = shows;
}
public List<String> getEdits() {
return edits;
}
public void setEdits(List<String> edits) {
this.edits = edits;
}
public List<Map> getFilters() {
return filters;
}
public void setFilters(List<Map> filters) {
this.filters = filters;
}
public MetaTable getMetaTable() {
return metaTable;
}
public void setMetaTable(MetaTable metaTable) {
this.metaTable = metaTable;
}
public List<MetaLink> getMetaLinks() {
return metaLinks;
}
public void setMetaLinks(List<MetaLink> metaLinks) {
this.metaLinks = metaLinks;
}
public Map<String, MetaTable> getTables() {
return tables;
}
public void setTables(Map<String, MetaTable> tables) {
this.tables = tables;
}
}

View File

@@ -0,0 +1,75 @@
package net.tccn.meta;
import net.tccn.base.arango.Doc;
import net.tccn.dbq.Field;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.List;
/**
* 元数据
*
* @author: liangxianyou at 2018/10/17 12:58.
*/
@Table(name = "MetaTable", catalog = "db_demo")
public class MetaTable extends Doc<MetaTable> implements Serializable {
public static final MetaTable dao = MetaTable.dao(MetaTable.class);
private String name;
private String alias; //表别名:全库唯一,程序自动生成
private String comment;
private List<Field> items;
private String dbPlatId; //所属数据平台
private String catalog; //所在database
//=============== getter/setter ============
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public List<Field> getItems() {
return items;
}
public void setItems(List<Field> items) {
this.items = items;
}
public String getDbPlatId() {
return dbPlatId;
}
public void setDbPlatId(String dbPlatId) {
this.dbPlatId = dbPlatId;
}
public String getCatalog() {
return catalog;
}
public void setCatalog(String catalog) {
this.catalog = catalog;
}
}

View File

@@ -0,0 +1,43 @@
package net.tccn.qtask;
import net.tccn.base.Kv;
/**
* cate:mysql
* queryId: select * from user where userid=#(userid)
* comment: 查询用户列表
* para: {userid:1}
*
* cate:method
* queryId:com.test.abc.take
* comment:调用Java函数take
* para:{name:xxx,age:12}
*
* cate:http
* query:http://127.0.0.1/meta/db_plat_list
* comment:查询数据平台列表
* para:{platToken:3421432}
*
*
*
*/
public class E {
public String cate;//MYSQL,ES,METHOD,HTTP
public String queryId;
public String dbPlatId;// MYSQL, ES,METHOD,http
public String comment;
public Kv para;
public String restType;//List, Map
public E(String cate, String queryId, String comment, Kv para) {
this.cate = cate;
this.queryId = queryId;
this.comment = comment;
this.para = para;
}
}

View File

@@ -0,0 +1,23 @@
package net.tccn.qtask;
import net.tccn.qtask.impl.QTaskEs;
import net.tccn.qtask.impl.QTaskHttp;
import net.tccn.qtask.impl.QTaskMethod;
import net.tccn.qtask.impl.QTaskMysql;
public class QRuner {
public static Object query(E e) {
switch (e.cate.toLowerCase()) {
case "mysql":
return new QTaskMysql(e).execute();
case "method":
return new QTaskMethod(e).execute();
case "http":
return new QTaskHttp(e).execute();
case "es":
return new QTaskEs(e).execute();
}
return null;
}
}

View File

@@ -0,0 +1,7 @@
package net.tccn.qtask;
public interface QTask {
E getE();
Object execute();
}

View File

@@ -0,0 +1,18 @@
package net.tccn.qtask.impl;
import net.tccn.qtask.E;
import net.tccn.qtask.QTask;
public abstract class QTaskAbs implements QTask {
private E e;
public QTaskAbs(E e) {
this.e = e;
}
@Override
public E getE() {
return e;
}
}

View File

@@ -0,0 +1,24 @@
package net.tccn.qtask.impl;
import net.tccn.qtask.E;
import net.tccn.qtask.QRuner;
import net.tccn.base.Kv;
public class QTaskEs extends QTaskAbs {
public QTaskEs(E e) {
super(e);
}
@Override
public Object execute() {
StringBuilder url = new StringBuilder(getE().queryId);
if (!url.toString().contains("?")) url.append("?");
getE().para.forEach((k, v) -> {
url.append("&" + k + "=" + v);
});
String _url = url.toString().replaceAll(" ", "%20");
return QRuner.query(new E("http", _url, "", Kv.of()));
}
}

View File

@@ -0,0 +1,82 @@
package net.tccn.qtask.impl;
import net.tccn.qtask.E;
import net.tccn.qtask.QTask;
import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author: liangxianyou at 2019/1/20 11:07.
*/
public class QTaskHttp extends QTaskAbs implements QTask {
public QTaskHttp(E e) {
super(e);
}
private static Map<String, HttpURLConnection> connetions = new HashMap();
private URLConnection getConnection() {
try {
URI uri = URI.create(getE().queryId);
URL url = uri.toURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
StringBuilder content = new StringBuilder();
getE().para.forEach((k,v) -> {
content.append(k).append("=").append(v).append("&");
});
if (content.length() > 0) {
content.deleteCharAt(content.length() - 1);
}
connection.setDoOutput(true);
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept-Charset", "utf-8");
//connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
String encode = content.toString().replaceAll(" ", "%20");
System.out.println(encode);
//connection.setRequestProperty("Content-Length", String.valueOf(content.length()));
//connection.getOutputStream().write(encode.getBytes());
connetions.put(getE().queryId, connection);
return connection;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public Object execute() {
URLConnection connection = getConnection();
try (
InputStream is = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(is);
BufferedReader br = new BufferedReader(reader);
){
String content = "";
String line;
while ((line = br.readLine()) != null) {
content += line + System.lineSeparator();
}
return content;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return null;
}
}

View File

@@ -0,0 +1,53 @@
package net.tccn.qtask.impl;
import net.tccn.qtask.E;
import net.tccn.base.Kv;
import net.tccn.qtask.QTask;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class QTaskMethod extends QTaskAbs implements QTask {
public QTaskMethod(E e) {
super(e);
}
public String getClazz(){
String queryId = getE().queryId;
return queryId.substring(0, queryId.lastIndexOf("."));
}
public String getMethod(){
String queryId = getE().queryId;
return queryId.substring(queryId.lastIndexOf(".") + 1);
}
public Kv getPara() {
return getE().para;
}
// execute JAVA method by CLASS AND METHOD
@Override
public Object execute() {
try {
Class<?> type = Class.forName(getClazz());
Object obj = type.newInstance();
Method method = type.getMethod(getMethod(), Kv.class);
return method.invoke(obj, getPara());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,31 @@
package net.tccn.qtask.impl;
import net.tccn.qtask.E;
import net.tccn.qtask.QTask;
public class QTaskMysql extends QTaskAbs implements QTask {
private Object mapper;
public QTaskMysql(E e) {
super(e);
}
public String getSQL(){
String sql = getE().para.get("sql")+"";
return sql;
}
@Override
public Object execute() {
System.out.println("QTaskMysql.execute: " + getE().queryId);
/*if ("Map".equalsIgnoreCase(getE().queryType)){
// return mapper.findFirst(getSQL()); todo:
} else if ("list".equalsIgnoreCase(getE().queryType)){
// return mapper.findList(getSQL()); todo:
}*/
return null;
}
}

View File

@@ -0,0 +1,88 @@
package net.tccn.service;
import com.arangodb.Predicate;
import com.google.gson.Gson;
import org.redkale.net.http.RestMapping;
import org.redkale.service.Service;
import org.redkale.source.CacheSource;
import org.redkale.util.AnyValue;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.function.Supplier;
import java.util.logging.Logger;
/**
* @author: liangxianyou at 2018/10/22 11:49.
*/
public class BaseService implements Service {
public static Gson gson = new Gson();
public Logger logger = Logger.getLogger(this.getClass().getSimpleName());
public static Predicate isEmpty = (x) -> {
if (x == null)
return true;
if (x instanceof List)
return ((List) x).isEmpty();
if (x instanceof String)
return ((String) x).isEmpty();
if (x instanceof Map)
return ((Map) x).isEmpty();
if (x instanceof Collection)
return ((Collection) x).isEmpty();
return false;
};
public static boolean isWinos = System.getProperty("os.name").contains("Window");
@Resource(name = "cacheSource")
protected CacheSource cacheSource;
@Resource(name = "APP_HOME")
protected File APP_HOME;
public static Properties prop = new Properties();
@Override
public void init(AnyValue config) {
try {
File file = new File(APP_HOME.toPath() + "/conf/config.txt");
if (file.exists()) {
prop.load(new FileInputStream(file));
}
} catch (IOException e) {
e.printStackTrace();
}
}
@RestMapping(ignore = true)
public <T> T getT(String key, Class<T> clazz, Supplier<T> supplier) {
Object obj = cacheSource.getAndRefresh(key, 1000 * 60 * 3, clazz);
if (obj != null) {
return (T) obj;
}
T t = supplier.get();
if (t != null) {
cacheSource.set(1000 * 60 * 3, key, clazz, t);
}
return t;
}
@RestMapping(ignore = true)
public String getProperty(String k, String defaultValue){
return prop.getProperty(k, defaultValue).replace("${APP_HOME}", APP_HOME.getPath());
}
@RestMapping(ignore = true)
public String getProperty(String k){
return prop.getProperty(k);
}
}

View File

@@ -0,0 +1,79 @@
package net.tccn.service;
import com.arangodb.ArangoDBException;
import com.google.gson.Gson;
import net.tccn.base.Kv;
import net.tccn.base.arango.ArangoSource;
import org.redkale.net.http.HttpRequest;
import org.redkale.net.http.HttpResponse;
import org.redkale.net.http.HttpServlet;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author: liangxianyou at 2018/11/8 17:05.
*/
public class BaseServlet extends HttpServlet {
public Logger logger = Logger.getLogger(this.getClass().getSimpleName());
protected static Gson gson = new Gson();
@Override
protected void preExecute(HttpRequest request, HttpResponse response) throws IOException {
String sessionid = request.getParameter("token");
if (sessionid == null) {
sessionid = request.getHeader("token");
}
if (sessionid == null) {
sessionid = request.getSessionid(true);
}
if (sessionid != null) {
//User user = userService.current(sessionid);
//request.setCurrentUser(user);
}
super.preExecute(request, response);
}
@Override
protected void authenticate(HttpRequest request, HttpResponse response) throws IOException {
/* fixme: 权限拦截
if (request.currentUser() == null) {
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
response.finish(JBean.by(-2, "未登陆"));
}else {
response.finish(HttpScope.refer("/user/login.html"));
}
return;
}*/
super.authenticate(request, response);
}
@Override
public void execute(HttpRequest request, HttpResponse response) throws IOException {
try {
super.execute(request, response);
} catch (ArangoDBException e) {
logger.log(Level.INFO, "arangodb init!", e);
ArangoSource.init();
}
}
public Kv getParams(HttpRequest request, String... key) {
Kv kv = Kv.of();
for (String k : key) {
if (k.contains("=")) { //如果没有值使用默认值
kv.put(k.split("=")[0], request.getParameter(k.split("=")[0], k.split("=")[1]));
continue;
} else if (k.contains("<")) { //强制使用"<"右侧的值
kv.put(k.split("<")[0], k.split("<")[1]);
continue;
}
kv.put(k, request.getParameter(k));
}
return kv;
}
}

View File

@@ -0,0 +1,181 @@
package net.tccn.service;
import net.tccn.base.JBean;
import net.tccn.base.Kv;
import net.tccn.dbq.DbPlat;
import net.tccn.dbq.Field;
import net.tccn.dbq.qtask.SysPlat;
import net.tccn.meta.MetaKit;
import net.tccn.meta.MetaService;
import net.tccn.meta.MetaTable;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestParam;
import org.redkale.net.http.RestService;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Collectors;
/**
* @author: liangxianyou at 2018/10/17 16:59.
*/
@RestService(name = "meta", automapping = true, comment = "元数据服务")
public class MetadataService extends BaseService { //arango
@Resource
private QtaskService qtaskService;
public MetaTable findMetaTable(String name, String token) {
return getT("meta_cols_" + name + token, MetaTable.class, () -> {
SysPlat sysPlat = qtaskService.getSysPlat(token);
if (sysPlat == null) {
logger.log(Level.INFO, "平台信息未知");
throw new IllegalArgumentException("平台信息未知");
}
return MetaKit.getMetaTables()
.stream()
.filter(x -> {
//fixme: 平台过滤
return x.getName().equals(name);
})
.findAny()
.get();
});
}
@RestMapping(name = "list_cfg", auth = false, comment = "内容列表配置")
public JBean listCfg(String key, @RestParam(name = "platToken") String token) {
JBean jBean = JBean.by(0, "");
MetaService metaService = MetaKit.metaService(key);
fixme: jBean.set(0, "", MetaKit.builderCfg.apply(metaService));
return jBean;
}
//----------- 数据平台 ---------------
@RestMapping(name = "db_plat_list", comment = "数据平台")
public List<DbPlat> dbPlatList() {
return MetaKit.getDbPlats();
}
//----------- 元数据管理 ---------------
@RestMapping(name = "tablelist", comment = "table列表")
public JBean tableList(@RestParam(name = "platToken") String token,
String catalog,
String dbPlatId,
String name) {
JBean jBean = JBean.by(0, "");
SysPlat sysPlat = qtaskService.getSysPlat(token);
if (sysPlat == null) {
return jBean.set(-1, "平台信息未知");
}
List<Kv> list = MetaKit.getMetaTables()
.stream()
.filter(x -> {
return (isEmpty.test(catalog) || catalog.equals(x.getCatalog())) &&
(isEmpty.test(dbPlatId) || dbPlatId.equals(x.getDbPlatId())) &&
(isEmpty.test(name) || x.getName().contains(name));
})
.sorted(Comparator.comparing(MetaTable::getName))
.map(x -> {
//组装返回的数据
Kv kv = Kv.of("name", x.getName())
.set("comment", x.getComment())
.set("catalog", x.getCatalog());
MetaKit.getDbPlats().stream().filter(d -> d.getKey().equals(x.getDbPlatId())).findAny().ifPresent(d -> kv.set("dbPlatName", d.getName()));
return kv;
})
.collect(Collectors.toList());
return jBean.setBody(list);
}
@RestMapping(name = "tableinfo", comment = "table详情")
public JBean tableInfo(@RestParam(name = "platToken") String token, String name) {
return JBean.by(0, "", findMetaTable(name, token));
}
//修改item的排序
@RestMapping(name = "itemsort", comment = "字段排序")
public String[] itemSortSave(String serviceKey , String[] items, @RestParam(name = "platToken") String token) {
MetaTable metaTable = findMetaTable(serviceKey, token);
MetaKit.sortItem.apply(metaTable, items);
metaTable.update();
return items;
}
@RestMapping(name = "itemupdate", comment = "字段修改")
public List<Field> itemUpdate(String serviceKey , List<Field> items, @RestParam(name = "platToken") String token) {
MetaTable metaTable = findMetaTable(serviceKey, token);
MetaKit.itemUpdate.apply(metaTable, items);
metaTable.update();
return items;
}
@RestMapping(name = "showsort", comment = "展示字段修改")
public List<String> showSort(String serviceKey , List<String> items, @RestParam(name = "platToken") String token) {
if (items == null || items.size() == 0) return null;
MetaTable metaTable = findMetaTable(serviceKey, token);
//fixme: metaTable.setShows(items);
metaTable.update();
return items;
}
@RestMapping(name = "exportsort", comment = "导出字段排序保存")
public List<String> exportSort(String serviceKey , List<String> items, @RestParam(name = "platToken") String token) {
if (items == null || items.size() == 0) return null;
MetaTable metaTable = findMetaTable(serviceKey, token);
//fixme: metaTable.setExports(items);
metaTable.update();
return items;
}
@RestMapping(name = "importsort", comment = "导入字段保存")
public List<String> importSort(String serviceKey , List<String> items, @RestParam(name = "platToken") String token) {
if (isEmpty.test(items)) return null;
MetaTable metaTable = findMetaTable(serviceKey, token);
//fixme: metaTable.setImports(items);
metaTable.update();
return items;
}
@RestMapping(name = "dbplatupdate", comment = "数据平台修改")
public JBean dbPlatUpdate(MetaTable metaTable, @RestParam(name = "platToken") String token) {
MetaTable _metaTable = MetaKit.getMetaTableByKey(metaTable.getKey());
_metaTable.setComment(metaTable.getComment());
_metaTable.setCatalog(metaTable.getCatalog());
_metaTable.setDbPlatId(metaTable.getDbPlatId());
_metaTable.setCatalog(metaTable.getCatalog());
_metaTable.update();
return JBean.by(0, "");
}
@RestMapping(name = "filter_update", comment = "查询配置修改")
public JBean filterUpdate(@RestParam(name = "serviceKey") String serviceKey,
@RestParam(name = "filters") String filters,
@RestParam(name = "platToken") String token) {
List _filters = gson.fromJson(filters, List.class);
MetaTable metaTable = findMetaTable(serviceKey, token);
//fixme: metaTable.setFilters(_filters);
metaTable.update();
return JBean.by(0, "");
}
}

View File

@@ -0,0 +1,122 @@
package net.tccn.service;
import net.tccn.base.JBean;
import net.tccn.base.Kv;
import net.tccn.base.arango.ArangoSource;
import net.tccn.dbq.DbPlat;
import net.tccn.dbq.qtask.Qtask;
import net.tccn.dbq.qtask.SysPlat;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestParam;
import org.redkale.net.http.RestService;
import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.function.Predicate;
/**
* @author: liangxianyou at 2018/11/13 18:14.
*/
@RestService(name = "qtask", automapping = true, comment = "qtask查询服务")
public class QtaskService extends BaseService {
private Predicate<String> checkObj = (s) -> s != null && s.startsWith("{") && s.endsWith("}");
public SysPlat getSysPlat(String token) {
return getT(token, SysPlat.class, () -> SysPlat.dao.findFirst(new SysPlat(token)));
}
///qtask/query?queryId=platform.list&para={id:211}
@RestMapping(name = "call", comment = "qtask查询")
public JBean call(String queryId, String para, @RestParam(name = "platToken") String token) {
JBean jBean = JBean.by(0, "");
do {
SysPlat sysPlat = getSysPlat(token);
if (sysPlat == null) {
jBean.set(-1, "平台信息未知"); break;
}
Qtask qtask = getQTask(queryId, sysPlat.getKey());
if (qtask == null) {
jBean.set(-1, "未知任务"); break;
}
if (!checkObj.test(para)) {
para = qtask.getPara();
}
Kv kv = null;
if (checkObj.test(para)) {
kv = BaseService.gson.fromJson(para, Kv.class);
}
try {
jBean.setBody(run(qtask, kv));
} catch (SQLException e) {
e.printStackTrace();
return jBean.set(-1, "数据查询失败", e.getMessage());
}
} while (false);
return jBean;
}
@RestMapping(name = "test", comment = "qtask调试")
public JBean test(Qtask qtask) {
JBean jBean = JBean.by(0, "");
do {
//check data
if (isEmpty.test(qtask.getSql())) {
jBean.set(-1, "查询失败请设置正确的【SQL】"); break;
}
if (isEmpty.test(qtask.getPlatId()) || isEmpty.test(qtask.getCatalog())) {
jBean.set(-1, "查询失败,请设置正确的【数据平台】"); break;
}
DbPlat dbPlat = DbPlat.dao.findByKey(qtask.getPlatId());//arangoSource.findById("db_plat/" + qTask.getPlatId(), DbPlat.class);
if (dbPlat == null) {
jBean.set(-1, "查询失败,请设置正确的【数据平台】"); break;
}
Kv kv = null;
if (checkObj.test(qtask.getPara())) {
try {
kv = BaseService.gson.fromJson(qtask.getPara(), Kv.class);
} catch (Exception e) {
jBean.set(-1, "查询失败,请设置正确的【查询参数】"); break;
}
}
try {
jBean.setBody(run(qtask, kv));
} catch (SQLException e) {
e.printStackTrace();
jBean.set(-1, e.getMessage());
}
} while (false);
return jBean;
}
// /qtask/query?queryId=platform.list&para={id:211}
@RestMapping(ignore = true, comment = "qtask查询数据")
private Object run(Qtask qTask, Kv kv) throws SQLException {
return null;
}
//----------- Qtask ---------------
@RestMapping(name = "qsave", comment = "qtask保存")
public JBean qtaskSave(Qtask qtask) {
JBean jBean = JBean.by(0, "");
return jBean;
}
@RestMapping(ignore = true, comment = "qtask获取")
public Qtask getQTask(String queryId, String sysPlatId) {
Qtask qtask = null;
return qtask;
}
//-------------------------------------------------------
}

View File

@@ -0,0 +1,29 @@
import net.tccn.qtask.E;
import net.tccn.qtask.QRuner;
import net.tccn.base.Kv;
import org.junit.Test;
/**
* @author: liangxianyou at 2019/1/20 12:43.
*/
public class RunTest<T> {
public static E A = new E("mysql", "select * from user where userid=#(userid)", "查询用户列表", Kv.of("userid", 1));
public static E B = new E("method", "User.say", "user调用", Kv.of("name", "张三").set("age", 13));
public static E C = new E("http", "http://127.0.0.1/meta/db_plat_list?platToken=3421432", "查询数据平台列表", Kv.of("abx", "abx111"));
public static E d = new E("es", "http://192.168.91.5:9200/_sql?", "查询数据平台列表", Kv.of("sql", "select * from basic_iotdevice_all limit 10"));
public static E e = new E("http", "http://192.168.91.5:9200/_sql?sql=select%20*%20from%20basic_iotdevice_all%20limit%2010", "查询数据平台列表", Kv.of());
//@Test
public void t() {
long start = System.currentTimeMillis();
Object query = QRuner.query(d);
System.out.printf("耗时:%s MS" ,System.currentTimeMillis() - start);
System.out.println();
System.out.println(query);
//System.out.println(query.getClass());
}
}

32
src/test/java/User.java Normal file
View File

@@ -0,0 +1,32 @@
import net.tccn.base.Kv;
/**
* @author: liangxianyou at 2019/1/20 12:52.
*/
public class User {
private int id;
private String IP;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getIP() {
return IP;
}
public void setIP(String IP) {
this.IP = IP;
}
public String say(Kv kv) {
String s = String.format("我叫:%s, 今年:%s岁", kv.get("name"), kv.get("age"));
System.out.println(s);
return s;
}
}