forked from fanruan/demo-tabledata-redis
richie
6 years ago
commit
b787d0897e
50 changed files with 2476 additions and 0 deletions
@ -0,0 +1,5 @@ |
|||||||
|
*.iml |
||||||
|
.idea/ |
||||||
|
lib/report/*.jar |
||||||
|
target/ |
||||||
|
.DS_Store |
@ -0,0 +1,130 @@ |
|||||||
|
<?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/Contents/Home"/> |
||||||
|
|
||||||
|
<property name="libs" value="${basedir}/lib"/> |
||||||
|
<property name="publicLibs" value=""/> |
||||||
|
<property name="reportLibs" value="${basedir}/../webroot/WEB-INF/lib"/> |
||||||
|
<property name="destLoc" value="."/> |
||||||
|
<property name="classes" value="classes"/> |
||||||
|
<xmlproperty file="${basedir}/plugin.xml"/> |
||||||
|
<property name="current-version" value="${plugin.version}"/> |
||||||
|
|
||||||
|
<!-- 插件版本--> |
||||||
|
<property name="plugin-version" value="${current-version}"/> |
||||||
|
<!-- 插件名字--> |
||||||
|
<property name="plugin-name" value="redis-db"/> |
||||||
|
<property name="plugin-jar" value="fr-plugin-${plugin-name}-${plugin-version}.jar"/> |
||||||
|
|
||||||
|
<target name="prepare"> |
||||||
|
<delete dir="${classes}"/> |
||||||
|
<delete dir="fr-plugin-${plugin-name}-${plugin-version}"/> |
||||||
|
<xmlproperty file="${basedir}/plugin.xml"/> |
||||||
|
<delete dir="${destLoc}/${plugin.name}"/> |
||||||
|
</target> |
||||||
|
<bucket id="compile.classpath"> |
||||||
|
<fileset dir="${libs}"> |
||||||
|
<include name="**/*.jar"/> |
||||||
|
</fileset> |
||||||
|
<fileset dir="${publicLibs}"> |
||||||
|
<include name="**/*.jar"/> |
||||||
|
</fileset> |
||||||
|
<fileset dir="${reportLibs}"> |
||||||
|
<include name="**/*.jar"/> |
||||||
|
</fileset> |
||||||
|
</bucket> |
||||||
|
<patternset id="resources4Jar"> |
||||||
|
<exclude name="**/.settings/**"/> |
||||||
|
<exclude name=".classpath"/> |
||||||
|
<exclude name=".project"/> |
||||||
|
|
||||||
|
<exclude name="**/*.java"/> |
||||||
|
<exclude name="**/*.db"/> |
||||||
|
<exclude name="**/*.g"/> |
||||||
|
<exclude name="**/package.html"/> |
||||||
|
</patternset> |
||||||
|
<target name="copy_resources"> |
||||||
|
<echo message="从${resources_from}拷贝图片,JS,CSS等资源文件"/> |
||||||
|
<delete dir="tmp"/> |
||||||
|
<copy todir="tmp"> |
||||||
|
<fileset dir="${resources_from}/src/main/resources"> |
||||||
|
<patternset refid="resources4Jar"/> |
||||||
|
</fileset> |
||||||
|
</copy> |
||||||
|
<copy todir="${classes}"> |
||||||
|
<fileset dir="tmp"/> |
||||||
|
</copy> |
||||||
|
<delete dir="tmp"/> |
||||||
|
</target> |
||||||
|
<target name="compile_javas"> |
||||||
|
<echo message="编译${compile_files}下的Java文件"/> |
||||||
|
<javac destdir="${classes}" debug="false" optimize="on" source="${source_jdk_version}" |
||||||
|
target="${target_jdk_version}" |
||||||
|
fork="true" memoryMaximumSize="512m" listfiles="false" srcdir="${basedir}" |
||||||
|
executable="${compile_jdk_version}/bin/javac"> |
||||||
|
<src bucket="${basedir}/src/main/java"/> |
||||||
|
<exclude name="**/.svn/**"/> |
||||||
|
<compilerarg line="-encoding UTF8 "/> |
||||||
|
<classpath refid="compile.classpath"/> |
||||||
|
</javac> |
||||||
|
<taskdef name="pretreatment" classname="com.fr.plugin.pack.PluginPretreatmentTask"> |
||||||
|
<classpath refid="compile.classpath"/> |
||||||
|
</taskdef> |
||||||
|
<pretreatment baseDir="${basedir}"/> |
||||||
|
</target> |
||||||
|
|
||||||
|
<target name="jar_classes"> |
||||||
|
<echo message="打Jar包:${jar_name}"/> |
||||||
|
<delete file="${basedir}/${jar_name}"/> |
||||||
|
<jar jarfile="${basedir}/${jar_name}"> |
||||||
|
<fileset dir="${classes}"> |
||||||
|
</fileset> |
||||||
|
</jar> |
||||||
|
</target> |
||||||
|
|
||||||
|
<target name="super_jar" depends="prepare"> |
||||||
|
<antcall target="copy_resources"> |
||||||
|
<param name="resources_from" value="${basedir}"/> |
||||||
|
</antcall> |
||||||
|
<antcall target="compile_javas"> |
||||||
|
<param name="source_jdk_version" value="1.6"/> |
||||||
|
<param name="target_jdk_version" value="1.6"/> |
||||||
|
<param name="compile_jdk_version" value="${jdk.home}"/> |
||||||
|
<param name="compile_files" value="${basedir}/src"/> |
||||||
|
</antcall> |
||||||
|
<echo message="compile plugin success!"/> |
||||||
|
|
||||||
|
<antcall target="jar_classes"> |
||||||
|
<param name="jar_name" value="${plugin-jar}"/> |
||||||
|
</antcall> |
||||||
|
<delete dir="${classes}"/> |
||||||
|
|
||||||
|
</target> |
||||||
|
|
||||||
|
<target name="jar" depends="super_jar"> |
||||||
|
<antcall target="zip"/> |
||||||
|
</target> |
||||||
|
|
||||||
|
<target name="zip"> |
||||||
|
<property name="plugin-folder" value="fr-plugin-${plugin-name}-${plugin-version}"/> |
||||||
|
<echo message="----------zip files----------"/> |
||||||
|
<mkdir dir="${plugin-folder}"/> |
||||||
|
<copy todir="${plugin-folder}"> |
||||||
|
<fileset dir="."> |
||||||
|
<include name="${plugin-jar}"/> |
||||||
|
<include name="plugin.xml"/> |
||||||
|
</fileset> |
||||||
|
<fileset dir="${libs}"> |
||||||
|
<include name="*.jar"/> |
||||||
|
<include name="*.dll"/> |
||||||
|
</fileset> |
||||||
|
</copy> |
||||||
|
<zip destfile="${basedir}/${plugin-folder}.zip" basedir="."> |
||||||
|
<include name="${plugin-folder}/*.jar"/> |
||||||
|
<include name="${plugin-folder}/*.dll"/> |
||||||
|
<include name="${plugin-folder}/plugin.xml"/> |
||||||
|
</zip> |
||||||
|
<move file="${plugin-folder}.zip" todir="${destLoc}/install"/> |
||||||
|
</target> |
||||||
|
</project> |
Binary file not shown.
@ -0,0 +1,29 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||||
|
<plugin> |
||||||
|
<id>com.fr.solution.plugin.db.redis.v10</id> |
||||||
|
<name><![CDATA[Redis数据集]]></name> |
||||||
|
<active>yes</active> |
||||||
|
<version>3.0</version> |
||||||
|
<env-version>10.0</env-version> |
||||||
|
<jartime>2018-08-20</jartime> |
||||||
|
<vendor>richie</vendor> |
||||||
|
<description><![CDATA[可以连接Redis数据库,支持哈希表、列表、集合以及有序集合]]></description> |
||||||
|
<change-notes><![CDATA[ |
||||||
|
[2018-09-12]适配10.0版本。<br/> |
||||||
|
[2018-05-12]增加了keys、hget、hmget、hkeys查询。<br/> |
||||||
|
[2018-05-11]增加连接错误判定。<br/> |
||||||
|
[2018-03-30]增加数据库编号选择。<br/> |
||||||
|
[2017-04-18]连接Redis数据库。<br/> |
||||||
|
]]></change-notes> |
||||||
|
<extra-core> |
||||||
|
<LocaleFinder class="com.fr.plugin.db.redis.RedisLocaleFinder"/> |
||||||
|
</extra-core> |
||||||
|
<extra-report> |
||||||
|
|
||||||
|
</extra-report> |
||||||
|
<extra-designer> |
||||||
|
<ConnectionProvider class="com.fr.plugin.db.redis.RedisConnectionImpl"/> |
||||||
|
<TableDataDefineProvider class="com.fr.plugin.db.redis.RedisTableDataDefine"/> |
||||||
|
<ServerTableDataDefineProvider class="com.fr.plugin.db.redis.RedisTableDataDefine"/> |
||||||
|
</extra-designer> |
||||||
|
</plugin> |
@ -0,0 +1,28 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
|
||||||
|
<parent> |
||||||
|
<groupId>com.fr.plugin</groupId> |
||||||
|
<artifactId>starter</artifactId> |
||||||
|
<version>10.0</version> |
||||||
|
</parent> |
||||||
|
<packaging>jar</packaging> |
||||||
|
<artifactId>demo-tabledata-redis</artifactId> |
||||||
|
<build> |
||||||
|
<!---如果要更改调试插件,改这里的配置就可以了--> |
||||||
|
<outputDirectory>${project.basedir}/../webroot/WEB-INF/plugins/plugin-com.fr.solution.plugin.db.redis.v10-1.0/classes</outputDirectory> |
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||||
|
<artifactId>maven-compiler-plugin</artifactId> |
||||||
|
<configuration> |
||||||
|
<source>6</source> |
||||||
|
<target>6</target> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
</project> |
@ -0,0 +1,42 @@ |
|||||||
|
# 帆软报表连接redis缓存数据库插件 |
||||||
|
## 插件编译 |
||||||
|
进入插件源码目录,执行命名 |
||||||
|
`ant -f build.xml jar` |
||||||
|
即可 |
||||||
|
|
||||||
|
## 插件安装 |
||||||
|
使用帆软设计器自带的插件管理器即可安装。 |
||||||
|
## 插件使用 |
||||||
|
### 新建数据连接 |
||||||
|
安装完插件后,在新建数据连接的地方可以看到Redis类型的数据连接,点击新建后可以看到如下的界面: |
||||||
|
|
||||||
|
![1](screenshots/1.png) |
||||||
|
|
||||||
|
按实际的配置填写上即可。 |
||||||
|
|
||||||
|
### 新建数据集 |
||||||
|
在模板数据集添加的地方会出现Redis数据集: |
||||||
|
|
||||||
|
![1](screenshots/2.png) |
||||||
|
|
||||||
|
点击新建后会出现如下的界面,输入查询条件即可: |
||||||
|
|
||||||
|
![1](screenshots/3.png) |
||||||
|
|
||||||
|
|
||||||
|
### 支持的查询语句 |
||||||
|
|
||||||
|
mget key [key ...] |
||||||
|
|
||||||
|
hgetall key |
||||||
|
|
||||||
|
lrange key 0 -1 |
||||||
|
|
||||||
|
smembers key |
||||||
|
|
||||||
|
zrange key 0 -1 |
||||||
|
|
||||||
|
### 更多查询语句的支持 |
||||||
|
只需要实现com.fr.plugin.db.redis.core.visit.Visitor接口,并在VisitorFactory中注册即可。 |
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 84 KiB |
@ -0,0 +1,35 @@ |
|||||||
|
package com.fr.plugin.db.redis; |
||||||
|
|
||||||
|
import com.fr.data.impl.Connection; |
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.fun.impl.AbstractConnectionProvider; |
||||||
|
import com.fr.plugin.db.redis.core.RedisDatabaseConnection; |
||||||
|
import com.fr.plugin.db.redis.ui.RedisConnectionPane; |
||||||
|
|
||||||
|
public class RedisConnectionImpl extends AbstractConnectionProvider { |
||||||
|
|
||||||
|
@Override |
||||||
|
public int currentAPILevel() { |
||||||
|
return CURRENT_LEVEL; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String nameForConnection() { |
||||||
|
return "Redis"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForConnection() { |
||||||
|
return "/com/fr/plugin/db/redis/images/redis.png"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Class<? extends Connection> classForConnection() { |
||||||
|
return RedisDatabaseConnection.class; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Class<? extends BasicBeanPane<? extends Connection>> appearanceForConnection() { |
||||||
|
return RedisConnectionPane.class; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.fr.plugin.db.redis; |
||||||
|
|
||||||
|
import com.fr.plugin.db.redis.core.RedisConstants; |
||||||
|
import com.fr.stable.fun.Authorize; |
||||||
|
import com.fr.stable.fun.impl.AbstractLocaleFinder; |
||||||
|
|
||||||
|
|
||||||
|
@Authorize(callSignKey = RedisConstants.PLUGIN_ID) |
||||||
|
public class RedisLocaleFinder extends AbstractLocaleFinder { |
||||||
|
@Override |
||||||
|
public String find() { |
||||||
|
return "com/fr/plugin/db/redis/locale/redis"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
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.general.Inter; |
||||||
|
import com.fr.plugin.db.redis.core.RedisTableData; |
||||||
|
import com.fr.plugin.db.redis.ui.RedisTableDataPane; |
||||||
|
|
||||||
|
|
||||||
|
public class RedisTableDataDefine extends AbstractTableDataDefineProvider implements ServerTableDataDefineProvider { |
||||||
|
|
||||||
|
@Override |
||||||
|
public int currentAPILevel() { |
||||||
|
return CURRENT_LEVEL; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Class<? extends TableData> classForTableData() { |
||||||
|
return RedisTableData.class; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Class<? extends TableData> classForInitTableData() { |
||||||
|
return RedisTableData.class; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Class<? extends AbstractTableDataPane> appearanceForTableData() { |
||||||
|
return RedisTableDataPane.class; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String nameForTableData() { |
||||||
|
return Inter.getLocText("Plugin-Redis_Table_Data"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String prefixForTableData() { |
||||||
|
return "redis"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String iconPathForTableData() { |
||||||
|
return "/com/fr/plugin/db/redis/images/redis.png"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,98 @@ |
|||||||
|
package com.fr.plugin.db.redis.conf; |
||||||
|
|
||||||
|
import com.fr.file.XMLFileManager; |
||||||
|
import com.fr.general.GeneralContext; |
||||||
|
import com.fr.stable.EnvChangedListener; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.xml.XMLPrintWriter; |
||||||
|
import com.fr.stable.xml.XMLTools; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
|
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/6/5. |
||||||
|
*/ |
||||||
|
public class ShellConfigManager extends XMLFileManager implements ShellConfigManagerProvider { |
||||||
|
|
||||||
|
private static final String XML_TAG = "ShellConfigManager"; |
||||||
|
|
||||||
|
private static ShellConfigManagerProvider shellManager = null; |
||||||
|
|
||||||
|
|
||||||
|
public synchronized static ShellConfigManager getInstance() { |
||||||
|
return (ShellConfigManager) getProviderInstance(); |
||||||
|
} |
||||||
|
|
||||||
|
public synchronized static ShellConfigManagerProvider getProviderInstance() { |
||||||
|
if (shellManager == null) { |
||||||
|
if (isClusterMember()) { |
||||||
|
return shellManager; |
||||||
|
} |
||||||
|
shellManager.readXMLFile(); |
||||||
|
} |
||||||
|
return shellManager; |
||||||
|
} |
||||||
|
|
||||||
|
private synchronized static boolean isClusterMember() { |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
static { |
||||||
|
GeneralContext.addEnvChangedListener(new EnvChangedListener() { |
||||||
|
public void envChanged() { |
||||||
|
ShellConfigManager.envChanged(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private synchronized static void envChanged() { |
||||||
|
shellManager = null; |
||||||
|
} |
||||||
|
|
||||||
|
private String shellText; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getShellText() { |
||||||
|
return shellText; |
||||||
|
} |
||||||
|
|
||||||
|
public void setShellText(String shellText) { |
||||||
|
this.shellText = shellText; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void readXML(XMLableReader reader) { |
||||||
|
if (reader.isAttr()) { |
||||||
|
shellText = reader.getAttrAsString("shell", StringUtils.EMPTY); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void writeXML(XMLPrintWriter writer) { |
||||||
|
writer.startTAG(XML_TAG); |
||||||
|
writer.attr("shell", shellText); |
||||||
|
writer.end(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String fileName() { |
||||||
|
return "redis.xml"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void readFromInputStream(InputStream input) throws Exception { |
||||||
|
// 服务器端新建一个对象
|
||||||
|
ShellConfigManager manager = new ShellConfigManager(); |
||||||
|
// 从客户端传过来的inputstream中读取对象属性
|
||||||
|
XMLTools.readInputStreamXML(manager, input); |
||||||
|
// 赋值给当前服务器端对象
|
||||||
|
shellManager = manager; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public Object clone() throws CloneNotSupportedException { |
||||||
|
return super.clone(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
package com.fr.plugin.db.redis.conf; |
||||||
|
|
||||||
|
import com.fr.stable.FCloneable; |
||||||
|
import com.fr.stable.file.RemoteXMLFileManagerProvider; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/6/5. |
||||||
|
*/ |
||||||
|
public interface ShellConfigManagerProvider extends RemoteXMLFileManagerProvider, java.io.Serializable, FCloneable { |
||||||
|
|
||||||
|
String getShellText(); |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package com.fr.plugin.db.redis.core; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/6/5. |
||||||
|
*/ |
||||||
|
public class DataWrapper<T> { |
||||||
|
|
||||||
|
public static <T> DataWrapper<T> create(List<List<T>> data, String[] columnNames) { |
||||||
|
return new DataWrapper<T>(data, columnNames); |
||||||
|
} |
||||||
|
|
||||||
|
public static DataWrapper EMPTY = new DataWrapper(null, RedisConstants.DEFAULT_COLUMN_NAMES); |
||||||
|
|
||||||
|
private List<List<T>> data; |
||||||
|
private String[] columnNames; |
||||||
|
|
||||||
|
private DataWrapper(List<List<T>> data, String[] columnNames) { |
||||||
|
this.data = data; |
||||||
|
this.columnNames = columnNames; |
||||||
|
} |
||||||
|
|
||||||
|
public String[] getColumnNames() { |
||||||
|
if (columnNames == null) { |
||||||
|
return RedisConstants.DEFAULT_COLUMN_NAMES; |
||||||
|
} |
||||||
|
return columnNames; |
||||||
|
} |
||||||
|
|
||||||
|
public List<List<T>> getData() { |
||||||
|
return data; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
package com.fr.plugin.db.redis.core; |
||||||
|
|
||||||
|
public class RedisConstants { |
||||||
|
|
||||||
|
public static final String PLUGIN_ID = "com.fr.solution.plugin.db.redis.v10"; |
||||||
|
|
||||||
|
public static final int DEFAULT_DB_INDEX = 0; |
||||||
|
|
||||||
|
public static final String[] DEFAULT_COLUMN_NAMES = new String[]{"text", "value"}; |
||||||
|
} |
@ -0,0 +1,161 @@ |
|||||||
|
package com.fr.plugin.db.redis.core; |
||||||
|
|
||||||
|
import com.fr.data.impl.AbstractDatabaseConnection; |
||||||
|
import com.fr.data.impl.Connection; |
||||||
|
import com.fr.general.Inter; |
||||||
|
import com.fr.stable.CodeUtils; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.xml.XMLPrintWriter; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
import redis.clients.jedis.exceptions.JedisConnectionException; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class RedisDatabaseConnection extends AbstractDatabaseConnection { |
||||||
|
|
||||||
|
private static final int DEFAULT_REDIS_PORT = 6379; |
||||||
|
|
||||||
|
|
||||||
|
private String host; |
||||||
|
private int port = DEFAULT_REDIS_PORT; |
||||||
|
private String password; |
||||||
|
|
||||||
|
public RedisDatabaseConnection() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public String getHost() { |
||||||
|
return host; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHost(String host) { |
||||||
|
this.host = host; |
||||||
|
} |
||||||
|
|
||||||
|
public int getPort() { |
||||||
|
return port; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPort(int port) { |
||||||
|
this.port = port; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPassword() { |
||||||
|
return password; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPassword(String password) { |
||||||
|
this.password = password; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void testConnection() throws Exception { |
||||||
|
Jedis client = createRedisClient(); |
||||||
|
try { |
||||||
|
String text = client.ping(); |
||||||
|
if (!"pong".equalsIgnoreCase(text)) { |
||||||
|
throw new Exception(text); |
||||||
|
} |
||||||
|
} finally { |
||||||
|
client.close(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public Jedis createRedisClient() { |
||||||
|
Jedis client = new Jedis(host, port); |
||||||
|
if (StringUtils.isNotEmpty(password)) { |
||||||
|
client.auth(password); |
||||||
|
} |
||||||
|
return client; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public java.sql.Connection createConnection() throws Exception { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String connectMessage(boolean status) { |
||||||
|
if (status) { |
||||||
|
return Inter.getLocText("Datasource-Connection_successfully") + "!"; |
||||||
|
} else { |
||||||
|
return Inter.getLocText("Datasource-Connection_failed") + "!"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addConnection(List<String> list, String connectionName, Class<? extends Connection>[] acceptTypes) { |
||||||
|
for (Class<? extends com.fr.data.impl.Connection> accept : acceptTypes) { |
||||||
|
if (StableUtils.classInstanceOf(getClass(), accept)) { |
||||||
|
list.add(connectionName); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDriver() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getOriginalCharsetName() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setOriginalCharsetName(String s) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getNewCharsetName() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setNewCharsetName(String s) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void readXML(XMLableReader reader) { |
||||||
|
super.readXML(reader); |
||||||
|
if (reader.isChildNode()) { |
||||||
|
String tagName = reader.getTagName(); |
||||||
|
if ("Attr".equals(tagName)) { |
||||||
|
host = reader.getAttrAsString("host", StringUtils.EMPTY); |
||||||
|
port = reader.getAttrAsInt("port", DEFAULT_REDIS_PORT); |
||||||
|
String pwd = reader.getAttrAsString("password", StringUtils.EMPTY); |
||||||
|
if (StringUtils.isNotEmpty(pwd)) { |
||||||
|
password = CodeUtils.passwordDecode(pwd); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void writeXML(XMLPrintWriter writer) { |
||||||
|
super.writeXML(writer); |
||||||
|
writer.startTAG("Attr"); |
||||||
|
writer.attr("host", host); |
||||||
|
writer.attr("port", port); |
||||||
|
if (StringUtils.isNotEmpty(password)) { |
||||||
|
writer.attr("password", CodeUtils.passwordEncode(password)); |
||||||
|
} |
||||||
|
writer.end(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object clone() throws CloneNotSupportedException { |
||||||
|
com.fr.plugin.db.redis.core.RedisDatabaseConnection cloned = (com.fr.plugin.db.redis.core.RedisDatabaseConnection) super.clone(); |
||||||
|
cloned.host = host; |
||||||
|
cloned.port = port; |
||||||
|
cloned.password = password; |
||||||
|
return cloned; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
package com.fr.plugin.db.redis.core; |
||||||
|
|
||||||
|
public enum RedisMechanism { |
||||||
|
|
||||||
|
NONE(0), SHA1(1),CR(2); |
||||||
|
|
||||||
|
|
||||||
|
private int type; |
||||||
|
RedisMechanism(int type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
|
||||||
|
public int toInt() { |
||||||
|
return type; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static RedisMechanism parse(int type) { |
||||||
|
for (RedisMechanism m : RedisMechanism.values()) { |
||||||
|
if (m.type == type) { |
||||||
|
return m; |
||||||
|
} |
||||||
|
} |
||||||
|
return RedisMechanism.NONE; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,167 @@ |
|||||||
|
package com.fr.plugin.db.redis.core; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.base.TableData; |
||||||
|
import com.fr.base.TemplateUtils; |
||||||
|
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.Inter; |
||||||
|
import com.fr.general.data.DataModel; |
||||||
|
import com.fr.general.xml.GeneralXMLTools; |
||||||
|
import com.fr.plugin.ExtraClassManager; |
||||||
|
import com.fr.plugin.db.redis.core.order.OrderValue; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import com.fr.stable.ParameterProvider; |
||||||
|
import com.fr.stable.fun.FunctionHelper; |
||||||
|
import com.fr.stable.fun.FunctionProcessor; |
||||||
|
import com.fr.stable.fun.impl.AbstractFunctionProcessor; |
||||||
|
import com.fr.stable.xml.XMLPrintWriter; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
|
||||||
|
public class RedisTableData extends AbstractParameterTableData { |
||||||
|
|
||||||
|
private static final FunctionProcessor REDIS = new AbstractFunctionProcessor() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getId() { |
||||||
|
return FunctionHelper.generateFunctionID(RedisConstants.PLUGIN_ID); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getLocaleKey() { |
||||||
|
return "Plugin-Redis_DB"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return Inter.getLocText("Plugin-Redis_DB"); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private Connection database; |
||||||
|
private OrderValue dbIndex; |
||||||
|
private String query; |
||||||
|
|
||||||
|
|
||||||
|
public void setDatabase(Connection c) { |
||||||
|
this.database = c; |
||||||
|
} |
||||||
|
|
||||||
|
public Connection getDatabase() { |
||||||
|
return database; |
||||||
|
} |
||||||
|
|
||||||
|
public OrderValue getOrderValue() { |
||||||
|
return dbIndex; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOrderValue(OrderValue dbIndex) { |
||||||
|
this.dbIndex = dbIndex; |
||||||
|
} |
||||||
|
|
||||||
|
public String getQuery() { |
||||||
|
return query; |
||||||
|
} |
||||||
|
|
||||||
|
public void setQuery(String query) { |
||||||
|
this.query = query; |
||||||
|
} |
||||||
|
|
||||||
|
public void setParameters(ParameterProvider[] providers) { |
||||||
|
super.setDefaultParameters(providers); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DataModel createDataModel(Calculator calculator) { |
||||||
|
return createDataModel(calculator, TableData.RESULT_ALL); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DataModel createDataModel(Calculator calculator, int rowCount) { |
||||||
|
FunctionProcessor processor = ExtraClassManager.getInstance().getFunctionProcessor(); |
||||||
|
if (processor != null) { |
||||||
|
processor.recordFunction(REDIS); |
||||||
|
} |
||||||
|
Parameter[] ps = Parameter.providers2Parameter(getParameters(calculator)); |
||||||
|
if (database instanceof NameDatabaseConnection) { |
||||||
|
String name = ((NameDatabaseConnection) database).getName(); |
||||||
|
RedisDatabaseConnection rc = DatasourceManager.getProviderInstance().getConnection(name, RedisDatabaseConnection.class); |
||||||
|
if (rc != null) { |
||||||
|
return new RedisTableDataModel(calculator, ps, rc, |
||||||
|
dbIndex == null ? 0 : dbIndex.toIndex(calculator, ps), |
||||||
|
calculateQuery(query, ps), |
||||||
|
rowCount); |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private 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 void readXML(XMLableReader reader) { |
||||||
|
super.readXML(reader); |
||||||
|
|
||||||
|
if (reader.isChildNode()) { |
||||||
|
String tmpName = reader.getTagName(); |
||||||
|
String tmpVal; |
||||||
|
|
||||||
|
if (OrderValue.XML_TAG.equals(tmpName)) { |
||||||
|
this.dbIndex = (OrderValue) GeneralXMLTools.readXMLable(reader); |
||||||
|
} 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 ("Query".equals(tmpName)) { |
||||||
|
tmpVal = reader.getElementValue(); |
||||||
|
if (isNotNullValue(tmpVal)) { |
||||||
|
this.setQuery(tmpVal); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void writeXML(XMLPrintWriter writer) { |
||||||
|
super.writeXML(writer); |
||||||
|
GeneralXMLTools.writeXMLable(writer, dbIndex, OrderValue.XML_TAG); |
||||||
|
if (this.database != null) { |
||||||
|
DataCoreXmlUtils.writeXMLConnection(writer, this.database); |
||||||
|
} |
||||||
|
writer.startTAG("Query").textNode(getQuery()).end(); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isNotNullValue(String value) { |
||||||
|
return value != null && !"null".equals(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object clone() throws CloneNotSupportedException { |
||||||
|
RedisTableData cloned = (RedisTableData) super.clone(); |
||||||
|
cloned.database = (Connection) database.clone(); |
||||||
|
cloned.query = query; |
||||||
|
cloned.dbIndex = dbIndex; |
||||||
|
return cloned; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,89 @@ |
|||||||
|
package com.fr.plugin.db.redis.core; |
||||||
|
|
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.data.AbstractDataModel; |
||||||
|
import com.fr.general.FRLogger; |
||||||
|
import com.fr.general.data.TableDataException; |
||||||
|
import com.fr.plugin.PluginLicense; |
||||||
|
import com.fr.plugin.PluginLicenseManager; |
||||||
|
import com.fr.plugin.db.redis.core.visit.VisitorFactory; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.*; |
||||||
|
|
||||||
|
public class RedisTableDataModel extends AbstractDataModel { |
||||||
|
|
||||||
|
private Jedis redisClient; |
||||||
|
private String[] columnNames; |
||||||
|
private List<List<Object>> data; |
||||||
|
|
||||||
|
|
||||||
|
public RedisTableDataModel(Calculator calculator, Parameter[] ps, RedisDatabaseConnection mc, int dbIndex, String query, int rowCount) { |
||||||
|
PluginLicense pluginLicense = PluginLicenseManager.getInstance().getPluginLicenseByID(RedisConstants.PLUGIN_ID); |
||||||
|
if (pluginLicense.isAvailable()) { |
||||||
|
initRedisData(calculator, ps, mc, dbIndex, query, 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) { |
||||||
|
if (StringUtils.isEmpty(query)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (redisClient == null) { |
||||||
|
redisClient = mc.createRedisClient(); |
||||||
|
redisClient.select(dbIndex); |
||||||
|
FRContext.getLogger().info("Connect to redis and select database:" + dbIndex); |
||||||
|
} |
||||||
|
try { |
||||||
|
DataWrapper<Object> wrapper = VisitorFactory.getKeyValueResult(calculator, ps, redisClient, query, rowCount); |
||||||
|
data = wrapper.getData(); |
||||||
|
columnNames = wrapper.getColumnNames(); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new RuntimeException(e.getCause()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getColumnCount() throws TableDataException { |
||||||
|
return columnNames.length; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getColumnName(int columnIndex) throws TableDataException { |
||||||
|
return columnNames[columnIndex]; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean hasRow(int rowIndex) throws TableDataException { |
||||||
|
return data != null && data.get(0).size() > rowIndex; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getRowCount() throws TableDataException { |
||||||
|
return data == null ? 0 : data.get(0).size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) throws TableDataException { |
||||||
|
if (data != null && data.size() > columnIndex) { |
||||||
|
List<Object> columnData = data.get(columnIndex); |
||||||
|
if (columnData != null && columnData.size() > rowIndex) { |
||||||
|
return columnData.get(rowIndex); |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void release() throws Exception { |
||||||
|
if (redisClient != null) { |
||||||
|
redisClient.quit(); |
||||||
|
redisClient = null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.order; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.general.GeneralUtils; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.ParameterProvider; |
||||||
|
import com.fr.stable.xml.XMLPrintWriter; |
||||||
|
import com.fr.stable.xml.XMLable; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
|
||||||
|
public abstract class OrderValue implements XMLable { |
||||||
|
|
||||||
|
private static final long serialVersionUID = -5421898153556627638L; |
||||||
|
|
||||||
|
public static final String XML_TAG = "OrderValue"; |
||||||
|
|
||||||
|
public abstract Object getValue(); |
||||||
|
|
||||||
|
public abstract int toIndex(Calculator cal, Parameter[] ps); |
||||||
|
|
||||||
|
public ParameterProvider[] analyze4Parameters() { |
||||||
|
return new ParameterProvider[0]; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void readXML(XMLableReader reader) { |
||||||
|
if (reader.isChildNode()) { |
||||||
|
String tagName = reader.getTagName(); |
||||||
|
if ("Attr".equals(tagName)) { |
||||||
|
readValue(reader); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void writeXML(XMLPrintWriter writer) { |
||||||
|
writer.startTAG("Attr"); |
||||||
|
writer.attr("value", GeneralUtils.objectToString(getValue())); |
||||||
|
writer.end(); |
||||||
|
} |
||||||
|
|
||||||
|
public abstract void readValue(XMLableReader reader); |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object clone() throws CloneNotSupportedException { |
||||||
|
return super.clone(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.order.impl; |
||||||
|
|
||||||
|
import com.fr.base.BaseFormula; |
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.base.ParameterHelper; |
||||||
|
import com.fr.base.ParameterMapNameSpace; |
||||||
|
import com.fr.general.GeneralUtils; |
||||||
|
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 com.fr.stable.UtilEvalError; |
||||||
|
import com.fr.stable.script.NameSpace; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
|
||||||
|
public class FormulaOrderValue extends OrderValue { |
||||||
|
|
||||||
|
private BaseFormula formula; |
||||||
|
|
||||||
|
public FormulaOrderValue() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public FormulaOrderValue(BaseFormula formula) { |
||||||
|
this.formula = formula; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValue(BaseFormula formula) { |
||||||
|
this.formula = formula; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseFormula getValue() { |
||||||
|
return formula; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int toIndex(Calculator cal, Parameter[] ps) { |
||||||
|
NameSpace nameSpace = ParameterMapNameSpace.create(ps); |
||||||
|
cal.pushNameSpace(nameSpace); |
||||||
|
try { |
||||||
|
return GeneralUtils.objectToNumber(formula.eval(cal)).intValue(); |
||||||
|
} catch (UtilEvalError u) { |
||||||
|
FRContext.getLogger().error(u.getMessage(), u); |
||||||
|
} finally { |
||||||
|
cal.removeNameSpace(nameSpace); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ParameterProvider[] analyze4Parameters() { |
||||||
|
if (formula == null) { |
||||||
|
return new ParameterProvider[0]; |
||||||
|
} |
||||||
|
return ParameterHelper.analyze4ParametersFromFormula(formula.getContent()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void readValue(XMLableReader reader) { |
||||||
|
this.formula = BaseFormula.createFormulaBuilder().build(reader.getAttrAsString("value", StringUtils.EMPTY)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return formula == null ? StringUtils.EMPTY : formula.getPureContent(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.order.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.order.OrderValue; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
|
||||||
|
public class NumberOrderValue extends OrderValue { |
||||||
|
|
||||||
|
private static final long serialVersionUID = -7086244583348467452L; |
||||||
|
private int value; |
||||||
|
|
||||||
|
public NumberOrderValue() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public NumberOrderValue(int value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Integer getValue() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int toIndex(Calculator cal, Parameter[] ps) { |
||||||
|
return getValue(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void readValue(XMLableReader reader) { |
||||||
|
this.value = reader.getAttrAsInt("value", 0); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return value + ""; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.DataWrapper; |
||||||
|
import com.fr.plugin.db.redis.core.RedisConstants; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/5/2. |
||||||
|
*/ |
||||||
|
public abstract class AbstractVisitor<T> implements Visitor<T> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public DataWrapper<T> buildData(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception { |
||||||
|
return DataWrapper.create(getContent(calculator, ps, client, query, rowCount), RedisConstants.DEFAULT_COLUMN_NAMES); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean match(String query) { |
||||||
|
return query.trim().toLowerCase().startsWith(keyWord()); |
||||||
|
} |
||||||
|
|
||||||
|
protected String trimCommand(String cmd) { |
||||||
|
return StringUtils.trim(cmd); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.DataWrapper; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/5/2. |
||||||
|
*/ |
||||||
|
public interface Visitor<T> { |
||||||
|
|
||||||
|
String TOKEN_SPACE = "\\s+"; |
||||||
|
|
||||||
|
List<List<T>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception; |
||||||
|
|
||||||
|
DataWrapper<T> buildData(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception; |
||||||
|
|
||||||
|
boolean match(String query); |
||||||
|
|
||||||
|
String keyWord(); |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.DataWrapper; |
||||||
|
import com.fr.plugin.db.redis.core.visit.impl.*; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/5/2. |
||||||
|
*/ |
||||||
|
public class VisitorFactory { |
||||||
|
|
||||||
|
private static List<Visitor> visitors = new ArrayList<Visitor>(); |
||||||
|
|
||||||
|
static { |
||||||
|
visitors.add(new GetVisitor()); |
||||||
|
visitors.add(new ListVisitor()); |
||||||
|
visitors.add(new HashVisitor()); |
||||||
|
visitors.add(new HashGetVisitor()); |
||||||
|
visitors.add(new HashMGetVisitor()); |
||||||
|
visitors.add(new HashKeysVisitor()); |
||||||
|
visitors.add(new SetVisitor()); |
||||||
|
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 { |
||||||
|
Visitor visitor = getMatchedVisitor(query); |
||||||
|
if (visitor == null) { |
||||||
|
return DataWrapper.EMPTY; |
||||||
|
} else { |
||||||
|
return visitor.buildData(calculator, ps, client, query, rowCount); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static Visitor getMatchedVisitor(String query) { |
||||||
|
for (Visitor visitor : visitors) { |
||||||
|
if (visitor.match(query)) { |
||||||
|
return visitor; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class GetVisitor 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 (arr.length < 2) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
String data = client.get(trimCommand(arr[1])); |
||||||
|
List<String> column = new ArrayList<String>(); |
||||||
|
column.add(data); |
||||||
|
|
||||||
|
List<List<String>> result = new ArrayList<List<String>>(); |
||||||
|
result.add(column); |
||||||
|
result.add(column); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "get"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class HashGetVisitor 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 (arr.length < 3) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
String data = client.hget(trimCommand(arr[1]), trimCommand(arr[2])); |
||||||
|
List<String> column = new ArrayList<String>(); |
||||||
|
column.add(data); |
||||||
|
|
||||||
|
List<List<String>> result = new ArrayList<List<String>>(); |
||||||
|
result.add(column); |
||||||
|
result.add(column); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "hget"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
public class HashKeysVisitor 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 (arr.length < 2) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
Set<String> data = client.hkeys(trimCommand(arr[1])); |
||||||
|
List<String> column = new ArrayList<String>(data); |
||||||
|
|
||||||
|
List<List<String>> result = new ArrayList<List<String>>(); |
||||||
|
result.add(column); |
||||||
|
result.add(column); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "hkeys"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class HashMGetVisitor 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 (arr.length < 3) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
List<String> keys = new ArrayList<String>(); |
||||||
|
for (int i = 2, len = arr.length; i < len; i ++) { |
||||||
|
keys.add(trimCommand(arr[i])); |
||||||
|
} |
||||||
|
String[] fields = keys.toArray(new String[keys.size()]); |
||||||
|
List<String> data = client.hmget(trimCommand(arr[1]), fields); |
||||||
|
|
||||||
|
List<List<String>> result = new ArrayList<List<String>>(); |
||||||
|
result.add(keys); |
||||||
|
result.add(data); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "hmget"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/5/2. |
||||||
|
*/ |
||||||
|
public class HashVisitor 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 (arr.length < 2) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
Map<String, String> map = client.hgetAll(trimCommand(arr[1])); |
||||||
|
List<String> column1 = new ArrayList<String>(); |
||||||
|
List<String> column2 = new ArrayList<String>(); |
||||||
|
for (Map.Entry<String, String> entry : map.entrySet()) { |
||||||
|
column1.add(entry.getKey()); |
||||||
|
column2.add(entry.getValue()); |
||||||
|
} |
||||||
|
List<List<String>> result = new ArrayList<List<String>>(); |
||||||
|
result.add(column1); |
||||||
|
result.add(column2); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "hgetall"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
public class KeysVisitor 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 (arr.length < 2) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
Set<String> data = client.keys(trimCommand(arr[1])); |
||||||
|
List<String> column = new ArrayList<String>(data); |
||||||
|
|
||||||
|
List<List<String>> result = new ArrayList<List<String>>(); |
||||||
|
result.add(column); |
||||||
|
result.add(column); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "keys"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.base.TableData; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/5/2. |
||||||
|
*/ |
||||||
|
public class ListVisitor 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 (arr.length < 4) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
long start = Long.parseLong(trimCommand(arr[2])); |
||||||
|
long end = Long.parseLong(trimCommand(arr[3])); |
||||||
|
if (rowCount != TableData.RESULT_ALL) { |
||||||
|
end = start + rowCount; |
||||||
|
} |
||||||
|
List<String> data = client.lrange(arr[1], start, end); |
||||||
|
List<List<String>> result = new ArrayList<List<String>>(); |
||||||
|
result.add(data); |
||||||
|
result.add(data); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "lrange"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/5/3. |
||||||
|
*/ |
||||||
|
public class MGetVisitor 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 (arr.length < 2) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
String[] args = (String[]) ArrayUtils.remove(arr, 0); |
||||||
|
List<String> data = client.mget(args); |
||||||
|
List<List<String>> result = new ArrayList<List<String>>(); |
||||||
|
result.add(data); |
||||||
|
result.add(data); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "mget"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/5/2. |
||||||
|
*/ |
||||||
|
public class SetVisitor 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 (arr.length < 2) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
Set<String> data = client.smembers(trimCommand(arr[1])); |
||||||
|
List<String> column = new ArrayList<String>(); |
||||||
|
for (String element : data) { |
||||||
|
column.add(element); |
||||||
|
} |
||||||
|
List<List<String>> result = new ArrayList<List<String>>(); |
||||||
|
result.add(column); |
||||||
|
result.add(column); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "smembers"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
package com.fr.plugin.db.redis.core.visit.impl; |
||||||
|
|
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.base.TableData; |
||||||
|
import com.fr.plugin.db.redis.core.visit.AbstractVisitor; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import redis.clients.jedis.Jedis; |
||||||
|
import redis.clients.jedis.Tuple; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by richie on 2017/5/2. |
||||||
|
*/ |
||||||
|
public class ZRangeVisitor extends AbstractVisitor<Object> { |
||||||
|
@Override |
||||||
|
public List<List<Object>> getContent(Calculator calculator, Parameter[] ps, Jedis client, String query, int rowCount) throws Exception { |
||||||
|
String[] arr = query.trim().split(TOKEN_SPACE); |
||||||
|
if (arr.length < 4) { |
||||||
|
throw new IllegalArgumentException("Illegal query:" + query); |
||||||
|
} |
||||||
|
long start = Long.parseLong(trimCommand(arr[2])); |
||||||
|
long end = Long.parseLong(trimCommand(arr[3])); |
||||||
|
if (rowCount != TableData.RESULT_ALL) { |
||||||
|
end = start + rowCount; |
||||||
|
} |
||||||
|
Set<Tuple> data = client.zrangeWithScores(trimCommand(arr[1]), start, end); |
||||||
|
List<Object> column = new ArrayList<Object>(); |
||||||
|
List<Object> value = new ArrayList<Object>(); |
||||||
|
for (Tuple element : data) { |
||||||
|
column.add(element.getElement()); |
||||||
|
value.add(element.getScore()); |
||||||
|
} |
||||||
|
List<List<Object>> result = new ArrayList<List<Object>>(); |
||||||
|
result.add(column); |
||||||
|
result.add(value); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String keyWord() { |
||||||
|
return "zrange"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
package com.fr.plugin.db.redis.ui; |
||||||
|
|
||||||
|
import com.fr.design.border.UITitledBorder; |
||||||
|
import com.fr.design.data.datapane.connect.DatabaseConnectionPane; |
||||||
|
import com.fr.design.gui.ibutton.UIPasswordField; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.itextfield.UIIntNumberField; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.general.Inter; |
||||||
|
import com.fr.plugin.db.redis.core.RedisDatabaseConnection; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
|
||||||
|
public class RedisConnectionPane extends DatabaseConnectionPane<com.fr.plugin.db.redis.core.RedisDatabaseConnection> { |
||||||
|
|
||||||
|
private UITextField hostTextField; |
||||||
|
private UIIntNumberField portNumberField; |
||||||
|
private UIPasswordField passwordTextField; |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected JPanel mainPanel() { |
||||||
|
JPanel pane = new JPanel(); |
||||||
|
pane.setLayout(new BorderLayout()); |
||||||
|
hostTextField = new UITextField(); |
||||||
|
portNumberField = new UIIntNumberField(); |
||||||
|
passwordTextField = new UIPasswordField(); |
||||||
|
|
||||||
|
Component[][] components = new Component[][]{ |
||||||
|
{new UILabel(Inter.getLocText("Plugin-Redis_Host") + ":"), hostTextField}, |
||||||
|
{new UILabel(Inter.getLocText("Plugin-Redis_Port") + ":"), portNumberField}, |
||||||
|
{new UILabel(Inter.getLocText("Plugin-Redis_Password") + ":"), passwordTextField} |
||||||
|
}; |
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
|
||||||
|
double[] rowSize = new double[]{p, p, p, p}; |
||||||
|
double[] columnSize = new double[]{p, 400}; |
||||||
|
|
||||||
|
JPanel settingsUI = TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); |
||||||
|
settingsUI.setBorder(UITitledBorder.createBorderWithTitle("Redis")); |
||||||
|
|
||||||
|
JPanel centerPane = FRGUIPaneFactory.createNormalFlowInnerContainer_M_Pane(); |
||||||
|
|
||||||
|
centerPane.add(settingsUI); |
||||||
|
|
||||||
|
pane.add(centerPane, BorderLayout.CENTER); |
||||||
|
return pane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected boolean isFineBI() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void populateSubDatabaseConnectionBean(RedisDatabaseConnection ob) { |
||||||
|
hostTextField.setText(ob.getHost()); |
||||||
|
portNumberField.setValue(ob.getPort()); |
||||||
|
passwordTextField.setText(ob.getPassword()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected com.fr.plugin.db.redis.core.RedisDatabaseConnection updateSubDatabaseConnectionBean() { |
||||||
|
RedisDatabaseConnection connection = new RedisDatabaseConnection(); |
||||||
|
connection.setHost(hostTextField.getText()); |
||||||
|
connection.setPort((int) portNumberField.getValue()); |
||||||
|
connection.setPassword(passwordTextField.getText()); |
||||||
|
return connection; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return "Redis"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,143 @@ |
|||||||
|
package com.fr.plugin.db.redis.ui; |
||||||
|
|
||||||
|
import com.fr.base.FRContext; |
||||||
|
import com.fr.data.impl.Connection; |
||||||
|
import com.fr.design.data.datapane.connect.ConnectionComboBoxPanel; |
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.itextfield.PlaceholderTextField; |
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.file.DatasourceManager; |
||||||
|
import com.fr.general.Inter; |
||||||
|
import com.fr.plugin.db.redis.ui.event.DataLoadedListener; |
||||||
|
import com.fr.plugin.db.redis.core.RedisDatabaseConnection; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.concurrent.ExecutionException; |
||||||
|
|
||||||
|
|
||||||
|
public class RedisDBConnectionChosePane extends BasicPane { |
||||||
|
|
||||||
|
private ConnectionComboBoxPanel connectionComboBoxPanel; |
||||||
|
private DefaultListModel listModel = new DefaultListModel(); |
||||||
|
private List<DataLoadedListener> listeners = new ArrayList<DataLoadedListener>(); |
||||||
|
private PlaceholderTextField keysPatternTextField; |
||||||
|
|
||||||
|
public RedisDBConnectionChosePane() { |
||||||
|
setLayout(new BorderLayout(4, 4)); |
||||||
|
connectionComboBoxPanel = new ConnectionComboBoxPanel(Connection.class) { |
||||||
|
|
||||||
|
protected void filterConnection(Connection connection, String conName, List<String> nameList) { |
||||||
|
connection.addConnection(nameList, conName, new Class[]{RedisDatabaseConnection.class}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
add(connectionComboBoxPanel, BorderLayout.NORTH); |
||||||
|
connectionComboBoxPanel.addComboBoxActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
loadKeys(); |
||||||
|
} |
||||||
|
}); |
||||||
|
JList list = new JList(listModel); |
||||||
|
|
||||||
|
keysPatternTextField = new PlaceholderTextField(10); |
||||||
|
keysPatternTextField.setPlaceholder(Inter.getLocText("Plugin-Redis_Keys_Pattern")); |
||||||
|
|
||||||
|
JPanel centerPane = new JPanel(new BorderLayout()); |
||||||
|
|
||||||
|
UIButton searchButton = new UIButton(Inter.getLocText("Plugin-Redis_Keys_Pattern_Search")); |
||||||
|
searchButton.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
loadKeys(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
centerPane.add(GUICoreUtils.createBorderLayoutPane( |
||||||
|
keysPatternTextField, BorderLayout.CENTER, |
||||||
|
searchButton, BorderLayout.EAST), BorderLayout.NORTH); |
||||||
|
|
||||||
|
centerPane.add(list, BorderLayout.CENTER); |
||||||
|
|
||||||
|
add(centerPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
private void loadKeys() { |
||||||
|
String name = getSelectRedisConnectionName(); |
||||||
|
if (StringUtils.isEmpty(name)) { |
||||||
|
clearList(); |
||||||
|
fireDataLoaded(ArrayUtils.EMPTY_STRING_ARRAY); |
||||||
|
return; |
||||||
|
} |
||||||
|
RedisDatabaseConnection connection = DatasourceManager.getProviderInstance().getConnection(name, RedisDatabaseConnection.class); |
||||||
|
if (connection != null) { |
||||||
|
listMatchedPatternKeys(connection); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void clearList() { |
||||||
|
listModel.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
private void listMatchedPatternKeys(final RedisDatabaseConnection connection) { |
||||||
|
clearList(); |
||||||
|
new SwingWorker<String[], Void>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String[] doInBackground() throws Exception { |
||||||
|
String keysPattern = keysPatternTextField.getText(); |
||||||
|
if (StringUtils.isEmpty(keysPattern)) { |
||||||
|
return ArrayUtils.EMPTY_STRING_ARRAY; |
||||||
|
} else { |
||||||
|
Set<String> keys = connection.createRedisClient().keys(keysPattern); |
||||||
|
return keys.toArray(new String[keys.size()]); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
try { |
||||||
|
String[] keys = get(); |
||||||
|
for (String name : keys) { |
||||||
|
listModel.addElement(name); |
||||||
|
} |
||||||
|
fireDataLoaded(keys); |
||||||
|
} catch (Exception e) { |
||||||
|
FRContext.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
}.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getSelectRedisConnectionName() { |
||||||
|
return connectionComboBoxPanel.getSelectedItem(); |
||||||
|
} |
||||||
|
|
||||||
|
public void populateConnection(Connection connection) { |
||||||
|
connectionComboBoxPanel.populate(connection); |
||||||
|
} |
||||||
|
|
||||||
|
public void addDataLoadedListener(DataLoadedListener listener) { |
||||||
|
listeners.add(listener); |
||||||
|
} |
||||||
|
|
||||||
|
private void fireDataLoaded(String[] data) { |
||||||
|
for (DataLoadedListener listener : listeners) { |
||||||
|
listener.fireEvent(data); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return "Choose"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
package com.fr.plugin.db.redis.ui; |
||||||
|
|
||||||
|
import com.fr.design.border.UIRoundedBorder; |
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.data.datapane.sqlpane.SQLEditPane; |
||||||
|
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.syntax.ui.rsyntaxtextarea.SyntaxConstants; |
||||||
|
import com.fr.design.gui.syntax.ui.rtextarea.RTextScrollPane; |
||||||
|
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.plugin.db.redis.core.order.OrderValue; |
||||||
|
import com.fr.plugin.db.redis.ui.value.IndexValuePaneFactory; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.io.IOException; |
||||||
|
import java.net.URI; |
||||||
|
|
||||||
|
|
||||||
|
public class RedisQueryPane extends BasicPane { |
||||||
|
|
||||||
|
private SQLEditPane sqlTextPane; |
||||||
|
private ValueEditorPane dbIndexEditor; |
||||||
|
|
||||||
|
public RedisQueryPane() { |
||||||
|
setLayout(new BorderLayout()); |
||||||
|
|
||||||
|
sqlTextPane = new SQLEditPane(); |
||||||
|
|
||||||
|
dbIndexEditor = IndexValuePaneFactory.createValueEditorPane(); |
||||||
|
|
||||||
|
ActionLabel helpLabel = new ActionLabel(Inter.getLocText("Plugin-Redis_Help")); |
||||||
|
helpLabel.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
try { |
||||||
|
Desktop.getDesktop().browse(URI.create(SiteCenter.getInstance().acquireUrlByKind("help.redis"))); |
||||||
|
} catch (IOException e1) { |
||||||
|
FRLogger.getLogger().error(e1.getMessage(), e1); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
Component[][] coms = new Component[][]{ |
||||||
|
{new UILabel(Inter.getLocText("Plugin-Redis_DB_Index") + ":"), dbIndexEditor}, |
||||||
|
{GUICoreUtils.createBorderLayoutPane(new UILabel(Inter.getLocText("Plugin-Redis_Query_Condition") + ":"), BorderLayout.NORTH), createConditionTextPane(sqlTextPane)} |
||||||
|
}; |
||||||
|
|
||||||
|
double p = TableLayout.PREFERRED; |
||||||
|
double f = TableLayout.FILL; |
||||||
|
|
||||||
|
double[] rowSize = {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); |
||||||
|
sqlTextScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); |
||||||
|
sqlTextScrollPane.setPreferredSize(new Dimension(680, 300)); |
||||||
|
return sqlTextScrollPane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return "Query"; |
||||||
|
} |
||||||
|
|
||||||
|
public String getQuery() { |
||||||
|
return sqlTextPane.getText(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setQuery(String query) { |
||||||
|
sqlTextPane.setText(query); |
||||||
|
} |
||||||
|
|
||||||
|
public OrderValue getOrderValue() { |
||||||
|
return (OrderValue) dbIndexEditor.update(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setOrderValue(OrderValue orderValue) { |
||||||
|
dbIndexEditor.populate(orderValue); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,209 @@ |
|||||||
|
package com.fr.plugin.db.redis.ui; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.base.Parameter; |
||||||
|
import com.fr.base.ParameterHelper; |
||||||
|
import com.fr.data.impl.NameDatabaseConnection; |
||||||
|
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.menu.ToolBarDef; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.general.Inter; |
||||||
|
import com.fr.plugin.db.redis.core.RedisTableData; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
import com.fr.stable.ParameterProvider; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.FocusEvent; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
|
||||||
|
public class RedisTableDataPane extends AbstractTableDataPane<RedisTableData> { |
||||||
|
private static final String PREVIEW_BUTTON = Inter.getLocText("Preview"); |
||||||
|
private static final String REFRESH_BUTTON = Inter.getLocText("Refresh"); |
||||||
|
|
||||||
|
private RedisDBConnectionChosePane chosePane; |
||||||
|
|
||||||
|
private UITableEditorPane<ParameterProvider> editorPane; |
||||||
|
|
||||||
|
private RedisQueryPane queryPane; |
||||||
|
|
||||||
|
|
||||||
|
public RedisTableDataPane() { |
||||||
|
this.setLayout(new BorderLayout(4, 4)); |
||||||
|
|
||||||
|
|
||||||
|
Box box = new Box(BoxLayout.Y_AXIS); |
||||||
|
|
||||||
|
|
||||||
|
queryPane = new RedisQueryPane(); |
||||||
|
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 RefreshAction()); |
||||||
|
} |
||||||
|
}; |
||||||
|
editorPane = new UITableEditorPane<ParameterProvider>(model); |
||||||
|
|
||||||
|
|
||||||
|
box.add(northPane); |
||||||
|
|
||||||
|
box.add(queryPane); |
||||||
|
|
||||||
|
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 boolean isPreviewOrRefreshButton(FocusEvent e) { |
||||||
|
if (e.getOppositeComponent() != null) { |
||||||
|
String name = e.getOppositeComponent().getName(); |
||||||
|
return ComparatorUtils.equals(name, PREVIEW_BUTTON) || ComparatorUtils.equals(name, REFRESH_BUTTON); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private JToolBar createToolBar() { |
||||||
|
ToolBarDef toolBarDef = new ToolBarDef(); |
||||||
|
toolBarDef.addShortCut(new PreviewAction()); |
||||||
|
UIToolbar editToolBar = ToolBarDef.createJToolBar(); |
||||||
|
toolBarDef.updateToolBar(editToolBar); |
||||||
|
return editToolBar; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return Inter.getLocText("DS-Database_Query"); |
||||||
|
} |
||||||
|
|
||||||
|
private void refresh() { |
||||||
|
String[] paramTexts = new String[]{queryPane.getQuery()}; |
||||||
|
|
||||||
|
ParameterProvider[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false); |
||||||
|
|
||||||
|
ParameterProvider[] providers = queryPane.getOrderValue().analyze4Parameters(); |
||||||
|
|
||||||
|
editorPane.populate(ArrayUtils.addAll(parameters, providers)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void checkParameter() { |
||||||
|
String[] paramTexts = new String[]{queryPane.getQuery()}; |
||||||
|
|
||||||
|
ParameterProvider[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false); |
||||||
|
parameters = ArrayUtils.addAll(parameters, queryPane.getOrderValue().analyze4Parameters()); |
||||||
|
|
||||||
|
if (parameters.length < 1 && editorPane.update().size() < 1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
boolean isIn = true; |
||||||
|
List<ParameterProvider> list = editorPane.update(); |
||||||
|
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(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(RedisTableData tableData) { |
||||||
|
if (tableData == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
Calculator c = Calculator.createCalculator(); |
||||||
|
editorPane.populate(tableData.getParameters(c)); |
||||||
|
|
||||||
|
chosePane.populateConnection(tableData.getDatabase()); |
||||||
|
|
||||||
|
queryPane.setQuery(tableData.getQuery()); |
||||||
|
|
||||||
|
queryPane.setOrderValue(tableData.getOrderValue()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public RedisTableData updateBean() { |
||||||
|
RedisTableData tableData = new RedisTableData(); |
||||||
|
|
||||||
|
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.setQuery(queryPane.getQuery()); |
||||||
|
|
||||||
|
tableData.setOrderValue(queryPane.getOrderValue()); |
||||||
|
|
||||||
|
return tableData; |
||||||
|
} |
||||||
|
|
||||||
|
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(RedisTableDataPane.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,6 @@ |
|||||||
|
package com.fr.plugin.db.redis.ui.event; |
||||||
|
|
||||||
|
public interface DataLoadedListener { |
||||||
|
|
||||||
|
void fireEvent(String[] data); |
||||||
|
} |
@ -0,0 +1,142 @@ |
|||||||
|
package com.fr.plugin.db.redis.ui.value; |
||||||
|
|
||||||
|
import com.fr.base.BaseFormula; |
||||||
|
import com.fr.design.dialog.DialogActionAdapter; |
||||||
|
import com.fr.design.editor.editor.Editor; |
||||||
|
import com.fr.design.formula.FormulaFactory; |
||||||
|
import com.fr.design.formula.UIFormula; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.plugin.db.redis.core.order.impl.FormulaOrderValue; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
|
||||||
|
public class FormulaEditor extends Editor<FormulaOrderValue> { |
||||||
|
|
||||||
|
private UITextField currentTextField; |
||||||
|
|
||||||
|
private FormulaEditor.ShowPaneListener listener = new FormulaEditor.ShowPaneListener(); |
||||||
|
|
||||||
|
private FormulaOrderValue orderValue = new FormulaOrderValue(BaseFormula.createFormulaBuilder().build()); |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
*/ |
||||||
|
public FormulaEditor() { |
||||||
|
this("公式"); |
||||||
|
} |
||||||
|
|
||||||
|
public FormulaEditor(String name) { |
||||||
|
this(name, null); |
||||||
|
} |
||||||
|
|
||||||
|
public FormulaEditor(String name, FormulaOrderValue formula) { |
||||||
|
if (formula != null) { |
||||||
|
this.orderValue = formula; |
||||||
|
} |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
|
||||||
|
JPanel editPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
currentTextField = new UITextField(28); |
||||||
|
currentTextField.setText(this.orderValue.getValue().getContent()); |
||||||
|
|
||||||
|
editPane.add(currentTextField, BorderLayout.CENTER); |
||||||
|
currentTextField.setEditable(false); |
||||||
|
currentTextField.addMouseListener(listener); |
||||||
|
this.add(editPane, BorderLayout.CENTER); |
||||||
|
this.setName(name); |
||||||
|
} |
||||||
|
|
||||||
|
private class ShowPaneListener extends MouseAdapter { |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
if (currentTextField.isEnabled()) { |
||||||
|
showFormulaPane(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setColumns(int i) { |
||||||
|
this.currentTextField.setColumns(i); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 选中时弹出公式编辑框 |
||||||
|
*/ |
||||||
|
public void selected() { |
||||||
|
showFormulaPane(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) { |
||||||
|
super.setEnabled(enabled); |
||||||
|
currentTextField.setEnabled(enabled); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected void showFormulaPane() { |
||||||
|
final UIFormula formulaPane = FormulaFactory.createFormulaPaneWhenReserveFormula(); |
||||||
|
formulaPane.populate(orderValue.getValue()); |
||||||
|
formulaPane.showLargeWindow(SwingUtilities.getWindowAncestor(FormulaEditor.this), new DialogActionAdapter() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
orderValue.setValue(formulaPane.update()); |
||||||
|
setValue(orderValue); |
||||||
|
fireStateChanged(); |
||||||
|
} |
||||||
|
}).setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Return the value of the CellEditor. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public FormulaOrderValue getValue() { |
||||||
|
return orderValue; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the value to the CellEditor. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void setValue(FormulaOrderValue value) { |
||||||
|
if (value == null) { |
||||||
|
value = new FormulaOrderValue(BaseFormula.createFormulaBuilder().build()); |
||||||
|
} |
||||||
|
this.orderValue = value; |
||||||
|
currentTextField.setText(value.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
public String getIconName() { |
||||||
|
return "type_formula"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* object是否是公司类型对象 |
||||||
|
* |
||||||
|
* @param object 需判断的对象 |
||||||
|
* @return 是公式类型则返回true |
||||||
|
*/ |
||||||
|
public boolean accept(Object object) { |
||||||
|
return object instanceof FormulaOrderValue; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 重置 |
||||||
|
*/ |
||||||
|
public void reset() { |
||||||
|
currentTextField.setText("="); |
||||||
|
orderValue = new FormulaOrderValue(BaseFormula.createFormulaBuilder().build()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 清楚数据 |
||||||
|
*/ |
||||||
|
public void clearData() { |
||||||
|
reset(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package com.fr.plugin.db.redis.ui.value; |
||||||
|
|
||||||
|
import com.fr.design.editor.ValueEditorPane; |
||||||
|
import com.fr.design.editor.ValueEditorPaneFactory; |
||||||
|
import com.fr.design.editor.editor.Editor; |
||||||
|
|
||||||
|
public class IndexValuePaneFactory { |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建带编辑器的ValueEditorPane |
||||||
|
* |
||||||
|
* @return 返回pane |
||||||
|
*/ |
||||||
|
public static ValueEditorPane createValueEditorPane() { |
||||||
|
return ValueEditorPaneFactory.createValueEditorPane(new Editor[]{ |
||||||
|
new IntegerEditor(), |
||||||
|
new FormulaEditor() |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
package com.fr.plugin.db.redis.ui.value; |
||||||
|
|
||||||
|
import com.fr.base.Utils; |
||||||
|
import com.fr.design.editor.editor.Editor; |
||||||
|
import com.fr.design.gui.itextfield.UIIntNumberField; |
||||||
|
import com.fr.design.gui.itextfield.UITextField; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.plugin.db.redis.core.order.impl.NumberOrderValue; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.KeyAdapter; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
import java.awt.event.KeyListener; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class IntegerEditor extends Editor<NumberOrderValue> { |
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
protected UIIntNumberField numberField; // text field.
|
||||||
|
|
||||||
|
protected String oldValue = StringUtils.EMPTY; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
*/ |
||||||
|
public IntegerEditor() { |
||||||
|
this(null, "序号"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructor. |
||||||
|
*/ |
||||||
|
public IntegerEditor(NumberOrderValue value, String name) { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
numberField = new UIIntNumberField(); |
||||||
|
this.add(numberField, BorderLayout.CENTER); |
||||||
|
this.numberField.addKeyListener(textKeyListener); |
||||||
|
this.numberField.setHorizontalAlignment(UITextField.RIGHT); |
||||||
|
this.setValue(value); |
||||||
|
this.setName(name); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void setColumns(int columns) { |
||||||
|
this.numberField.setColumns(columns); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public int getHorizontalAlignment() { |
||||||
|
return this.numberField.getHorizontalAlignment(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void setHorizontalAlignment(int horizontalAlignment) { |
||||||
|
this.numberField.setHorizontalAlignment(horizontalAlignment); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) { |
||||||
|
this.numberField.setEnabled(enabled); |
||||||
|
} |
||||||
|
|
||||||
|
public void selected() { |
||||||
|
this.requestFocus(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getIconName() { |
||||||
|
return "type_double"; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void requestFocus() { |
||||||
|
this.numberField.requestFocus(); |
||||||
|
} |
||||||
|
|
||||||
|
KeyListener textKeyListener = new KeyAdapter() { |
||||||
|
|
||||||
|
public void keyReleased(KeyEvent evt) { |
||||||
|
int code = evt.getKeyCode(); |
||||||
|
|
||||||
|
if (code == KeyEvent.VK_ESCAPE) { |
||||||
|
numberField.setText(oldValue); |
||||||
|
} |
||||||
|
if (code == KeyEvent.VK_ENTER) { |
||||||
|
fireEditingStopped(); |
||||||
|
} else { |
||||||
|
fireStateChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
public NumberOrderValue getValue() { |
||||||
|
return new NumberOrderValue((int)this.numberField.getValue()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setValue(NumberOrderValue value) { |
||||||
|
if (value == null) { |
||||||
|
value = new NumberOrderValue(0); |
||||||
|
} |
||||||
|
this.numberField.setValue(value.getValue()); |
||||||
|
oldValue = Utils.objectToString(value); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean accept(Object object) { |
||||||
|
return object != null && object instanceof NumberOrderValue; |
||||||
|
} |
||||||
|
|
||||||
|
} |
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,10 @@ |
|||||||
|
Plugin-Redis_Host=Host |
||||||
|
Plugin-Redis_Port=Port |
||||||
|
Plugin-Redis_Password=Password |
||||||
|
Plugin-Redis_Table_Data=Redis Table Data |
||||||
|
Plugin-Redis_Query_Condition=Query Condition |
||||||
|
Plugin-Redis_DB=RedisDB |
||||||
|
Plugin-Redis_Help=Help Doc |
||||||
|
Plugin-Redis_Keys_Pattern=Keys Pattern |
||||||
|
Plugin-Redis_Keys_Pattern_Search=Search |
||||||
|
Plugin-Redis_DB_Index=DB Index |
@ -0,0 +1,10 @@ |
|||||||
|
Plugin-Redis_Host=Host |
||||||
|
Plugin-Redis_Port=Port |
||||||
|
Plugin-Redis_Password=Password |
||||||
|
Plugin-Redis_Table_Data=Redis |
||||||
|
Plugin-Redis_Query_Condition=Query Condition |
||||||
|
Plugin-Redis_DB=RedisDB |
||||||
|
Plugin-Redis_Help=Help Doc |
||||||
|
Plugin-Redis_Keys_Pattern=Keys Pattern |
||||||
|
Plugin-Redis_Keys_Pattern_Search=Search |
||||||
|
Plugin-Redis_DB_Index=DB Index |
@ -0,0 +1,10 @@ |
|||||||
|
Plugin-Redis_Host=\u6570\u636E\u5E93\u5730\u5740 |
||||||
|
Plugin-Redis_Port=\u7AEF\u53E3 |
||||||
|
Plugin-Redis_Password=\u5BC6\u7801 |
||||||
|
Plugin-Redis_Table_Data=Redis\u6570\u636E\u96C6 |
||||||
|
Plugin-Redis_Query_Condition=\u67E5\u8BE2\u6761\u4EF6 |
||||||
|
Plugin-Redis_DB=RedisDB\u6570\u636E\u96C6 |
||||||
|
Plugin-Redis_Help=\u5E2E\u52A9\u6587\u6863 |
||||||
|
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 |
Loading…
Reference in new issue