Browse Source

redis支持脚本转换值

paid
richie 6 years ago
parent
commit
412a4756db
  1. 2
      build.xml
  2. 3
      plugin.xml
  3. 69
      src/main/java/com/fr/plugin/db/redis/core/DataWrapper.java
  4. 17
      src/main/java/com/fr/plugin/db/redis/core/RedisTableData.java
  5. 7
      src/main/java/com/fr/plugin/db/redis/core/RedisTableDataModel.java
  6. 1
      src/main/java/com/fr/plugin/db/redis/core/visit/VisitorFactory.java
  7. 91
      src/main/java/com/fr/plugin/db/redis/core/visit/impl/SingleArrayVisitor.java
  8. 43
      src/main/java/com/fr/plugin/db/redis/ui/RedisQueryPane.java
  9. 8
      src/main/java/com/fr/plugin/db/redis/ui/RedisTableDataPane.java
  10. 2
      src/main/resources/com/fr/plugin/db/redis/locale/redis.properties
  11. 8
      src/main/resources/com/fr/plugin/db/redis/locale/redis_en_US.properties
  12. 8
      src/main/resources/com/fr/plugin/db/redis/locale/redis_zh_CN.properties

2
build.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="jar" name="plugin">
<!-- JDK路径,根据自己机器上实际位置修改-->
<property name="jdk.home" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home"/>
<property name="jdk.home" value="/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home"/>
<property name="libs" value="${basedir}/lib"/>
<property name="publicLibs" value=""/>

3
plugin.xml

@ -3,12 +3,13 @@
<id>com.fr.solution.plugin.db.redis.v10</id>
<name><![CDATA[Redis数据集]]></name>
<active>yes</active>
<version>4.1</version>
<version>4.2</version>
<env-version>10.0</env-version>
<jartime>2018-11-29</jartime>
<vendor>richie</vendor>
<description><![CDATA[可以连接Redis数据库,支持哈希表、列表、集合以及有序集合]]></description>
<change-notes><![CDATA[
[2019-02-15]结果集可以通过JavaScript脚本进行转换。<br/>
[2018-11-30]解决远程设计时无法查询key列表的问题。<br/>
[2018-11-26]解决10.0版本中服务器数据集无法保存的问题。<br/>
[2018-09-12]适配10.0版本。<br/>

69
src/main/java/com/fr/plugin/db/redis/core/DataWrapper.java

@ -1,6 +1,19 @@
package com.fr.plugin.db.redis.core;
import com.fr.general.GeneralUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.script.ScriptFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by richie on 2017/6/5.
@ -31,4 +44,60 @@ public class DataWrapper<T> {
public List<List<T>> getData() {
return data;
}
public void transform(String script) throws ScriptException {
if (StringUtils.isBlank(script)) {
return;
}
String scriptText = null;
if (script.startsWith("file:///")) {
try {
FileInputStream in = new FileInputStream(new File(readAndRenderScriptFile(script)));
scriptText = IOUtils.inputStream2String(in);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
} else {
scriptText = String.format("(function(){%s})()", script);
}
ScriptEngine scriptEngine = ScriptFactory.newScriptEngine();
scriptEngine.put("$content", data);
scriptEngine.put("$column", columnNames);
Object r = scriptEngine.eval(scriptText);
if (r instanceof Map) {
Map<String, Object> map = (Map<String, Object>)r;
if (map.containsKey("column") && map.containsKey("content")) {
Object vector = map.get("column");
List<String> names = new ArrayList<String>();
for (Object name : ((Map)vector).values()) {
names.add(GeneralUtils.objectToString(name));
}
columnNames = names.toArray(new String[0]);
Object content = map.get("content");
if (content instanceof Map) {
List<List<T>> list = new ArrayList<List<T>>();
for (Object element : ((Map)content).values()) {
list.add(object2List(element));
}
data = list;
}
}
}
}
private List<T> object2List(Object obj) {
List<T> list = new ArrayList<T>();
if (obj instanceof Map) {
for (Object element : ((Map)obj).values()) {
list.add((T)element);
}
} else {
list.add((T)obj);
}
return list;
}
private String readAndRenderScriptFile(String filePath) {
return filePath.replaceFirst("\\$ENV_HOME", WorkContext.getCurrent().getPath());
}
}

17
src/main/java/com/fr/plugin/db/redis/core/RedisTableData.java

@ -36,6 +36,7 @@ public class RedisTableData extends AbstractParameterTableData {
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> query = Holders.simple(StringUtils.EMPTY);
private Conf<String> script = Holders.simple(StringUtils.EMPTY);
public void setDatabase(Connection c) {
this.database.set(c);
@ -61,6 +62,14 @@ public class RedisTableData extends AbstractParameterTableData {
this.query.set(query);
}
public String getScript() {
return script.get();
}
public void setScript(String script) {
this.script.set(script);
}
public void setParameters(ParameterProvider[] providers) {
super.setDefaultParameters(providers);
}
@ -83,6 +92,7 @@ public class RedisTableData extends AbstractParameterTableData {
return new RedisTableDataModel(calculator, ps, rc,
orderValue == null ? 0 : orderValue.toIndex(calculator, ps),
calculateQuery(query.get(), ps),
calculateQuery(script.get(), ps),
rowCount);
}
}
@ -126,6 +136,11 @@ public class RedisTableData extends AbstractParameterTableData {
if (isNotNullValue(tmpVal)) {
this.setQuery(tmpVal);
}
} else if ("Script".equals(tmpName)) {
tmpVal = reader.getElementValue();
if (isNotNullValue(tmpVal)) {
this.setScript(tmpVal);
}
}
}
}
@ -138,6 +153,7 @@ public class RedisTableData extends AbstractParameterTableData {
DataCoreXmlUtils.writeXMLConnection(writer, this.database.get());
}
writer.startTAG("Query").textNode(getQuery()).end();
writer.startTAG("Script").textNode(getScript()).end();
}
private boolean isNotNullValue(String value) {
@ -149,6 +165,7 @@ public class RedisTableData extends AbstractParameterTableData {
RedisTableData cloned = (RedisTableData) super.clone();
cloned.database = (Conf<Connection>) database.clone();
cloned.query = (Conf<String>) query.clone();
cloned.script = (Conf<String>) script.clone();
cloned.dbIndex = (Conf<OrderValue>) dbIndex.clone();
return cloned;
}

7
src/main/java/com/fr/plugin/db/redis/core/RedisTableDataModel.java

@ -20,16 +20,16 @@ public class RedisTableDataModel extends AbstractDataModel {
private List<List<Object>> data;
public RedisTableDataModel(Calculator calculator, Parameter[] ps, RedisDatabaseConnection mc, int dbIndex, String query, int rowCount) {
public RedisTableDataModel(Calculator calculator, Parameter[] ps, RedisDatabaseConnection mc, int dbIndex, String query, String script, int rowCount) {
PluginLicense pluginLicense = PluginLicenseManager.getInstance().getPluginLicenseByID(RedisConstants.PLUGIN_ID);
if (pluginLicense.isAvailable()) {
initRedisData(calculator, ps, mc, dbIndex, query, rowCount);
initRedisData(calculator, ps, mc, dbIndex, query, script, rowCount);
} else {
throw new RuntimeException("Redis Plugin License Expired!");
}
}
private synchronized void initRedisData(Calculator calculator, Parameter[] ps, RedisDatabaseConnection mc, int dbIndex, String query, int rowCount) {
private synchronized void initRedisData(Calculator calculator, Parameter[] ps, RedisDatabaseConnection mc, int dbIndex, String query, String script, int rowCount) {
if (StringUtils.isEmpty(query)) {
return;
}
@ -40,6 +40,7 @@ public class RedisTableDataModel extends AbstractDataModel {
}
try {
DataWrapper<Object> wrapper = VisitorFactory.getKeyValueResult(calculator, ps, redisClient, query, rowCount);
wrapper.transform(script);
data = wrapper.getData();
columnNames = wrapper.getColumnNames();
} catch (Exception e) {

1
src/main/java/com/fr/plugin/db/redis/core/visit/VisitorFactory.java

@ -27,7 +27,6 @@ public class VisitorFactory {
visitors.add(new ZRangeVisitor());
visitors.add(new MGetVisitor());
visitors.add(new KeysVisitor());
visitors.add(new SingleArrayVisitor());
}
public static <T> DataWrapper<T> getKeyValueResult(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {

91
src/main/java/com/fr/plugin/db/redis/core/visit/impl/SingleArrayVisitor.java

@ -1,91 +0,0 @@
package com.fr.plugin.db.redis.core.visit.impl;
import com.fr.base.Parameter;
import com.fr.general.FRLogger;
import com.fr.plugin.db.redis.conf.ShellConfigManager;
import com.fr.plugin.db.redis.core.DataWrapper;
import com.fr.plugin.db.redis.core.visit.AbstractVisitor;
import com.fr.script.Calculator;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import redis.clients.jedis.Jedis;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* Created by richie on 2017/6/5.
*/
public class SingleArrayVisitor extends AbstractVisitor<String> {
@Override
public List<List<String>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
String[] arr = query.trim().split(TOKEN_SPACE);
if (ArrayUtils.getLength(arr) < 1) {
throw new IllegalArgumentException("Illegal query:" + query);
}
String shell = ShellConfigManager.getProviderInstance().getShellText();
if (StringUtils.isNotEmpty(shell)) {
for (Parameter parameter : ps) {
shell += " " + parameter.getName() + " " + parameter.getValue();
}
Process process = Runtime.getRuntime().exec(shell);
String statusText = getShellResult(process);
if (isSuccess(statusText)) {
return calculateData(client, arr[1]);
}
}
return null;
}
@Override
public String keyWord() {
return "singlemaparray";
}
private boolean isSuccess(String statusText) {
return "success".equals(statusText);
}
// TODO:richie 只要实现这个方法就可以了,还要处理列名的时候,需要修改下面 buildData方法
private List<List<String>> calculateData(Jedis client, String key) {
String result = client.get(key);
return null;
}
@Override
public DataWrapper<String> buildData(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception {
return super.buildData(calculator, ps, client, query, rowCount);
}
private String getShellResult(Process process) {
String result = null;
try {
ByteArrayOutputStream resultOutStream = new ByteArrayOutputStream();
InputStream errorInStream = new BufferedInputStream(process.getErrorStream());
InputStream processInStream = new BufferedInputStream(process.getInputStream());
int num = 0;
byte[] bs = new byte[1024];
while ((num = errorInStream.read(bs)) != -1) {
resultOutStream.write(bs, 0, num);
}
while ((num = processInStream.read(bs)) != -1) {
resultOutStream.write(bs, 0, num);
}
result = new String(resultOutStream.toByteArray());
errorInStream.close();
processInStream.close();
resultOutStream.close();
} catch (IOException e) {
FRLogger.getLogger().error(e.getMessage(), e);
} finally {
if (process != null) {
process.destroy();
}
}
return result;
}
}

43
src/main/java/com/fr/plugin/db/redis/ui/RedisQueryPane.java

@ -7,18 +7,19 @@ import com.fr.design.dialog.BasicPane;
import com.fr.design.editor.ValueEditorPane;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextarea.DescriptionTextArea;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants;
import com.fr.design.gui.syntax.ui.rtextarea.RTextScrollPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.FRLogger;
import com.fr.general.Inter;
import com.fr.general.SiteCenter;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.db.redis.core.order.OrderValue;
import com.fr.plugin.db.redis.ui.value.IndexValuePaneFactory;
import ij.gui.MultiLineLabel;
import java.awt.*;
import java.awt.event.ActionEvent;
@ -31,12 +32,15 @@ public class RedisQueryPane extends BasicPane {
private SQLEditPane sqlTextPane;
private ValueEditorPane dbIndexEditor;
private RSyntaxTextArea scriptTextPane;
public RedisQueryPane() {
setLayout(new BorderLayout());
sqlTextPane = new SQLEditPane();
scriptTextPane = new RSyntaxTextArea();
dbIndexEditor = IndexValuePaneFactory.createValueEditorPane();
ActionLabel helpLabel = new ActionLabel(Toolkit.i18nText("Plugin-Redis_Help"));
@ -51,25 +55,40 @@ public class RedisQueryPane extends BasicPane {
}
});
DescriptionTextArea descriptionArea = new DescriptionTextArea();
descriptionArea.setWrapStyleWord(true);
descriptionArea.setLineWrap(true);
descriptionArea.setText(Toolkit.i18nText("Plugin-Redis_Script_Text_Description"));
Component[][] coms = new Component[][]{
{new UILabel(Toolkit.i18nText("Plugin-Redis_DB_Index") + ":"), dbIndexEditor},
{GUICoreUtils.createBorderLayoutPane(new UILabel(Toolkit.i18nText("Plugin-Redis_Query_Condition") + ":"), BorderLayout.NORTH), createConditionTextPane(sqlTextPane)}
{GUICoreUtils.createBorderLayoutPane(new UILabel(Toolkit.i18nText("Plugin-Redis_Query_Condition") + ":"), BorderLayout.NORTH), createConditionTextPane(sqlTextPane, SyntaxConstants.SYNTAX_STYLE_SQL, 50)},
{GUICoreUtils.createBorderLayoutPane(
new UILabel(Toolkit.i18nText("Plugin-Redis_Script_Text") + ":"), BorderLayout.NORTH),
GUICoreUtils.createBorderLayoutPane(
createConditionTextPane(scriptTextPane, SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT, 200), BorderLayout.CENTER,
descriptionArea, BorderLayout.SOUTH
),
},
};
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = {p, p};
double[] rowSize = {p, p, p};
double[] columnSize = {p, f};
add(TableLayoutHelper.createTableLayoutPane(coms, rowSize, columnSize));
}
private RTextScrollPane createConditionTextPane(SQLEditPane sqlTextPane) {
sqlTextPane.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SQL);
RTextScrollPane sqlTextScrollPane = new RTextScrollPane(sqlTextPane);
private 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, 300));
sqlTextScrollPane.setPreferredSize(new Dimension(680, height));
sqlTextScrollPane.setLineNumbersEnabled(false);
return sqlTextScrollPane;
}
@ -93,4 +112,12 @@ public class RedisQueryPane extends BasicPane {
public void setOrderValue(OrderValue orderValue) {
dbIndexEditor.populate(orderValue);
}
public String getScript() {
return scriptTextPane.getText();
}
public void setScript(String script) {
scriptTextPane.setText(script);
}
}

8
src/main/java/com/fr/plugin/db/redis/ui/RedisTableDataPane.java

@ -100,7 +100,7 @@ public class RedisTableDataPane extends AbstractTableDataPane<RedisTableData> {
}
private void refresh() {
String[] paramTexts = new String[]{queryPane.getQuery()};
String[] paramTexts = new String[]{queryPane.getQuery(), queryPane.getScript()};
ParameterProvider[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false);
@ -111,7 +111,7 @@ public class RedisTableDataPane extends AbstractTableDataPane<RedisTableData> {
private void checkParameter() {
String[] paramTexts = new String[]{queryPane.getQuery()};
String[] paramTexts = new String[]{queryPane.getQuery(), queryPane.getScript()};
ParameterProvider[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false);
parameters = ArrayUtils.addAll(parameters, queryPane.getOrderValue().analyze4Parameters());
@ -149,6 +149,8 @@ public class RedisTableDataPane extends AbstractTableDataPane<RedisTableData> {
queryPane.setQuery(tableData.getQuery());
queryPane.setScript(tableData.getScript());
queryPane.setOrderValue(tableData.getOrderValue());
}
@ -169,6 +171,8 @@ public class RedisTableDataPane extends AbstractTableDataPane<RedisTableData> {
tableData.setQuery(queryPane.getQuery());
tableData.setScript(queryPane.getScript());
tableData.setOrderValue(queryPane.getOrderValue());
return tableData;

2
src/main/resources/com/fr/plugin/db/redis/locale/redis.properties

@ -14,3 +14,5 @@ Plugin-Redis_Formula=Formula
Plugin-Redis_Query=Query
Plugin-Redis_Connection_Successfully=Connection Successfully
Plugin-Redis_Connection_Failed=Connection Failed
Plugin-Redis_Script_Text=Transform Script
Plugin-Redis_Script_Text_Description=Script Description

8
src/main/resources/com/fr/plugin/db/redis/locale/redis_en_US.properties

@ -8,3 +8,11 @@ Plugin-Redis_Help=Help Doc
Plugin-Redis_Keys_Pattern=Keys Pattern
Plugin-Redis_Keys_Pattern_Search=Search
Plugin-Redis_DB_Index=DB Index
Plugin-Redis_Preview=Preview
Plugin-Redis_Refresh=Refresh
Plugin-Redis_Formula=Formula
Plugin-Redis_Query=Query
Plugin-Redis_Connection_Successfully=Connection Successfully
Plugin-Redis_Connection_Failed=Connection Failed
Plugin-Redis_Script_Text=Transform Script
Plugin-Redis_Script_Text_Description=Script Description

8
src/main/resources/com/fr/plugin/db/redis/locale/redis_zh_CN.properties

@ -9,3 +9,11 @@ Plugin-Redis_Keys_Pattern=\u952E\u503C\u7684\u6B63\u5219\u8868\u8FBE\u5F0F
Plugin-Redis_Keys_Pattern_Search=\u641C\u7D22
Plugin-Redis_DB_Index=\u6570\u636E\u5E93\u7F16\u53F7
Plugin-Redis_Preview=\u9884\u89C8
Plugin-Redis_Refresh=\u5237\u65B0
Plugin-Redis_Formula=\u516C\u5F0F
Plugin-Redis_Query=\u67E5\u8BE2
Plugin-Redis_Connection_Successfully=\u8FDE\u63A5\u6210\u529F
Plugin-Redis_Connection_Failed=\u8FDE\u63A5\u5931\u8D25
Plugin-Redis_Script_Text=\u8F6C\u6362\u811A\u672C
Plugin-Redis_Script_Text_Description=\u53EF\u4EE5\u4F7F\u7528JavaScript\u811A\u672C\u6765\u8F6C\u6362\u67E5\u8BE2\u7ED3\u679C\u3002\n\u6CE8\u610F1\uFF1A\u5185\u7F6E\u53C2\u6570$content\u548C$column\uFF0C\u5206\u522B\u8868\u793A\u539F\u59CB\u7684\u6570\u636E\u96C6\u5185\u5BB9\uFF08\u4E8C\u7EF4\u6570\u7EC4\uFF09\u548C\u6570\u636E\u96C6\u7684\u5217\u540D\uFF08\u4E00\u7EF4\u6570\u7EC4\uFF09\u3002\u5982\u679C\u8FD4\u56DE\u4E00\u4E2A\u4E8C\u7EF4\u6570\u7EC4\uFF0C\u8868\u793A\u4EC5\u4FEE\u6539\u6570\u636E\u96C6\u5185\u5BB9\uFF0C\u4E0D\u4FEE\u6539\u6570\u636E\u96C6\u7684\u5217\u540D\uFF1B\u5982\u679C\u8FD4\u56DE\u4E00\u4E2A\u5982\u4E0B\u683C\u5F0F\u7684\u5BF9\u8C61:\
{content:[][],column:[]}\uFF0C\u8868\u793A\u540C\u65F6\u4FEE\u6539\u4E86\u6570\u636E\u96C6\u7684\u5185\u5BB9\u548C\u5217\u540D\u3002\n\u6CE8\u610F2\uFF1A\u5982\u679C\u5E0C\u671B\u5F15\u7528\u5916\u90E8JS\uFF0C\u53EF\u4EE5\u5728\u811A\u672C\u6846\u4E2D\u5199\u5165file:///$ENV_HOME/transform.js\uFF0C\u5176\u4E2D$ENV_HOME\u8868\u793A\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002
Loading…
Cancel
Save