Browse Source

支持多条SQL配置

AE86 2 years ago
parent
commit
9191419ebc

+ 12 - 9
dbsyncer-biz/src/main/java/org/dbsyncer/biz/checker/impl/connector/AbstractDataBaseConfigChecker.java

@@ -1,11 +1,12 @@
 package org.dbsyncer.biz.checker.impl.connector;
 
 import org.dbsyncer.biz.checker.ConnectorConfigChecker;
+import org.dbsyncer.common.util.CollectionUtils;
+import org.dbsyncer.common.util.JsonUtil;
 import org.dbsyncer.connector.config.DatabaseConfig;
 import org.dbsyncer.connector.model.SqlTable;
 import org.springframework.util.Assert;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -33,14 +34,16 @@ public abstract class AbstractDataBaseConfigChecker implements ConnectorConfigCh
     }
 
     protected void modifyDql(DatabaseConfig connectorConfig, Map<String, String> params) {
-        String sql = params.get("sql");
-        String table = params.get("table");
-        Assert.hasText(sql, "Sql is empty.");
-        Assert.hasText(table, "Table is empty.");
-
-        List<SqlTable> list = new ArrayList<>();
-        list.add(new SqlTable(sql, table));
-        connectorConfig.setSqlTables(list);
+        String sqlTableParams = params.get("sqlTableParams");
+        Assert.hasText(sqlTableParams, "sqlTableParams is empty.");
+        List<SqlTable> sqlTables = JsonUtil.jsonToArray(sqlTableParams, SqlTable.class);
+        Assert.isTrue(!CollectionUtils.isEmpty(sqlTables), "sqlTables is empty.");
+        sqlTables.forEach(sqlTable -> {
+            Assert.hasText(sqlTable.getSqlName(), "SqlName is empty.");
+            Assert.hasText(sqlTable.getSql(), "Sql is empty.");
+            Assert.hasText(sqlTable.getTable(), "Table is empty.");
+        });
+        connectorConfig.setSqlTables(sqlTables);
     }
 
     protected void modifySchema(DatabaseConfig connectorConfig, Map<String, String> params) {

+ 12 - 1
dbsyncer-connector/src/main/java/org/dbsyncer/connector/model/SqlTable.java

@@ -2,6 +2,8 @@ package org.dbsyncer.connector.model;
 
 public class SqlTable {
 
+    private String sqlName;
+
     private String sql;
 
     private String table;
@@ -9,11 +11,20 @@ public class SqlTable {
     public SqlTable() {
     }
 
-    public SqlTable(String sql, String table) {
+    public SqlTable(String sqlName, String sql, String table) {
+        this.sqlName = sqlName;
         this.sql = sql;
         this.table = table;
     }
 
+    public String getSqlName() {
+        return sqlName;
+    }
+
+    public void setSqlName(String sqlName) {
+        this.sqlName = sqlName;
+    }
+
     public String getSql() {
         return sql;
     }

+ 0 - 1
dbsyncer-web/src/main/resources/public/connector/addDqlMysql.html

@@ -34,7 +34,6 @@
             $("#sql").val("SELECT T1.* FROM USER T1");
         })
     </script>
-    <script th:src="@{/js/connector/editSQL.js}"></script>
 </div>
 
 </html>

+ 0 - 1
dbsyncer-web/src/main/resources/public/connector/addDqlOracle.html

@@ -45,7 +45,6 @@
             $("#sql").val("SELECT T1.*,ROWIDTOCHAR(ROWID) as RID FROM \"USER\" T1");
         })
     </script>
-    <script th:src="@{/js/connector/editSQL.js}"></script>
 </div>
 
 </html>

+ 0 - 1
dbsyncer-web/src/main/resources/public/connector/addDqlPostgreSQL.html

@@ -72,7 +72,6 @@
             $("#sql").val("SELECT T1.* FROM \"USER\" T1");
         })
     </script>
