forked from fanruan/demo-tabledata-redis
richie
6 years ago
35 changed files with 1044 additions and 186 deletions
@ -0,0 +1,52 @@
|
||||
package com.fr.plugin.db.redis; |
||||
|
||||
import com.fr.base.TableData; |
||||
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane; |
||||
import com.fr.design.fun.ServerTableDataDefineProvider; |
||||
import com.fr.design.fun.impl.AbstractTableDataDefineProvider; |
||||
import com.fr.locale.InterProviderFactory; |
||||
import com.fr.plugin.db.redis.core.RedisScriptTableData; |
||||
import com.fr.plugin.db.redis.ui.RedisScriptTableDataPane; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public class RedisScriptTableDataDefine extends AbstractTableDataDefineProvider implements ServerTableDataDefineProvider { |
||||
|
||||
@Override |
||||
public int currentAPILevel() { |
||||
return CURRENT_LEVEL; |
||||
} |
||||
|
||||
@Override |
||||
public Class<? extends TableData> classForTableData() { |
||||
return RedisScriptTableData.class; |
||||
} |
||||
|
||||
@Override |
||||
public Class<? extends TableData> classForInitTableData() { |
||||
return RedisScriptTableData.class; |
||||
} |
||||
|
||||
@Override |
||||
public Class<? extends AbstractTableDataPane> appearanceForTableData() { |
||||
return RedisScriptTableDataPane.class; |
||||
} |
||||
|
||||
@Override |
||||
public String nameForTableData() { |
||||
return InterProviderFactory.getProvider().getLocText("Plugin-Redis_Script_Table_Data"); |
||||
} |
||||
|
||||
@Override |
||||
public String prefixForTableData() { |
||||
return "redis"; |
||||
} |
||||
|
||||
@Override |
||||
public String iconPathForTableData() { |
||||
return "/com/fr/plugin/db/redis/images/redis.png"; |
||||
} |
||||
} |
@ -0,0 +1,75 @@
|
||||
package com.fr.plugin.db.redis.core; |
||||
|
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.redis.clients.jedis.Jedis; |
||||
import com.fr.third.redis.clients.jedis.JedisPool; |
||||
import com.fr.third.redis.clients.jedis.JedisPoolConfig; |
||||
|
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public class RedisPool { |
||||
|
||||
private static final int TIME_OUT = 100 * 1000; |
||||
|
||||
private static RedisPool pool = new RedisPool(); |
||||
|
||||
public static RedisPool getPool() { |
||||
return pool; |
||||
} |
||||
|
||||
private Map<String, JedisPool> jedisPoolMap = new ConcurrentHashMap<String, JedisPool>(); |
||||
|
||||
public Jedis getResource(String host, int port, String password, int maxTotal) { |
||||
JedisPool jedisPool = jedisPoolMap.get(host); |
||||
if (jedisPool == null) { |
||||
jedisPool = createJedisPool(host, port, password, maxTotal); |
||||
jedisPoolMap.put(host, jedisPool); |
||||
} |
||||
return jedisPool.getResource(); |
||||
} |
||||
|
||||
private JedisPool createJedisPool(String host, int port, String password, int maxTotal) { |
||||
JedisPoolConfig config = new JedisPoolConfig(); |
||||
config.setMaxTotal(maxTotal); |
||||
//连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
|
||||
config.setBlockWhenExhausted(true); |
||||
//设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)
|
||||
config.setEvictionPolicyClassName("com.fr.third.org.apache.commons.pool2.impl.DefaultEvictionPolicy"); |
||||
//是否启用pool的jmx管理功能, 默认true
|
||||
config.setJmxEnabled(true); |
||||
//MBean ObjectName = new ObjectName("org.apache.commons.pool2:type=GenericObjectPool,name=" + "pool" + i); 默认为"pool", JMX不熟,具体不知道是干啥的...默认就好.
|
||||
config.setJmxNamePrefix("pool"); |
||||
//是否启用后进先出, 默认true
|
||||
config.setLifo(true); |
||||
//最大空闲连接数
|
||||
config.setMaxIdle(10); |
||||
//最大连接数,可配置
|
||||
//获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
|
||||
config.setMaxWaitMillis(-1); |
||||
//逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
|
||||
config.setMinEvictableIdleTimeMillis(1800000); |
||||
//最小空闲连接数, 默认0
|
||||
config.setMinIdle(0); |
||||
//每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
|
||||
config.setNumTestsPerEvictionRun(3); |
||||
//对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断 (默认逐出策略)
|
||||
config.setSoftMinEvictableIdleTimeMillis(1800000); |
||||
//在获取连接的时候检查有效性, 默认false
|
||||
config.setTestOnBorrow(false); |
||||
//在空闲时检查有效性, 默认false
|
||||
config.setTestWhileIdle(false); |
||||
//逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
|
||||
config.setTimeBetweenEvictionRunsMillis(-1); |
||||
if (StringUtils.isNotBlank(password)) { |
||||
return new JedisPool(config, host, port, TIME_OUT, password); |
||||
} else { |
||||
return new JedisPool(config, host, port, TIME_OUT); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,144 @@
|
||||
package com.fr.plugin.db.redis.core; |
||||
|
||||
import com.fr.base.Parameter; |
||||
import com.fr.base.TableData; |
||||
import com.fr.config.holder.Conf; |
||||
import com.fr.config.holder.factory.Holders; |
||||
import com.fr.config.holder.factory.XmlHolders; |
||||
import com.fr.data.AbstractParameterTableData; |
||||
import com.fr.data.core.DataCoreXmlUtils; |
||||
import com.fr.data.impl.Connection; |
||||
import com.fr.data.impl.NameDatabaseConnection; |
||||
import com.fr.file.DatasourceManager; |
||||
import com.fr.general.data.DataModel; |
||||
import com.fr.general.xml.GeneralXMLTools; |
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.plugin.db.redis.core.order.OrderValue; |
||||
import com.fr.plugin.db.redis.core.order.impl.NumberOrderValue; |
||||
import com.fr.plugin.db.redis.util.RedisUtils; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
import com.fr.script.Calculator; |
||||
import com.fr.stable.ParameterProvider; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.xml.XMLPrintWriter; |
||||
import com.fr.stable.xml.XMLableReader; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
@EnableMetrics |
||||
public class RedisScriptTableData extends AbstractParameterTableData { |
||||
|
||||
private static final long serialVersionUID = 1525853354993816818L; |
||||
|
||||
private Conf<Connection> database = Holders.obj(null, Connection.class); |
||||
private Conf<OrderValue> dbIndex = XmlHolders.obj(new NumberOrderValue(0), OrderValue.class, OrderValue.XML_TAG); |
||||
private Conf<String> script = Holders.simple(StringUtils.EMPTY); |
||||
|
||||
public void setDatabase(Connection c) { |
||||
this.database.set(c); |
||||
} |
||||
|
||||
public Connection getDatabase() { |
||||
return database.get(); |
||||
} |
||||
|
||||
public OrderValue getOrderValue() { |
||||
return dbIndex.get(); |
||||
} |
||||
|
||||
public void setOrderValue(OrderValue dbIndex) { |
||||
this.dbIndex.set(dbIndex); |
||||
} |
||||
|
||||
public String getScript() { |
||||
return script.get(); |
||||
} |
||||
|
||||
public void setScript(String script) { |
||||
this.script.set(script); |
||||
} |
||||
|
||||
public void setParameters(ParameterProvider[] providers) { |
||||
super.setDefaultParameters(providers); |
||||
} |
||||
|
||||
@Override |
||||
public DataModel createDataModel(Calculator calculator) { |
||||
return createDataModel(calculator, TableData.RESULT_ALL); |
||||
} |
||||
|
||||
@Override |
||||
@Focus(id = RedisConstants.PLUGIN_ID, text = "Plugin-Redis_Script_Table_Data") |
||||
public DataModel createDataModel(Calculator calculator, int rowCount) { |
||||
long start = System.currentTimeMillis(); |
||||
Parameter[] ps = Parameter.providers2Parameter(getParameters(calculator)); |
||||
Connection connection = database.get(); |
||||
if (connection instanceof NameDatabaseConnection) { |
||||
String name = ((NameDatabaseConnection) connection).getName(); |
||||
RedisDatabaseConnection rc = DatasourceManager.getProviderInstance().getConnection(name, RedisDatabaseConnection.class); |
||||
if (rc != null) { |
||||
OrderValue orderValue = dbIndex.get(); |
||||
DataModel model = new RedisScriptTableDataModel(rc, |
||||
orderValue == null ? 0 : orderValue.toIndex(calculator, ps), |
||||
RedisUtils.calculateQuery(script.get(), ps), |
||||
rowCount); |
||||
FineLoggerFactory.getLogger().info("Build data model spend time {} ms.", System.currentTimeMillis() - start); |
||||
return model; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public void readXML(XMLableReader reader) { |
||||
super.readXML(reader); |
||||
|
||||
if (reader.isChildNode()) { |
||||
String tmpName = reader.getTagName(); |
||||
String tmpVal; |
||||
|
||||
if (OrderValue.XML_TAG.equals(tmpName)) { |
||||
OrderValue orderValue = (OrderValue) GeneralXMLTools.readXMLable(reader); |
||||
if (orderValue != null) { |
||||
setOrderValue(orderValue); |
||||
} |
||||
} else if (com.fr.data.impl.Connection.XML_TAG.equals(tmpName)) { |
||||
if (reader.getAttrAsString("class", null) != null) { |
||||
com.fr.data.impl.Connection con = DataCoreXmlUtils.readXMLConnection(reader); |
||||
this.setDatabase(con); |
||||
} |
||||
} else if ("Script".equals(tmpName)) { |
||||
tmpVal = reader.getElementValue(); |
||||
if (isNotNullValue(tmpVal)) { |
||||
this.setScript(tmpVal); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void writeXML(XMLPrintWriter writer) { |
||||
super.writeXML(writer); |
||||
GeneralXMLTools.writeXMLable(writer, dbIndex.get(), OrderValue.XML_TAG); |
||||
if (this.database.get() != null) { |
||||
DataCoreXmlUtils.writeXMLConnection(writer, this.database.get()); |
||||
} |
||||
writer.startTAG("Script").textNode(getScript()).end(); |
||||
} |
||||
|
||||
private boolean isNotNullValue(String value) { |
||||
return value != null && !"null".equals(value); |
||||
} |
||||
|
||||
@Override |
||||
public Object clone() throws CloneNotSupportedException { |
||||
RedisScriptTableData cloned = (RedisScriptTableData) super.clone(); |
||||
cloned.database = (Conf<Connection>) database.clone(); |
||||
cloned.script = (Conf<String>) script.clone(); |
||||
cloned.dbIndex = (Conf<OrderValue>) dbIndex.clone(); |
||||
return cloned; |
||||
} |
||||
} |
@ -0,0 +1,141 @@
|
||||
package com.fr.plugin.db.redis.core; |
||||
|
||||
import com.eclipsesource.v8.V8; |
||||
import com.eclipsesource.v8.V8Array; |
||||
import com.eclipsesource.v8.V8Object; |
||||
import com.fr.data.AbstractDataModel; |
||||
import com.fr.plugin.db.redis.help.Console; |
||||
import com.fr.plugin.db.redis.help.Files; |
||||
import com.fr.plugin.db.redis.help.RedisClient; |
||||
import com.fr.plugin.db.redis.util.RedisUtils; |
||||
import com.fr.third.redis.clients.jedis.Jedis; |
||||
|
||||
import java.lang.reflect.Method; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public class RedisScriptTableDataModel extends AbstractDataModel { |
||||
|
||||
private RedisDatabaseConnection mc; |
||||
private String script; |
||||
private int dbIndex; |
||||
private int rowCount; |
||||
private List<List<Object>> data = new ArrayList<List<Object>>(); |
||||
private String[] columnNames = null; |
||||
|
||||
public RedisScriptTableDataModel(RedisDatabaseConnection mc, int dbIndex, String script, int rowCount) { |
||||
this.mc = mc; |
||||
this.script = script; |
||||
this.dbIndex = dbIndex; |
||||
this.rowCount = rowCount; |
||||
} |
||||
|
||||
private void buildData() { |
||||
if (columnNames != null) { |
||||
return; |
||||
} |
||||
Jedis jedis = mc.createRedisClient(); |
||||
jedis.select(dbIndex); |
||||
V8 v8 = V8.createV8Runtime(); |
||||
RedisClient client = new RedisClient(v8, jedis); |
||||
V8Object v8Console = initConsole(v8); |
||||
V8Object v8Require = initRequire(v8); |
||||
V8Object v8Client = initRedis(v8, client); |
||||
|
||||
v8.executeVoidScript( |
||||
"function unique(array) {return Array.from(new Set(array));};" + |
||||
"function merge(table, column) {return {content:table, column:column}};"); |
||||
|
||||
V8Object returnObj = v8.executeObjectScript(String.format("(function(){%s})();", script)); |
||||
|
||||
V8Array v8Column = returnObj.getArray("column"); |
||||
V8Array v8Table = returnObj.getArray("content"); |
||||
int columnCount = v8Column.length(); |
||||
columnNames = new String[columnCount]; |
||||
for (int i = 0; i < columnCount; i++) { |
||||
columnNames[i] = String.valueOf(v8Column.get(i)); |
||||
} |
||||
int returnRowCount = v8Table.length(); |
||||
for (int i = 0, realCount = Math.min(returnRowCount, this.rowCount); i < realCount; i++) { |
||||
V8Array v8Row = v8Table.getArray(i); |
||||
List<Object> row = new ArrayList<Object>(); |
||||
for (int j = 0, col = v8Row.length(); j < col; j++) { |
||||
row.add(v8Row.get(j)); |
||||
} |
||||
v8Row.release(); |
||||
data.add(row); |
||||
} |
||||
jedis.close(); |
||||
v8Table.release(); |
||||
v8Column.release(); |
||||
returnObj.release(); |
||||
v8Client.release(); |
||||
v8Require.release(); |
||||
v8Console.release(); |
||||
|
||||
v8.release(true); |
||||
} |
||||
|
||||
private V8Object initConsole(V8 v8) { |
||||
V8Object v8Console = new V8Object(v8); |
||||
v8.add("console", v8Console); |
||||
Console console = new Console(v8); |
||||
RedisUtils.registerJavaMethods(v8Console, console); |
||||
return v8Console; |
||||
} |
||||
|
||||
private V8Object initRequire(V8 v8) { |
||||
V8Object v8Files = new V8Object(v8); |
||||
v8.add("Files", v8Files); |
||||
Files console = new Files(v8); |
||||
RedisUtils.registerJavaMethods(v8Files, console); |
||||
return v8Files; |
||||
} |
||||
|
||||
private V8Object initRedis(final V8 v8, final RedisClient client) { |
||||
V8Object v8Client = new V8Object(v8); |
||||
v8.add("redis", v8Client); |
||||
RedisUtils.registerJavaMethods(v8Client, client); |
||||
return v8Client; |
||||
} |
||||
|
||||
@Override |
||||
public int getColumnCount() { |
||||
buildData(); |
||||
return columnNames == null ? 0 : columnNames.length; |
||||
} |
||||
|
||||
@Override |
||||
public String getColumnName(int i) { |
||||
buildData(); |
||||
return columnNames == null ? null : columnNames[i]; |
||||
} |
||||
|
||||
@Override |
||||
public int getRowCount() { |
||||
buildData(); |
||||
return data.size(); |
||||
} |
||||
|
||||
@Override |
||||
public Object getValueAt(int rowIndex, int columnIndex) { |
||||
buildData(); |
||||
if (data != null && data.size() > rowIndex) { |
||||
List<Object> rowData = data.get(rowIndex); |
||||
if (rowData != null && rowData.size() > columnIndex) { |
||||
return rowData.get(columnIndex); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public void release() throws Exception { |
||||
|
||||
} |
||||
} |
@ -0,0 +1,36 @@
|
||||
package com.fr.plugin.db.redis.help; |
||||
|
||||
import com.eclipsesource.v8.V8; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.io.utils.ResourceIOUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.EncodeConstants; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileNotFoundException; |
||||
import java.io.InputStream; |
||||
import java.io.UnsupportedEncodingException; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public class Console { |
||||
|
||||
private V8 v8; |
||||
|
||||
public Console(V8 v8) { |
||||
this.v8 = v8; |
||||
} |
||||
|
||||
public void log(Object message) { |
||||
FineLoggerFactory.getLogger().info(message == null ? null : message.toString()); |
||||
} |
||||
|
||||
public void error(Object message) { |
||||
FineLoggerFactory.getLogger().error(message == null ? null : message.toString()); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,34 @@
|
||||
package com.fr.plugin.db.redis.help; |
||||
|
||||
import com.eclipsesource.v8.V8; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.io.utils.ResourceIOUtils; |
||||
import com.fr.stable.EncodeConstants; |
||||
|
||||
import java.io.InputStream; |
||||
import java.io.UnsupportedEncodingException; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-19 |
||||
*/ |
||||
public class Files { |
||||
|
||||
private V8 v8; |
||||
|
||||
public Files(V8 v8) { |
||||
this.v8 = v8; |
||||
} |
||||
|
||||
public void require(String filePath) { |
||||
InputStream in = ResourceIOUtils.read(filePath); |
||||
if (in != null) { |
||||
try { |
||||
v8.executeVoidScript(IOUtils.inputStream2String(in, EncodeConstants.ENCODING_UTF_8)); |
||||
} catch (UnsupportedEncodingException ignore) { |
||||
|
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,102 @@
|
||||
package com.fr.plugin.db.redis.help; |
||||
|
||||
import com.eclipsesource.v8.V8; |
||||
import com.eclipsesource.v8.V8Array; |
||||
import com.eclipsesource.v8.V8Object; |
||||
import com.eclipsesource.v8.utils.V8ObjectUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.third.redis.clients.jedis.Jedis; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public class RedisClient { |
||||
|
||||
private Jedis jedis; |
||||
private V8 v8; |
||||
|
||||
public RedisClient(V8 v8, Jedis jedis) { |
||||
this.jedis = jedis; |
||||
this.v8 = v8; |
||||
} |
||||
|
||||
public String get(String key) { |
||||
long start = System.currentTimeMillis(); |
||||
try { |
||||
return jedis.get(key); |
||||
} finally { |
||||
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); |
||||
} |
||||
} |
||||
|
||||
public String hget(String key, String field) { |
||||
long start = System.currentTimeMillis(); |
||||
try { |
||||
return jedis.hget(key, field); |
||||
} finally { |
||||
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); |
||||
} |
||||
} |
||||
|
||||
public V8Array hkeys(String key) { |
||||
long start = System.currentTimeMillis(); |
||||
Set<String> set = jedis.keys(key); |
||||
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); |
||||
return V8ObjectUtils.toV8Array(v8, new ArrayList<String>(set)); |
||||
} |
||||
|
||||
public V8Array hmget(String key, String... fields) { |
||||
long start = System.currentTimeMillis(); |
||||
List<String> list = jedis.hmget(key, fields); |
||||
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); |
||||
return V8ObjectUtils.toV8Array(v8, list); |
||||
} |
||||
|
||||
public V8Object hgetAll(String key) { |
||||
long start = System.currentTimeMillis(); |
||||
Map<String, String> map = jedis.hgetAll(key); |
||||
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); |
||||
return V8ObjectUtils.toV8Object(v8, map); |
||||
} |
||||
|
||||
public V8Array keys(String pattern) { |
||||
long start = System.currentTimeMillis(); |
||||
Set<String> set = jedis.keys(pattern); |
||||
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); |
||||
return V8ObjectUtils.toV8Array(v8, new ArrayList<String>(set)); |
||||
} |
||||
|
||||
public V8Array lrange(String key, long start, long end) { |
||||
long start0 = System.currentTimeMillis(); |
||||
List<String> list = jedis.lrange(key, start, end); |
||||
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start0); |
||||
return V8ObjectUtils.toV8Array(v8, list); |
||||
} |
||||
|
||||
public V8Array mget(V8Array keys) { |
||||
long start = System.currentTimeMillis(); |
||||
int len = keys.length(); |
||||
String[] parameters = new String[len]; |
||||
for (int i = 0; i < len; i ++) { |
||||
parameters[i] = keys.getString(i); |
||||
} |
||||
List<String> list = jedis.mget(parameters); |
||||
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); |
||||
keys.release(); |
||||
return V8ObjectUtils.toV8Array(v8, list); |
||||
} |
||||
|
||||
public V8Array smembers(String key) { |
||||
long start = System.currentTimeMillis(); |
||||
Set<String> set = jedis.smembers(key); |
||||
FineLoggerFactory.getLogger().info("Fetch data from redis spend time {} ms.", System.currentTimeMillis() - start); |
||||
return V8ObjectUtils.toV8Array(v8, new ArrayList<String>(set)); |
||||
} |
||||
} |
@ -0,0 +1,164 @@
|
||||
package com.fr.plugin.db.redis.ui; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.base.ParameterHelper; |
||||
import com.fr.base.TableData; |
||||
import com.fr.design.actions.UpdateAction; |
||||
import com.fr.design.data.datapane.preview.PreviewTablePane; |
||||
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane; |
||||
import com.fr.design.gui.itableeditorpane.ParameterTableModel; |
||||
import com.fr.design.gui.itableeditorpane.UITableEditAction; |
||||
import com.fr.design.gui.itableeditorpane.UITableEditorPane; |
||||
import com.fr.design.gui.itoolbar.UIToolbar; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.menu.ToolBarDef; |
||||
import com.fr.plugin.db.redis.core.order.OrderValue; |
||||
import com.fr.stable.ArrayUtils; |
||||
import com.fr.stable.ParameterProvider; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
import java.awt.event.ActionEvent; |
||||
import java.util.ArrayList; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public abstract class RedisBaseTableDataPane<T extends TableData> extends AbstractTableDataPane<T> { |
||||
|
||||
private static final String PREVIEW_BUTTON = Toolkit.i18nText("Plugin-Redis_Preview"); |
||||
private static final String REFRESH_BUTTON = Toolkit.i18nText("Plugin-Redis_Refresh"); |
||||
|
||||
protected RedisDBConnectionChosePane chosePane; |
||||
|
||||
protected UITableEditorPane<ParameterProvider> editorPane; |
||||
|
||||
|
||||
public RedisBaseTableDataPane() { |
||||
this.setLayout(new BorderLayout(4, 4)); |
||||
|
||||
Box box = new Box(BoxLayout.Y_AXIS); |
||||
|
||||
JPanel northPane = new JPanel(new BorderLayout(4, 4)); |
||||
JToolBar editToolBar = createToolBar(); |
||||
northPane.add(editToolBar, BorderLayout.CENTER); |
||||
northPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0)); |
||||
|
||||
|
||||
ParameterTableModel model = new ParameterTableModel() { |
||||
@Override |
||||
public UITableEditAction[] createAction() { |
||||
return ArrayUtils.add(super.createDBTableAction(), new RedisBaseTableDataPane.RefreshAction()); |
||||
} |
||||
}; |
||||
editorPane = new UITableEditorPane<ParameterProvider>(model); |
||||
|
||||
box.add(northPane); |
||||
|
||||
box.add(createQueryPane()); |
||||
|
||||
box.add(editorPane); |
||||
|
||||
JPanel sqlSplitPane = new JPanel(new BorderLayout(4, 4)); |
||||
sqlSplitPane.add(box, BorderLayout.CENTER); |
||||
|
||||
chosePane = new RedisDBConnectionChosePane(); |
||||
chosePane.setPreferredSize(new Dimension(200, 200)); |
||||
sqlSplitPane.add(chosePane, BorderLayout.WEST); |
||||
|
||||
this.add(sqlSplitPane, BorderLayout.CENTER); |
||||
} |
||||
|
||||
private JToolBar createToolBar() { |
||||
ToolBarDef toolBarDef = new ToolBarDef(); |
||||
toolBarDef.addShortCut(new RedisBaseTableDataPane.PreviewAction()); |
||||
UIToolbar editToolBar = ToolBarDef.createJToolBar(); |
||||
toolBarDef.updateToolBar(editToolBar); |
||||
return editToolBar; |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return Toolkit.i18nText("Plugin-Redis_Query"); |
||||
} |
||||
|
||||
protected abstract JComponent createQueryPane(); |
||||
|
||||
protected abstract String[] paramTexts(); |
||||
|
||||
public abstract OrderValue getOrderValue(); |
||||
|
||||
|
||||
private void refresh() { |
||||
String[] paramTexts = paramTexts(); |
||||
|
||||
ParameterProvider[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false); |
||||
|
||||
ParameterProvider[] providers = getOrderValue().analyze4Parameters(); |
||||
|
||||
editorPane.populate(ArrayUtils.addAll(parameters, providers)); |
||||
} |
||||
|
||||
|
||||
private void checkParameter() { |
||||
String[] paramTexts = paramTexts(); |
||||
|
||||
ParameterProvider[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false); |
||||
parameters = ArrayUtils.addAll(parameters, getOrderValue().analyze4Parameters()); |
||||
|
||||
if (parameters.length < 1 && editorPane.update().size() < 1) { |
||||
return; |
||||
} |
||||
boolean isIn = true; |
||||
java.util.List<ParameterProvider> list = editorPane.update(); |
||||
java.util.List<String> name = new ArrayList<String>(); |
||||
for (int i = 0; i < list.size(); i++) { |
||||
name.add(list.get(i).getName()); |
||||
} |
||||
for (int i = 0; i < parameters.length; i++) { |
||||
if (!name.contains(parameters[i].getName())) { |
||||
isIn = false; |
||||
break; |
||||
} |
||||
} |
||||
if (list.size() == parameters.length && isIn) { |
||||
return; |
||||
} |
||||
refresh(); |
||||
} |
||||
|
||||
|
||||
private class PreviewAction extends UpdateAction { |
||||
public PreviewAction() { |
||||
this.setName(PREVIEW_BUTTON); |
||||
this.setMnemonic('P'); |
||||
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_file/preview.png")); |
||||
} |
||||
|
||||
public void actionPerformed(ActionEvent evt) { |
||||
checkParameter(); |
||||
PreviewTablePane.previewTableData(RedisBaseTableDataPane.this.updateBean()); |
||||
} |
||||
} |
||||
|
||||
|
||||
protected class RefreshAction extends UITableEditAction { |
||||
public RefreshAction() { |
||||
this.setName(REFRESH_BUTTON); |
||||
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/control/refresh.png")); |
||||
} |
||||
|
||||
public void actionPerformed(ActionEvent e) { |
||||
refresh(); |
||||
} |
||||
|
||||
@Override |
||||
public void checkEnabled() { |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,71 @@
|
||||
package com.fr.plugin.db.redis.ui; |
||||
|
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.design.editor.ValueEditorPane; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea; |
||||
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.plugin.db.redis.core.order.OrderValue; |
||||
import com.fr.plugin.db.redis.ui.value.IndexValuePaneFactory; |
||||
import com.fr.plugin.db.redis.util.RedisDesignUtils; |
||||
|
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public class RedisScriptPane extends BasicPane { |
||||
|
||||
private ValueEditorPane dbIndexEditor; |
||||
private RSyntaxTextArea scriptTextPane; |
||||
|
||||
public RedisScriptPane() { |
||||
|
||||
setLayout(new BorderLayout()); |
||||
|
||||
scriptTextPane = new RSyntaxTextArea(); |
||||
|
||||
dbIndexEditor = IndexValuePaneFactory.createValueEditorPane(); |
||||
|
||||
Component[][] coms = new Component[][]{ |
||||
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Plugin-Redis_DB_Index") + ":"), dbIndexEditor}, |
||||
{new UILabel(Toolkit.i18nText("Plugin-Redis_Script_Query_Text") + ":"), |
||||
RedisDesignUtils.createConditionTextPane(scriptTextPane, SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT, 350)}, |
||||
}; |
||||
|
||||
double p = TableLayout.PREFERRED; |
||||
double f = TableLayout.FILL; |
||||
|
||||
double[] rowSize = {p, p, p}; |
||||
double[] columnSize = {p, f}; |
||||
|
||||
add(TableLayoutHelper.createTableLayoutPane(coms, rowSize, columnSize)); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return "Script"; |
||||
} |
||||
|
||||
public OrderValue getOrderValue() { |
||||
return (OrderValue) dbIndexEditor.update(); |
||||
} |
||||
|
||||
public void setOrderValue(OrderValue orderValue) { |
||||
dbIndexEditor.populate(orderValue); |
||||
} |
||||
|
||||
public String getScript() { |
||||
return scriptTextPane.getText(); |
||||
} |
||||
|
||||
public void setScript(String script) { |
||||
scriptTextPane.setText(script); |
||||
} |
||||
} |
@ -0,0 +1,76 @@
|
||||
package com.fr.plugin.db.redis.ui; |
||||
|
||||
import com.fr.data.impl.NameDatabaseConnection; |
||||
import com.fr.plugin.db.redis.core.RedisScriptTableData; |
||||
import com.fr.plugin.db.redis.core.order.OrderValue; |
||||
import com.fr.script.Calculator; |
||||
import com.fr.stable.ParameterProvider; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.*; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public class RedisScriptTableDataPane extends RedisBaseTableDataPane<RedisScriptTableData> { |
||||
|
||||
private RedisScriptPane scriptPane; |
||||
|
||||
public RedisScriptTableDataPane() { |
||||
super(); |
||||
} |
||||
|
||||
@Override |
||||
protected JComponent createQueryPane() { |
||||
if (scriptPane == null) { |
||||
scriptPane = new RedisScriptPane(); |
||||
} |
||||
return scriptPane; |
||||
} |
||||
|
||||
@Override |
||||
protected String[] paramTexts() { |
||||
return new String[] {scriptPane.getScript()}; |
||||
} |
||||
|
||||
@Override |
||||
public OrderValue getOrderValue() { |
||||
return scriptPane.getOrderValue(); |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(RedisScriptTableData tableData) { |
||||
if (tableData == null) { |
||||
return; |
||||
} |
||||
Calculator c = Calculator.createCalculator(); |
||||
|
||||
editorPane.populate(tableData.getParameters(c)); |
||||
|
||||
chosePane.populateConnection(tableData.getDatabase()); |
||||
|
||||
scriptPane.setScript(tableData.getScript()); |
||||
|
||||
scriptPane.setOrderValue(tableData.getOrderValue()); |
||||
} |
||||
|
||||
@Override |
||||
public RedisScriptTableData updateBean() { |
||||
RedisScriptTableData tableData = new RedisScriptTableData(); |
||||
String connectionName = chosePane.getSelectRedisConnectionName(); |
||||
if (StringUtils.isNotEmpty(connectionName)) { |
||||
tableData.setDatabase(new NameDatabaseConnection(connectionName)); |
||||
} |
||||
List<ParameterProvider> parameterList = editorPane.update(); |
||||
ParameterProvider[] parameters = parameterList.toArray(new ParameterProvider[parameterList.size()]); |
||||
tableData.setParameters(parameters); |
||||
|
||||
tableData.setScript(scriptPane.getScript()); |
||||
tableData.setOrderValue(scriptPane.getOrderValue()); |
||||
|
||||
return tableData; |
||||
} |
||||
} |
@ -0,0 +1,24 @@
|
||||
package com.fr.plugin.db.redis.util; |
||||
|
||||
import com.fr.design.border.UIRoundedBorder; |
||||
import com.fr.design.constants.UIConstants; |
||||
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea; |
||||
import com.fr.design.gui.syntax.ui.rtextarea.RTextScrollPane; |
||||
|
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public class RedisDesignUtils { |
||||
public static RTextScrollPane createConditionTextPane(RSyntaxTextArea editorPane, String type, int height) { |
||||
editorPane.setSyntaxEditingStyle(type); |
||||
RTextScrollPane sqlTextScrollPane = new RTextScrollPane(editorPane); |
||||
sqlTextScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); |
||||
sqlTextScrollPane.setPreferredSize(new Dimension(680, height)); |
||||
sqlTextScrollPane.setLineNumbersEnabled(false); |
||||
return sqlTextScrollPane; |
||||
} |
||||
} |
@ -0,0 +1,40 @@
|
||||
package com.fr.plugin.db.redis.util; |
||||
|
||||
import com.eclipsesource.v8.V8Object; |
||||
import com.fr.base.Parameter; |
||||
import com.fr.base.TemplateUtils; |
||||
import com.fr.stable.ArrayUtils; |
||||
|
||||
import java.lang.reflect.Method; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-03-18 |
||||
*/ |
||||
public class RedisUtils { |
||||
|
||||
public static String calculateQuery(String query, Parameter[] ps) { |
||||
if (ArrayUtils.isEmpty(ps)) { |
||||
return query; |
||||
} |
||||
Map<String, Object> map = new HashMap<String, Object>(); |
||||
for (Parameter p : ps) { |
||||
map.put(p.getName(), p.getValue()); |
||||
} |
||||
try { |
||||
return TemplateUtils.renderParameter4Tpl(query, map); |
||||
} catch (Exception e) { |
||||
return query; |
||||
} |
||||
} |
||||
|
||||
public static void registerJavaMethods(V8Object v8Object, Object target) { |
||||
Method[] methods = target.getClass().getDeclaredMethods(); |
||||
for (Method m : methods) { |
||||
v8Object.registerJavaMethod(target, m.getName(), m.getName(), m.getParameterTypes()); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue