├── README.md
├── sql2redis.iml
└── src
├── META-INF
└── MANIFEST.MF
└── sql2redis
├── Controller.java
├── Main.java
├── models
└── ImportTaskModel.java
├── sql2redis.fxml
├── sql2redis_img.jpg
├── style.css
└── tasks
└── ImportTask.java
/README.md:
--------------------------------------------------------------------------------
1 | # sql-to-redis #
2 |
3 |
4 | Very simple Java app. My first usage of JavaFx. Created for my tests and development reasons. Sql-to-redis can be used to export and transform data from SQL tables to Redis key-value.
5 |
6 | 
7 |
8 |
9 | How to run:
10 | -----------
11 |
12 | 1. (optional) Get the latest JRE from Oracle website.
13 | 2. (optional) If you are using OpenJDK (instead of OracleJDK) you probably have to install javafx packages (they are not included by default in OpenJDK), for Debian/Ubuntu this should help:
14 | ```
15 | aptitude install openjfx
16 | ```
17 | 3. Get latest sql-to-redis JAR file from [releases](https://github.com/mojeprojekty/sql-to-redis/releases)
18 | 4. Just check Java version (should be "1.8.0_112" or greater):
19 | ```
20 | user@localhost:~$ java -version
21 | ```
22 | 5. Go to downloaded JAR file and run command:
23 | ```
24 | java -jar sql-to-redis.jar
25 | ```
26 | 6. JDBC for:
27 |
28 | * MYSQL: jdbc:mysql://HOST:PORT/DBNAME
29 |
30 | * PostgreSQL: jdbc:postgresql://HOST:PORT/DBNAME
31 |
32 | DB support:
33 | -----------
34 | | SQL databases | Support |
35 | | ------------- |:-------:|
36 | | PostgreSQL | Yes |
37 | | MySQL | Yes |
38 | | Oracle | Not yet |
39 | | SQL Server | Not yet |
40 |
41 | Details:
42 | -----------
43 | * all queries run using Connection/ResultSets classes
44 | * fetchSize of Statement is hardcoded and it is set to 40,000 rows (import 7 milion rows takes few minutes, but if you have bigger tables you can decrease this value)
45 | * all connections to sql use Connection class from DriverManager
46 | * all imports are run as background task , threads
47 |
48 |
49 | How to use:
50 | -----------
51 | * prepare connection string and setup sql/redis hosts,
52 | * choose table to import,
53 | * modify (if you want) JSON schema
54 | * choose redis key name (default value is table name)
55 | * choose redis suffix (value should be unique if not then you will override previouse keys, you can choose column value - so your SQL PK can be saved, default value is autoincrement id from loop)
56 | * in JSON schema, all $$words$$ are variables, they will be replaced on the fly with row values
57 |
58 |
59 | Thanks for drivers/dbs to:
60 | -----------
61 | * Jedis (https://github.com/xetorthio/jedis),
62 | * PostgreSQL,
63 | * Redis.
64 |
--------------------------------------------------------------------------------
/sql2redis.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: sql2redis.Main
3 |
4 |
--------------------------------------------------------------------------------
/src/sql2redis/Controller.java:
--------------------------------------------------------------------------------
1 | package sql2redis;
2 |
3 | import javafx.animation.KeyFrame;
4 | import javafx.animation.Timeline;
5 | import javafx.collections.FXCollections;
6 | import javafx.collections.ObservableList;
7 | import javafx.event.ActionEvent;
8 | import javafx.event.EventHandler;
9 | import javafx.fxml.FXML;
10 | import javafx.scene.control.*;
11 | import javafx.util.Duration;
12 | import redis.clients.jedis.Jedis;
13 | import sql2redis.models.ImportTaskModel;
14 | import sql2redis.tasks.ImportTask;
15 |
16 | import java.sql.*;
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | public class Controller {
21 |
22 | @FXML
23 | public PasswordField sqlPassword;
24 |
25 | @FXML
26 | public TextField sqlConnectionString, sqlUsername, redisHostname, redisPort, redisKeyName, redisAuth;
27 |
28 | @FXML
29 | public ListView tableList;
30 |
31 | @FXML
32 | public ChoiceBox redisSuffix;
33 |
34 | @FXML
35 | public Button importSqlToRedis, connect;
36 |
37 | @FXML
38 | public ListView tokenList;
39 |
40 | @FXML
41 | public TextArea jsonSchema;
42 |
43 | @FXML
44 | public TableView backgroundThreadsTable;
45 |
46 | @FXML
47 | private TextArea log;
48 |
49 | private Connection connection = null;
50 |
51 | private String selectedTable;
52 |
53 | private int selectedTableFetchSize = 0;
54 |
55 | private Jedis jedis;
56 |
57 | private boolean isRedisConnected = false;
58 |
59 | private boolean isSqlConnected = false;
60 |
61 | public int importCounter = 0;
62 |
63 | private List backgroundThreads = new ArrayList();
64 |
65 | private List selectedTableColumns = new ArrayList<>();
66 |
67 | @FXML
68 | private void initialize() {
69 | this.log.setEditable(false);
70 | this.tokenList.setMouseTransparent(true);
71 | this.tokenList.setFocusTraversable(false);
72 |
73 | Timeline fiveSecondsWonder = new Timeline(new KeyFrame(Duration.seconds(1), new EventHandler() {
74 | @Override
75 | public void handle(ActionEvent event) {
76 | getThreadsSize();
77 | }
78 | }));
79 | fiveSecondsWonder.setCycleCount(Timeline.INDEFINITE);
80 | fiveSecondsWonder.play();
81 | }
82 |
83 | public void connect() {
84 | this.redisConnect();
85 | this.sqlConnect();
86 | if (this.isSqlConnected && this.isRedisConnected) {
87 | this.getTableList();
88 | }
89 | }
90 |
91 | private void getTableList() {
92 | try {
93 | DatabaseMetaData dmd = this.connection.getMetaData();
94 | String[] systemName = {"TABLE", "VIEW", "VIEWS"};
95 | ResultSet rs = dmd.getTables(null, null, "%", systemName);
96 | ArrayList tmpTables = new ArrayList();
97 | while (rs.next()) {
98 | tmpTables.add(rs.getString(3));
99 | }
100 | this.tableList.setItems(FXCollections.observableArrayList(tmpTables));
101 | } catch (Exception e) {
102 | this.log("error", e.getMessage());
103 | }
104 | }
105 |
106 | public void selectTableList() {
107 | if (tableList.getItems().size() == 0) {
108 | return;
109 | }
110 | String tableName = tableList.getSelectionModel().getSelectedItem().toString();
111 | this.selectedTable = tableName;
112 | this.redisKeyName.setText(tableName);
113 | this.getTableInfo(tableName);
114 | this.tokenList.setVisible(true);
115 | this.setTokenlist();
116 | this.prepareJsonSchema();
117 | this.log("info", "Rows count: " + this.selectedTableFetchSize);
118 | this.selectedTableColumns.add("Auto-increment id");
119 | this.redisSuffix.setItems(FXCollections.observableArrayList(this.selectedTableColumns));
120 | this.redisSuffix.setValue("Auto-increment id");
121 | this.importSqlToRedis.setDisable(false);
122 | }
123 |
124 | private void log(String type, String text) {
125 | this.log.appendText("[" +type.toUpperCase()+ "] "+ text +"\n");
126 | }
127 |
128 | private void getTableInfo(String tableName) {
129 | try {
130 | DatabaseMetaData dmd = this.connection.getMetaData();
131 | ResultSet resultSet = dmd.getColumns(null, null, tableName, "%");
132 | List columns = new ArrayList<>();
133 | while (resultSet.next()) {
134 | columns.add(resultSet.getString(4));
135 | }
136 | this.selectedTableColumns = columns;
137 |
138 | String sql = "SELECT count(*) as total FROM $tableName".replace("$tableName", tableName);
139 | Statement stmt = this.connection.createStatement();
140 | ResultSet resultSetCount = stmt.executeQuery(sql);
141 | while (resultSetCount.next()) {
142 | this.selectedTableFetchSize = resultSetCount.getInt("total");
143 | }
144 | } catch (SQLException e) {
145 | this.log("error", e.getMessage());
146 | }
147 | }
148 |
149 | private void sqlConnect() {
150 | try {
151 | String connectionString = this.sqlConnectionString.getText();
152 | String username = this.sqlUsername.getText();
153 | String password = this.sqlPassword.getText();
154 | this.connection = DriverManager.getConnection(connectionString, username, password);
155 | this.connect.setText("Reconnect");
156 | this.isSqlConnected = true;
157 | this.log("info", "Successfully connected to sql database");
158 | } catch (Exception e) {
159 | this.log("error", e.getMessage());
160 | }
161 | }
162 |
163 | private void redisConnect() {
164 | try {
165 | String hostname = this.redisHostname.getText();
166 | int port = Integer.parseInt(this.redisPort.getText());
167 | this.jedis = new Jedis(hostname, port);
168 | this.jedis.connect();
169 | if (this.jedis.isConnected()) {
170 | this.isRedisConnected = true;
171 | this.log("info", "Successfully connected to redis");
172 | } else {
173 | this.log("error", "The connection to the redis has failed");
174 | }
175 | } catch (Exception e) {
176 | this.log("error", e.getMessage());
177 | }
178 | }
179 |
180 | final public void getThreadsSize() {
181 | for (int i = 0, j = this.backgroundThreads.size(); i < j; i++) {
182 | Thread tmpThread = this.backgroundThreads.get(i);
183 | this.backgroundThreadsTable.getItems().forEach(item -> {
184 | if (item.getName().equals(tmpThread.getName())) {
185 | item.setStatus(tmpThread.getState().toString());
186 | }
187 | });
188 | ObservableList tableSource = this.backgroundThreadsTable.getItems();
189 | FXCollections.copy(this.backgroundThreadsTable.getItems(), tableSource);
190 | }
191 | }
192 |
193 | public void importSqlToRedis() {
194 | String sqlUrl = this.sqlConnectionString.getText();
195 | String sqlUser = this.sqlUsername.getText();
196 | String sqlPassword = this.sqlPassword.getText();
197 | String redisHost = this.redisHostname.getText();
198 | String redisPort = this.redisPort.getText();
199 | String redisAuth = this.redisAuth.getText();
200 | String tableToImport = this.selectedTable;
201 | String jsonSchema = this.jsonSchema.getText();
202 | Boolean isAutoIncrementSuffix;
203 | String redisKeyBodySchema = this.redisKeyName.getText();
204 | String redisKeySuffixSchema = this.redisSuffix.getSelectionModel().getSelectedItem().toString();
205 | if (redisKeySuffixSchema.equals("Auto-increment id")) {
206 | isAutoIncrementSuffix = true;
207 | } else {
208 | isAutoIncrementSuffix = false;
209 | }
210 |
211 | ImportTask importTask = new ImportTask(sqlUrl, sqlUser, sqlPassword, redisHost, redisPort, tableToImport, jsonSchema, isAutoIncrementSuffix, redisKeySuffixSchema, redisKeyBodySchema, redisAuth);
212 | Thread th = new Thread(importTask);
213 | th.setName("Task" + this.importCounter);
214 | this.importCounter++;
215 | this.backgroundThreads.add(th);
216 | th.setDaemon(true);
217 | th.start();
218 | this.log("info", "Started");
219 |
220 | ImportTaskModel newTask = new ImportTaskModel(th.getName(), tableToImport, ImportTaskModel.translateState(th.getState().toString()));
221 | final ObservableList row = FXCollections.observableArrayList(newTask);
222 | this.backgroundThreadsTable.getItems().addAll(row);
223 | }
224 |
225 | private void setTokenlist() {
226 | this.tokenList.setItems(FXCollections.observableArrayList(this.selectedTableColumns));
227 | }
228 |
229 | private void prepareJsonSchema() {
230 | StringBuilder jsonSchemaText = new StringBuilder();
231 | jsonSchemaText.append("{\n");
232 | for (int i = 0; i < this.selectedTableColumns.size(); i++) {
233 | String tmpName = this.selectedTableColumns.get(i);
234 | if (i == this.selectedTableColumns.size() - 1) {
235 | jsonSchemaText.append(" \""+tmpName+"\": " + "\"$$"+tmpName+"$$\"\n");
236 | } else {
237 | jsonSchemaText.append(" \""+tmpName+"\": " + "\"$$"+tmpName+"$$\",\n");
238 | }
239 | }
240 | jsonSchemaText.append("}");
241 | this.jsonSchema.setText(jsonSchemaText.toString());
242 | }
243 | }
244 |
--------------------------------------------------------------------------------
/src/sql2redis/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | SQL to Redis (sql-to-redis)
3 | Created for my tests and development reasons. Sql-to-redis can be used to export and transform data
4 | from sql database to redis. Redis keys are stored as JSON.
5 | */
6 | package sql2redis;
7 |
8 | import javafx.application.Application;
9 | import javafx.fxml.FXMLLoader;
10 | import javafx.scene.Parent;
11 | import javafx.scene.Scene;
12 | import javafx.stage.Stage;
13 |
14 | import java.sql.DriverManager;
15 |
16 | public class Main extends Application {
17 |
18 | @Override
19 | public void start(Stage primaryStage) throws Exception{
20 | Parent root = FXMLLoader.load(getClass().getResource("sql2redis.fxml"));
21 | primaryStage.setTitle("SQL2Redis - import data from SQL to Redis as JSON");
22 | primaryStage.setScene(new Scene(root, 1024, 754));
23 | primaryStage.setResizable(false);
24 | primaryStage.show();
25 | }
26 |
27 | public static void main(String[] args) {
28 | try {
29 | DriverManager.registerDriver(new com.mysql.jdbc.Driver());
30 | } catch (Exception e) {
31 |
32 | }
33 | launch(args);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/sql2redis/models/ImportTaskModel.java:
--------------------------------------------------------------------------------
1 | package sql2redis.models;
2 |
3 |
4 | public class ImportTaskModel {
5 |
6 | private String id;
7 |
8 | private String name;
9 |
10 | private String description;
11 |
12 | private String status;
13 |
14 | public ImportTaskModel(String name, String description, String status) {
15 | this.name = name;
16 | this.description = description;
17 | this.status = translateState(status);
18 | }
19 | public String getId() {
20 | return this.id;
21 | }
22 |
23 | public void setId(String id) {
24 | this.id = id;
25 | }
26 |
27 | public String getName() {
28 | return this.name;
29 | }
30 |
31 | public void setName(String name) {
32 | this.name = name;
33 | }
34 |
35 | public String getDescription() {
36 | return this.description;
37 | }
38 |
39 | public void setDescription(String description) {
40 | this.description = description;
41 | }
42 |
43 | public String getStatus() {
44 | return this.status;
45 | }
46 |
47 | public void setStatus(String status) {
48 | this.status = translateState(status);
49 | }
50 |
51 | public static String translateState(String status) {
52 | if (status.equals("TERMINATED")) {
53 | return "Done";
54 | } else if(status.equals("RUNNABLE")) {
55 | return "Running";
56 | } else if(status.equals("NEW")) {
57 | return "Waiting";
58 | } else if(status.equals("BLOCKED")) {
59 | return "Waiting";
60 | } else if(status.equals("WAITING")) {
61 | return "Waiting";
62 | } else if(status.equals("TIMED_WAITING")) {
63 | return "Waiting";
64 | } else if (status.equals("user_stop_action")) {
65 | return "Canceled";
66 | } else {
67 | return "";
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/sql2redis/sql2redis.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
27 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
48 |
52 |
53 |
57 |
58 |
63 |
64 |
69 |
74 |
79 |
84 |
89 |
94 |
99 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
141 |
146 |
147 |
152 |
153 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/src/sql2redis/sql2redis_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/michaldoda/sql-to-redis/b0dbef9f1c20efd89ad7a8586d55df6ef3f7a1c4/src/sql2redis/sql2redis_img.jpg
--------------------------------------------------------------------------------
/src/sql2redis/style.css:
--------------------------------------------------------------------------------
1 | #log {
2 | -fx-background-color: none;
3 | -fx-border-style: none;
4 | -fx-focus-color: transparent;
5 | -fx-faint-focus-color: transparent;
6 | }
7 |
8 | .list-view {
9 | -fx-font-size: 13px;
10 | }
11 |
12 |
13 | .text-area .content{
14 | -fx-background-color: #45494A;
15 | }
16 |
17 | #jsonSchema {
18 | -fx-font-size: 13px;
19 | -fx-text-fill: #e7e7e7;
20 | -fx-font-weight: bolder;
21 | -fx-background-color: #45494A;
22 | }
23 |
24 | .text-field .content {
25 | -fx-prompt-text-fill: #e2e2e2;
26 | }
27 |
28 | #log {
29 | -fx-text-fill: #a2a2a2;
30 | }
31 | #log .content {
32 | -fx-background-color: #2B2B2B;
33 | }
34 |
35 | #sqlConnectionString {
36 | -fx-text-fill: #EBEBEB;
37 | -fx-font-weight: bold;
38 | }
39 |
40 | #sqlPassword {
41 | -fx-text-fill: #EBEBEB;
42 | -fx-font-weight: bold;
43 | }
44 |
45 | #sqlUsername {
46 | -fx-text-fill: #EBEBEB;
47 | -fx-font-weight: bold;
48 | }
49 |
50 | #redisHostname {
51 | -fx-text-fill: #EBEBEB;
52 | -fx-font-weight: bold;
53 | }
54 |
55 | #redisAuth {
56 | -fx-text-fill: #EBEBEB;
57 | -fx-font-weight: bold;
58 | }
59 |
60 | #redisPort {
61 | -fx-text-fill: #EBEBEB;
62 | -fx-font-weight: bold;
63 | }
64 |
65 | #redisKeyName {
66 | -fx-text-fill: #EBEBEB;
67 | -fx-font-weight: bold;
68 | }
69 |
70 |
71 | .table-view .filler {
72 | -fx-background-color: #7733ee;
73 | }
74 |
75 | .table-view .column-header .label {
76 | -fx-text-fill: #a2a2a2;
77 | -fx-background-color: #45494A;
78 | -fx-font-weight: bold;
79 | }
80 |
81 | .list-cell:filled:selected:focused, .list-cell:filled:selected {
82 | -fx-background-color: #2F65CA;
83 | -fx-text-fill: white;
84 | }
85 |
86 | .list-cell {
87 | -fx-text-fill: #aaaaaa;
88 | -fx-background-color: #414547;
89 | }
90 |
91 | .list-cell:even {
92 | -fx-text-fill: #aaaaaa;
93 | -fx-background-color: #3C3F41;
94 | }
95 |
96 | .list-cell:filled:hover {
97 | -fx-background-color: #2F65CA;
98 | -fx-text-fill: white;
99 | }
100 |
101 | .hide-thumb .scroll-bar:vertical .thumb {
102 | -fx-background-color: transparent;
103 | }
104 |
105 | .button {
106 | -fx-text-fill: #BBBBBB;
107 | -fx-font-size: 13px;
108 | -fx-font-weight: bold;
109 | -fx-background-color: #4A4F51;
110 | -fx-border-color: #2F65CA;
111 | -fx-border-radius: 3;
112 |
113 | }
114 |
115 |
116 | .button:hover {
117 | -fx-cursor: hand;
118 | }
119 |
120 | .choice-box {
121 | -fx-focus-color: transparent;
122 | -fx-font-size: 13px;
123 | -fx-font-weight: bold;
124 | -fx-background-color: #4A4F51;
125 | -fx-border-color: #595A5A;
126 | }
127 |
128 | .choice-box > * {
129 | -fx-text-fill: #BBBBBB;
130 | }
131 |
132 |
133 | .scroll-bar{
134 | -fx-background-color: rgb(96,96,96);
135 | }
136 | .scroll-bar:horizontal .track,
137 | .scroll-bar:vertical .track {
138 | -fx-background-color: transparent;
139 | -fx-border-color:transparent;
140 | }
141 | .scroll-bar:vertical .track-background,
142 | .scroll-bar:horizontal .track-background {
143 | -fx-background-color: transparent;
144 | -fx-background-insets: 0;
145 | }
146 | .scroll-bar:horizontal .thumb {
147 | -fx-background-color: #545657;
148 | -fx-background-insets: 4 0 4 0;
149 | }
150 | .scroll-bar:vertical .thumb {
151 | -fx-background-color: #545657;
152 | -fx-background-insets: 0 4 0 4;
153 | }
154 | .scroll-bar:horizontal .thumb:hover,
155 | .scroll-bar:vertical .thumb:hover {
156 | -fx-background-color: #545657;
157 | }
158 | .scroll-bar:horizontal .thumb:pressed,
159 | .scroll-bar:vertical .thumb:pressed {
160 | -fx-background-color: #545657;
161 | }
162 | .scroll-bar:vertical .increment-button, .scroll-bar:vertical .decrement-button {
163 | -fx-background-color:transparent;
164 | -fx-padding: 1;
165 | }
166 | .scroll-bar:horizontal .increment-button, .scroll-bar:horizontal .decrement-button {
167 | -fx-background-color:transparent;
168 | -fx-padding: 1;
169 | }
170 | .scroll-bar:horizontal .increment-arrow {
171 | -fx-shape: "M 0 0 L 4 8 L 8 0 Z";
172 | -fx-background-color: #545657;
173 |
174 | }
175 | .scroll-bar:vertical .increment-arrow {
176 | -fx-background-color: #545657;
177 | -fx-shape: "M 0 0 L 4 8 L 8 0 Z";
178 |
179 | }
180 | .scroll-bar:horizontal .decrement-arrow {
181 | -fx-background-color: #545657;
182 |
183 | }
184 | .scroll-bar:vertical .decrement-arrow {
185 | -fx-background-color: #545657;
186 |
187 | }
188 | .scroll-bar:vertical:focused,
189 | .scroll-bar:horizontal:focused {
190 | -fx-background-color: transparent,rgb(96,96,96),rgb(96,96,96);
191 | }
192 |
193 |
194 | .table-view {
195 | -fx-background-color: #3C3F41;
196 | -fx-text-fill: #e7e7e7 ;
197 | }
198 | .table-cell {
199 | -fx-text-fill: #e7e7e7 ;
200 | }
201 |
202 | .table-view:focused .table-row-cell:filled:focused:selected {
203 | -fx-background-color: #414547;
204 | -fx-background-insets: 0, 1, 2;
205 | -fx-background: -fx-accent;
206 | -fx-text-fill: -fx-selection-bar-text;
207 | }
208 |
209 | /* Selected row when table not focused */
210 | .table-row-cell:filled:focused:selected {
211 | -fx-background-color: #414547;
212 | -fx-background-insets: 0, 1, 2;
213 | -fx-background: -fx-accent;
214 | -fx-text-fill: -fx-selection-bar-text;
215 | }
216 |
217 | .table-view:row-selection .table-row-cell:filled:hover {
218 | -fx-background-color: #414547;
219 | -fx-background-insets: 0, 0 0 1 0;
220 | -fx-text-fill: -fx-text-inner-color;
221 | }
222 |
223 | .table-view:focused .table-row-cell:filled:focused:selected:hover {
224 | -fx-background: -fx-accent;
225 | -fx-background-color: #414547;
226 | -fx-background-insets: 0, 1, 2;
227 | -fx-text-fill: -fx-selection-bar-text;
228 | }
229 |
230 | .table-view:row-selection .table-row-cell:filled:focused:hover {
231 | -fx-background-color: #414547;
232 | -fx-background-insets: 0, 0 0 1 0, 1 1 2 1, 2 2 3 2, 3 3 4 3;
233 | -fx-text-fill: -fx-text-inner-color;
234 | }
235 |
236 | .table-row-cell {
237 | -fx-background-color: #2B2B2B;
238 | }
239 | .table-row-cell:selected {
240 | -fx-background-color: #414547;
241 | }
242 | .table-row-cell:even .table-cell {
243 | -fx-fill: #414547;
244 | -fx-background-color: #3b3b3b;
245 | -fx-text-fill: #BBBBBB ;
246 | }
--------------------------------------------------------------------------------
/src/sql2redis/tasks/ImportTask.java:
--------------------------------------------------------------------------------
1 | package sql2redis.tasks;
2 |
3 |
4 | import javafx.concurrent.Task;
5 | import redis.clients.jedis.Jedis;
6 |
7 | import java.sql.*;
8 |
9 | public class ImportTask extends Task {
10 | private final String sqlUrl, sqlUser, sqlPassword, redisHost, redisPort, redisKeySuffixSchema, redisKeyBodySchema, tableToImport, jsonSchema, redisAuth;
11 | private final Boolean isAutoIncrementSuffix;
12 |
13 |
14 |
15 | public ImportTask(String sqlUrl, String sqlUser, String sqlPassword, String redisHost, String redisPort, String tableToImport, String jsonSchema, Boolean isAutoIncrementSuffix, String redisKeySuffixSchema, String redisKeyBodySchema, String redisAuth) {
16 | this.sqlUrl = sqlUrl;
17 | this.sqlUser = sqlUser;
18 | this.sqlPassword = sqlPassword;
19 | this.redisHost = redisHost;
20 | this.redisPort = redisPort;
21 | this.redisAuth = redisAuth;
22 | this.jsonSchema = jsonSchema;
23 | this.tableToImport = tableToImport;
24 | this.isAutoIncrementSuffix = isAutoIncrementSuffix;
25 | this.redisKeySuffixSchema = redisKeySuffixSchema;
26 | this.redisKeyBodySchema = redisKeyBodySchema;
27 | System.out.println("Task, constructor");
28 | }
29 |
30 | @Override protected Integer call() throws Exception {
31 | int counter = 0;
32 | try {
33 | System.out.println("Task, call method");
34 | Connection connection = DriverManager.getConnection(this.sqlUrl, this.sqlUser, this.sqlPassword);
35 | Jedis jedis = new Jedis(this.redisHost, Integer.parseInt(this.redisPort));
36 | if (!this.redisAuth.equals("")) {
37 | jedis.auth(this.redisAuth);
38 | }
39 | String sql = "SELECT * FROM $tableName".replace("$tableName", this.tableToImport);
40 | Statement stmt = connection.createStatement();
41 | connection.setAutoCommit(false);
42 | stmt.setFetchSize(40000);
43 | ResultSet rs = stmt.executeQuery(sql);
44 |
45 | ResultSetMetaData rsmd = rs.getMetaData();
46 | int columnCount = rsmd.getColumnCount();
47 |
48 | while (rs.next()) {
49 | String jsonRow = jsonSchema;
50 | counter++;
51 | for (int i = 1; i <= columnCount; i++ ) {
52 | String name = rsmd.getColumnName(i);
53 | if (rs.getString(name) == null) {
54 | jsonRow = jsonRow.replace("$$"+name+"$$", "");
55 | } else {
56 | jsonRow = jsonRow.replace("$$"+name+"$$", rs.getString(name).replace("\"", "'"));
57 | }
58 | }
59 | String out = jsonRow.replaceAll("\\s+","").replace("\n", "").replace("\r", "").replace("\\/", "/").trim();
60 | out = out.replaceAll("\\\\/", "/").replace("\\", "").replaceAll ("\\\\", "").replace('\\','/');
61 | if (this.isAutoIncrementSuffix) {
62 | jedis.set(this.redisKeyBodySchema+"_"+counter, out);
63 | } else {
64 | jedis.set(this.redisKeyBodySchema+"_"+rs.getString(this.redisKeySuffixSchema), out);
65 | }
66 |
67 | }
68 | connection.close();
69 | jedis.close();
70 | } catch (Exception e) {
71 | System.out.println(e.getMessage());
72 | }
73 | return counter;
74 | }
75 | }
--------------------------------------------------------------------------------