-    <script th:src="@{/js/connector/editSQL.js}"></script>
 </div>
 
 </html>

+ 0 - 1
dbsyncer-web/src/main/resources/public/connector/addDqlSqlServer.html

@@ -45,7 +45,6 @@
             $("#sql").val("SELECT T1.* FROM USER T1");
         })
     </script>
-    <script th:src="@{/js/connector/editSQL.js}"></script>
 </div>
 
 </html>

+ 210 - 3
dbsyncer-web/src/main/resources/public/connector/addSQL.html

@@ -11,13 +11,15 @@
         <label class="col-sm-2 control-label">SQL表</label>
         <div class="col-sm-4">
             <select id="sqlTableSelect" class="form-control select-control">
-                <option th:each="sqlTable,state:${connector?.config?.sqlTables}" th:value="${sqlTable?.sql}" th:text="${sqlTable?.table}" />
+                <option th:each="sqlTable,state:${connector?.config?.sqlTables}" th:text="${sqlTable?.sqlName}" />
             </select>
         </div>
         <div class="col-sm-6 text-right">
-            <button id="addSqlTableBtn" type="button" class="btn btn-default"> <span class="fa fa-plus"></span>添加([[${sqlTableList?.size()} ?: 0]])</button>
+            <button id="delSqlTableBtn" type="button" class="btn btn-default hidden"> <span class="fa fa-remove"></span>删除</button>
+            <button id="editSqlTableBtn" type="button" class="btn btn-default hidden"> <span class="fa fa-pencil"></span>修改</button>
+            <button id="addSqlTableBtn" type="button" class="btn btn-primary"> <span class="fa fa-plus"></span>添加(<span id="sqlTableCount">[[${connector?.config?.sqlTables?.size()} ?: 0]]</span>)</button>
         </div>
-        <input type="hidden" id="sqlTableSelectParams" name="sqlTableSelect"/>
+        <input type="hidden" id="sqlTableParams" name="sqlTableParams"/>
     </div>
 
     <div class="form-group">
@@ -42,5 +44,210 @@
         </div>
     </div>
 
+<script type="text/javascript" th:inline="javascript">
+    $(function () {
+        let sqlTables = [[${connector?.config?.sqlTables}]];
+        // SQL配置模板
+        let $template = {
+            selector: initSelectIndex($("#sqlTableSelect"), 1),
+            addSqlTableBtn: $("#addSqlTableBtn"),
+            editSqlTableBtn: $("#editSqlTableBtn"),
+            delSqlTableBtn: $("#delSqlTableBtn"),
+            sqlTableCount: $("#sqlTableCount"),
+            sqlTableParams: $("#sqlTableParams"),
+            sqlTableArray: sqlTables == null ? [] : sqlTables,
+            sqlNameInput: $("#sqlName"),
+            tableInput: $("#table"),
+            sqlInput: $("#sql"),
+            // 禁用按钮
+            before: function ($btn) {
+                $btn.prop('disabled', true);
+            },
+            // 校验表单
+            validate: function (callback) {
+                let itemSqlName = this.validateItem(this.sqlNameInput, "SQL名称不能空.");
+                if (!itemSqlName) {
+                    return;
+                }
+                let itemTable = this.validateItem(this.tableInput, "主表不能空.");
+                if (!itemTable) {
+                    return;
+                }
+                let itemSql = this.validateItem(this.sqlInput, "SQL不能空.");
+                if (!itemSql) {
+                    return;
+                }
+                callback();
+            },
+            // 校验参数
+            validateItem: function ($input, $msg) {
+                if (isBlank($input.val())) {
+                    bootGrowl($msg, "danger");
+                    return false;
+                }
+                return true;
+            },
+            // 加入新项到下拉
+            addOption: function () {
+                let sqlName = this.sqlNameInput.val();
+                this.sqlTableArray.push({"sqlName": sqlName, "table": this.tableInput.val(), "sql": this.sqlInput.val()});
+                this.selector.append('<option>' + sqlName + '</option>');
+                this.selector.selectpicker('refresh');
+                this.selector.selectpicker('val', sqlName);
+                this.stash();
+            },
+            // 删除下拉选中项
+            removeOption: function () {
+                this.sqlTableArray = removeSqlTableBySqlName(this.sqlTableArray, this.selectedVal());
+                this.selector.find('option:selected').remove();
+                this.selector.selectpicker('refresh');
+                this.stash();
+            },
+            // 暂存配置
+            stash: function () {
+                this.sqlTableParams.val(JSON.stringify(this.sqlTableArray));
+            },
+            // 清空表单
+            clear: function () {
+                this.sqlNameInput.val('');
+                this.tableInput.val('');
+                this.sqlInput.val('');
+            },
+            // 显示默认配置
+            popStash: function(){
+                if (this.hasOption()) {
+                    this.selector.selectpicker('val', this.sqlTableArray[0].sqlName);
+                }
+            },
+            // 回显下拉选中配置
+            apply: function () {
+                let sqlTable = findSqlTableBySqlName(this.sqlTableArray, this.selectedVal());
+                if (sqlTable != null) {
+                    this.sqlNameInput.val(sqlTable.sqlName);
+                    this.tableInput.val(sqlTable.table);
+                    this.sqlInput.val(sqlTable.sql);
+                }
+                this.reset();
+            },
+            // 显示操作菜单
+            showMenu: function () {
+                if (this.hasOption()) {
+                    this.editSqlTableBtn.removeClass("hidden");
+                    this.delSqlTableBtn.removeClass("hidden");
+                } else {
+                    this.editSqlTableBtn.addClass("hidden");
+                    this.delSqlTableBtn.addClass("hidden");
+                }
+            },
+            // 更新添加按钮数量显示
+            refreshCount: function () {
+                this.sqlTableCount.text(this.sqlTableArray.length);
+            },
+            // 是否有配置
+            hasOption: function () {
+                return this.sqlTableArray.length > 0;
+            },
+            // 下拉选择值
+            selectedVal: function () {
+                return this.selector.selectpicker('val');
+            },
+            // 清空美化记录
+            reset: function () {
+                this.sqlInput.removeAttr('tmp');
+            },
+            // 恢复按钮
+            after: function ($btn) {
+                $btn.removeAttr('disabled');
+            }
+        }
+
+        $template.showMenu();
+        $template.selector.on('changed.bs.select', function () {
+            $template.apply();
+        });
+        $template.stash();
+        $template.popStash();
+        bindSqlTableAddEvent($template);
+        bindSqlTableEditEvent($template);
+        bindSqlTableDelEvent($template);
+    })
+
+    function findSqlTableBySqlName(sqlTableArray, sqlName) {
+        if (!isBlank(sqlName)) {
+            let tLen = sqlTableArray.length;
+            for (let j = 0; j < tLen; j++) {
+                if (sqlTableArray[j].sqlName == sqlName) {
+                    return sqlTableArray[j];
+                }
+            }
+        }
+        return null;
+    }
+    function removeSqlTableBySqlName(sqlTableArray, sqlName) {
+        let newArray = [];
+        if (!isBlank(sqlName)) {
+            let tLen = sqlTableArray.length;
+            for (let j = 0; j < tLen; j++) {
+                if (sqlTableArray[j].sqlName != sqlName) {
+                    newArray.push(sqlTableArray[j]);
+                }
+            }
+        }
+        return newArray;
+    }
+    function bindSqlTableAddEvent($template) {
+        $template.addSqlTableBtn.click(function () {
+            $template.before($(this));
+            $template.validate(function () {
+                // 重复校验
+                let newSqlName = $template.sqlNameInput.val();
+                let sqlTable = findSqlTableBySqlName($template.sqlTableArray, newSqlName);
+                if (sqlTable != null) {
+                    bootGrowl(newSqlName + " 已存在.", "danger");
+                } else {
+                    $template.addOption();
+                    $template.refreshCount();
+                    $template.showMenu();
+                }
+            });
+            $template.reset();
+            $template.after($(this));
+        });
+    }
+    function bindSqlTableEditEvent($template) {
+        $template.editSqlTableBtn.click(function () {
+            $template.before($(this));
+            $template.validate(function () {
+                let oldSqlName = $template.selectedVal();
+                if (!isBlank(oldSqlName)) {
+                    let newSqlName = $template.sqlNameInput.val();
+                    // 重命名的SQL名称已存在
+                    if (oldSqlName != newSqlName && findSqlTableBySqlName($template.sqlTableArray, newSqlName) != null) {
+                        bootGrowl(newSqlName + " 已存在.", "danger");
+                        return;
+                    }
+                    $template.removeOption();
+                    $template.addOption();
+                } else {
+                    bootGrowl("修改无效.", "danger");
+                }
+            });
+            $template.reset();
+            $template.after($(this));
+        });
+    }
+    function bindSqlTableDelEvent($template) {
+        $template.delSqlTableBtn.click(function () {
+            $template.before($(this));
+            $template.removeOption();
+            $template.refreshCount();
+            $template.clear();
+            $template.showMenu();
+            $template.popStash();
+            $template.reset();
+            $template.after($(this));
+        });
+    }
+</script>
 </div>
 </html>

