├── .gitignore ├── LICENSE ├── README.en.md ├── README.md ├── pom.xml └── tdengine ├── pom.xml └── src └── main ├── java └── com │ └── gitee │ └── dbquery │ └── tdgenie │ ├── AppStartup.java │ ├── common │ ├── constant │ │ └── ConfigConstants.java │ └── enums │ │ └── NodeTypeEnum.java │ ├── gui │ ├── MainController.java │ └── component │ │ ├── ClusterQueryController.java │ │ ├── ConnectionMonitorController.java │ │ ├── DbTabController.java │ │ ├── MonitorController.java │ │ ├── QueryMonitorController.java │ │ ├── QueryTabController.java │ │ ├── RecordTabController.java │ │ ├── StbTabController.java │ │ ├── TableQueryController.java │ │ ├── TableRecordTabController.java │ │ └── UserQueryController.java │ ├── model │ ├── CommonNode.java │ ├── ConnectionModel.java │ ├── DatabaseModel.java │ └── StableModel.java │ ├── sdk │ ├── annotation │ │ └── TdField.java │ ├── constant │ │ └── TdClientConstants.java │ ├── dto │ │ ├── ConnectionDTO.java │ │ ├── QueryRstDTO.java │ │ ├── data │ │ │ └── TsData.java │ │ ├── db │ │ │ ├── DbConfigAddDTO.java │ │ │ └── DbConfigUpdateDTO.java │ │ ├── field │ │ │ └── TableFieldDTO.java │ │ ├── res │ │ │ ├── BaseResDTO.java │ │ │ ├── DatabaseCreateResDTO.java │ │ │ ├── DatabaseResDTO.java │ │ │ ├── StableCreateResDTO.java │ │ │ ├── StableResDTO.java │ │ │ ├── SystemVariableResDTO.java │ │ │ ├── TableCreateResDTO.java │ │ │ ├── TableFieldResDTO.java │ │ │ └── TableResDTO.java │ │ ├── stb │ │ │ ├── StableAddDTO.java │ │ │ └── StableUpdateDTO.java │ │ └── tb │ │ │ ├── TableAddByStableDTO.java │ │ │ ├── TableAddDTO.java │ │ │ └── TableUpdateDTO.java │ ├── enums │ │ └── package-info.java │ ├── exception │ │ ├── DatabaseAlreadyExistException.java │ │ └── TableAlreadyExistException.java │ └── util │ │ ├── DataBaseUtils.java │ │ ├── RestConnectionUtils.java │ │ ├── SuperTableUtils.java │ │ ├── TableUtils.java │ │ ├── TsDataUpdateUtils.java │ │ └── VersionUtils.java │ ├── store │ ├── ApplicationStore.java │ ├── H2ConnectionPool.java │ └── H2DbUtils.java │ └── util │ ├── AlertUtils.java │ ├── ConnectionDAO.java │ ├── ContextMenuUtils.java │ ├── DateTimeUtils.java │ ├── GridPaneUtils.java │ ├── ImageViewUtils.java │ ├── JavaFxBeanUtils.java │ ├── ObjectUtils.java │ ├── PropertiesUtils.java │ ├── TabUtils.java │ ├── TableUtils.java │ ├── TimeUtils.java │ ├── TreeUtils.java │ ├── TsdbConnectionUtils.java │ └── ValueUtils.java └── resources ├── css ├── app.css └── sql-keyword.css ├── fxml ├── component │ ├── cluster_tab.fxml │ ├── connection_monitor_tab.fxml │ ├── db_tab.fxml │ ├── monitor.fxml │ ├── query_monitor_tab.fxml │ ├── query_tab.fxml │ ├── record_tab.fxml │ ├── stb_tab.fxml │ ├── table_query_tab.fxml │ ├── table_record_tab.fxml │ └── user_query_tab.fxml └── main.fxml ├── images ├── cluster.png ├── connection.png ├── connections.png ├── db.png ├── format.png ├── logo.ico ├── logo.png ├── monitor.png ├── query.png ├── query_monitor.png ├── readme │ ├── clusterquery.png │ ├── connectionquery.png │ ├── createConnection.png │ ├── createDB.png │ ├── createSTB.png │ ├── executeSQL.png │ ├── exportDDL.png │ ├── image.png │ ├── insertData.png │ ├── logo.png │ ├── queryStbRecord.png │ ├── querymonitor.png │ ├── start.png │ ├── tableDataQuery.png │ ├── tableQuery.png │ ├── updateData.png │ ├── updateDataSelectItem.png │ └── userquery.png ├── resourceMonitor.png ├── save.png ├── stb.png ├── tb.png ├── tdengine.png └── user_query.png └── logback.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | # it's better to unpack these files and commit the raw source 13 | # git has its own built in compression methods 14 | *.7z 15 | *.dmg 16 | *.gz 17 | *.iso 18 | *.rar 19 | *.tar 20 | *.zip 21 | 22 | # Logs and databases # 23 | ###################### 24 | *.log 25 | 26 | # OS generated files # 27 | ###################### 28 | .DS_Store* 29 | ehthumbs.db 30 | Thumbs.db 31 | 32 | # Editor Files # 33 | ################ 34 | *~ 35 | *.swp 36 | 37 | # Build output directies 38 | /target 39 | **/test-output 40 | **/target 41 | **/bin 42 | build 43 | */build 44 | .m2 45 | 46 | # IntelliJ specific files/directories 47 | out 48 | .idea 49 | *.ipr 50 | *.iws 51 | *.iml 52 | atlassian-ide-plugin.xml 53 | 54 | # Eclipse specific files/directories 55 | .classpath 56 | .project 57 | .settings 58 | .metadata 59 | .factorypath 60 | .generated 61 | 62 | #font 63 | *.ttc 64 | 65 | 66 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 |

2 | logo 3 |

4 | 5 |

Td-Genie v2.1.2

6 |

A free and open-source time-series database management tools for TDengine, offers a graphical user interface tool that provides users with an intuitive and easy-to-use experience for database management and operations!

7 | 8 | ---- 9 | English | [简体中文](README.md) 10 | 11 | #### Description 12 | Td-Genie is a comprehensive and easy-to-use graphical interface tool for TDengine time-series database. The current V2.1.2 version supports the following TDengine Server versions: 13 | 14 | 1. TDengine 2.x version (including 2.6.0.34, which has been tested) 15 | 2. TDengine 3.x version (including 3.2.3.0, which has been tested) 16 | With this tool, users can enjoy a seamless and intuitive experience in managing and operating their TDengine databases. 17 | 18 | Td-Genie's main features include: 19 | 1. Data Connection Management: Ability to add, modify, query, and delete data connections. 20 | 2. Database Maintenance: Capability to create, modify, query, and delete databases. 21 | 3. Super Table Maintenance: Functionality to create, modify, query, and delete super tables. 22 | 4. Super Table Data Query: Supports time-based queries and automatically displays data in paginated format. 23 | 5. Data Manipulation: Features to add, update, and copy field values, as well as copy as Insert statements. 24 | 6. Custom SQL Execution: Executes update or query SQLs, displaying results, execution time, and error information. 25 | 7. Resource Monitoring: Provides visibility into database CPU, memory, and disk usage trends. 26 | 8. DDL Export for Databases and Tables: Exports SQL scripts for database and table creation. 27 | 9. Cluster Overview: Displays information about data nodes and management nodes. 28 | 10. User Management: Viewing and managing user accounts. 29 | 11. Connection Monitoring: Monitors established connections. 30 | 12. Query Monitoring: Keeps track of actively executing query SQLs. 31 | 32 | With these features, Td-Genie offers a comprehensive and user-friendly interface for managing and operating TDengine time-series databases, enhancing the overall database management experience. 33 | #### Software Architecture 34 | 35 | Using JavaFX to Implement UI Functions. 36 | 37 | 38 | #### Installation 39 | 40 | 1. Download the latest version from the distribution, extract it, and double-click the td-genie.exe file to execute it.(https://gitee.com/dbquery/td-genie/releases) 41 | 42 | #### Instructions 43 | 44 | 1. Initial interface 45 | ![输入图片说明](tdengine/src/main/resources/images/readme/start.png) 46 | 2. 创建连接(输入连接名称、IP、端口、用户名、密码) 47 | ![输入图片说明](tdengine/src/main/resources/images/readme/createConnection.png) 48 | 3. Create a connection (enter connection name, IP, port, username, password) 49 | ![输入图片说明](tdengine/src/main/resources/images/readme/createDB.png) 50 | 4. Create a super table (input table name, field information) 51 | ![输入图片说明](tdengine/src/main/resources/images/readme/createSTB.png) 52 | 5. View super table data (view all databases under the connection, all super tables under the database, support searching data in the super table by time, pagination query, and the ability to copy query results in the table) 53 | ![输入图片说明](tdengine/src/main/resources/images/readme/queryStbRecord.png) 54 | 6. New data (input fields and tag information) 55 | ![输入图片说明](tdengine/src/main/resources/images/readme/insertData.png) 56 | 7. Edit data (input field information) 57 | ![输入图片说明](tdengine/src/main/resources/images/readme/updateDataSelectItem.png) 58 | ![输入图片说明](tdengine/src/main/resources/images/readme/updateData.png) 59 | 8. Custom SQL execution (can execute any SQL, for query SQL, display query results, support saving SQL, beautifying SQL) 60 | ![输入图片说明](tdengine/src/main/resources/images/readme/executeSQL.png) 61 | 9. Resource monitoring and viewing (can view database CPU, memory, and disk usage trends) 62 | ![输入图片说明](tdengine/src/main/resources/images/resourceMonitor.png) 63 | 10. Export Library Table DDL 64 | ![输入图片说明](tdengine/src/main/resources/images/readme/exportDDL.png) 65 | 11. Cluster view (viewing data nodes, managing nodes) 66 | ![输入图片说明](tdengine/src/main/resources/images/readme/clusterquery.png) 67 | 12. User View 68 | ![输入图片说明](tdengine/src/main/resources/images/readme/userquery.png) 69 | 13. Connection monitoring (monitoring established connections) 70 | ![输入图片说明](tdengine/src/main/resources/images/readme/connectionquery.png) 71 | 14. Query monitoring (monitoring executing query SQL) 72 | ![输入图片说明](tdengine/src/main/resources/images/readme/querymonitor.png) 73 | ####Contribution 74 | 75 | Fork the repository 76 | Create Feat_xxx branch 77 | Commit your code 78 | Create Pull Request 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | logo 3 |

4 | 5 |

Td-Genie v2.1.2

6 |

免费开源的TDengine时序数据库图形用户界面工具,为用户提供直观、易用的数据库管理和操作体验!

7 | 8 | ---- 9 | 10 | 简体中文|[English](README.en.md) 11 | 12 | #### 介绍 13 | Td-Genie是一款功能全面、操作简便的TDengine时序数据库图形界面工具,V2.1.2目前支持的TDengine Server版本列表如下: 14 | 1. TDengine2.x版本(2.6.0.34已测试) 15 | 2. TDengine3.x版本(3.2.3.0已测试) 16 | 17 | 主要功能: 18 | 1. 数据连接维护(新增、修改、查询、删除) 19 | 2. 数据库维护(新增、修改、查询、删除) 20 | 3. 超级表维护(新增、修改、查询、删除) 21 | 4. 超级表数据查询(支持按时间查询,自动分页展示) 22 | 5. 普通表数据查看(支持按库、超级表、表名查询,支持查看普通表数据) 23 | 6. 数据操作(新增、更新、复制字段值,复制为Insert语句) 24 | 7. 自定义SQL执行(可执行更新SQL或查询SQL,可展示查询结果、执行耗时、错误信息等) 25 | 8. 资源监控查看(可查看数据库CPU、内存、磁盘使用趋势) 26 | 9. 库表DDL导出(数据库创建SQL、表创建SQL) 27 | 10. 集群查看(查看数据节点、管理节点) 28 | 11. 用户查看 29 | 12. 连接监控(监控已建立的连接) 30 | 13. 查询监控(监控正在执行的查询SQL) 31 | #### 软件架构 32 | 基于JavaFX实现UI功能。 33 | 34 | 35 | #### 安装教程 36 | 37 | 1. 从发行版中下载最新版本,解压,双击执行td-genie.exe文件即可(https://gitee.com/dbquery/td-genie/releases) 38 | 39 | #### 使用说明 40 | 41 | 1. 初始界面 42 | ![输入图片说明](tdengine/src/main/resources/images/readme/start.png) 43 | 2. 创建连接(输入连接名称、IP、端口、用户名、密码) 44 | ![输入图片说明](tdengine/src/main/resources/images/readme/createConnection.png) 45 | 3. 创建数据库(输入数据库名、副本个数、数据保留天数、VNODE内存块数目、文件压缩标志位) 46 | ![输入图片说明](tdengine/src/main/resources/images/readme/createDB.png) 47 | 4. 创建超级表(输入表名称,字段信息) 48 | ![输入图片说明](tdengine/src/main/resources/images/readme/createSTB.png) 49 | 5. 查看超级表数据(查看连接下的所有数据库、数据库下的所有超级表,支持按时间搜索超级表中数据,分页查询,可复制表格中的查询结果) 50 | ![输入图片说明](tdengine/src/main/resources/images/readme/queryStbRecord.png) 51 | 6. 查看普通表(支持按库、超级表、表名查询,支持查看普通表数据) 52 | ![输入图片说明](tdengine/src/main/resources/images/readme/tableQuery.png) 53 | ![输入图片说明](tdengine/src/main/resources/images/readme/tableDataQuery.png) 54 | 7. 新增数据(输入字段和Tag信息) 55 | ![输入图片说明](tdengine/src/main/resources/images/readme/insertData.png) 56 | 8. 编辑数据 (输入字段信息) 57 | ![输入图片说明](tdengine/src/main/resources/images/readme/updateDataSelectItem.png) 58 | ![输入图片说明](tdengine/src/main/resources/images/readme/updateData.png) 59 | 9. 自定义SQL执行(可执行任意SQL,对于查询SQL,可展示查询结果,支持保存SQL、美化SQL) 60 | ![输入图片说明](tdengine/src/main/resources/images/readme/executeSQL.png) 61 | 10. 资源监控查看(可查看数据库CPU、内存、磁盘使用趋势) 62 | ![输入图片说明](tdengine/src/main/resources/images/resourceMonitor.png) 63 | 11. 导出库表DDL 64 | ![输入图片说明](tdengine/src/main/resources/images/readme/exportDDL.png) 65 | 12. 集群查看(查看数据节点、管理节点) 66 | ![输入图片说明](tdengine/src/main/resources/images/readme/clusterquery.png) 67 | 13. 用户查看 68 | ![输入图片说明](tdengine/src/main/resources/images/readme/userquery.png) 69 | 14. 连接监控(监控已建立的连接) 70 | ![输入图片说明](tdengine/src/main/resources/images/readme/connectionquery.png) 71 | 15. 查询监控(监控正在执行的查询SQL) 72 | ![输入图片说明](tdengine/src/main/resources/images/readme/querymonitor.png) 73 | #### 参与贡献 74 | 75 | 1. Fork 本仓库 76 | 2. 新建 Feat_xxx 分支 77 | 3. 提交代码 78 | 4. 新建 Pull Request 79 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.gitee.dbquery 7 | td-genie 8 | pom 9 | 2.1.2 10 | 11 | 12 | 13 | tdengine 14 | 15 | 16 | 1.8 17 | UTF-8 18 | UTF-8 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tdengine/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | td-genie 7 | com.gitee.dbquery 8 | 2.1.2 9 | 10 | 4.0.0 11 | 12 | tdengine 13 | 14 | 15 | UTF-8 16 | UTF-8 17 | 1.8 18 | 10.9 19 | 8.0.10 20 | 8.0.1 21 | 22 | 23 | 24 | 25 | 26 | cn.hutool 27 | hutool-all 28 | 5.5.7 29 | 30 | 31 | com.h2database 32 | h2 33 | 2.2.220 34 | 35 | 36 | com.zaxxer 37 | HikariCP 38 | 4.0.3 39 | 40 | 41 | 42 | org.controlsfx 43 | controlsfx 44 | 11.0.3 45 | 46 | 47 | com.jfoenix 48 | jfoenix 49 | 8.0.10 50 | 51 | 52 | eu.hansolo 53 | tilesfx 54 | 1.6.8 55 | 56 | 57 | io.datafx 58 | core 59 | 8.0.1 60 | 61 | 62 | io.datafx 63 | eventsystem 64 | 8.0.1 65 | 66 | 67 | io.datafx 68 | featuretoggle 69 | 8.0.1 70 | 71 | 72 | io.datafx 73 | flow 74 | 8.0.1 75 | 76 | 77 | io.datafx 78 | injection 79 | 8.0.1 80 | 81 | 82 | javax.inject 83 | javax.inject 84 | 1 85 | 86 | 87 | junit 88 | junit 89 | 4.12 90 | 91 | 92 | 93 | 94 | ch.qos.logback 95 | logback-classic 96 | 1.1.7 97 | 98 | 99 | org.projectlombok 100 | lombok 101 | 1.18.16 102 | 103 | 104 | 105 | org.fxmisc.richtext 106 | richtextfx 107 | 0.10.0 108 | 109 | 110 | com.github.vertical-blank 111 | sql-formatter 112 | 2.0.4 113 | 114 | 115 | com.exe4j 116 | exe4j 117 | 5.0.1 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | org.apache.maven.plugins 126 | maven-compiler-plugin 127 | 3.8.1 128 | 129 | 1.8 130 | 1.8 131 | UTF-8 132 | 133 | 134 | 135 | org.springframework.boot 136 | spring-boot-maven-plugin 137 | 2.3.7.RELEASE 138 | 139 | com.gitee.dbquery.tdgenie.AppStartup 140 | false 141 | true 142 | 143 | 144 | 145 | repackage 146 | 147 | repackage 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/AppStartup.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie; 2 | 3 | import com.gitee.dbquery.tdgenie.gui.MainController; 4 | import com.gitee.dbquery.tdgenie.store.ApplicationStore; 5 | import com.gitee.dbquery.tdgenie.util.PropertiesUtils; 6 | import com.gitee.dbquery.tdgenie.util.ValueUtils; 7 | import com.jfoenix.controls.JFXDecorator; 8 | import com.jfoenix.svg.SVGGlyph; 9 | import io.datafx.controller.context.ApplicationContext; 10 | import io.datafx.controller.flow.Flow; 11 | import io.datafx.controller.flow.FlowHandler; 12 | import io.datafx.controller.flow.container.AnimatedFlowContainer; 13 | import io.datafx.controller.flow.container.ContainerAnimations; 14 | import io.datafx.controller.flow.context.FXMLViewFlowContext; 15 | import io.datafx.controller.flow.context.ViewFlowContext; 16 | import javafx.application.Application; 17 | import javafx.scene.Scene; 18 | import javafx.scene.control.SplitPane; 19 | import javafx.scene.image.Image; 20 | import javafx.scene.paint.Color; 21 | import javafx.stage.Stage; 22 | import javafx.util.Duration; 23 | import lombok.extern.slf4j.Slf4j; 24 | 25 | import java.io.FileInputStream; 26 | import java.io.FileOutputStream; 27 | import java.io.IOException; 28 | import java.util.Properties; 29 | 30 | import static com.gitee.dbquery.tdgenie.common.constant.ConfigConstants.*; 31 | 32 | 33 | /** 34 | * 启动类 35 | * 36 | * @author pc 37 | * @since 2024/01/31 38 | **/ 39 | @Slf4j 40 | public class AppStartup extends Application { 41 | 42 | @FXMLViewFlowContext 43 | private ViewFlowContext flowContext; 44 | 45 | public static Scene scene; 46 | private ApplicationContext applicationContext = ApplicationContext.getInstance(); 47 | public static Properties sysConfigProperties = new Properties(); 48 | 49 | static { 50 | try { 51 | sysConfigProperties.load(new FileInputStream(System.getProperty("user.home") + "/windowState.properties")); 52 | } catch (IOException e) { 53 | log.warn(e.getMessage()); 54 | } 55 | 56 | } 57 | 58 | 59 | @Override 60 | public void start(Stage stage) throws Exception { 61 | // Image 的 url 是 classpath 的相对目录,也可以是一个绝对目录 62 | Image image = new Image("/images/logo.png"); 63 | stage.getIcons().add(image); 64 | 65 | Flow contentFlow = new Flow(MainController.class); 66 | AnimatedFlowContainer container = new AnimatedFlowContainer(Duration.millis(320), ContainerAnimations.SWIPE_LEFT); 67 | flowContext = new ViewFlowContext(); 68 | final FlowHandler contentFlowHandler = contentFlow.createHandler(flowContext); 69 | applicationContext.register(stage, Stage.class); 70 | applicationContext.register("ContentFlowHandler", contentFlowHandler); 71 | contentFlowHandler.start(container); 72 | 73 | JFXDecorator wfxDecorator = new JFXDecorator(stage, container.getView()); 74 | wfxDecorator.setCustomMaximize(true); 75 | wfxDecorator.setGraphic(new SVGGlyph("")); 76 | 77 | scene = new Scene(wfxDecorator); 78 | stage.setTitle("td-genie"); 79 | scene.setFill(Color.TRANSPARENT); 80 | stage.setScene(scene); 81 | stage.setX(PropertiesUtils.getDouble(sysConfigProperties, WINDOW_X_PROPERTY, 100.)); 82 | stage.setY(PropertiesUtils.getDouble(sysConfigProperties, WINDOW_Y_PROPERTY, 100.)); 83 | stage.setWidth(PropertiesUtils.getDouble(sysConfigProperties, WINDOW_WIDTH_PROPERTY, 800.)); 84 | stage.setHeight(PropertiesUtils.getDouble(sysConfigProperties, WINDOW_HEIGHT_PROPERTY, 600.)); 85 | stage.show(); 86 | stage.setOnCloseRequest(event -> { 87 | // 记录窗口位置和大小到本地存储 88 | Properties windowProperties = new Properties(); 89 | windowProperties.put(WINDOW_X_PROPERTY, stage.getX() + ""); 90 | windowProperties.put(WINDOW_Y_PROPERTY, stage.getY() + ""); 91 | windowProperties.put(WINDOW_WIDTH_PROPERTY, stage.getWidth() + ""); 92 | windowProperties.put(WINDOW_HEIGHT_PROPERTY, stage.getHeight() + ""); 93 | windowProperties.put(DIVIDER_POSITIONS, ApplicationStore.getMainPaneLastDividerPositions().toString()); 94 | try { 95 | windowProperties.store(new FileOutputStream(System.getProperty("user.home") + "/windowState.properties"), ""); 96 | } catch (IOException e) { 97 | e.printStackTrace(); 98 | } 99 | }); 100 | /*全局样式*/ 101 | scene.getStylesheets().addAll(AppStartup.class.getResource("/css/app.css").toExternalForm()); 102 | scene.getStylesheets().addAll(AppStartup.class.getResource("/css/sql-keyword.css").toExternalForm()); 103 | System.out.println(Double.parseDouble(ValueUtils.getString(AppStartup.sysConfigProperties.getProperty("dividerPositions"), 0.2))); 104 | ((SplitPane) (scene.lookup("#splitPane"))).setDividerPositions(Double.parseDouble(ValueUtils.getString(AppStartup.sysConfigProperties.getProperty("dividerPositions"), 0.2))); 105 | 106 | com.exe4j.Controller.hide(); 107 | System.out.println("hide..."); 108 | } 109 | 110 | 111 | public static void main(String[] args) { 112 | launch(args); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/common/constant/ConfigConstants.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.common.constant; 2 | 3 | /** 4 | * @author chenpi 5 | * @since 2024/3/25 6 | **/ 7 | public class ConfigConstants { 8 | public static final String WINDOW_X_PROPERTY = "windowX"; 9 | public static final String WINDOW_Y_PROPERTY = "windowY"; 10 | public static final String WINDOW_WIDTH_PROPERTY = "windowWidth"; 11 | public static final String WINDOW_HEIGHT_PROPERTY = "windowHeight"; 12 | public static final String DIVIDER_POSITIONS = "dividerPositions"; 13 | } 14 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/common/enums/NodeTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.common.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * @author 风一样的码农 7 | * @since 2024/2/6 8 | **/ 9 | @Getter 10 | public enum NodeTypeEnum { 11 | /** 12 | * 根节点 13 | */ 14 | ROOT(-1, "根节点"), 15 | /** 16 | * 连接 17 | */ 18 | CONNECTION(1, "连接"), 19 | /** 20 | * 数据库 21 | */ 22 | DB(2, "数据库"), 23 | /** 24 | * 超级表 25 | */ 26 | STB(3, "超级表"), 27 | /** 28 | * 表 29 | */ 30 | TB(4, "表"); 31 | 32 | /** 33 | * 类型 34 | */ 35 | private Integer value; 36 | /** 37 | * 描述 38 | */ 39 | private String desc; 40 | 41 | NodeTypeEnum(Integer value, String desc) { 42 | this.value = value; 43 | this.desc = desc; 44 | } 45 | 46 | /** 47 | * 根据类型获取枚举 48 | * 49 | * @param type 类型 50 | * @return NodeTypeEnum 51 | */ 52 | public static NodeTypeEnum getByType(Integer type) { 53 | for (NodeTypeEnum o : NodeTypeEnum.values()) { 54 | if (o.getValue().equals(type)) { 55 | return o; 56 | } 57 | } 58 | throw new RuntimeException("invalid Node type "); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/gui/component/ClusterQueryController.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.gui.component; 2 | 3 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 4 | import com.gitee.dbquery.tdgenie.model.CommonNode; 5 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 6 | import com.gitee.dbquery.tdgenie.model.DatabaseModel; 7 | import com.gitee.dbquery.tdgenie.model.StableModel; 8 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 9 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 10 | import com.gitee.dbquery.tdgenie.sdk.util.RestConnectionUtils; 11 | import com.gitee.dbquery.tdgenie.store.ApplicationStore; 12 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 13 | import com.gitee.dbquery.tdgenie.util.TableUtils; 14 | import com.gitee.dbquery.tdgenie.util.TsdbConnectionUtils; 15 | import com.jfoenix.controls.JFXButton; 16 | import com.jfoenix.controls.JFXComboBox; 17 | import com.jfoenix.controls.JFXTabPane; 18 | import io.datafx.controller.ViewController; 19 | import io.datafx.controller.flow.action.ActionMethod; 20 | import io.datafx.controller.flow.action.ActionTrigger; 21 | import javafx.beans.property.IntegerProperty; 22 | import javafx.beans.property.ListProperty; 23 | import javafx.beans.property.SimpleIntegerProperty; 24 | import javafx.beans.property.SimpleListProperty; 25 | import javafx.collections.FXCollections; 26 | import javafx.collections.ObservableList; 27 | import javafx.collections.transformation.FilteredList; 28 | import javafx.event.ActionEvent; 29 | import javafx.event.EventHandler; 30 | import javafx.fxml.FXML; 31 | import javafx.scene.control.*; 32 | import javafx.scene.control.cell.MapValueFactory; 33 | import javafx.scene.input.Clipboard; 34 | import javafx.scene.input.ClipboardContent; 35 | import javafx.scene.layout.HBox; 36 | import javafx.scene.layout.StackPane; 37 | import javafx.scene.text.Text; 38 | 39 | import javax.annotation.PostConstruct; 40 | import javax.annotation.PreDestroy; 41 | import java.util.HashMap; 42 | import java.util.Map; 43 | 44 | /** 45 | * CommonTabController 46 | * 47 | * @author pc 48 | * @since 2024/01/31 49 | **/ 50 | @ViewController(value = "/fxml/component/cluster_tab.fxml") 51 | public class ClusterQueryController { 52 | 53 | 54 | @FXML 55 | private Label pageInformation; 56 | @FXML 57 | private Label selectLocInfo; 58 | @FXML 59 | private Pagination pagination; 60 | @FXML 61 | private StackPane rootPane; 62 | @FXML 63 | private TableView> tableView; 64 | 65 | @FXML 66 | private JFXTabPane executeResultTabPane; 67 | @FXML 68 | private JFXComboBox connectionComboBox; 69 | @FXML 70 | private JFXComboBox nodeTypeComboBox; 71 | @FXML 72 | private Text executeSql; 73 | @FXML 74 | private Text executeStatus; 75 | @FXML 76 | private Text executeCost; 77 | @FXML 78 | @ActionTrigger("executeQuery") 79 | private JFXButton executeButton; 80 | @FXML 81 | private HBox prettySqlBox; 82 | @FXML 83 | private HBox saveSqlBox; 84 | private IntegerProperty pageCount = new SimpleIntegerProperty(); 85 | private ListProperty> dataModelMapList = new SimpleListProperty<>(FXCollections.observableArrayList()); 86 | 87 | 88 | @ActionMethod("executeQuery") 89 | private void executeQuery() { 90 | showPage(1); 91 | } 92 | 93 | 94 | @PostConstruct 95 | public void init() { 96 | 97 | rootPane.setOnContextMenuRequested(event -> { 98 | event.consume(); // 标记事件已被处理,防止默认的上下文菜单显示 99 | }); 100 | 101 | 102 | if (ApplicationStore.getConnectionTree() != null) { 103 | ApplicationStore.getConnectionTree().getChildren().forEach(d -> { 104 | connectionComboBox.getItems().add(d.getValue().getName()); 105 | }); 106 | } 107 | 108 | 109 | if (null == ApplicationStore.getCurrentNode()) { 110 | if(connectionComboBox.getItems().size()>0) { 111 | connectionComboBox.getSelectionModel().select(0); 112 | } 113 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.CONNECTION) { 114 | ConnectionModel connectionModel = (ConnectionModel) ApplicationStore.getCurrentNode().getData(); 115 | 116 | connectionComboBox.getSelectionModel().select(connectionModel.getName()); 117 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.DB) { 118 | DatabaseModel databaseModel = (DatabaseModel) ApplicationStore.getCurrentNode().getData(); 119 | 120 | connectionComboBox.getSelectionModel().select(databaseModel.getConnectionModel().getName()); 121 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.STB) { 122 | StableModel stableModel = (StableModel) ApplicationStore.getCurrentNode().getData(); 123 | DatabaseModel databaseModel = stableModel.getDb(); 124 | connectionComboBox.getSelectionModel().select(databaseModel.getConnectionModel().getName()); 125 | } 126 | 127 | nodeTypeComboBox.getItems().add("数据节点"); 128 | nodeTypeComboBox.getItems().add("管理节点"); 129 | nodeTypeComboBox.getSelectionModel().select(0); 130 | 131 | // enable copy/paste 132 | TableUtils.installCopyPasteHandler(tableView); 133 | tableView.getSelectionModel().setCellSelectionEnabled(true); 134 | tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 135 | 136 | MenuItem item = new MenuItem("复制"); 137 | item.setOnAction(new EventHandler() { 138 | @Override 139 | public void handle(ActionEvent event) { 140 | ObservableList posList = tableView.getSelectionModel().getSelectedCells(); 141 | int old_r = -1; 142 | StringBuilder clipboardString = new StringBuilder(); 143 | for (TablePosition p : posList) { 144 | int r = p.getRow(); 145 | int c = p.getColumn(); 146 | Object cell = tableView.getColumns().get(c).getCellData(r); 147 | if (cell == null) { 148 | cell = ""; 149 | } 150 | if (old_r == r) { 151 | clipboardString.append('\t'); 152 | } else if (old_r != -1) { 153 | clipboardString.append('\n'); 154 | } 155 | clipboardString.append(cell); 156 | old_r = r; 157 | } 158 | final ClipboardContent content = new ClipboardContent(); 159 | content.putString(clipboardString.toString()); 160 | Clipboard.getSystemClipboard().setContent(content); 161 | } 162 | }); 163 | ContextMenu menu = new ContextMenu(); 164 | menu.getItems().add(item); 165 | tableView.setContextMenu(menu); 166 | 167 | FilteredList> filteredData = new FilteredList<>(dataModelMapList, p -> true); 168 | tableView.setItems(filteredData); 169 | 170 | pagination.pageCountProperty().bind(pageCount); 171 | pagination.setPageFactory(param -> { 172 | showPage(param + 1); 173 | return tableView; 174 | }); 175 | 176 | showPage(1); 177 | 178 | } 179 | 180 | 181 | private void showPage(Integer page) { 182 | Map queryMap = new HashMap<>(); 183 | queryMap.put("page", page); 184 | query(queryMap); 185 | 186 | } 187 | 188 | private ConnectionModel getConnectionModel(String connectionName) { 189 | 190 | for (TreeItem item : ApplicationStore.getConnectionTree().getChildren()) { 191 | if (item.getValue().getName().equals(connectionName)) { 192 | return (ConnectionModel) item.getValue().getData(); 193 | } 194 | } 195 | 196 | return null; 197 | } 198 | 199 | private void query(Map queryMap) { 200 | if (connectionComboBox.getSelectionModel().isEmpty() || nodeTypeComboBox.getSelectionModel().isEmpty() ) { 201 | return; 202 | } 203 | 204 | String connectionName = connectionComboBox.getSelectionModel().getSelectedItem(); 205 | String nodeType = nodeTypeComboBox.getSelectionModel().getSelectedItem(); 206 | ConnectionModel connectionModel = getConnectionModel(connectionName); 207 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(connectionModel); 208 | 209 | String sql = nodeType.equals("数据节点") ? "show dnodes;" : "show mnodes;"; 210 | processSingleSql(queryMap, sql.trim(), connection); 211 | 212 | 213 | } 214 | 215 | private void processSingleSql(Map queryMap, String sql, ConnectionDTO connection) { 216 | if (ObjectUtils.isEmpty(sql)) { 217 | return; 218 | } 219 | 220 | QueryRstDTO queryRstDTO = null; 221 | try { 222 | queryRstDTO = RestConnectionUtils.executeQuery(connection, sql.replaceAll(";", "")); 223 | } catch (Exception e) { 224 | tableView.getColumns().clear(); 225 | return; 226 | } 227 | 228 | if (null != queryRstDTO) { 229 | tableView.getColumns().clear(); 230 | queryRstDTO.getColumnList().forEach(column -> { 231 | TableColumn, String> tmpColumn = new TableColumn<>(); 232 | tmpColumn.setId(column + "Column"); 233 | tmpColumn.setText(column); 234 | tmpColumn.setCellValueFactory(new MapValueFactory(column)); 235 | tableView.getColumns().add(tmpColumn); 236 | }); 237 | 238 | dataModelMapList.clear(); 239 | queryRstDTO.getDataList().forEach(db -> { 240 | db.forEach((k, v) -> { 241 | if (v instanceof Byte[] || v instanceof byte[]) { 242 | db.put(k, new String((byte[]) v)); 243 | } 244 | }); 245 | dataModelMapList.add(db); 246 | }); 247 | } 248 | 249 | 250 | pageCount.setValue(1); 251 | pagination.setMaxPageIndicatorCount(1); 252 | 253 | } 254 | 255 | 256 | @PreDestroy 257 | private void destroy() { 258 | System.err.println("destroy " + this); 259 | } 260 | 261 | 262 | } 263 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/gui/component/ConnectionMonitorController.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.gui.component; 2 | 3 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 4 | import com.gitee.dbquery.tdgenie.model.CommonNode; 5 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 6 | import com.gitee.dbquery.tdgenie.model.DatabaseModel; 7 | import com.gitee.dbquery.tdgenie.model.StableModel; 8 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 9 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 10 | import com.gitee.dbquery.tdgenie.sdk.util.RestConnectionUtils; 11 | import com.gitee.dbquery.tdgenie.store.ApplicationStore; 12 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 13 | import com.gitee.dbquery.tdgenie.util.TableUtils; 14 | import com.gitee.dbquery.tdgenie.util.TsdbConnectionUtils; 15 | import com.jfoenix.controls.JFXButton; 16 | import com.jfoenix.controls.JFXComboBox; 17 | import com.jfoenix.controls.JFXTabPane; 18 | import io.datafx.controller.ViewController; 19 | import io.datafx.controller.flow.action.ActionMethod; 20 | import io.datafx.controller.flow.action.ActionTrigger; 21 | import javafx.beans.property.IntegerProperty; 22 | import javafx.beans.property.ListProperty; 23 | import javafx.beans.property.SimpleIntegerProperty; 24 | import javafx.beans.property.SimpleListProperty; 25 | import javafx.collections.FXCollections; 26 | import javafx.collections.ObservableList; 27 | import javafx.collections.transformation.FilteredList; 28 | import javafx.event.ActionEvent; 29 | import javafx.event.EventHandler; 30 | import javafx.fxml.FXML; 31 | import javafx.scene.control.*; 32 | import javafx.scene.control.cell.MapValueFactory; 33 | import javafx.scene.input.Clipboard; 34 | import javafx.scene.input.ClipboardContent; 35 | import javafx.scene.layout.HBox; 36 | import javafx.scene.layout.StackPane; 37 | import javafx.scene.text.Text; 38 | 39 | import javax.annotation.PostConstruct; 40 | import javax.annotation.PreDestroy; 41 | import java.util.HashMap; 42 | import java.util.Map; 43 | 44 | /** 45 | * CommonTabController 46 | * 47 | * @author pc 48 | * @since 2024/01/31 49 | **/ 50 | @ViewController(value = "/fxml/component/connection_monitor_tab.fxml") 51 | public class ConnectionMonitorController { 52 | 53 | 54 | @FXML 55 | private Label pageInformation; 56 | @FXML 57 | private Label selectLocInfo; 58 | @FXML 59 | private Pagination pagination; 60 | @FXML 61 | private StackPane rootPane; 62 | @FXML 63 | private TableView> tableView; 64 | 65 | @FXML 66 | private JFXTabPane executeResultTabPane; 67 | @FXML 68 | private JFXComboBox connectionComboBox; 69 | @FXML 70 | private Text executeSql; 71 | @FXML 72 | private Text executeStatus; 73 | @FXML 74 | private Text executeCost; 75 | @FXML 76 | @ActionTrigger("executeQuery") 77 | private JFXButton executeButton; 78 | @FXML 79 | private HBox prettySqlBox; 80 | @FXML 81 | private HBox saveSqlBox; 82 | private IntegerProperty pageCount = new SimpleIntegerProperty(); 83 | private ListProperty> dataModelMapList = new SimpleListProperty<>(FXCollections.observableArrayList()); 84 | 85 | 86 | @ActionMethod("executeQuery") 87 | private void executeQuery() { 88 | showPage(1); 89 | } 90 | 91 | 92 | @PostConstruct 93 | public void init() { 94 | 95 | rootPane.setOnContextMenuRequested(event -> { 96 | event.consume(); // 标记事件已被处理,防止默认的上下文菜单显示 97 | }); 98 | 99 | 100 | if (ApplicationStore.getConnectionTree() != null) { 101 | ApplicationStore.getConnectionTree().getChildren().forEach(d -> { 102 | connectionComboBox.getItems().add(d.getValue().getName()); 103 | }); 104 | } 105 | 106 | 107 | if (null == ApplicationStore.getCurrentNode()) { 108 | if(connectionComboBox.getItems().size()>0) { 109 | connectionComboBox.getSelectionModel().select(0); 110 | } 111 | 112 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.CONNECTION) { 113 | ConnectionModel connectionModel = (ConnectionModel) ApplicationStore.getCurrentNode().getData(); 114 | 115 | connectionComboBox.getSelectionModel().select(connectionModel.getName()); 116 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.DB) { 117 | DatabaseModel databaseModel = (DatabaseModel) ApplicationStore.getCurrentNode().getData(); 118 | 119 | connectionComboBox.getSelectionModel().select(databaseModel.getConnectionModel().getName()); 120 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.STB) { 121 | StableModel stableModel = (StableModel) ApplicationStore.getCurrentNode().getData(); 122 | DatabaseModel databaseModel = stableModel.getDb(); 123 | connectionComboBox.getSelectionModel().select(databaseModel.getConnectionModel().getName()); 124 | } 125 | 126 | 127 | 128 | // enable copy/paste 129 | TableUtils.installCopyPasteHandler(tableView); 130 | tableView.getSelectionModel().setCellSelectionEnabled(true); 131 | tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 132 | 133 | MenuItem item = new MenuItem("复制"); 134 | item.setOnAction(new EventHandler() { 135 | @Override 136 | public void handle(ActionEvent event) { 137 | ObservableList posList = tableView.getSelectionModel().getSelectedCells(); 138 | int old_r = -1; 139 | StringBuilder clipboardString = new StringBuilder(); 140 | for (TablePosition p : posList) { 141 | int r = p.getRow(); 142 | int c = p.getColumn(); 143 | Object cell = tableView.getColumns().get(c).getCellData(r); 144 | if (cell == null) { 145 | cell = ""; 146 | } 147 | if (old_r == r) { 148 | clipboardString.append('\t'); 149 | } else if (old_r != -1) { 150 | clipboardString.append('\n'); 151 | } 152 | clipboardString.append(cell); 153 | old_r = r; 154 | } 155 | final ClipboardContent content = new ClipboardContent(); 156 | content.putString(clipboardString.toString()); 157 | Clipboard.getSystemClipboard().setContent(content); 158 | } 159 | }); 160 | ContextMenu menu = new ContextMenu(); 161 | menu.getItems().add(item); 162 | tableView.setContextMenu(menu); 163 | 164 | FilteredList> filteredData = new FilteredList<>(dataModelMapList, p -> true); 165 | tableView.setItems(filteredData); 166 | 167 | pagination.pageCountProperty().bind(pageCount); 168 | pagination.setPageFactory(param -> { 169 | showPage(param + 1); 170 | return tableView; 171 | }); 172 | 173 | showPage(1); 174 | 175 | } 176 | 177 | 178 | private void showPage(Integer page) { 179 | Map queryMap = new HashMap<>(); 180 | queryMap.put("page", page); 181 | query(queryMap); 182 | 183 | } 184 | 185 | private ConnectionModel getConnectionModel(String connectionName) { 186 | 187 | for (TreeItem item : ApplicationStore.getConnectionTree().getChildren()) { 188 | if (item.getValue().getName().equals(connectionName)) { 189 | return (ConnectionModel) item.getValue().getData(); 190 | } 191 | } 192 | 193 | return null; 194 | } 195 | 196 | private void query(Map queryMap) { 197 | if (connectionComboBox.getSelectionModel().isEmpty() ) { 198 | return; 199 | } 200 | 201 | String connectionName = connectionComboBox.getSelectionModel().getSelectedItem(); 202 | ConnectionModel connectionModel = getConnectionModel(connectionName); 203 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(connectionModel); 204 | 205 | String sql = "show connections;"; 206 | processSingleSql(queryMap, sql.trim(), connection); 207 | 208 | 209 | } 210 | 211 | private void processSingleSql(Map queryMap, String sql, ConnectionDTO connection) { 212 | if (ObjectUtils.isEmpty(sql)) { 213 | return; 214 | } 215 | 216 | QueryRstDTO queryRstDTO = null; 217 | try { 218 | queryRstDTO = RestConnectionUtils.executeQuery(connection, sql.replaceAll(";", "")); 219 | } catch (Exception e) { 220 | tableView.getColumns().clear(); 221 | return; 222 | } 223 | 224 | if (null != queryRstDTO) { 225 | tableView.getColumns().clear(); 226 | queryRstDTO.getColumnList().forEach(column -> { 227 | TableColumn, String> tmpColumn = new TableColumn<>(); 228 | tmpColumn.setId(column + "Column"); 229 | tmpColumn.setText(column); 230 | tmpColumn.setCellValueFactory(new MapValueFactory(column)); 231 | tableView.getColumns().add(tmpColumn); 232 | }); 233 | 234 | dataModelMapList.clear(); 235 | queryRstDTO.getDataList().forEach(db -> { 236 | db.forEach((k, v) -> { 237 | if (v instanceof Byte[] || v instanceof byte[]) { 238 | db.put(k, new String((byte[]) v)); 239 | } 240 | }); 241 | dataModelMapList.add(db); 242 | }); 243 | } 244 | 245 | 246 | pageCount.setValue(1); 247 | pagination.setMaxPageIndicatorCount(1); 248 | 249 | } 250 | 251 | 252 | @PreDestroy 253 | private void destroy() { 254 | System.err.println("destroy " + this); 255 | } 256 | 257 | 258 | } 259 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/gui/component/DbTabController.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.gui.component; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.util.RestConnectionUtils; 4 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 5 | import com.gitee.dbquery.tdgenie.util.TsdbConnectionUtils; 6 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 7 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 8 | import com.gitee.dbquery.tdgenie.model.DatabaseModel; 9 | import com.gitee.dbquery.tdgenie.model.StableModel; 10 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 11 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 12 | import com.gitee.dbquery.tdgenie.sdk.util.DataBaseUtils; 13 | import com.gitee.dbquery.tdgenie.sdk.util.SuperTableUtils; 14 | import com.gitee.dbquery.tdgenie.store.ApplicationStore; 15 | import com.gitee.dbquery.tdgenie.util.TableUtils; 16 | import io.datafx.controller.ViewController; 17 | import javafx.beans.property.IntegerProperty; 18 | import javafx.beans.property.ListProperty; 19 | import javafx.beans.property.SimpleIntegerProperty; 20 | import javafx.beans.property.SimpleListProperty; 21 | import javafx.collections.FXCollections; 22 | import javafx.collections.ObservableList; 23 | import javafx.collections.transformation.FilteredList; 24 | import javafx.event.ActionEvent; 25 | import javafx.event.EventHandler; 26 | import javafx.fxml.FXML; 27 | import javafx.scene.control.*; 28 | import javafx.scene.control.cell.MapValueFactory; 29 | import javafx.scene.input.Clipboard; 30 | import javafx.scene.input.ClipboardContent; 31 | import javafx.scene.layout.HBox; 32 | import javafx.scene.layout.VBox; 33 | 34 | import javax.annotation.PostConstruct; 35 | import javax.annotation.PreDestroy; 36 | import java.util.HashMap; 37 | import java.util.Map; 38 | 39 | /** 40 | * CommonTabController 41 | * 42 | * @author pc 43 | * @since 2024/01/31 44 | **/ 45 | @ViewController(value = "/fxml/component/db_tab.fxml") 46 | public class DbTabController { 47 | @FXML 48 | private VBox centPane; 49 | @FXML 50 | private HBox queryBox; 51 | @FXML 52 | private Pagination pagination; 53 | 54 | @FXML 55 | private TableView> tableView; 56 | 57 | 58 | private IntegerProperty pageCount = new SimpleIntegerProperty(); 59 | private ListProperty> dataModelMapList = new SimpleListProperty<>(FXCollections.observableArrayList()); 60 | 61 | @PostConstruct 62 | public void init() { 63 | // enable copy/paste 64 | TableUtils.installCopyPasteHandler(tableView); 65 | tableView.getSelectionModel().setCellSelectionEnabled(true); 66 | tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 67 | 68 | MenuItem item = new MenuItem("复制"); 69 | item.setOnAction(new EventHandler() { 70 | @Override 71 | public void handle(ActionEvent event) { 72 | ObservableList posList = tableView.getSelectionModel().getSelectedCells(); 73 | int old_r = -1; 74 | StringBuilder clipboardString = new StringBuilder(); 75 | for (TablePosition p : posList) { 76 | int r = p.getRow(); 77 | int c = p.getColumn(); 78 | Object cell = tableView.getColumns().get(c).getCellData(r); 79 | if (cell == null) { 80 | cell = ""; 81 | } 82 | if (old_r == r) { 83 | clipboardString.append('\t'); 84 | } else if (old_r != -1) { 85 | clipboardString.append('\n'); 86 | } 87 | clipboardString.append(cell); 88 | old_r = r; 89 | } 90 | final ClipboardContent content = new ClipboardContent(); 91 | content.putString(clipboardString.toString()); 92 | Clipboard.getSystemClipboard().setContent(content); 93 | } 94 | }); 95 | ContextMenu menu = new ContextMenu(); 96 | menu.getItems().add(item); 97 | tableView.setContextMenu(menu); 98 | 99 | FilteredList> filteredData = new FilteredList<>(dataModelMapList, p -> true); 100 | tableView.setItems(filteredData); 101 | 102 | pagination.pageCountProperty().bind(pageCount); 103 | pagination.setPageFactory(param -> { 104 | showPage(param + 1); 105 | return tableView; 106 | }); 107 | 108 | 109 | if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.CONNECTION) { 110 | ConnectionModel connectionModel = (ConnectionModel) ApplicationStore.getCurrentNode().getData(); 111 | QueryRstDTO dbList = DataBaseUtils.getAllDatabase(TsdbConnectionUtils.getConnection(connectionModel)); 112 | 113 | for(String column : dbList.getColumnList()) { 114 | TableColumn, String> dbNameColumn = new TableColumn<>(); 115 | dbNameColumn.setId("column_" + column); 116 | dbNameColumn.setText(column); 117 | dbNameColumn.setCellValueFactory(new MapValueFactory(column)); 118 | tableView.getColumns().add(dbNameColumn); 119 | } 120 | 121 | dataModelMapList.addAll(dbList.getDataList()); 122 | 123 | centPane.getChildren().removeAll(queryBox); 124 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.DB) { 125 | DatabaseModel databaseModel = (DatabaseModel) ApplicationStore.getCurrentNode().getData(); 126 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(databaseModel.getConnectionModel()); 127 | 128 | QueryRstDTO stbList = SuperTableUtils.getAllStable(connection, ApplicationStore.getCurrentNode().getName()); 129 | 130 | for(String column : stbList.getColumnList()) { 131 | TableColumn, String> dbNameColumn = new TableColumn<>(); 132 | dbNameColumn.setId("column_" + column); 133 | dbNameColumn.setText(column); 134 | dbNameColumn.setCellValueFactory(new MapValueFactory(column)); 135 | tableView.getColumns().add(dbNameColumn); 136 | } 137 | 138 | dataModelMapList.addAll(stbList.getDataList()); 139 | 140 | 141 | 142 | centPane.getChildren().removeAll(queryBox); 143 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.STB) { 144 | StableModel stableModel = (StableModel) ApplicationStore.getCurrentNode().getData(); 145 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(stableModel.getDb().getConnectionModel()); 146 | QueryRstDTO queryRstDTO = RestConnectionUtils.executeQuery(connection, "select * from `" + stableModel.getDb().getName() + "`.`" + 147 | stableModel.getStb().get("name") + "` limit 1, 10"); 148 | 149 | queryRstDTO.getColumnList().forEach(column -> { 150 | TableColumn, String> tmpColumn = new TableColumn<>(); 151 | tmpColumn.setId(column + "Column"); 152 | tmpColumn.setText(column); 153 | tmpColumn.setCellValueFactory(new MapValueFactory(column)); 154 | tableView.getColumns().add(tmpColumn); 155 | }); 156 | 157 | queryRstDTO.getDataList().forEach(db -> { 158 | db.forEach((k, v) -> { 159 | if (v instanceof Byte[] || v instanceof byte[]) { 160 | db.put(k, new String((byte[]) v)); 161 | } 162 | }); 163 | dataModelMapList.add(db); 164 | }); 165 | 166 | 167 | } 168 | 169 | 170 | } 171 | 172 | 173 | private void showPage(Integer page) { 174 | Map queryMap = new HashMap<>(); 175 | queryMap.put("page", page); 176 | query(queryMap); 177 | 178 | } 179 | 180 | 181 | private void query(Map queryMap) { 182 | 183 | if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.STB) { 184 | Integer page = (Integer) queryMap.get("page"); 185 | int start = (page - 1) * 1000; 186 | StableModel stableModel = (StableModel) ApplicationStore.getCurrentNode().getData(); 187 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(stableModel.getDb().getConnectionModel()); 188 | QueryRstDTO queryRstDTO = RestConnectionUtils.executeQuery(connection, "select * from `" + stableModel.getDb().getName() + "`.`" + 189 | stableModel.getStb().get("name") + "` limit " + start + ", " + 1000); 190 | 191 | tableView.getColumns().clear(); 192 | queryRstDTO.getColumnList().forEach(column -> { 193 | TableColumn, String> tmpColumn = new TableColumn<>(); 194 | tmpColumn.setId(column + "Column"); 195 | tmpColumn.setText(column); 196 | tmpColumn.setCellValueFactory(new MapValueFactory(column)); 197 | tableView.getColumns().add(tmpColumn); 198 | }); 199 | 200 | dataModelMapList.clear(); 201 | queryRstDTO.getDataList().forEach(db -> { 202 | db.forEach((k, v) -> { 203 | if (v instanceof Byte[] || v instanceof byte[]) { 204 | db.put(k, new String((byte[]) v)); 205 | } 206 | }); 207 | dataModelMapList.add(db); 208 | }); 209 | 210 | 211 | QueryRstDTO countRstDTO = RestConnectionUtils.executeQuery(connection, "select count(*) from `" + stableModel.getDb().getName() + "`.`" + 212 | stableModel.getStb().get("name") + "`") ; 213 | long total = ObjectUtils.isEmpty(countRstDTO.getDataList()) ? 0 : (long) countRstDTO.getDataList().get(0).get("count(*)"); 214 | pageCount.setValue((total / 1000) + 1); 215 | } 216 | 217 | } 218 | 219 | 220 | @PreDestroy 221 | private void destroy() { 222 | System.err.println("destroy " + this); 223 | } 224 | 225 | 226 | } 227 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/gui/component/QueryMonitorController.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.gui.component; 2 | 3 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 4 | import com.gitee.dbquery.tdgenie.model.CommonNode; 5 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 6 | import com.gitee.dbquery.tdgenie.model.DatabaseModel; 7 | import com.gitee.dbquery.tdgenie.model.StableModel; 8 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 9 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 10 | import com.gitee.dbquery.tdgenie.sdk.util.RestConnectionUtils; 11 | import com.gitee.dbquery.tdgenie.store.ApplicationStore; 12 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 13 | import com.gitee.dbquery.tdgenie.util.TableUtils; 14 | import com.gitee.dbquery.tdgenie.util.TsdbConnectionUtils; 15 | import com.jfoenix.controls.JFXButton; 16 | import com.jfoenix.controls.JFXComboBox; 17 | import com.jfoenix.controls.JFXTabPane; 18 | import io.datafx.controller.ViewController; 19 | import io.datafx.controller.flow.action.ActionMethod; 20 | import io.datafx.controller.flow.action.ActionTrigger; 21 | import javafx.beans.property.IntegerProperty; 22 | import javafx.beans.property.ListProperty; 23 | import javafx.beans.property.SimpleIntegerProperty; 24 | import javafx.beans.property.SimpleListProperty; 25 | import javafx.collections.FXCollections; 26 | import javafx.collections.ObservableList; 27 | import javafx.collections.transformation.FilteredList; 28 | import javafx.event.ActionEvent; 29 | import javafx.event.EventHandler; 30 | import javafx.fxml.FXML; 31 | import javafx.scene.control.*; 32 | import javafx.scene.control.cell.MapValueFactory; 33 | import javafx.scene.input.Clipboard; 34 | import javafx.scene.input.ClipboardContent; 35 | import javafx.scene.layout.HBox; 36 | import javafx.scene.layout.StackPane; 37 | import javafx.scene.text.Text; 38 | 39 | import javax.annotation.PostConstruct; 40 | import javax.annotation.PreDestroy; 41 | import java.util.HashMap; 42 | import java.util.Map; 43 | 44 | /** 45 | * CommonTabController 46 | * 47 | * @author pc 48 | * @since 2024/01/31 49 | **/ 50 | @ViewController(value = "/fxml/component/connection_monitor_tab.fxml") 51 | public class QueryMonitorController { 52 | 53 | 54 | @FXML 55 | private Label pageInformation; 56 | @FXML 57 | private Label selectLocInfo; 58 | @FXML 59 | private Pagination pagination; 60 | @FXML 61 | private StackPane rootPane; 62 | @FXML 63 | private TableView> tableView; 64 | 65 | @FXML 66 | private JFXTabPane executeResultTabPane; 67 | @FXML 68 | private JFXComboBox connectionComboBox; 69 | @FXML 70 | private Text executeSql; 71 | @FXML 72 | private Text executeStatus; 73 | @FXML 74 | private Text executeCost; 75 | @FXML 76 | @ActionTrigger("executeQuery") 77 | private JFXButton executeButton; 78 | @FXML 79 | private HBox prettySqlBox; 80 | @FXML 81 | private HBox saveSqlBox; 82 | private IntegerProperty pageCount = new SimpleIntegerProperty(); 83 | private ListProperty> dataModelMapList = new SimpleListProperty<>(FXCollections.observableArrayList()); 84 | 85 | 86 | @ActionMethod("executeQuery") 87 | private void executeQuery() { 88 | showPage(1); 89 | } 90 | 91 | 92 | @PostConstruct 93 | public void init() { 94 | 95 | rootPane.setOnContextMenuRequested(event -> { 96 | event.consume(); // 标记事件已被处理,防止默认的上下文菜单显示 97 | }); 98 | 99 | 100 | if (ApplicationStore.getConnectionTree() != null) { 101 | ApplicationStore.getConnectionTree().getChildren().forEach(d -> { 102 | connectionComboBox.getItems().add(d.getValue().getName()); 103 | }); 104 | } 105 | 106 | 107 | if (null == ApplicationStore.getCurrentNode()) { 108 | if(connectionComboBox.getItems().size()>0) { 109 | connectionComboBox.getSelectionModel().select(0); 110 | } 111 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.CONNECTION) { 112 | ConnectionModel connectionModel = (ConnectionModel) ApplicationStore.getCurrentNode().getData(); 113 | 114 | connectionComboBox.getSelectionModel().select(connectionModel.getName()); 115 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.DB) { 116 | DatabaseModel databaseModel = (DatabaseModel) ApplicationStore.getCurrentNode().getData(); 117 | 118 | connectionComboBox.getSelectionModel().select(databaseModel.getConnectionModel().getName()); 119 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.STB) { 120 | StableModel stableModel = (StableModel) ApplicationStore.getCurrentNode().getData(); 121 | DatabaseModel databaseModel = stableModel.getDb(); 122 | connectionComboBox.getSelectionModel().select(databaseModel.getConnectionModel().getName()); 123 | } 124 | 125 | 126 | 127 | // enable copy/paste 128 | TableUtils.installCopyPasteHandler(tableView); 129 | tableView.getSelectionModel().setCellSelectionEnabled(true); 130 | tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 131 | 132 | MenuItem item = new MenuItem("复制"); 133 | item.setOnAction(new EventHandler() { 134 | @Override 135 | public void handle(ActionEvent event) { 136 | ObservableList posList = tableView.getSelectionModel().getSelectedCells(); 137 | int old_r = -1; 138 | StringBuilder clipboardString = new StringBuilder(); 139 | for (TablePosition p : posList) { 140 | int r = p.getRow(); 141 | int c = p.getColumn(); 142 | Object cell = tableView.getColumns().get(c).getCellData(r); 143 | if (cell == null) { 144 | cell = ""; 145 | } 146 | if (old_r == r) { 147 | clipboardString.append('\t'); 148 | } else if (old_r != -1) { 149 | clipboardString.append('\n'); 150 | } 151 | clipboardString.append(cell); 152 | old_r = r; 153 | } 154 | final ClipboardContent content = new ClipboardContent(); 155 | content.putString(clipboardString.toString()); 156 | Clipboard.getSystemClipboard().setContent(content); 157 | } 158 | }); 159 | ContextMenu menu = new ContextMenu(); 160 | menu.getItems().add(item); 161 | tableView.setContextMenu(menu); 162 | 163 | FilteredList> filteredData = new FilteredList<>(dataModelMapList, p -> true); 164 | tableView.setItems(filteredData); 165 | 166 | pagination.pageCountProperty().bind(pageCount); 167 | pagination.setPageFactory(param -> { 168 | showPage(param + 1); 169 | return tableView; 170 | }); 171 | 172 | showPage(1); 173 | 174 | } 175 | 176 | 177 | private void showPage(Integer page) { 178 | Map queryMap = new HashMap<>(); 179 | queryMap.put("page", page); 180 | query(queryMap); 181 | 182 | } 183 | 184 | private ConnectionModel getConnectionModel(String connectionName) { 185 | 186 | for (TreeItem item : ApplicationStore.getConnectionTree().getChildren()) { 187 | if (item.getValue().getName().equals(connectionName)) { 188 | return (ConnectionModel) item.getValue().getData(); 189 | } 190 | } 191 | 192 | return null; 193 | } 194 | 195 | private void query(Map queryMap) { 196 | if (connectionComboBox.getSelectionModel().isEmpty() ) { 197 | return; 198 | } 199 | 200 | String connectionName = connectionComboBox.getSelectionModel().getSelectedItem(); 201 | ConnectionModel connectionModel = getConnectionModel(connectionName); 202 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(connectionModel); 203 | 204 | String sql = "SHOW QUERIES;"; 205 | processSingleSql(queryMap, sql.trim(), connection); 206 | 207 | 208 | } 209 | 210 | private void processSingleSql(Map queryMap, String sql, ConnectionDTO connection) { 211 | if (ObjectUtils.isEmpty(sql)) { 212 | return; 213 | } 214 | 215 | QueryRstDTO queryRstDTO = null; 216 | try { 217 | queryRstDTO = RestConnectionUtils.executeQuery(connection, sql.replaceAll(";", "")); 218 | } catch (Exception e) { 219 | tableView.getColumns().clear(); 220 | return; 221 | } 222 | 223 | if (null != queryRstDTO) { 224 | tableView.getColumns().clear(); 225 | queryRstDTO.getColumnList().forEach(column -> { 226 | TableColumn, String> tmpColumn = new TableColumn<>(); 227 | tmpColumn.setId(column + "Column"); 228 | tmpColumn.setText(column); 229 | tmpColumn.setCellValueFactory(new MapValueFactory(column)); 230 | tableView.getColumns().add(tmpColumn); 231 | }); 232 | 233 | dataModelMapList.clear(); 234 | queryRstDTO.getDataList().forEach(db -> { 235 | db.forEach((k, v) -> { 236 | if (v instanceof Byte[] || v instanceof byte[]) { 237 | db.put(k, new String((byte[]) v)); 238 | } 239 | }); 240 | dataModelMapList.add(db); 241 | }); 242 | } 243 | 244 | 245 | pageCount.setValue(1); 246 | pagination.setMaxPageIndicatorCount(1); 247 | 248 | } 249 | 250 | 251 | @PreDestroy 252 | private void destroy() { 253 | System.err.println("destroy " + this); 254 | } 255 | 256 | 257 | } 258 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/gui/component/StbTabController.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.gui.component; 2 | 3 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 4 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 5 | import com.gitee.dbquery.tdgenie.model.DatabaseModel; 6 | import com.gitee.dbquery.tdgenie.model.StableModel; 7 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 8 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 9 | import com.gitee.dbquery.tdgenie.sdk.util.DataBaseUtils; 10 | import com.gitee.dbquery.tdgenie.sdk.util.RestConnectionUtils; 11 | import com.gitee.dbquery.tdgenie.sdk.util.SuperTableUtils; 12 | import com.gitee.dbquery.tdgenie.store.ApplicationStore; 13 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 14 | import com.gitee.dbquery.tdgenie.util.TableUtils; 15 | import com.gitee.dbquery.tdgenie.util.TsdbConnectionUtils; 16 | import io.datafx.controller.ViewController; 17 | import javafx.beans.property.IntegerProperty; 18 | import javafx.beans.property.ListProperty; 19 | import javafx.beans.property.SimpleIntegerProperty; 20 | import javafx.beans.property.SimpleListProperty; 21 | import javafx.collections.FXCollections; 22 | import javafx.collections.ObservableList; 23 | import javafx.collections.transformation.FilteredList; 24 | import javafx.event.ActionEvent; 25 | import javafx.event.EventHandler; 26 | import javafx.fxml.FXML; 27 | import javafx.scene.control.*; 28 | import javafx.scene.control.cell.MapValueFactory; 29 | import javafx.scene.input.Clipboard; 30 | import javafx.scene.input.ClipboardContent; 31 | import javafx.scene.layout.HBox; 32 | import javafx.scene.layout.VBox; 33 | 34 | import javax.annotation.PostConstruct; 35 | import javax.annotation.PreDestroy; 36 | import java.util.HashMap; 37 | import java.util.Map; 38 | 39 | /** 40 | * CommonTabController 41 | * 42 | * @author pc 43 | * @since 2024/01/31 44 | **/ 45 | @ViewController(value = "/fxml/component/stb_tab.fxml") 46 | public class StbTabController { 47 | @FXML 48 | private VBox centPane; 49 | @FXML 50 | private HBox queryBox; 51 | @FXML 52 | private Pagination pagination; 53 | 54 | @FXML 55 | private TableView> tableView; 56 | 57 | 58 | private IntegerProperty pageCount = new SimpleIntegerProperty(); 59 | private ListProperty> dataModelMapList = new SimpleListProperty<>(FXCollections.observableArrayList()); 60 | 61 | @PostConstruct 62 | public void init() { 63 | // enable copy/paste 64 | TableUtils.installCopyPasteHandler(tableView); 65 | tableView.getSelectionModel().setCellSelectionEnabled(true); 66 | tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 67 | 68 | MenuItem item = new MenuItem("复制"); 69 | item.setOnAction(new EventHandler() { 70 | @Override 71 | public void handle(ActionEvent event) { 72 | ObservableList posList = tableView.getSelectionModel().getSelectedCells(); 73 | int old_r = -1; 74 | StringBuilder clipboardString = new StringBuilder(); 75 | for (TablePosition p : posList) { 76 | int r = p.getRow(); 77 | int c = p.getColumn(); 78 | Object cell = tableView.getColumns().get(c).getCellData(r); 79 | if (cell == null) { 80 | cell = ""; 81 | } 82 | if (old_r == r) { 83 | clipboardString.append('\t'); 84 | } else if (old_r != -1) { 85 | clipboardString.append('\n'); 86 | } 87 | clipboardString.append(cell); 88 | old_r = r; 89 | } 90 | final ClipboardContent content = new ClipboardContent(); 91 | content.putString(clipboardString.toString()); 92 | Clipboard.getSystemClipboard().setContent(content); 93 | } 94 | }); 95 | ContextMenu menu = new ContextMenu(); 96 | menu.getItems().add(item); 97 | tableView.setContextMenu(menu); 98 | 99 | FilteredList> filteredData = new FilteredList<>(dataModelMapList, p -> true); 100 | tableView.setItems(filteredData); 101 | 102 | pagination.pageCountProperty().bind(pageCount); 103 | pagination.setPageFactory(param -> { 104 | showPage(param + 1); 105 | return tableView; 106 | }); 107 | 108 | 109 | if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.CONNECTION) { 110 | ConnectionModel connectionModel = (ConnectionModel) ApplicationStore.getCurrentNode().getData(); 111 | QueryRstDTO dbList = DataBaseUtils.getAllDatabase(TsdbConnectionUtils.getConnection(connectionModel)); 112 | 113 | for(String column : dbList.getColumnList()) { 114 | TableColumn, String> dbNameColumn = new TableColumn<>(); 115 | dbNameColumn.setId("name_" + column); 116 | dbNameColumn.setText(column); 117 | dbNameColumn.setCellValueFactory(new MapValueFactory(column)); 118 | tableView.getColumns().add(dbNameColumn); 119 | } 120 | 121 | dataModelMapList.addAll(dbList.getDataList()); 122 | 123 | centPane.getChildren().removeAll(queryBox); 124 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.DB) { 125 | 126 | DatabaseModel databaseModel = (DatabaseModel) ApplicationStore.getCurrentNode().getData(); 127 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(databaseModel.getConnectionModel()); 128 | 129 | QueryRstDTO stbList = SuperTableUtils.getAllStable(connection, ApplicationStore.getCurrentNode().getName()); 130 | for(String column : stbList.getColumnList()) { 131 | TableColumn, String> dbNameColumn = new TableColumn<>(); 132 | dbNameColumn.setId("name_" + column); 133 | dbNameColumn.setText(column); 134 | dbNameColumn.setCellValueFactory(new MapValueFactory(column)); 135 | tableView.getColumns().add(dbNameColumn); 136 | } 137 | 138 | dataModelMapList.addAll(stbList.getDataList()); 139 | 140 | centPane.getChildren().removeAll(queryBox); 141 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.STB) { 142 | StableModel stableModel = (StableModel) ApplicationStore.getCurrentNode().getData(); 143 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(stableModel.getDb().getConnectionModel()); 144 | QueryRstDTO queryRstDTO = RestConnectionUtils.executeQuery(connection, "select * from " + stableModel.getDb().getName() + "." + 145 | stableModel.getStb().get("name") + " limit 1, 10"); 146 | 147 | queryRstDTO.getColumnList().forEach(column -> { 148 | TableColumn, String> tmpColumn = new TableColumn<>(); 149 | tmpColumn.setId(column + "Column"); 150 | tmpColumn.setText(column); 151 | tmpColumn.setCellValueFactory(new MapValueFactory(column)); 152 | tableView.getColumns().add(tmpColumn); 153 | }); 154 | 155 | queryRstDTO.getDataList().forEach(db -> { 156 | db.forEach((k, v) -> { 157 | if (v instanceof Byte[] || v instanceof byte[]) { 158 | db.put(k, new String((byte[]) v)); 159 | } 160 | }); 161 | dataModelMapList.add(db); 162 | }); 163 | 164 | 165 | } 166 | 167 | 168 | } 169 | 170 | 171 | private void showPage(Integer page) { 172 | Map queryMap = new HashMap<>(); 173 | queryMap.put("page", page); 174 | query(queryMap); 175 | 176 | } 177 | 178 | 179 | private void query(Map queryMap) { 180 | 181 | if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.STB) { 182 | Integer page = (Integer) queryMap.get("page"); 183 | int start = (page - 1) * 1000; 184 | StableModel stableModel = (StableModel) ApplicationStore.getCurrentNode().getData(); 185 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(stableModel.getDb().getConnectionModel()); 186 | QueryRstDTO queryRstDTO = RestConnectionUtils.executeQuery(connection, "select * from " + stableModel.getDb().getName() + "." + 187 | stableModel.getStb().get("name") + " limit " + start + ", " + 1000); 188 | 189 | tableView.getColumns().clear(); 190 | queryRstDTO.getColumnList().forEach(column -> { 191 | TableColumn, String> tmpColumn = new TableColumn<>(); 192 | tmpColumn.setId(column + "Column"); 193 | tmpColumn.setText(column); 194 | tmpColumn.setCellValueFactory(new MapValueFactory(column)); 195 | tableView.getColumns().add(tmpColumn); 196 | }); 197 | 198 | dataModelMapList.clear(); 199 | queryRstDTO.getDataList().forEach(db -> { 200 | db.forEach((k, v) -> { 201 | if (v instanceof Byte[] || v instanceof byte[]) { 202 | db.put(k, new String((byte[]) v)); 203 | } 204 | }); 205 | dataModelMapList.add(db); 206 | }); 207 | 208 | 209 | QueryRstDTO countRstDTO = RestConnectionUtils.executeQuery(connection, "select count(*) from " + stableModel.getDb().getName() + "." + 210 | stableModel.getStb().get("name") ); 211 | long total = ObjectUtils.isEmpty(countRstDTO.getDataList()) ? 0 : (long) countRstDTO.getDataList().get(0).get("count(*)"); 212 | pageCount.setValue((total / 1000) + 1); 213 | } 214 | 215 | } 216 | 217 | 218 | @PreDestroy 219 | private void destroy() { 220 | System.err.println("destroy " + this); 221 | } 222 | 223 | 224 | } 225 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/gui/component/UserQueryController.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.gui.component; 2 | 3 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 4 | import com.gitee.dbquery.tdgenie.model.CommonNode; 5 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 6 | import com.gitee.dbquery.tdgenie.model.DatabaseModel; 7 | import com.gitee.dbquery.tdgenie.model.StableModel; 8 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 9 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 10 | import com.gitee.dbquery.tdgenie.sdk.util.RestConnectionUtils; 11 | import com.gitee.dbquery.tdgenie.store.ApplicationStore; 12 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 13 | import com.gitee.dbquery.tdgenie.util.TableUtils; 14 | import com.gitee.dbquery.tdgenie.util.TsdbConnectionUtils; 15 | import com.jfoenix.controls.JFXButton; 16 | import com.jfoenix.controls.JFXComboBox; 17 | import com.jfoenix.controls.JFXTabPane; 18 | import io.datafx.controller.ViewController; 19 | import io.datafx.controller.flow.action.ActionMethod; 20 | import io.datafx.controller.flow.action.ActionTrigger; 21 | import javafx.beans.property.IntegerProperty; 22 | import javafx.beans.property.ListProperty; 23 | import javafx.beans.property.SimpleIntegerProperty; 24 | import javafx.beans.property.SimpleListProperty; 25 | import javafx.collections.FXCollections; 26 | import javafx.collections.ObservableList; 27 | import javafx.collections.transformation.FilteredList; 28 | import javafx.event.ActionEvent; 29 | import javafx.event.EventHandler; 30 | import javafx.fxml.FXML; 31 | import javafx.scene.control.*; 32 | import javafx.scene.control.cell.MapValueFactory; 33 | import javafx.scene.input.Clipboard; 34 | import javafx.scene.input.ClipboardContent; 35 | import javafx.scene.layout.HBox; 36 | import javafx.scene.layout.StackPane; 37 | import javafx.scene.text.Text; 38 | 39 | import javax.annotation.PostConstruct; 40 | import javax.annotation.PreDestroy; 41 | import java.util.HashMap; 42 | import java.util.Map; 43 | 44 | /** 45 | * CommonTabController 46 | * 47 | * @author pc 48 | * @since 2024/01/31 49 | **/ 50 | @ViewController(value = "/fxml/component/user_query_tab.fxml") 51 | public class UserQueryController { 52 | 53 | 54 | @FXML 55 | private Label pageInformation; 56 | @FXML 57 | private Label selectLocInfo; 58 | @FXML 59 | private Pagination pagination; 60 | @FXML 61 | private StackPane rootPane; 62 | @FXML 63 | private TableView> tableView; 64 | 65 | @FXML 66 | private JFXTabPane executeResultTabPane; 67 | @FXML 68 | private JFXComboBox connectionComboBox; 69 | @FXML 70 | private Text executeSql; 71 | @FXML 72 | private Text executeStatus; 73 | @FXML 74 | private Text executeCost; 75 | @FXML 76 | @ActionTrigger("executeQuery") 77 | private JFXButton executeButton; 78 | @FXML 79 | private HBox prettySqlBox; 80 | @FXML 81 | private HBox saveSqlBox; 82 | private IntegerProperty pageCount = new SimpleIntegerProperty(); 83 | private ListProperty> dataModelMapList = new SimpleListProperty<>(FXCollections.observableArrayList()); 84 | 85 | 86 | @ActionMethod("executeQuery") 87 | private void executeQuery() { 88 | showPage(1); 89 | } 90 | 91 | 92 | @PostConstruct 93 | public void init() { 94 | 95 | rootPane.setOnContextMenuRequested(event -> { 96 | event.consume(); // 标记事件已被处理,防止默认的上下文菜单显示 97 | }); 98 | 99 | 100 | if (ApplicationStore.getConnectionTree() != null) { 101 | ApplicationStore.getConnectionTree().getChildren().forEach(d -> { 102 | connectionComboBox.getItems().add(d.getValue().getName()); 103 | }); 104 | } 105 | 106 | 107 | if (null == ApplicationStore.getCurrentNode()) { 108 | if(connectionComboBox.getItems().size()>0) { 109 | connectionComboBox.getSelectionModel().select(0); 110 | } 111 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.CONNECTION) { 112 | ConnectionModel connectionModel = (ConnectionModel) ApplicationStore.getCurrentNode().getData(); 113 | 114 | connectionComboBox.getSelectionModel().select(connectionModel.getName()); 115 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.DB) { 116 | DatabaseModel databaseModel = (DatabaseModel) ApplicationStore.getCurrentNode().getData(); 117 | 118 | connectionComboBox.getSelectionModel().select(databaseModel.getConnectionModel().getName()); 119 | } else if (ApplicationStore.getCurrentNode().getType() == NodeTypeEnum.STB) { 120 | StableModel stableModel = (StableModel) ApplicationStore.getCurrentNode().getData(); 121 | DatabaseModel databaseModel = stableModel.getDb(); 122 | connectionComboBox.getSelectionModel().select(databaseModel.getConnectionModel().getName()); 123 | } 124 | 125 | 126 | 127 | // enable copy/paste 128 | TableUtils.installCopyPasteHandler(tableView); 129 | tableView.getSelectionModel().setCellSelectionEnabled(true); 130 | tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); 131 | 132 | MenuItem item = new MenuItem("复制"); 133 | item.setOnAction(new EventHandler() { 134 | @Override 135 | public void handle(ActionEvent event) { 136 | ObservableList posList = tableView.getSelectionModel().getSelectedCells(); 137 | int old_r = -1; 138 | StringBuilder clipboardString = new StringBuilder(); 139 | for (TablePosition p : posList) { 140 | int r = p.getRow(); 141 | int c = p.getColumn(); 142 | Object cell = tableView.getColumns().get(c).getCellData(r); 143 | if (cell == null) { 144 | cell = ""; 145 | } 146 | if (old_r == r) { 147 | clipboardString.append('\t'); 148 | } else if (old_r != -1) { 149 | clipboardString.append('\n'); 150 | } 151 | clipboardString.append(cell); 152 | old_r = r; 153 | } 154 | final ClipboardContent content = new ClipboardContent(); 155 | content.putString(clipboardString.toString()); 156 | Clipboard.getSystemClipboard().setContent(content); 157 | } 158 | }); 159 | ContextMenu menu = new ContextMenu(); 160 | menu.getItems().add(item); 161 | tableView.setContextMenu(menu); 162 | 163 | FilteredList> filteredData = new FilteredList<>(dataModelMapList, p -> true); 164 | tableView.setItems(filteredData); 165 | 166 | pagination.pageCountProperty().bind(pageCount); 167 | pagination.setPageFactory(param -> { 168 | showPage(param + 1); 169 | return tableView; 170 | }); 171 | 172 | showPage(1); 173 | 174 | } 175 | 176 | 177 | private void showPage(Integer page) { 178 | Map queryMap = new HashMap<>(); 179 | queryMap.put("page", page); 180 | query(queryMap); 181 | 182 | } 183 | 184 | private ConnectionModel getConnectionModel(String connectionName) { 185 | 186 | for (TreeItem item : ApplicationStore.getConnectionTree().getChildren()) { 187 | if (item.getValue().getName().equals(connectionName)) { 188 | return (ConnectionModel) item.getValue().getData(); 189 | } 190 | } 191 | 192 | return null; 193 | } 194 | 195 | private void query(Map queryMap) { 196 | if (connectionComboBox.getSelectionModel().isEmpty() ) { 197 | return; 198 | } 199 | 200 | String connectionName = connectionComboBox.getSelectionModel().getSelectedItem(); 201 | ConnectionModel connectionModel = getConnectionModel(connectionName); 202 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(connectionModel); 203 | 204 | String sql = "show users;"; 205 | processSingleSql(queryMap, sql.trim(), connection); 206 | 207 | 208 | } 209 | 210 | private void processSingleSql(Map queryMap, String sql, ConnectionDTO connection) { 211 | if (ObjectUtils.isEmpty(sql)) { 212 | return; 213 | } 214 | 215 | QueryRstDTO queryRstDTO = null; 216 | try { 217 | queryRstDTO = RestConnectionUtils.executeQuery(connection, sql.replaceAll(";", "")); 218 | } catch (Exception e) { 219 | tableView.getColumns().clear(); 220 | return; 221 | } 222 | 223 | if (null != queryRstDTO) { 224 | tableView.getColumns().clear(); 225 | queryRstDTO.getColumnList().forEach(column -> { 226 | TableColumn, String> tmpColumn = new TableColumn<>(); 227 | tmpColumn.setId(column + "Column"); 228 | tmpColumn.setText(column); 229 | tmpColumn.setCellValueFactory(new MapValueFactory(column)); 230 | tableView.getColumns().add(tmpColumn); 231 | }); 232 | 233 | dataModelMapList.clear(); 234 | queryRstDTO.getDataList().forEach(db -> { 235 | db.forEach((k, v) -> { 236 | if (v instanceof Byte[] || v instanceof byte[]) { 237 | db.put(k, new String((byte[]) v)); 238 | } 239 | }); 240 | dataModelMapList.add(db); 241 | }); 242 | } 243 | 244 | 245 | pageCount.setValue(1); 246 | pagination.setMaxPageIndicatorCount(1); 247 | 248 | } 249 | 250 | 251 | @PreDestroy 252 | private void destroy() { 253 | System.err.println("destroy " + this); 254 | } 255 | 256 | 257 | } 258 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/model/CommonNode.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.model; 2 | 3 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * CommonNode 10 | * 11 | * @author pc 12 | * @since 2024/01/31 13 | **/ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class CommonNode { 18 | private String name; 19 | private NodeTypeEnum type; 20 | private Object Data; 21 | 22 | 23 | @Override 24 | public String toString() { 25 | return name; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/model/ConnectionModel.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * ConnectionModel 11 | * 12 | * @author pc 13 | * @since 2024/01/31 14 | **/ 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Data 18 | public class ConnectionModel { 19 | private String name; 20 | private String ip; 21 | private String port; 22 | private String username; 23 | private String password; 24 | private String version; 25 | private List dbList; 26 | 27 | @Override 28 | public String toString() { 29 | return name; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/model/DatabaseModel.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * DatabaseModel 11 | * 12 | * @author pc 13 | * @since 2024/01/31 14 | **/ 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Data 18 | public class DatabaseModel { 19 | private String name; 20 | private Map databaseResDTO; 21 | private ConnectionModel connectionModel; 22 | 23 | @Override 24 | public String toString() { 25 | return name + "@" + connectionModel.getName(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/model/StableModel.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * TableModel 11 | * 12 | * @author pc 13 | * @since 2024/01/31 14 | **/ 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Data 18 | public class StableModel { 19 | private Map stb; 20 | private DatabaseModel db; 21 | 22 | @Override 23 | public String toString() { 24 | return stb.get("name") + "@" + db.getName() + "@" + db.getConnectionModel().getName(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/annotation/TdField.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.annotation; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2021/12/13 9 | **/ 10 | @Retention(RetentionPolicy.RUNTIME) 11 | public @interface TdField { 12 | String value() default ""; 13 | } 14 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/constant/TdClientConstants.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.constant; 2 | 3 | /** 4 | * 公共常量类 5 | * 6 | * @author 风一样的码农 7 | * @since 2023/8/10 8 | **/ 9 | public class TdClientConstants { 10 | 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/ConnectionDTO.java: -------------------------------------------------------------------------------- 1 | 2 | package com.gitee.dbquery.tdgenie.sdk.dto; 3 | 4 | 5 | import lombok.Data; 6 | 7 | /** 8 | *

