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