+ 4 - 3
dbsyncer-web/src/main/resources/static/js/common.js

@@ -51,10 +51,10 @@ function beautifySql(){
 
 // 初始化select组件,默认选中
 function initSelectIndex($select, $selectedIndex){
-    initSelect($select);
+    let select = initSelect($select);
 
     if($selectedIndex < 0){
-        return;
+        return select;
     }
 
     $.each($select, function () {
@@ -66,9 +66,10 @@ function initSelectIndex($select, $selectedIndex){
             }
         }
     });
+    return select;
 }
 function initSelect($select){
-    $select.selectpicker({
+    return $select.selectpicker({
         "style":'dbsyncer_btn-info',
         "title":"请选择",
         "actionsBox":true,

+ 0 - 45
dbsyncer-web/src/main/resources/static/js/connector/editSQL.js

@@ -1,45 +0,0 @@
-$(function () {
-    // 添加SQL配置项
-    let $addSqlTableBtn = $("#addSqlTableBtn");
-    $addSqlTableBtn.click(function () {
-        $addSqlTableBtn.prop('disabled', true);
-        let $sqlTableSelectParams = $("#sqlTableSelectParams");
-        let json = $sqlTableSelectParams.val();
-        let jsonArray = [];
-        if(!isBlank(json)){
-            jsonArray = JSON.parse(json);
-        }
-
-        // 校验参数
-        let $sqlName = $("#sqlName");
-        if(isBlank($sqlName.val())){
-            bootGrowl("SQL名称不能空.", "danger");
-            $addSqlTableBtn.removeAttr('disabled');
-            return;
-        }
-        let $table = $("#table");
-        if(isBlank($table.val())){
-            bootGrowl("主表不能空.", "danger");
-            $addSqlTableBtn.removeAttr('disabled');
-            return;
-        }
-        let $sql = $("#sql");
-        if(isBlank($sql.val())){
-            bootGrowl("SQL不能空.", "danger");
-            $addSqlTableBtn.removeAttr('disabled');
-            return;
-        }
-        // 重复校验
-
-        // 暂存配置
-        jsonArray.push({"sqlName": $sqlName.val(), "table": $table.val(), "sql": $sql.val()});
-        $sqlTableSelectParams.val(JSON.stringify(jsonArray));
-
-        $sqlName.val("");
-        $table.val("");
-        $sql.val("");
-        $addSqlTableBtn.removeAttr('disabled');
-    });
-
-
-})