9 | * 数据连接 10 | *

11 | * 12 | * @author PiChen 13 | * @since 2021-11-30 14 | */ 15 | @Data 16 | public class ConnectionDTO { 17 | 18 | private String ip; 19 | 20 | private String restfulPort; 21 | 22 | private String username; 23 | 24 | private String password; 25 | 26 | private String db; 27 | 28 | private String version; 29 | } 30 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/QueryRstDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author 风一样的码农 11 | * @since 2022/3/7 12 | **/ 13 | @AllArgsConstructor 14 | @Data 15 | public class QueryRstDTO { 16 | private List columnList; 17 | private List> dataList; 18 | } 19 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/data/TsData.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.data; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.List; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2023/8/24 9 | **/ 10 | public class TsData { 11 | private List> dataList; 12 | } 13 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/db/DbConfigAddDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.db; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class DbConfigAddDTO { 7 | private String dbName; 8 | private String days; 9 | private String keep; 10 | private String cache; 11 | private String blocks; 12 | private String quorum; 13 | private String comp; 14 | private String walLevel; 15 | private String fsync; 16 | private String replica; 17 | private String precision; 18 | private String update; 19 | private String cacheLast; 20 | private String minRows; 21 | private String maxRows; 22 | } 23 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/db/DbConfigUpdateDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.db; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class DbConfigUpdateDTO { 7 | private String dbName; 8 | private String cacheLast; 9 | private String comp; 10 | private String blocks; 11 | private String keep; 12 | private String quorum; 13 | private String replica; 14 | } 15 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/field/TableFieldDTO.java: -------------------------------------------------------------------------------- 1 | 2 | package com.gitee.dbquery.tdgenie.sdk.dto.field; 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | *

12 | * 表字段 13 | *

14 | * 15 | * @author PiChen 16 | * @since 2021-11-30 17 | */ 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Data 21 | public class TableFieldDTO implements Serializable { 22 | private static final long serialVersionUID = 1L; 23 | private String name; 24 | private String dataType; 25 | private Integer length; 26 | /** 27 | * 有定义TAG的为STABLE 28 | */ 29 | private Boolean isTag; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/res/BaseResDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.res; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author chenpi 9 | * @since 2024/3/20 10 | **/ 11 | @Data 12 | public class BaseResDTO { 13 | private String status; 14 | private Integer code; 15 | private String desc; 16 | private Integer rows; 17 | private List head; 18 | private List> column_meta; 19 | private List> data; 20 | } 21 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/res/DatabaseCreateResDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.res; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.annotation.TdField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2023/8/11 9 | **/ 10 | @Data 11 | public class DatabaseCreateResDTO { 12 | @TdField("Database") 13 | private String db; 14 | @TdField("Create Database") 15 | private String createDbSql; 16 | } 17 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/res/DatabaseResDTO.java: -------------------------------------------------------------------------------- 1 | 2 | package com.gitee.dbquery.tdgenie.sdk.dto.res; 3 | 4 | import com.gitee.dbquery.tdgenie.sdk.annotation.TdField; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 数据库 12 | *

13 | * 14 | * @author PiChen 15 | * @since 2021-12-01 16 | */ 17 | @Data 18 | public class DatabaseResDTO implements Serializable { 19 | @TdField 20 | private String name; 21 | @TdField 22 | private String days; 23 | @TdField 24 | private String keep; 25 | @TdField("cache(MB)") 26 | private String cache; 27 | @TdField 28 | private String blocks; 29 | @TdField 30 | private String quorum; 31 | @TdField 32 | private String comp; 33 | @TdField("wallevel") 34 | private String walLevel; 35 | @TdField 36 | private String fsync; 37 | @TdField 38 | private String replica; 39 | @TdField 40 | private String update; 41 | @TdField("cachelast") 42 | private String cacheLast; 43 | @TdField("minrows") 44 | private String minRows; 45 | @TdField("maxrows") 46 | private String maxRows; 47 | @TdField 48 | private String precision; 49 | } 50 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/res/StableCreateResDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.res; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.annotation.TdField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2023/8/11 9 | **/ 10 | @Data 11 | public class StableCreateResDTO { 12 | @TdField("Table") 13 | private String db; 14 | @TdField("Create Table") 15 | private String createDbSql; 16 | } 17 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/res/StableResDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.res; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.annotation.TdField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2023/8/18 9 | **/ 10 | @Data 11 | public class StableResDTO { 12 | @TdField 13 | private String name; 14 | @TdField 15 | private String createdTime; 16 | @TdField 17 | private Integer columns; 18 | @TdField 19 | private Integer tags; 20 | @TdField 21 | private Integer tables; 22 | } 23 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/res/SystemVariableResDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.res; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.annotation.TdField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2023/8/11 9 | **/ 10 | @Data 11 | public class SystemVariableResDTO { 12 | @TdField 13 | private String name; 14 | @TdField 15 | private String value; 16 | } 17 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/res/TableCreateResDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.res; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.annotation.TdField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2023/8/11 9 | **/ 10 | @Data 11 | public class TableCreateResDTO { 12 | @TdField("Table") 13 | private String db; 14 | @TdField("Create Table") 15 | private String createDbSql; 16 | } 17 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/res/TableFieldResDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.res; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.annotation.TdField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2023/8/23 9 | **/ 10 | @Data 11 | public class TableFieldResDTO { 12 | @TdField("Field") 13 | private String field; 14 | @TdField("Type") 15 | private String type; 16 | @TdField("Length") 17 | private Integer length; 18 | @TdField("Note") 19 | private String note; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/res/TableResDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.res; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.annotation.TdField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2023/8/18 9 | **/ 10 | @Data 11 | public class TableResDTO { 12 | @TdField("table_name") 13 | private String name; 14 | @TdField 15 | private String createdTime; 16 | @TdField 17 | private Integer columns; 18 | @TdField 19 | private String stableName; 20 | @TdField 21 | private String uid; 22 | @TdField 23 | private String tid; 24 | @TdField("vgId") 25 | private String vgId; 26 | } 27 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/stb/StableAddDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.stb; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.dto.tb.TableAddDTO; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2023/8/18 9 | **/ 10 | @Data 11 | public class StableAddDTO extends TableAddDTO { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/stb/StableUpdateDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.stb; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.dto.field.TableFieldDTO; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author 风一样的码农 11 | * @since 2023/8/23 12 | **/ 13 | @Data 14 | public class StableUpdateDTO { 15 | private String db; 16 | private String tb; 17 | private List addList; 18 | private List deleteList; 19 | private List updateList; 20 | /** 21 | * Tag Name替换Map 22 | */ 23 | private Map tagNameChangeMap; 24 | } 25 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/tb/TableAddByStableDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.tb; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * @author 风一样的码农 9 | * @since 2023/8/23 10 | **/ 11 | @Data 12 | public class TableAddByStableDTO { 13 | private String dbName; 14 | private String tableName; 15 | private String stableName; 16 | private Map tagValueMap; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/tb/TableAddDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.tb; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.dto.field.TableFieldDTO; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author 风一样的码农 10 | * @since 2023/8/18 11 | **/ 12 | @Data 13 | public class TableAddDTO { 14 | private String db; 15 | private String tb; 16 | private List fieldList; 17 | } 18 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/dto/tb/TableUpdateDTO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.dto.tb; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.dto.field.TableFieldDTO; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author 风一样的码农 11 | * @since 2023/8/23 12 | **/ 13 | @Data 14 | public class TableUpdateDTO { 15 | private String db; 16 | private String tb; 17 | private List addList; 18 | private List deleteList; 19 | private List updateList; 20 | /** 21 | * Tag Name修改Map 22 | */ 23 | private Map tagNameChangeMap; 24 | } 25 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/enums/package-info.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.enums; 2 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/exception/DatabaseAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.exception; 2 | 3 | /** 4 | * @author 风一样的码农 5 | * @since 2023/8/17 6 | **/ 7 | public class DatabaseAlreadyExistException extends RuntimeException { 8 | } 9 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/exception/TableAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.exception; 2 | 3 | /** 4 | * @author 风一样的码农 5 | * @since 2023/8/17 6 | **/ 7 | public class TableAlreadyExistException extends RuntimeException { 8 | } 9 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/util/DataBaseUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.util; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 4 | import com.gitee.dbquery.tdgenie.sdk.dto.db.DbConfigAddDTO; 5 | import com.gitee.dbquery.tdgenie.sdk.dto.db.DbConfigUpdateDTO; 6 | import com.gitee.dbquery.tdgenie.sdk.exception.DatabaseAlreadyExistException; 7 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 8 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 9 | import com.gitee.dbquery.tdgenie.sdk.dto.res.DatabaseCreateResDTO; 10 | import lombok.extern.slf4j.Slf4j; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collections; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | /** 18 | * 数据库工具类 19 | * 20 | * @author 风一样的码农 21 | * @since 2023/8/11 22 | **/ 23 | @Slf4j 24 | public class DataBaseUtils { 25 | 26 | /** 27 | * 创建数据库 28 | * 29 | * @param connection 数据连接 30 | * @param dbConfigAddDTO 数据库配置 31 | */ 32 | public static void createDatabase(ConnectionDTO connection, DbConfigAddDTO dbConfigAddDTO) { 33 | String createSql = "CREATE DATABASE `" + dbConfigAddDTO.getDbName() + "`"; 34 | if (ObjectUtils.isNotEmpty(dbConfigAddDTO.getBlocks())) { 35 | createSql += " " + getBufferParamCode(connection.getVersion()) + " " + dbConfigAddDTO.getBlocks(); 36 | } 37 | 38 | if (ObjectUtils.isNotEmpty(dbConfigAddDTO.getKeep())) { 39 | createSql += " keep " + dbConfigAddDTO.getKeep(); 40 | } 41 | 42 | if (ObjectUtils.isNotEmpty(dbConfigAddDTO.getReplica())) { 43 | createSql += " replica " + dbConfigAddDTO.getReplica(); 44 | } 45 | createSql = createSql + ";"; 46 | 47 | try { 48 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList(createSql)); 49 | } catch (Exception e) { 50 | if (e.getMessage() != null && e.getMessage().contains("TDengine ERROR (381)")) { 51 | throw new DatabaseAlreadyExistException(); 52 | } 53 | throw e; 54 | } 55 | } 56 | 57 | /** 58 | * 删除数据库,谨慎操作 59 | * 60 | * @param connection 连接 61 | * @param dbName 库名 62 | */ 63 | public static void deleteDatabase(ConnectionDTO connection, String dbName) { 64 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList("DROP DATABASE IF EXISTS `" + dbName + "`;")); 65 | } 66 | 67 | /** 68 | * 获取数据库列表 69 | * 70 | * @param connection 连接 71 | * @return 数据库列表 72 | */ 73 | public static QueryRstDTO getAllDatabase(ConnectionDTO connection) { 74 | if(VersionUtils.compareVersion(connection.getVersion(), "3.0") > 0) { 75 | return RestConnectionUtils.executeQuery(connection, "select * from INFORMATION_SCHEMA.INS_DATABASES ;"); 76 | } 77 | return RestConnectionUtils.executeQuery(connection, "show databases;"); 78 | } 79 | 80 | /** 81 | * 获取数据库 82 | * 83 | * @param connection 连接 84 | * @param dbName 数据库名 85 | * @return 数据库 86 | */ 87 | public static Map getDatabase(ConnectionDTO connection, String dbName) { 88 | QueryRstDTO allDb = getAllDatabase(connection); 89 | for (Map db : allDb.getDataList()) { 90 | if (db.get("name").equals(dbName)) { 91 | return db; 92 | } 93 | } 94 | return null; 95 | } 96 | 97 | /** 98 | * 获取数据库建表语句 99 | * 100 | * @param connection 连接 101 | * @param dbName 数据库名 102 | * @return CREATE语句 103 | */ 104 | public static String getDatabaseCreateSql(ConnectionDTO connection, String dbName) { 105 | List list = RestConnectionUtils.executeQuery(connection, "SHOW CREATE DATABASE `" + dbName + "`;", DatabaseCreateResDTO.class); 106 | return list.get(0).getCreateDbSql(); 107 | } 108 | 109 | private static boolean needUpdate(Object oldObj, Object newObj) { 110 | if (newObj == null) { 111 | return false; 112 | } 113 | return !newObj.equals(oldObj); 114 | } 115 | 116 | /** 117 | * 更新数据库 118 | * 119 | * @param connection 连接 120 | * @param dbConfigUpdateDTO 数据库配置 121 | */ 122 | public static void updateDatabase(ConnectionDTO connection, DbConfigUpdateDTO dbConfigUpdateDTO) { 123 | Map databaseResDTO = getDatabase(connection, dbConfigUpdateDTO.getDbName()); 124 | if (databaseResDTO == null) { 125 | throw new RuntimeException("database not exist..."); 126 | } 127 | List sqlList = new ArrayList<>(); 128 | if (needUpdate(databaseResDTO.get("replica"), dbConfigUpdateDTO.getReplica())) { 129 | sqlList.add("ALTER DATABASE `" + dbConfigUpdateDTO.getDbName() + "` replica " + dbConfigUpdateDTO.getReplica() + ";"); 130 | } 131 | 132 | if (needUpdate(databaseResDTO.get("keep"), dbConfigUpdateDTO.getKeep())) { 133 | sqlList.add("ALTER DATABASE `" + dbConfigUpdateDTO.getDbName() + "` keep " + dbConfigUpdateDTO.getKeep() + ";"); 134 | } 135 | 136 | if(VersionUtils.compareVersion(connection.getVersion(), "3.0") > 0) { 137 | if (needUpdate(databaseResDTO.get("buffer"), dbConfigUpdateDTO.getBlocks())) { 138 | sqlList.add("ALTER DATABASE `" + dbConfigUpdateDTO.getDbName() + "` BUFFER " + dbConfigUpdateDTO.getBlocks() + ";"); 139 | } 140 | } else { 141 | if (needUpdate(databaseResDTO.get("blocks"), dbConfigUpdateDTO.getBlocks())) { 142 | sqlList.add("ALTER DATABASE `" + dbConfigUpdateDTO.getDbName() + "` blocks " + dbConfigUpdateDTO.getBlocks() + ";"); 143 | } 144 | 145 | } 146 | 147 | 148 | RestConnectionUtils.executeUpdate(connection, sqlList); 149 | } 150 | 151 | public static String getBufferParamCode(String version) { 152 | if (VersionUtils.compareVersion(version, "3.0") > 0) { 153 | return "buffer"; 154 | } else { 155 | return "blocks"; 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/util/RestConnectionUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.util; 2 | 3 | import cn.hutool.core.codec.Base64; 4 | import cn.hutool.core.util.StrUtil; 5 | import cn.hutool.http.HttpRequest; 6 | import cn.hutool.http.HttpResponse; 7 | import cn.hutool.http.HttpUtil; 8 | import cn.hutool.json.JSONUtil; 9 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 10 | import com.gitee.dbquery.tdgenie.sdk.annotation.TdField; 11 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 12 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 13 | import com.gitee.dbquery.tdgenie.sdk.dto.res.BaseResDTO; 14 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 15 | import lombok.extern.slf4j.Slf4j; 16 | 17 | import java.lang.reflect.Field; 18 | import java.lang.reflect.InvocationTargetException; 19 | import java.lang.reflect.Method; 20 | import java.sql.SQLException; 21 | import java.util.*; 22 | 23 | /** 24 | * @author chenpi 25 | * @since 2024/3/19 26 | **/ 27 | @Slf4j 28 | public class RestConnectionUtils { 29 | public final static Map columnMetaTypeMap = new HashMap<>(); 30 | static { 31 | columnMetaTypeMap.put(1, "BOOL"); 32 | columnMetaTypeMap.put(2, "TINYINT"); 33 | columnMetaTypeMap.put(3, "SMALLINT"); 34 | columnMetaTypeMap.put(4, "INT"); 35 | columnMetaTypeMap.put(5, "BIGINT"); 36 | columnMetaTypeMap.put(6, "FLOAT"); 37 | columnMetaTypeMap.put(7, "DOUBLE"); 38 | columnMetaTypeMap.put(8, "BINARY"); 39 | columnMetaTypeMap.put(9, "TIMESTAMP"); 40 | columnMetaTypeMap.put(10, "NCHAR"); 41 | } 42 | 43 | 44 | public static String getServerVersion(ConnectionModel connectionModel) { 45 | ConnectionDTO connectionDTO = new ConnectionDTO(); 46 | connectionDTO.setIp(connectionModel.getIp()); 47 | connectionDTO.setRestfulPort(connectionModel.getPort()); 48 | connectionDTO.setUsername(connectionModel.getUsername()); 49 | connectionDTO.setPassword(connectionModel.getPassword()); 50 | BaseResDTO baseResDTO = executeSql(connectionDTO, "select server_version();"); 51 | return baseResDTO.getData().get(0).get(0).toString(); 52 | } 53 | 54 | public static BaseResDTO executeSql(ConnectionDTO connectionDTO, String sql) { 55 | HttpRequest request = HttpUtil.createPost("http://"+connectionDTO.getIp()+":"+connectionDTO.getRestfulPort()+"/rest/sql" + (connectionDTO.getDb()==null ? "":("/" + connectionDTO.getDb()))); 56 | request.header("Authorization", "Basic " + Base64.encode(connectionDTO.getUsername() + ":" + connectionDTO.getPassword())); 57 | request.body(sql); 58 | HttpResponse response = request.execute(); 59 | BaseResDTO baseResDTO = JSONUtil.toBean(response.body(), BaseResDTO.class); 60 | if(!new Integer(0).equals(baseResDTO.getCode()) && !"succ".equals(baseResDTO.getStatus())) { 61 | throw new RuntimeException(baseResDTO.getDesc()); 62 | } 63 | 64 | return baseResDTO; 65 | } 66 | 67 | public static List executeQuery(ConnectionDTO connection, String sql, Class clazz) { 68 | log.info("======> 执行 TD SQL: {}", sql); 69 | if (ObjectUtils.isEmpty(sql)) { 70 | return Collections.emptyList(); 71 | } 72 | 73 | try { 74 | 75 | BaseResDTO baseResDTO = executeSql(connection, sql); 76 | Field[] fields = clazz.getDeclaredFields(); 77 | List list = new ArrayList<>(); 78 | for (List record : baseResDTO.getData()) { 79 | Map dbObj = getDbObj(baseResDTO.getColumn_meta(), record); 80 | 81 | T obj = clazz.newInstance(); 82 | for (Field field : fields) { 83 | TdField fieldAnnotation = field.getAnnotation(TdField.class); 84 | if (fieldAnnotation == null) { 85 | continue; 86 | } 87 | String columnName = fieldAnnotation.value(); 88 | setValue(obj, columnName, field, dbObj); 89 | } 90 | list.add(obj); 91 | } 92 | return list; 93 | } catch (SQLException | IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchMethodException e) { 94 | log.error(e.toString(), e); 95 | log.error("======> 执行SQL失败, sql:{}, error:{}", sql, e.getMessage()); 96 | throw new RuntimeException(e.getMessage()); 97 | } 98 | } 99 | 100 | /** 101 | * 执行查询操作 102 | * 注意Connection需要调用方手动关闭 103 | * 104 | * @param connection 连接 105 | * @param sql SQL语句 106 | * @return 查询结果 107 | */ 108 | public static QueryRstDTO executeQuery(ConnectionDTO connection, String sql) { 109 | log.info("======> 执行 TD SQL: {}", sql); 110 | if (ObjectUtils.isEmpty(sql)) { 111 | return null; 112 | } 113 | 114 | try { 115 | BaseResDTO baseResDTO = executeSql(connection, sql); 116 | List> list = new ArrayList<>(); 117 | 118 | List> md = baseResDTO.getColumn_meta(); 119 | List columnList = new ArrayList<>(); 120 | for (int i = 0; i < md.size(); i++) { 121 | columnList.add(md.get(i).get(0).toString()); 122 | } 123 | for (List record : baseResDTO.getData()) { 124 | Map dbObj = getDbObj(baseResDTO.getColumn_meta(), record); 125 | list.add(dbObj); 126 | } 127 | return new QueryRstDTO(columnList, list); 128 | } catch (Exception e) { 129 | log.error(e.toString(), e); 130 | log.error("======> 执行SQL失败, sql:{}, error:{}", sql, e.getMessage()); 131 | throw new RuntimeException(e.getMessage()); 132 | } 133 | } 134 | 135 | 136 | /** 137 | * 执行更新操作 138 | * 注意Connection需要调用方手动关闭 139 | * 140 | * @param connection java.sql.Connection连接 141 | * @param batchSql sql语句列表 142 | * @return an array of update counts containing one element for each 143 | * command in the batch. The elements of the array are ordered according 144 | * to the order in which commands were added to the batch. 145 | */ 146 | public static List executeUpdate(ConnectionDTO connection, List batchSql) { 147 | log.info("======> 执行 TD SQL: {}", batchSql); 148 | if (ObjectUtils.isEmpty(batchSql)) { 149 | return Collections.emptyList(); 150 | } 151 | try { 152 | List resList = new ArrayList<>(); 153 | for (String sqlTmp : batchSql) { 154 | resList.add(executeQuery(connection, sqlTmp)); 155 | } 156 | return resList; 157 | } catch (Exception e) { 158 | log.error(e.toString(), e); 159 | log.error("======> 执行SQL失败, sql:{}, error:{}", batchSql, e.getMessage()); 160 | throw new RuntimeException(e.getMessage()); 161 | } 162 | } 163 | 164 | private static Map getDbObj (List> columnMeta, List record) { 165 | Map obj = new HashMap<>(); 166 | for(int i = 0; i < columnMeta.size(); i++) { 167 | obj.put(columnMeta.get(i).get(0).toString(), record.get(i)); 168 | } 169 | return obj; 170 | } 171 | 172 | private static void setValue(Object obj, String columnName, Field field, Map rs) throws NoSuchMethodException, SQLException, InvocationTargetException, IllegalAccessException { 173 | String tdColumnName = ObjectUtils.isEmpty(columnName) ? StrUtil.toUnderlineCase(field.getName()) : columnName; 174 | if(rs.get(tdColumnName) == null) { 175 | return; 176 | } 177 | 178 | String fieldName = field.getName(); 179 | String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); 180 | Method setMethod = obj.getClass().getMethod(setMethodName, field.getType()); 181 | Class fieldType = field.getType(); 182 | if (fieldType.equals(String.class)) { 183 | setMethod.invoke(obj, rs.get(tdColumnName) + ""); 184 | } else if (fieldType.equals(Double.class) || fieldType.equals(Double.TYPE)) { 185 | setMethod.invoke(obj, Double.valueOf(rs.get(tdColumnName) + "")); 186 | } else if (fieldType.equals(Integer.class) || fieldType.equals(Integer.TYPE)) { 187 | setMethod.invoke(obj, Integer.valueOf(rs.get(tdColumnName) + "")); 188 | } else if (fieldType.equals(Float.class) || fieldType.equals(Float.TYPE)) { 189 | setMethod.invoke(obj, Float.valueOf(rs.get(tdColumnName) + "")); 190 | } else if (fieldType.equals(Long.class) || fieldType.equals(Long.TYPE)) { 191 | setMethod.invoke(obj, Long.valueOf(rs.get(tdColumnName) + "")); 192 | } else if (fieldType.equals(Boolean.class) || fieldType.equals(Boolean.TYPE)) { 193 | setMethod.invoke(obj, Boolean.valueOf(rs.get(tdColumnName) + "")); 194 | } else { 195 | setMethod.invoke(obj, rs.get(tdColumnName)); 196 | } 197 | } 198 | 199 | 200 | public static void main(String[] args) { 201 | ConnectionDTO connectionDTO1 = new ConnectionDTO(); 202 | connectionDTO1.setIp("10.162.201.62"); 203 | connectionDTO1.setRestfulPort("6041"); 204 | connectionDTO1.setUsername("root"); 205 | connectionDTO1.setPassword("Abc123_"); 206 | connectionDTO1.setVersion("2.6.0.34"); 207 | 208 | 209 | 210 | ConnectionDTO connectionDTO2 = new ConnectionDTO(); 211 | connectionDTO2.setIp("10.162.201.112"); 212 | connectionDTO2.setRestfulPort("6041"); 213 | connectionDTO2.setUsername("root"); 214 | connectionDTO2.setPassword("taosdata"); 215 | connectionDTO2.setVersion("3.2.3.0"); 216 | 217 | // List list = executeQuery(connectionDTO2, "show databases;", DatabaseResDTO.class); 218 | // System.out.println(list); 219 | 220 | QueryRstDTO res = executeQuery(connectionDTO2, "create STABLE ptest.p_stable (time TIMESTAMP,tag_value DOUBLE,is_good BOOL) tags (tag_name NCHAR(120),company_code TINYINT,point_source NCHAR(8),alis NCHAR(50));"); 221 | System.out.println(res); 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/util/SuperTableUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.util; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.dto.stb.StableUpdateDTO; 4 | import com.gitee.dbquery.tdgenie.sdk.exception.TableAlreadyExistException; 5 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 6 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 7 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 8 | import com.gitee.dbquery.tdgenie.sdk.dto.field.TableFieldDTO; 9 | import com.gitee.dbquery.tdgenie.sdk.dto.res.StableCreateResDTO; 10 | import com.gitee.dbquery.tdgenie.sdk.dto.stb.StableAddDTO; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collections; 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.stream.Collectors; 17 | 18 | /** 19 | * 超级表工具类 20 | * 21 | * @author 风一样的码农 22 | * @since 2023/8/18 23 | **/ 24 | public class SuperTableUtils { 25 | 26 | /** 27 | * 创建超级表 28 | * 29 | * @param connection 连接 30 | * @param stableAddDTO 建表信息 31 | */ 32 | public static void createStable(ConnectionDTO connection, StableAddDTO stableAddDTO) { 33 | List fieldList = stableAddDTO.getFieldList().stream().filter(f -> !f.getIsTag()).collect(Collectors.toList()); 34 | List tagList = stableAddDTO.getFieldList().stream().filter(TableFieldDTO::getIsTag).collect(Collectors.toList()); 35 | 36 | StringBuilder sql = new StringBuilder("create " + (ObjectUtils.isEmpty(tagList) ? "TABLE " : "STABLE ") + "`" + stableAddDTO.getDb() + "`.`"); 37 | sql.append(stableAddDTO.getTb()).append("` ("); 38 | fieldList.forEach(field -> { 39 | sql.append(field.getName()).append(" ").append(getFieldType(field)).append(","); 40 | }); 41 | 42 | if (fieldList.size() > 0) { 43 | sql.deleteCharAt(sql.lastIndexOf(",")); 44 | sql.append(")"); 45 | } 46 | 47 | 48 | if (ObjectUtils.isNotEmpty(tagList)) { 49 | sql.append(" tags ("); 50 | tagList.forEach(tag -> { 51 | sql.append(tag.getName()).append(" ").append(getFieldType(tag)).append(","); 52 | }); 53 | 54 | if (tagList.size() > 0) { 55 | sql.deleteCharAt(sql.lastIndexOf(",")); 56 | sql.append(")"); 57 | } 58 | } 59 | 60 | sql.append(";"); 61 | 62 | try { 63 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList(sql.toString())); 64 | } catch (Exception e) { 65 | if (e.getMessage() != null && e.getMessage().contains("TDengine ERROR (360)")) { 66 | throw new TableAlreadyExistException(); 67 | } 68 | throw e; 69 | } 70 | } 71 | 72 | /** 73 | * 删除超级表,谨慎操作 74 | * 75 | * @param connection 连接 76 | * @param dbName 库名 77 | * @param tbName 表名 78 | */ 79 | public static void deleteStable(ConnectionDTO connection, String dbName, String tbName) { 80 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList("DROP STABLE IF EXISTS `" + dbName + "`.`" + tbName + "`;")); 81 | } 82 | 83 | /** 84 | * 获取所有超级表 85 | * 86 | * @param connection 连接 87 | * @param db 库 88 | * @return 超级表列表 89 | */ 90 | public static QueryRstDTO getAllStable(ConnectionDTO connection, String db) { 91 | if(VersionUtils.compareVersion(connection.getVersion(), "3.0") > 0) { 92 | QueryRstDTO queryRstDTO = RestConnectionUtils.executeQuery(connection, "select stable_name as name, * from INFORMATION_SCHEMA.INS_STABLES where db_name = '"+db+"';"); 93 | 94 | if(null!= queryRstDTO) { 95 | if(ObjectUtils.isNotEmpty(queryRstDTO.getColumnList())) { 96 | queryRstDTO.getColumnList().remove("stable_name"); 97 | } 98 | 99 | for(Map map : queryRstDTO.getDataList()) { 100 | if(map.get("stable_name") !=null) { 101 | map.remove("stable_name"); 102 | } 103 | } 104 | } 105 | 106 | 107 | return queryRstDTO; 108 | } 109 | return RestConnectionUtils.executeQuery(connection, "show `" + db + "`.stables;"); 110 | } 111 | 112 | /** 113 | * 生成字段类型 114 | * 115 | * @param field 字段 116 | * @return 类型+长度 117 | */ 118 | private static String getFieldType(TableFieldDTO field) { 119 | if (ObjectUtils.isEmpty(field.getLength())) { 120 | return field.getDataType(); 121 | } else { 122 | return field.getDataType() + "(" + field.getLength() + ")"; 123 | } 124 | } 125 | 126 | /** 127 | * 获取单个超级表 128 | * 129 | * @param connection 连接 130 | * @param db 库 131 | * @param stb 超级表 132 | * @return 超级表 133 | */ 134 | public static Map getStable(ConnectionDTO connection, String db, String stb) { 135 | QueryRstDTO allStb = getAllStable(connection, db); 136 | for (Map stbTmp : allStb.getDataList()) { 137 | if (stbTmp.get("name").equals(stb)) { 138 | return stbTmp; 139 | } 140 | } 141 | return null; 142 | } 143 | 144 | /** 145 | * 获取超级表字段信息 146 | * 147 | * @param connection 连接 148 | * @param dbName 库 149 | * @param tbName 表 150 | * @return 字段列表 151 | */ 152 | public static List getStableField(ConnectionDTO connection, String dbName, String tbName) { 153 | QueryRstDTO fieldList = RestConnectionUtils.executeQuery(connection, "DESCRIBE `" + dbName + "`.`" + tbName + "`;"); 154 | 155 | return fieldList.getDataList().stream().map(f -> { 156 | TableFieldDTO tf = new TableFieldDTO(); 157 | tf.setLength(f.get("length") == null ? Integer.valueOf((f.get("Length") + "")) :Integer.valueOf( f.get("length").toString())); 158 | tf.setDataType(f.get("type") == null ? (f.get("Type") + "") : f.get("type").toString()); 159 | tf.setName(f.get("field") == null ? (f.get("Field") + "") : f.get("field").toString()); 160 | tf.setIsTag("TAG".equals(f.get("note")) || "TAG".equals(f.get("Note"))); 161 | return tf; 162 | }).collect(Collectors.toList()); 163 | } 164 | 165 | /** 166 | * 获取建表语句 167 | * 168 | * @param connection 连接 169 | * @param dbName 库 170 | * @param stb 超级表 171 | * @return SQL 172 | */ 173 | public static String getStableSql(ConnectionDTO connection, String dbName, String stb) { 174 | List list = RestConnectionUtils.executeQuery(connection, "SHOW CREATE STABLE `" + dbName + "`.`" + stb + "`;", StableCreateResDTO.class); 175 | return list.get(0).getCreateDbSql(); 176 | } 177 | 178 | /** 179 | * 修改超级表 180 | * 181 | * @param connection 连接 182 | * @param stableUpdateDTO 更新信息 183 | */ 184 | public static void updateStable(ConnectionDTO connection, StableUpdateDTO stableUpdateDTO) { 185 | List batchSql = new ArrayList<>(); 186 | if (ObjectUtils.isNotEmpty(stableUpdateDTO.getAddList())) { 187 | stableUpdateDTO.getAddList().forEach(f -> batchSql.add("ALTER STABLE `" + stableUpdateDTO.getDb() + "`.`" + stableUpdateDTO.getTb() + "` ADD " + (f.getIsTag() ? "TAG " : "COLUMN ") + f.getName() + " " + getFieldType(f) + ";")); 188 | } 189 | 190 | if (ObjectUtils.isNotEmpty(stableUpdateDTO.getDeleteList())) { 191 | stableUpdateDTO.getDeleteList().forEach(f -> batchSql.add("ALTER STABLE `" + stableUpdateDTO.getDb() + "`.`" + stableUpdateDTO.getTb() + "` DROP " + (f.getIsTag() ? "TAG " : "COLUMN ") + f.getName() + ";")); 192 | } 193 | 194 | if (ObjectUtils.isNotEmpty(stableUpdateDTO.getUpdateList())) { 195 | stableUpdateDTO.getUpdateList().forEach(f -> batchSql.add("ALTER STABLE `" + stableUpdateDTO.getDb() + "`.`" + stableUpdateDTO.getTb() + "` MODIFY " + (f.getIsTag() ? "TAG " : "COLUMN ") + f.getName() + " " + getFieldType(f) + ";")); 196 | } 197 | 198 | if (ObjectUtils.isNotEmpty(stableUpdateDTO.getTagNameChangeMap())) { 199 | stableUpdateDTO.getTagNameChangeMap().forEach((k, v) -> batchSql.add("ALTER STABLE `" + stableUpdateDTO.getDb() + "`.`" + stableUpdateDTO.getTb() + "` CHANGE TAG " + k + " " + v + ";")); 200 | } 201 | 202 | RestConnectionUtils.executeUpdate(connection, batchSql); 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/util/TableUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.util; 2 | 3 | import com.gitee.dbquery.tdgenie.sdk.dto.res.TableFieldResDTO; 4 | import com.gitee.dbquery.tdgenie.sdk.dto.tb.TableAddByStableDTO; 5 | import com.gitee.dbquery.tdgenie.sdk.dto.tb.TableUpdateDTO; 6 | import com.gitee.dbquery.tdgenie.sdk.exception.TableAlreadyExistException; 7 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 8 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 9 | import com.gitee.dbquery.tdgenie.sdk.dto.field.TableFieldDTO; 10 | import com.gitee.dbquery.tdgenie.sdk.dto.res.TableCreateResDTO; 11 | import com.gitee.dbquery.tdgenie.sdk.dto.res.TableResDTO; 12 | import com.gitee.dbquery.tdgenie.sdk.dto.tb.TableAddDTO; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Collections; 16 | import java.util.List; 17 | import java.util.stream.Collectors; 18 | 19 | /** 20 | * 表工具类 21 | * 22 | * @author 风一样的码农 23 | * @since 2023/8/18 24 | **/ 25 | public class TableUtils { 26 | 27 | /** 28 | * 创建表 29 | * 30 | * @param connection 连接 31 | * @param stableAddDTO 建表信息 32 | */ 33 | public static void createTable(ConnectionDTO connection, TableAddDTO stableAddDTO) { 34 | List fieldList = stableAddDTO.getFieldList().stream().filter(f -> !f.getIsTag()).collect(Collectors.toList()); 35 | List tagList = stableAddDTO.getFieldList().stream().filter(TableFieldDTO::getIsTag).collect(Collectors.toList()); 36 | 37 | StringBuilder sql = new StringBuilder("create " + (ObjectUtils.isEmpty(tagList) ? "TABLE " : "STABLE ") + "`" + stableAddDTO.getDb() + "`.`"); 38 | sql.append(stableAddDTO.getTb()).append("` ("); 39 | fieldList.forEach(field -> { 40 | sql.append(field.getName()).append(" ").append(getFieldType(field)).append(","); 41 | }); 42 | 43 | if (fieldList.size() > 0) { 44 | sql.deleteCharAt(sql.lastIndexOf(",")); 45 | sql.append(")"); 46 | } 47 | 48 | 49 | if (ObjectUtils.isNotEmpty(tagList)) { 50 | sql.append(" tags ("); 51 | tagList.forEach(tag -> { 52 | sql.append(tag.getName()).append(" ").append(getFieldType(tag)).append(","); 53 | }); 54 | 55 | if (tagList.size() > 0) { 56 | sql.deleteCharAt(sql.lastIndexOf(",")); 57 | sql.append(")"); 58 | } 59 | } 60 | 61 | sql.append(";"); 62 | 63 | try { 64 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList(sql.toString())); 65 | } catch (Exception e) { 66 | if (e.getMessage() != null && e.getMessage().contains("TDengine ERROR (360)")) { 67 | throw new TableAlreadyExistException(); 68 | } 69 | throw e; 70 | } 71 | } 72 | 73 | /** 74 | * 通过超级表批量建表 75 | * 76 | * @param connection 连接 77 | * @param dtoList 建表信息 78 | */ 79 | public static void createTableUsingStable(ConnectionDTO connection, List dtoList) { 80 | StringBuilder sb = new StringBuilder("CREATE TABLE "); 81 | for (TableAddByStableDTO dto : dtoList) { 82 | sb.append("`").append(dto.getDbName()).append("`.`").append(dto.getTableName()).append("`").append(" USING `").append(dto.getDbName()).append("`.`").append(dto.getStableName()).append("`"); 83 | StringBuilder tags = new StringBuilder("("); 84 | StringBuilder tagValues = new StringBuilder("("); 85 | dto.getTagValueMap().forEach((k, v) -> { 86 | tags.append(k).append(","); 87 | tagValues.append("'").append(v).append("'").append(","); 88 | }); 89 | sb.append(tags.substring(0, tags.length() - 1)).append(") TAGS ").append(tagValues.substring(0, tagValues.length() - 1)).append(") "); 90 | } 91 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList(sb.toString() + ";")); 92 | } 93 | 94 | /** 95 | * 删除表,谨慎操作 96 | * 97 | * @param connection 连接 98 | * @param dbName 库名 99 | * @param tbName 表名 100 | */ 101 | public static void deleteTable(ConnectionDTO connection, String dbName, String tbName) { 102 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList("DROP TABLE IF EXISTS `" + dbName + "`.`" + tbName + "`;")); 103 | } 104 | 105 | /** 106 | * 获取所有表 107 | * 108 | * @param connection 连接 109 | * @param db 库 110 | * @return 表列表 111 | */ 112 | public static List getAllTable(ConnectionDTO connection, String db) { 113 | return RestConnectionUtils.executeQuery(connection, "show `" + db + "`.tables;", TableResDTO.class); 114 | } 115 | 116 | /** 117 | * 生成字段类型 118 | * 119 | * @param field 字段 120 | * @return 类型+长度 121 | */ 122 | private static String getFieldType(TableFieldDTO field) { 123 | if (ObjectUtils.isEmpty(field.getLength())) { 124 | return field.getDataType(); 125 | } else { 126 | return field.getDataType() + "(" + field.getLength() + ")"; 127 | } 128 | } 129 | 130 | /** 131 | * 获取单个表 132 | * 133 | * @param connection 连接 134 | * @param db 库 135 | * @param tb 表 136 | * @return 表 137 | */ 138 | public static TableResDTO getStable(ConnectionDTO connection, String db, String tb) { 139 | List allStb = getAllTable(connection, db); 140 | for (TableResDTO stbTmp : allStb) { 141 | if (stbTmp.getName().equals(tb)) { 142 | return stbTmp; 143 | } 144 | } 145 | return null; 146 | } 147 | 148 | /** 149 | * 获取表字段信息 150 | * 151 | * @param connection 连接 152 | * @param dbName 库 153 | * @param tbName 表 154 | * @return 字段列表 155 | */ 156 | public static List getTableField(ConnectionDTO connection, String dbName, String tbName) { 157 | List fieldList = RestConnectionUtils.executeQuery(connection, "DESCRIBE `" + dbName + "`.`" + tbName + "`;", TableFieldResDTO.class); 158 | 159 | return fieldList.stream().map(f -> { 160 | TableFieldDTO tf = new TableFieldDTO(); 161 | tf.setLength(f.getLength()); 162 | tf.setDataType(f.getType()); 163 | tf.setName(f.getField()); 164 | tf.setIsTag("TAG".equals(f.getNote())); 165 | return tf; 166 | }).collect(Collectors.toList()); 167 | } 168 | 169 | /** 170 | * 获取建表语句 171 | * 172 | * @param connection 连接 173 | * @param dbName 库 174 | * @param tb 超级表 175 | * @return SQL 176 | */ 177 | public static String getTableSql(ConnectionDTO connection, String dbName, String tb) { 178 | List list = RestConnectionUtils.executeQuery(connection, "SHOW CREATE TABLE `" + dbName + "`.`" + tb + "`;", TableCreateResDTO.class); 179 | return list.get(0).getCreateDbSql(); 180 | } 181 | 182 | /** 183 | * 修改超级表 184 | * 185 | * @param connection 连接 186 | * @param stableUpdateDTO 更新信息 187 | */ 188 | public static void updateTable(ConnectionDTO connection, TableUpdateDTO stableUpdateDTO) { 189 | List batchSql = new ArrayList<>(); 190 | if (ObjectUtils.isNotEmpty(stableUpdateDTO.getAddList())) { 191 | stableUpdateDTO.getAddList().forEach(f -> batchSql.add("ALTER TABLE `" + stableUpdateDTO.getDb() + "`.`" + stableUpdateDTO.getTb() + "` ADD " + ("COLUMN ") + f.getName() + " " + getFieldType(f) + ";")); 192 | } 193 | 194 | if (ObjectUtils.isNotEmpty(stableUpdateDTO.getDeleteList())) { 195 | stableUpdateDTO.getDeleteList().forEach(f -> batchSql.add("ALTER TABLE `" + stableUpdateDTO.getDb() + "`.`" + stableUpdateDTO.getTb() + "` DROP " + ("COLUMN ") + f.getName() + ";")); 196 | } 197 | 198 | if (ObjectUtils.isNotEmpty(stableUpdateDTO.getUpdateList())) { 199 | stableUpdateDTO.getUpdateList().forEach(f -> batchSql.add("ALTER TABLE `" + stableUpdateDTO.getDb() + "`.`" + stableUpdateDTO.getTb() + "` MODIFY " + ("COLUMN ") + f.getName() + " " + getFieldType(f) + ";")); 200 | } 201 | 202 | if (ObjectUtils.isNotEmpty(stableUpdateDTO.getTagNameChangeMap())) { 203 | stableUpdateDTO.getTagNameChangeMap().forEach((k, v) -> batchSql.add("ALTER TABLE `" + stableUpdateDTO.getDb() + "`.`" + stableUpdateDTO.getTb() + "` SET TAG " + k + " = '" + v + "';")); 204 | } 205 | 206 | RestConnectionUtils.executeUpdate(connection, batchSql); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/util/TsDataUpdateUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.util; 2 | 3 | import com.gitee.dbquery.tdgenie.util.DateTimeUtils; 4 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 5 | 6 | import java.time.LocalDate; 7 | import java.time.LocalDateTime; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | /** 12 | * 时序数据更新工具类 13 | * 14 | * @author 风一样的码农 15 | * @since 2023/8/24 16 | **/ 17 | public class TsDataUpdateUtils { 18 | 19 | 20 | /** 21 | * 批量插入数据,自动建子表 22 | * 23 | * @param connection 连接 24 | * @param db 库 25 | * @param tb 表 26 | * @param stbDb 超级表所在库 27 | * @param stb 超级表 28 | * @param tagValueList TAG值 29 | * @param dataList 插入数据列表 30 | */ 31 | public static void batchInsertAutoCreateTable(ConnectionDTO connection, String db, String tb, 32 | String stbDb, String stb, 33 | List tagValueList, 34 | List> dataList) { 35 | 36 | StringBuilder sql = new StringBuilder("INSERT INTO `" + db + "`.`" + tb + "` USING `" + stbDb + "`.`" + stb + "` TAGS " + getFieldValueSql(tagValueList) + " VALUES "); 37 | dataList.forEach(d -> sql.append(getFieldValueSql(d))); 38 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList(sql.toString())); 39 | } 40 | 41 | /** 42 | * 不指定列,也即使用全列模式批量写入(推荐,性能较好) 43 | * 44 | * @param connection 连接 45 | * @param db 数据库 46 | * @param tb 数据表 47 | * @param dataList 数据列表 48 | */ 49 | public static void batchInsertFullColumn(ConnectionDTO connection, String db, String tb, List> dataList) { 50 | StringBuilder sql = new StringBuilder("INSERT INTO `" + db + "`.`" + tb + "` VALUES"); 51 | dataList.forEach(d -> sql.append(getFieldValueSql(d))); 52 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList(sql.toString())); 53 | } 54 | 55 | /** 56 | * 指定列批量插入 57 | * 58 | * @param connection 连接 59 | * @param db 数据库 60 | * @param tb 数据表 61 | * @param columnList 指定列 62 | * @param dataList 数据列表 63 | */ 64 | public static void batchInsertSpecifyColumn(ConnectionDTO connection, String db, String tb, 65 | List columnList, 66 | List> dataList) { 67 | StringBuilder columns = new StringBuilder("("); 68 | for (String column : columnList) { 69 | columns.append(column + ","); 70 | } 71 | columns.deleteCharAt(columns.length() - 1); 72 | columns.append(")"); 73 | 74 | StringBuilder sql = new StringBuilder("INSERT INTO `" + db + "`.`" + tb + "` " + columns + " VALUES "); 75 | dataList.forEach(d -> sql.append(getFieldValueSql(d))); 76 | RestConnectionUtils.executeUpdate(connection, Collections.singletonList(sql.toString())); 77 | } 78 | 79 | private static String getFieldValueSql(List fieldList) { 80 | StringBuilder sb = new StringBuilder("( "); 81 | for (Object obj : fieldList) { 82 | if (obj instanceof String) { 83 | sb.append("'").append(obj.toString()).append("',"); 84 | } else if (obj instanceof LocalDateTime) { 85 | sb.append("'").append(DateTimeUtils.format((LocalDateTime) obj, "yyyy-MM-dd HH:mm:ss.SSS")).append("',"); 86 | } else if (obj instanceof LocalDate) { 87 | sb.append("'").append(DateTimeUtils.format(((LocalDate) obj).atStartOfDay(), "yyyy-MM-dd HH:mm:ss.SSS")).append("',"); 88 | } else { 89 | sb.append(obj == null ? null : obj.toString()).append(","); 90 | } 91 | } 92 | sb.deleteCharAt(sb.length() - 1); 93 | sb.append(") "); 94 | return sb.toString(); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/sdk/util/VersionUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.sdk.util; 2 | 3 | /** 4 | * @author chenpi 5 | * @since 2024/3/20 6 | **/ 7 | public class VersionUtils { 8 | public static int compareVersion(String version1, String version2) { 9 | 10 | String[] s1 = version1.split("\\."); 11 | String[] s2 = version2.split("\\."); 12 | int len1 = s1.length; 13 | int len2 = s2.length; 14 | 15 | for(int i = 0; i < len1 || i < len2; i ++) { 16 | int xx = 0, yy = 0; 17 | if(i < len1) { 18 | xx = Integer.parseInt(s1[i]); 19 | } 20 | if(i < len2) { 21 | yy = Integer.parseInt(s2[i]); 22 | } 23 | if(xx > yy) { 24 | return 1; 25 | } 26 | if(xx < yy) { 27 | return -1; 28 | } 29 | } 30 | return 0; 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/store/ApplicationStore.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.store; 2 | 3 | import com.gitee.dbquery.tdgenie.model.CommonNode; 4 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 5 | import javafx.scene.control.Tab; 6 | import javafx.scene.control.TreeItem; 7 | import lombok.Data; 8 | 9 | import java.util.HashMap; 10 | 11 | /** 12 | * ApplicationStore 13 | * 14 | * @author pc 15 | * @since 2024/01/31 16 | **/ 17 | @Data 18 | public class ApplicationStore { 19 | private static TreeItem connectionTree; 20 | private static CommonNode currentNode; 21 | private static TreeItem currentTreeItem; 22 | private static HashMap tabsMap = new HashMap<>(); 23 | private static Double mainPaneLastDividerPositions; 24 | 25 | public static TreeItem getConnectionTree() { 26 | return connectionTree; 27 | } 28 | 29 | public static void setConnectionTree(TreeItem connectionTree) { 30 | ApplicationStore.connectionTree = connectionTree; 31 | } 32 | 33 | public static ConnectionModel getConnection(String name) { 34 | for(TreeItem node : connectionTree.getChildren()) { 35 | if(node.getValue().getName().equals(name)) { 36 | return (ConnectionModel)(node.getValue().getData()); 37 | } 38 | } 39 | return null; 40 | } 41 | 42 | public static CommonNode getCurrentNode() { 43 | return currentTreeItem == null ? null : currentTreeItem.getValue(); 44 | } 45 | 46 | public static HashMap getTabsMap() { 47 | return tabsMap; 48 | } 49 | 50 | public static void setTabsMap(HashMap tabsMap) { 51 | ApplicationStore.tabsMap = tabsMap; 52 | } 53 | 54 | public static TreeItem getCurrentTreeItem() { 55 | return currentTreeItem; 56 | } 57 | 58 | public static void setCurrentTreeItem(TreeItem currentTreeItem) { 59 | ApplicationStore.currentTreeItem = currentTreeItem; 60 | } 61 | 62 | public static Double getMainPaneLastDividerPositions() { 63 | return mainPaneLastDividerPositions; 64 | } 65 | 66 | public static void setMainPaneLastDividerPositions(Double mainPaneLastDividerPositions) { 67 | ApplicationStore.mainPaneLastDividerPositions = mainPaneLastDividerPositions; 68 | } 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/store/H2ConnectionPool.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.store; 2 | 3 | import com.zaxxer.hikari.HikariConfig; 4 | import com.zaxxer.hikari.HikariDataSource; 5 | 6 | import java.sql.Connection; 7 | import java.sql.SQLException; 8 | 9 | /** 10 | * H2ConnectionPool 11 | * 12 | * @author pc 13 | * @since 2024/02/01 14 | **/ 15 | public class H2ConnectionPool { 16 | private static final String url = "jdbc:h2:~/tsdb_jui"; 17 | private static final String username = "sa"; 18 | private static final String password = ""; 19 | private static final HikariConfig config = new HikariConfig(); 20 | private static final HikariDataSource dataSource; 21 | 22 | static { 23 | config.setJdbcUrl(url); 24 | config.setUsername(username); 25 | config.setPassword(password); 26 | // 设置连接池大小,默认为10 27 | config.setMaximumPoolSize(10); 28 | dataSource = new HikariDataSource(config); 29 | } 30 | 31 | public static void close() { 32 | dataSource.close(); 33 | } 34 | 35 | public static Connection getConnection() throws SQLException { 36 | return dataSource.getConnection(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/store/H2DbUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.store; 2 | 3 | import com.gitee.dbquery.tdgenie.util.ObjectUtils; 4 | 5 | import java.math.BigDecimal; 6 | import java.sql.*; 7 | import java.time.LocalDateTime; 8 | import java.util.*; 9 | import java.util.concurrent.atomic.AtomicInteger; 10 | 11 | /** 12 | * @author 风一样的码农 13 | * @since 2024/2/1 14 | **/ 15 | public class H2DbUtils { 16 | public static boolean createTable(String tableName, Map fieldMap) throws SQLException { 17 | if (ObjectUtils.isEmpty(tableName)) { 18 | return false; 19 | } 20 | if (fieldMap == null) { 21 | return false; 22 | } 23 | 24 | try (Connection conn = H2ConnectionPool.getConnection(); Statement stmt = conn.createStatement()) { 25 | // 连接到H2数据库 26 | // 创建Statement对象 27 | // 创建表的SQL语句 28 | String sql = getCreateSql(tableName, fieldMap); 29 | // 执行SQL语句 30 | stmt.executeUpdate(sql); 31 | } 32 | return true; 33 | } 34 | 35 | public static boolean dropTable(String tableName) throws SQLException { 36 | if (ObjectUtils.isEmpty(tableName)) { 37 | return false; 38 | } 39 | 40 | try (Connection conn = H2ConnectionPool.getConnection(); Statement stmt = conn.createStatement()) { 41 | // 连接到H2数据库 42 | // 创建Statement对象 43 | String sql = "DROP TABLE " + tableName; 44 | stmt.executeUpdate(sql); 45 | } 46 | return true; 47 | } 48 | 49 | private static String getCreateSql(String tableName, Map fieldMap) { 50 | StringBuilder builder = new StringBuilder("CREATE TABLE " + tableName + " ("); 51 | fieldMap.forEach((key, value) -> { 52 | builder.append(key); 53 | builder.append(" "); 54 | if (value.equals(Long.class)) { 55 | builder.append("bigint"); 56 | } else if (value.equals(Integer.class)) { 57 | builder.append("int"); 58 | } else if (value.equals(String.class)) { 59 | builder.append("varchar"); 60 | } else if (value.equals(BigDecimal.class)) { 61 | builder.append("decimal"); 62 | } else if (value.equals(Double.class)) { 63 | builder.append("double"); 64 | } else if (value.equals(Boolean.class)) { 65 | builder.append("int"); 66 | } else if (value.equals(LocalDateTime.class)) { 67 | builder.append("datetime"); 68 | } else { 69 | throw new RuntimeException("invalid field type"); 70 | } 71 | builder.append(","); 72 | }); 73 | builder.deleteCharAt(builder.length() - 1); 74 | return builder + ")"; 75 | } 76 | 77 | private static String getInsertSql(String tableName, Map map, HashMap indexMap) { 78 | StringBuilder builder = new StringBuilder("INSERT INTO " + tableName + " ("); 79 | StringBuilder builder2 = new StringBuilder(" VALUES ("); 80 | AtomicInteger index = new AtomicInteger(1); 81 | map.forEach((key, value) -> { 82 | builder.append(key); 83 | builder.append(" "); 84 | builder.append(","); 85 | builder2.append("?"); 86 | builder2.append(" "); 87 | builder2.append(","); 88 | indexMap.put(key, index.get()); 89 | index.getAndIncrement(); 90 | }); 91 | builder.deleteCharAt(builder.length() - 1); 92 | builder2.deleteCharAt(builder2.length() - 1); 93 | // 插入表的SQL语句 94 | return builder + ")" + builder2 + ")"; 95 | } 96 | 97 | public static boolean insertByHashMap(String tableName, List> listMap) throws SQLException { 98 | 99 | Connection connection = null; 100 | PreparedStatement statement = null; 101 | try { 102 | // 连接到H2数据库 103 | connection = H2ConnectionPool.getConnection(); 104 | HashMap indexMap = new HashMap<>(listMap.get(0).size()); 105 | String sql = getInsertSql(tableName, listMap.get(0), indexMap); 106 | statement = connection.prepareStatement(sql); 107 | 108 | setValue(listMap, indexMap, statement); 109 | // 执行批处理 110 | int[] rowsInserted = statement.executeBatch(); 111 | if (rowsInserted.length != listMap.size()) { 112 | return false; 113 | } 114 | } finally { 115 | if (connection != null) { 116 | connection.close(); 117 | } 118 | if (statement != null) { 119 | statement.close(); 120 | } 121 | } 122 | 123 | return true; 124 | } 125 | 126 | public static boolean executeUpdate(String sql) throws SQLException { 127 | try (Connection connection = H2ConnectionPool.getConnection(); Statement statement = connection.createStatement()) { 128 | // 连接到H2数据库 129 | // 执行批处理 130 | return statement.execute(sql); 131 | } 132 | } 133 | 134 | public static List> query(String sql) throws SQLException { 135 | // 创建List对象来存储查询结果 136 | List> resultList = new ArrayList<>(); 137 | try (Connection connection = H2ConnectionPool.getConnection(); Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(sql)) { 138 | // 执行查询 139 | // 获取结果集的元数据 140 | ResultSetMetaData metaData = rs.getMetaData(); 141 | int columnCount = metaData.getColumnCount(); 142 | 143 | // 处理查询结果 144 | while (rs.next()) { 145 | HashMap map = new HashMap<>(columnCount); 146 | for (int i = 1; i <= columnCount; i++) { 147 | map.put(metaData.getColumnName(i), rs.getObject(i)); 148 | } 149 | resultList.add(map); 150 | } 151 | 152 | } 153 | return resultList; 154 | } 155 | 156 | private static void setValue(List> listMap, HashMap indexMap, 157 | PreparedStatement statement) throws SQLException { 158 | // 批量插入数据 159 | for (Map m : listMap) { 160 | m.forEach((key, value) -> { 161 | if (value instanceof Long) { 162 | try { 163 | statement.setLong(indexMap.get(key), (Long) value); 164 | } catch (SQLException e) { 165 | throw new RuntimeException(e); 166 | } 167 | } else if (value instanceof Integer) { 168 | try { 169 | statement.setInt(indexMap.get(key), (Integer) value); 170 | } catch (SQLException e) { 171 | throw new RuntimeException(e); 172 | } 173 | } else if (value instanceof String) { 174 | try { 175 | statement.setString(indexMap.get(key), (String) value); 176 | } catch (SQLException e) { 177 | throw new RuntimeException(e); 178 | } 179 | } else if (value instanceof BigDecimal) { 180 | try { 181 | statement.setBigDecimal(indexMap.get(key), (BigDecimal) value); 182 | } catch (SQLException e) { 183 | throw new RuntimeException(e); 184 | } 185 | } else if (value instanceof Double) { 186 | try { 187 | statement.setDouble(indexMap.get(key), (Double) value); 188 | } catch (SQLException e) { 189 | throw new RuntimeException(e); 190 | } 191 | } else if (value instanceof Boolean) { 192 | int flag = (Boolean) value ? 1 : 0; 193 | try { 194 | statement.setInt(indexMap.get(key), flag); 195 | } catch (SQLException e) { 196 | throw new RuntimeException(e); 197 | } 198 | } else if (value instanceof Byte) { 199 | try { 200 | statement.setByte(indexMap.get(key), (Byte) value); 201 | } catch (SQLException e) { 202 | throw new RuntimeException(e); 203 | } 204 | } else if (value instanceof LocalDateTime) { 205 | try { 206 | statement.setTimestamp(indexMap.get(key), Timestamp.valueOf(((LocalDateTime) value))); 207 | } catch (SQLException e) { 208 | throw new RuntimeException(e); 209 | } 210 | } 211 | }); 212 | statement.addBatch(); 213 | } 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/AlertUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import com.jfoenix.controls.JFXAlert; 4 | import com.jfoenix.controls.JFXButton; 5 | import com.jfoenix.controls.JFXDialogLayout; 6 | import io.datafx.controller.context.ApplicationContext; 7 | import javafx.scene.control.Label; 8 | import javafx.stage.Modality; 9 | import javafx.stage.Stage; 10 | import lombok.extern.slf4j.Slf4j; 11 | 12 | /** 13 | * @author 风一样的码农 14 | * @since 2024/2/8 15 | **/ 16 | @Slf4j 17 | public class AlertUtils { 18 | 19 | public static void show(String msg) { 20 | JFXAlert alert = new JFXAlert<>(ApplicationContext.getInstance().getRegisteredObject(Stage.class)); 21 | alert.initModality(Modality.APPLICATION_MODAL); 22 | alert.setOverlayClose(true); 23 | JFXDialogLayout layout = new JFXDialogLayout(); 24 | layout.setHeading(new Label("提示")); 25 | layout.setBody(new Label(msg)); 26 | JFXButton closeButton = new JFXButton("确定"); 27 | closeButton.setOnAction(event -> alert.hideWithAnimation()); 28 | layout.setActions(closeButton); 29 | alert.setContent(layout); 30 | alert.show(); 31 | } 32 | 33 | public static void showException(Throwable t) { 34 | log.error(t.toString(), t); 35 | show("程序异常:" + t.getMessage()); 36 | } 37 | 38 | public static void showExceptionMsg(String msg) { 39 | show("程序异常:" + msg); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/ConnectionDAO.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 4 | import com.gitee.dbquery.tdgenie.sdk.util.RestConnectionUtils; 5 | import com.gitee.dbquery.tdgenie.store.H2DbUtils; 6 | import lombok.extern.slf4j.Slf4j; 7 | 8 | import java.sql.SQLException; 9 | import java.util.*; 10 | import java.util.stream.Collectors; 11 | 12 | /** 13 | * @author chenpi 14 | * @since 2024/3/25 15 | **/ 16 | @Slf4j 17 | public class ConnectionDAO { 18 | public static List> queryByName(String name) { 19 | try { 20 | return H2DbUtils.query("select * from t_connection where name='" + name + "'"); 21 | } catch (SQLException e) { 22 | AlertUtils.showException(e); 23 | } 24 | return Collections.emptyList(); 25 | } 26 | 27 | public static void deleteConnection(String name) { 28 | if(ObjectUtils.isEmpty(name)) { 29 | return; 30 | } 31 | try { 32 | H2DbUtils.executeUpdate("delete from t_connection where name='" + name + "';"); 33 | } catch (SQLException e) { 34 | AlertUtils.showException(e); 35 | } 36 | } 37 | public static void connectionTbExistCheck() throws SQLException { 38 | List tableNameList = new ArrayList<>(); 39 | List> tables = H2DbUtils.query("show tables;"); 40 | for (Map tb : tables) { 41 | tableNameList.add(tb.get("TABLE_NAME").toString()); 42 | } 43 | 44 | if (!tableNameList.contains("t_connection".toUpperCase())) { 45 | Map fieldMap = new HashMap<>(); 46 | fieldMap.put("name", String.class); 47 | fieldMap.put("ip", String.class); 48 | fieldMap.put("port", String.class); 49 | fieldMap.put("username", String.class); 50 | fieldMap.put("password", String.class); 51 | fieldMap.put("version", String.class); 52 | H2DbUtils.createTable("t_connection", fieldMap); 53 | } 54 | } 55 | 56 | public static List getConnectionList() throws SQLException { 57 | List> connectionList = H2DbUtils.query("select * from t_connection;"); 58 | return connectionList.stream().map(con -> { 59 | ConnectionModel connectionDTO = new ConnectionModel(); 60 | connectionDTO.setIp(con.get("IP").toString()); 61 | connectionDTO.setPort(con.get("PORT").toString()); 62 | connectionDTO.setUsername(con.get("USERNAME").toString()); 63 | connectionDTO.setPassword(con.get("PASSWORD").toString()); 64 | connectionDTO.setName(con.get("NAME").toString()); 65 | if(con.get("VERSION") == null) { 66 | connectionDTO.setVersion(RestConnectionUtils.getServerVersion(connectionDTO)); 67 | } else { 68 | connectionDTO.setVersion(con.get("VERSION").toString()); 69 | } 70 | 71 | return connectionDTO; 72 | }).collect(Collectors.toList()); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/ContextMenuUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import com.gitee.dbquery.tdgenie.store.ApplicationStore; 4 | import javafx.scene.control.ContextMenu; 5 | import javafx.scene.control.MenuItem; 6 | import javafx.scene.control.Tab; 7 | import javafx.scene.control.TabPane; 8 | 9 | /** 10 | * @author chenpi 11 | * @since 1.0.0 2024/3/22 21:44 12 | **/ 13 | public class ContextMenuUtils { 14 | 15 | public static ContextMenu generateTabPaneContextMenu(TabPane tabPane) { 16 | ContextMenu contextMenu = new ContextMenu(); 17 | MenuItem closeAllMenuItem = new MenuItem("全部关闭"); 18 | closeAllMenuItem.setOnAction(event -> { 19 | tabPane.getTabs().clear(); 20 | ApplicationStore.getTabsMap().clear(); 21 | }); 22 | MenuItem closeOtherMenuItem = new MenuItem("关闭未选中"); 23 | closeOtherMenuItem.setOnAction(event -> { 24 | for (Tab tab : tabPane.getTabs()) { 25 | if (tab.selectedProperty().getValue()) { 26 | tabPane.getTabs().clear(); 27 | ApplicationStore.getTabsMap().clear(); 28 | tabPane.getTabs().add(tab); 29 | ApplicationStore.getTabsMap().put(tab.getText(), tab); 30 | break; 31 | } 32 | } 33 | }); 34 | MenuItem closeCurrentMenuItem = new MenuItem("关闭选中"); 35 | closeCurrentMenuItem.setOnAction(event -> { 36 | for (Tab tab : tabPane.getTabs()) { 37 | if (tab.selectedProperty().getValue()) { 38 | tabPane.getTabs().remove(tab); 39 | ApplicationStore.getTabsMap().remove(tab.getText()); 40 | break; 41 | } 42 | } 43 | }); 44 | contextMenu.getItems().addAll(closeCurrentMenuItem, closeOtherMenuItem, closeAllMenuItem); 45 | 46 | return contextMenu; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/GridPaneUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import com.jfoenix.controls.JFXButton; 4 | import javafx.scene.Node; 5 | import javafx.scene.layout.GridPane; 6 | 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | 10 | /** 11 | * @author chenpi 12 | * @since 1.0.0 2024/3/22 21:38 13 | **/ 14 | public class GridPaneUtils { 15 | public static void deleteFieldRow(GridPane grid, final JFXButton delButton) { 16 | Set deleteNodes = new HashSet<>(); 17 | boolean matchFlag = false; 18 | for (Node child : grid.getChildren()) { 19 | // get index from child 20 | Integer rowIndex = GridPane.getRowIndex(child); 21 | 22 | // handle null values for index=0 23 | int r = rowIndex == null ? 0 : rowIndex; 24 | 25 | 26 | if (matchFlag && !child.getId().contains(delButton.getId().split("_")[0] + "_")) {//you bug TODO 27 | // decrement rows for rows after the deleted row 28 | GridPane.setRowIndex(child, r - 1); 29 | } 30 | if (child.getId().contains(delButton.getId().split("_")[0] + "_")) { 31 | // collect matching rows for deletion 32 | deleteNodes.add(child); 33 | matchFlag = true; 34 | } 35 | } 36 | 37 | // remove nodes from row 38 | grid.getChildren().removeAll(deleteNodes); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/ImageViewUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 4 | import javafx.scene.image.ImageView; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 2024/2/6 9 | **/ 10 | public class ImageViewUtils { 11 | public static ImageView getImageViewByType(NodeTypeEnum nodeTypeEnum) { 12 | ImageView imageView; 13 | switch (nodeTypeEnum) { 14 | case ROOT: 15 | imageView = new ImageView("/images/logo.png"); 16 | break; 17 | case CONNECTION: 18 | imageView = new ImageView("/images/tdengine.png"); 19 | break; 20 | case DB: 21 | imageView = new ImageView("/images/db.png"); 22 | break; 23 | case STB: 24 | imageView = new ImageView("/images/stb.png"); 25 | break; 26 | case TB: 27 | imageView = new ImageView("/images/tb.png"); 28 | break; 29 | default: 30 | throw new IllegalStateException("Unexpected value: " + nodeTypeEnum); 31 | } 32 | 33 | return imageView; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/JavaFxBeanUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import javafx.beans.property.ListProperty; 4 | import javafx.beans.property.SimpleListProperty; 5 | import javafx.collections.FXCollections; 6 | import javafx.collections.ObservableList; 7 | 8 | /** 9 | * @author 风一样的码农 10 | * @since 2024/2/20 11 | **/ 12 | public class JavaFxBeanUtils { 13 | public static ObservableList getTrueFalseObservableList() { 14 | ObservableList innerList = FXCollections.observableArrayList(); 15 | ListProperty dataValues = new SimpleListProperty<>(innerList); 16 | dataValues.add("true"); 17 | dataValues.add("false"); 18 | return innerList; 19 | } 20 | 21 | public static ObservableList getDataTypeObservableList() { 22 | ObservableList innerList = FXCollections.observableArrayList(); 23 | ListProperty dataValues = new SimpleListProperty<>(innerList); 24 | dataValues.add("TINYINT"); 25 | dataValues.add("BOOL"); 26 | dataValues.add("BINARY"); 27 | dataValues.add("INT"); 28 | dataValues.add("FLOAT"); 29 | dataValues.add("NCHAR"); 30 | dataValues.add("DOUBLE"); 31 | dataValues.add("TIMESTAMP"); 32 | dataValues.add("BIGINT"); 33 | dataValues.add("SMALLINT"); 34 | return innerList; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/ObjectUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | 4 | import java.lang.reflect.Array; 5 | import java.util.Collection; 6 | import java.util.Map; 7 | import java.util.Optional; 8 | 9 | /** 10 | * 对象工具类 11 | * 12 | * @author 风一样的码农 13 | * @since 1.0.3 14 | **/ 15 | public class ObjectUtils { 16 | 17 | public static boolean isNotEmpty(Object[] array) { 18 | return !isEmpty(array); 19 | } 20 | 21 | public static boolean isNotEmpty(Object obj) { 22 | return !isEmpty(obj); 23 | } 24 | 25 | public static boolean isEmpty(Object obj) { 26 | if (obj == null) { 27 | return true; 28 | } else if (obj instanceof Optional) { 29 | return !((Optional) obj).isPresent(); 30 | } else if (obj instanceof CharSequence) { 31 | return ((CharSequence) obj).length() == 0; 32 | } else if (obj.getClass().isArray()) { 33 | return Array.getLength(obj) == 0; 34 | } else if (obj instanceof Collection) { 35 | return ((Collection) obj).isEmpty(); 36 | } else { 37 | return obj instanceof Map ? ((Map) obj).isEmpty() : false; 38 | } 39 | } 40 | 41 | 42 | public static Object stringTypeConvert(String dataType, String value) { 43 | if(ObjectUtils.isEmpty(value)) { 44 | return null; 45 | } 46 | 47 | if("NCHAR".equals(dataType) || "TIMESTAMP".equals(dataType)) { 48 | return value; 49 | } else if("BOOL".equals(dataType)) { 50 | return Boolean.valueOf(value); 51 | } else if("FLOAT".equals(dataType)||"DOUBLE".equals(dataType)) { 52 | return Double.valueOf(value); 53 | } else { 54 | return Long.valueOf(value); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/PropertiesUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import java.util.Properties; 4 | 5 | /** 6 | * @author chenpi 7 | * @since 2024/3/25 8 | **/ 9 | public class PropertiesUtils { 10 | public static Double getDouble(Properties properties, String key, Double defaultValue) { 11 | return Double.parseDouble(ValueUtils.getString(properties.getProperty(key), defaultValue)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/TabUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 4 | import com.gitee.dbquery.tdgenie.gui.component.DbTabController; 5 | import com.gitee.dbquery.tdgenie.gui.component.QueryTabController; 6 | import com.gitee.dbquery.tdgenie.gui.component.RecordTabController; 7 | import com.gitee.dbquery.tdgenie.gui.component.StbTabController; 8 | import com.gitee.dbquery.tdgenie.store.ApplicationStore; 9 | import io.datafx.controller.flow.Flow; 10 | import io.datafx.controller.flow.FlowException; 11 | import io.datafx.controller.flow.FlowHandler; 12 | import io.datafx.controller.flow.container.AnimatedFlowContainer; 13 | import io.datafx.controller.flow.container.ContainerAnimations; 14 | import javafx.scene.Node; 15 | import javafx.scene.control.Tab; 16 | import javafx.scene.control.TabPane; 17 | import javafx.scene.image.ImageView; 18 | import javafx.scene.layout.StackPane; 19 | import javafx.util.Duration; 20 | import lombok.extern.slf4j.Slf4j; 21 | 22 | import java.lang.reflect.InvocationTargetException; 23 | 24 | /** 25 | * @author chenpi 26 | * @since 2024/3/26 27 | **/ 28 | @Slf4j 29 | public class TabUtils { 30 | public static void addConnectionTab(TabPane tabPane, String title) { 31 | try { 32 | addTab(tabPane, title, ImageViewUtils.getImageViewByType(NodeTypeEnum.CONNECTION), DbTabController.class, null); 33 | } catch (Exception e) { 34 | AlertUtils.showException(e); 35 | } 36 | } 37 | 38 | public static void addDbTab(TabPane tabPane, String title) { 39 | try { 40 | addTab(tabPane, title, ImageViewUtils.getImageViewByType(NodeTypeEnum.DB), StbTabController.class, null); 41 | } catch (Exception e) { 42 | AlertUtils.showException(e); 43 | } 44 | } 45 | 46 | public static void addQueryTab(TabPane tabPane) { 47 | try { 48 | addTab(tabPane, "数据查询", new ImageView("/images/query.png"), QueryTabController.class, null); 49 | } catch (Exception e) { 50 | AlertUtils.showException(e); 51 | } 52 | } 53 | 54 | public static void addStbTab(TabPane tabPane, String title) { 55 | try { 56 | addTab(tabPane, title, ImageViewUtils.getImageViewByType(NodeTypeEnum.STB), RecordTabController.class, null); 57 | } catch (Exception e) { 58 | AlertUtils.showException(e); 59 | } 60 | } 61 | 62 | public static void addTab(TabPane tabPane, String title, Node icon, Class controllerClass) { 63 | try { 64 | addTab(tabPane, title, icon, controllerClass, null); 65 | } catch (Exception e) { 66 | AlertUtils.showException(e); 67 | } 68 | } 69 | public static void addTab(TabPane tabPane, String title, Node icon, Class controllerClass, Object userData) throws FlowException { 70 | 71 | FlowHandler flowHandler = new Flow(controllerClass).createHandler(); 72 | Tab tab = ApplicationStore.getTabsMap().get(title); 73 | 74 | if (tab == null) { 75 | 76 | tab = new Tab(title); 77 | tab.setUserData(userData); 78 | tab.setGraphic(icon); 79 | tabPane.getTabs().add(tab); 80 | tabPane.getSelectionModel().select(tab); 81 | 82 | StackPane node = flowHandler.start(new AnimatedFlowContainer(Duration.millis(320), ContainerAnimations.SWIPE_LEFT)); 83 | node.getStyleClass().addAll("tab-content"); 84 | tab.setContent(node); 85 | 86 | ApplicationStore.getTabsMap().put(title, tab); 87 | tab.setOnClosed(event -> { 88 | ApplicationStore.getTabsMap().remove(title); 89 | try { 90 | flowHandler.getCurrentViewContext().destroy(); 91 | } catch (IllegalAccessException | InvocationTargetException e) { 92 | AlertUtils.showException(e); 93 | } 94 | 95 | }); 96 | } 97 | 98 | tabPane.getSelectionModel().select(tab); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/TableUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | import javafx.collections.ObservableList; 7 | import javafx.event.EventHandler; 8 | import javafx.scene.control.TablePosition; 9 | import javafx.scene.control.TableView; 10 | import javafx.scene.input.Clipboard; 11 | import javafx.scene.input.ClipboardContent; 12 | import javafx.scene.input.KeyCode; 13 | import javafx.scene.input.KeyCodeCombination; 14 | import javafx.scene.input.KeyCombination; 15 | import javafx.scene.input.KeyEvent; 16 | 17 | public class TableUtils { 18 | 19 | /** 20 | * Install the keyboard handler: 21 | * + CTRL + C = copy to clipboard 22 | * + CTRL + V = paste to clipboard 23 | * 24 | * @param table 25 | */ 26 | public static void installCopyPasteHandler(TableView table) { 27 | 28 | // install copy/paste keyboard handler 29 | table.setOnKeyPressed(new TableKeyEventHandler()); 30 | 31 | } 32 | 33 | /** 34 | * Copy/Paste keyboard event handler. 35 | * The handler uses the keyEvent's source for the clipboard data. The source must be of type TableView. 36 | */ 37 | public static class TableKeyEventHandler implements EventHandler { 38 | 39 | KeyCodeCombination copyKeyCodeCompination = new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY); 40 | KeyCodeCombination pasteKeyCodeCompination = new KeyCodeCombination(KeyCode.V, KeyCombination.CONTROL_ANY); 41 | 42 | public void handle(final KeyEvent keyEvent) { 43 | 44 | if (copyKeyCodeCompination.match(keyEvent)) { 45 | 46 | if (keyEvent.getSource() instanceof TableView) { 47 | 48 | // copy to clipboard 49 | copySelectionToClipboard((TableView) keyEvent.getSource()); 50 | 51 | // event is handled, consume it 52 | keyEvent.consume(); 53 | 54 | } 55 | 56 | } else if (pasteKeyCodeCompination.match(keyEvent)) { 57 | 58 | if (keyEvent.getSource() instanceof TableView) { 59 | 60 | // copy to clipboard 61 | pasteClipboard((TableView) keyEvent.getSource()); 62 | 63 | // event is handled, consume it 64 | keyEvent.consume(); 65 | 66 | } 67 | 68 | } 69 | 70 | } 71 | 72 | } 73 | 74 | /** 75 | * Get table selection and copy it to the clipboard. 76 | * 77 | * @param table 78 | */ 79 | public static void copySelectionToClipboard(TableView table) { 80 | 81 | StringBuilder clipboardString = new StringBuilder(); 82 | 83 | ObservableList positionList = table.getSelectionModel().getSelectedCells(); 84 | 85 | int prevRow = -1; 86 | 87 | for (TablePosition position : positionList) { 88 | 89 | int row = position.getRow(); 90 | int col = position.getColumn(); 91 | 92 | Object cell = (Object) table.getColumns().get(col).getCellData(row); 93 | 94 | // null-check: provide empty string for nulls 95 | if (cell == null) { 96 | cell = ""; 97 | } 98 | 99 | // determine whether we advance in a row (tab) or a column 100 | // (newline). 101 | if (prevRow == row) { 102 | 103 | clipboardString.append('\t'); 104 | 105 | } else if (prevRow != -1) { 106 | 107 | clipboardString.append('\n'); 108 | 109 | } 110 | 111 | // create string from cell 112 | String text = cell.toString(); 113 | 114 | // add new item to clipboard 115 | clipboardString.append(text); 116 | 117 | // remember previous 118 | prevRow = row; 119 | } 120 | 121 | // create clipboard content 122 | final ClipboardContent clipboardContent = new ClipboardContent(); 123 | clipboardContent.putString(clipboardString.toString()); 124 | 125 | // set clipboard content 126 | Clipboard.getSystemClipboard().setContent(clipboardContent); 127 | 128 | System.out.println("Clipboard string: " + clipboardContent); 129 | 130 | } 131 | 132 | public static void pasteClipboard(TableView table) { 133 | 134 | TablePosition focusedCellPosition = table.getFocusModel().getFocusedCell(); 135 | 136 | System.out.println("Pasting into cells starting at " + focusedCellPosition); 137 | 138 | String pasteString = Clipboard.getSystemClipboard().getString(); 139 | 140 | System.out.println(pasteString); 141 | 142 | Pattern pattern = Pattern.compile("([^\t]*)\t([^\t]*)\t([^\n]*)(\n)?"); 143 | Matcher matcher = pattern.matcher(pasteString); 144 | while (matcher.find()) { 145 | 146 | System.out.println(matcher.group(1) + "," + matcher.group(2) + "," + matcher.group(3)); 147 | 148 | // TODO: what now? how to paste the data? 149 | 150 | } 151 | 152 | } 153 | 154 | 155 | } 156 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/TimeUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import java.time.Instant; 4 | import java.time.LocalDate; 5 | import java.time.ZoneId; 6 | 7 | /** 8 | * @author 风一样的码农 9 | * @since 2024/2/21 10 | **/ 11 | public class TimeUtils { 12 | public static Long LocalDateToLong(LocalDate localDate) { 13 | ZoneId zone = ZoneId.systemDefault(); 14 | Instant instant = localDate.atStartOfDay().atZone(zone).toInstant(); 15 | // long stamp = instant.toEpochMilli() / 1000; 16 | return instant.toEpochMilli(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/TreeUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import com.gitee.dbquery.tdgenie.common.enums.NodeTypeEnum; 4 | import com.gitee.dbquery.tdgenie.model.CommonNode; 5 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 6 | import com.gitee.dbquery.tdgenie.model.DatabaseModel; 7 | import com.gitee.dbquery.tdgenie.model.StableModel; 8 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 9 | import com.gitee.dbquery.tdgenie.sdk.dto.QueryRstDTO; 10 | import com.gitee.dbquery.tdgenie.sdk.util.DataBaseUtils; 11 | import com.gitee.dbquery.tdgenie.sdk.util.SuperTableUtils; 12 | import javafx.scene.control.TreeItem; 13 | 14 | import java.util.Map; 15 | 16 | /** 17 | * @author chenpi 18 | * @since 1.0.0 2024/3/22 21:41 19 | **/ 20 | public class TreeUtils { 21 | public static TreeItem generateConnectionTree(ConnectionModel connectionModel) { 22 | TreeItem connectionItem = new TreeItem<>(new CommonNode(connectionModel.getName(), NodeTypeEnum.CONNECTION, connectionModel), ImageViewUtils.getImageViewByType(NodeTypeEnum.CONNECTION)); 23 | 24 | 25 | ConnectionDTO connection = TsdbConnectionUtils.getConnection(connectionModel); 26 | 27 | QueryRstDTO dbList ; 28 | try { 29 | dbList = DataBaseUtils.getAllDatabase(connection); 30 | } catch (Exception e) { 31 | return connectionItem; 32 | } 33 | 34 | 35 | for (Map db : dbList.getDataList()) { 36 | QueryRstDTO tbList = SuperTableUtils.getAllStable(connection, db.get("name").toString()); 37 | DatabaseModel databaseModel = new DatabaseModel(db.get("name").toString(), db, connectionModel); 38 | TreeItem dbNode = new TreeItem<>(new CommonNode(db.get("name").toString(), NodeTypeEnum.DB, databaseModel), ImageViewUtils.getImageViewByType(NodeTypeEnum.DB)); 39 | connectionItem.getChildren().add(dbNode); 40 | 41 | for (Map tb : tbList.getDataList()) { 42 | TreeItem tbNode = new TreeItem<>(new CommonNode(tb.get("name").toString(), NodeTypeEnum.STB, new StableModel(tb, databaseModel)), ImageViewUtils.getImageViewByType(NodeTypeEnum.STB)); 43 | dbNode.getChildren().add(tbNode); 44 | } 45 | } 46 | 47 | return connectionItem; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/TsdbConnectionUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | import com.gitee.dbquery.tdgenie.model.ConnectionModel; 4 | import com.gitee.dbquery.tdgenie.sdk.dto.ConnectionDTO; 5 | 6 | /** 7 | * @author 风一样的码农 8 | * @since 1.0.0 2024/2/1 21:18 9 | **/ 10 | public class TsdbConnectionUtils { 11 | public static ConnectionDTO getConnection(ConnectionModel connectionModel) { 12 | ConnectionDTO connectionDTO = new ConnectionDTO(); 13 | connectionDTO.setIp(connectionModel.getIp()); 14 | connectionDTO.setRestfulPort(connectionModel.getPort()); 15 | connectionDTO.setUsername(connectionModel.getUsername()); 16 | connectionDTO.setPassword(connectionModel.getPassword()); 17 | connectionDTO.setVersion(connectionModel.getVersion()); 18 | return connectionDTO; 19 | } 20 | 21 | public static ConnectionDTO getConnectionWithDB(ConnectionModel connectionModel, String db) { 22 | ConnectionDTO connectionDTO = new ConnectionDTO(); 23 | connectionDTO.setIp(connectionModel.getIp()); 24 | connectionDTO.setRestfulPort(connectionModel.getPort()); 25 | connectionDTO.setUsername(connectionModel.getUsername()); 26 | connectionDTO.setPassword(connectionModel.getPassword()); 27 | connectionDTO.setVersion(connectionModel.getVersion()); 28 | connectionDTO.setDb(db); 29 | return connectionDTO; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tdengine/src/main/java/com/gitee/dbquery/tdgenie/util/ValueUtils.java: -------------------------------------------------------------------------------- 1 | package com.gitee.dbquery.tdgenie.util; 2 | 3 | /** 4 | * @author 风一样的码农 5 | * @since 1.0.0 2024/2/4 21:11 6 | **/ 7 | public class ValueUtils { 8 | public static String getString(String obj, Object defaultValue) { 9 | return obj == null ? defaultValue.toString() : obj; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/css/sql-keyword.css: -------------------------------------------------------------------------------- 1 | .keyword { 2 | -fx-fill: purple; 3 | -fx-font-weight: bold; 4 | } 5 | .semicolon { 6 | -fx-font-weight: bold; 7 | } 8 | .paren { 9 | -fx-fill: firebrick; 10 | -fx-font-weight: bold; 11 | } 12 | .bracket { 13 | -fx-fill: darkgreen; 14 | -fx-font-weight: bold; 15 | } 16 | .brace { 17 | -fx-fill: teal; 18 | -fx-font-weight: bold; 19 | } 20 | .string { 21 | -fx-fill: blue; 22 | } 23 | 24 | .comment { 25 | -fx-fill: cadetblue; 26 | } 27 | 28 | .paragraph-box:has-caret { 29 | -fx-background-color: #f2f9fc; 30 | } 31 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/cluster_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | 查询 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/connection_monitor_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 查询 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/db_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/monitor.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/query_monitor_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 查询 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/query_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 保存 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 美化SQL 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 49 | 50 | 51 | 执行 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 81 | 84 | 85 | 86 | 87 | 88 | 89 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/record_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/stb_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/table_query_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 查询 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 49 | 50 | 51 | 52 | 53 | 54 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/table_record_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/fxml/component/user_query_tab.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 查询 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/cluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/cluster.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/connection.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/connections.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/db.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/format.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/format.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/logo.ico -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/logo.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/monitor.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/query.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/query_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/query_monitor.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/clusterquery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/clusterquery.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/connectionquery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/connectionquery.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/createConnection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/createConnection.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/createDB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/createDB.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/createSTB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/createSTB.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/executeSQL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/executeSQL.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/exportDDL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/exportDDL.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/image.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/insertData.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/insertData.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/logo.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/queryStbRecord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/queryStbRecord.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/querymonitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/querymonitor.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/start.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/tableDataQuery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/tableDataQuery.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/tableQuery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/tableQuery.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/updateData.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/updateData.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/updateDataSelectItem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/updateDataSelectItem.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/readme/userquery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/readme/userquery.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/resourceMonitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/resourceMonitor.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/save.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/stb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/stb.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/tb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/tb.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/tdengine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/tdengine.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/images/user_query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterchenhdu/td-genie/3ecac42ffbdc3aa25d082555af669465711027b3/tdengine/src/main/resources/images/user_query.png -------------------------------------------------------------------------------- /tdengine/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | logback 4 | 5 | 6 | 7 | %d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | true 14 | 15 | 16 | /var/logs/td-genie/client-%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log 17 | 18 | 19 | 20 | 21 | %d{yyyy-MM-dd HH:mm:ss} -%msg%n 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | --------------------------------------------------------------------------------