Browse Source

新增动态数据源

zhouhao 8 năm trước cách đây
mục cha
commit
d778b92d4a

+ 28 - 9
hsweb-web-controller/src/main/java/org/hsweb/web/controller/system/DatabaseManagerController.java

@@ -9,6 +9,7 @@ import org.hsweb.ezorm.render.SqlAppender;
 import org.hsweb.ezorm.render.SqlRender;
 import org.hsweb.web.bean.po.user.User;
 import org.hsweb.web.core.authorize.annotation.Authorize;
+import org.hsweb.web.core.datasource.DynamicDataSource;
 import org.hsweb.web.core.exception.AuthorizeException;
 import org.hsweb.web.core.exception.AuthorizeForbiddenException;
 import org.hsweb.web.core.logger.annotation.AccessLogger;
@@ -61,15 +62,19 @@ public class DatabaseManagerController {
         return ResponseMessage.ok(dataBaseManagerService.createCreateSql(createTableMetaDataByJson(jsonObject)));
     }
 
-
     @RequestMapping(value = "/tables/{dataSourceId}", method = RequestMethod.GET)
     @Authorize(action = "R")
     @AccessLogger("指定数据源获取表结构")
     public ResponseMessage showTables(@PathVariable("dataSourceId") String dataSourceId) throws SQLException {
-        return ResponseMessage.ok(dataBaseManagerService.getTableList(dataSourceId))
-                .include(TableMetaData.class, "name", "alias", "comment", "fields")
-                .include(FieldMetaData.class, "name", "alias", "comment", "dataType", "properties")
-                .onlyData();
+        try {
+            DynamicDataSource.use(dataSourceId);
+            return ResponseMessage.ok(dataBaseManagerService.getTableList())
+                    .include(TableMetaData.class, "name", "alias", "comment", "fields")
+                    .include(FieldMetaData.class, "name", "alias", "comment", "dataType", "properties")
+                    .onlyData();
+        } finally {
+            DynamicDataSource.useDefault(false);
+        }
     }
 
     public List<String> buildSqlList(String sql) {
@@ -104,20 +109,34 @@ public class DatabaseManagerController {
     @RequestMapping(value = "/exec/{dataSourceId}", method = RequestMethod.POST)
     @AccessLogger("指定数据源执行SQL")
     public ResponseMessage exec(@PathVariable("dataSourceId") String dataSourceId, @RequestBody String sql) throws Exception {
-
-        return ResponseMessage.ok(dataBaseManagerService.execSql(dataSourceId, buildSqlList(sql)));
+        DynamicDataSource.use(dataSourceId);
+        try {
+            return ResponseMessage.ok(dataBaseManagerService.execSql(buildSqlList(sql)));
+        } finally {
+            DynamicDataSource.useDefault(false);
+        }
     }
 
     @RequestMapping(value = "/sql/alter/{dataSourceId}", method = RequestMethod.POST)
     @AccessLogger("指定数据源查询修改表结构SQL")
     public ResponseMessage showAlterSql(@PathVariable("dataSourceId") String dataSourceId, @RequestBody JSONObject jsonObject) throws Exception {
-        return ResponseMessage.ok(dataBaseManagerService.createAlterSql(dataSourceId, createTableMetaDataByJson(jsonObject)));
+        try {
+            DynamicDataSource.use(dataSourceId);
+            return ResponseMessage.ok(dataBaseManagerService.createAlterSql(createTableMetaDataByJson(jsonObject)));
+        } finally {
+            DynamicDataSource.useDefault(false);
+        }
     }
 
     @RequestMapping(value = "/sql/create/{dataSourceId}", method = RequestMethod.POST)
     @AccessLogger("指定数据源查询创建表结构SQL")
     public ResponseMessage showCreateSql(@PathVariable("dataSourceId") String dataSourceId, @RequestBody JSONObject jsonObject) throws Exception {
-        return ResponseMessage.ok(dataBaseManagerService.createCreateSql(dataSourceId, createTableMetaDataByJson(jsonObject)));
+        try {
+            DynamicDataSource.use(dataSourceId);
+            return ResponseMessage.ok(dataBaseManagerService.createCreateSql(createTableMetaDataByJson(jsonObject)));
+        } finally {
+            DynamicDataSource.useDefault(false);
+        }
     }
 
     protected TableMetaData createTableMetaDataByJson(JSONObject jsonObject) {

+ 54 - 0
hsweb-web-core/src/main/java/org/hsweb/web/core/datasource/DynamicDataSource.java

@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.core.datasource;
+
+import org.hsweb.web.core.utils.ThreadLocalUtils;
+
+import javax.sql.DataSource;
+
+/**
+ * @author zhouhao
+ */
+public interface DynamicDataSource extends DataSource {
+    String DATA_SOURCE_FLAG = "data-source-id";
+
+    String DATA_SOURCE_FLAG_LAST = "data-source-id-last";
+
+    static void useLast() {
+        use(ThreadLocalUtils.get(DATA_SOURCE_FLAG_LAST));
+    }
+
+    static void use(String dataSourceId) {
+        ThreadLocalUtils.put(DATA_SOURCE_FLAG, dataSourceId);
+    }
+
+    static String getActiveDataSourceId() {
+        return ThreadLocalUtils.get(DATA_SOURCE_FLAG);
+    }
+
+    static void useDefault(boolean rememberLast) {
+        if (getActiveDataSourceId() != null && rememberLast)
+            ThreadLocalUtils.put(DATA_SOURCE_FLAG_LAST, getActiveDataSourceId());
+        ThreadLocalUtils.remove(DATA_SOURCE_FLAG);
+    }
+
+    static void useDefault() {
+        useDefault(true);
+    }
+
+    DataSource getActiveDataSource();
+}

+ 5 - 0
hsweb-web-dao-impl-mybatis/pom.xml

@@ -22,6 +22,11 @@
             <artifactId>hsweb-web-dao-interface</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.hsweb</groupId>
+            <artifactId>hsweb-web-core</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-jdbc</artifactId>

+ 53 - 0
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/DynamicDataSourceAutoConfiguration.java

@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl;
+
+import org.hsweb.web.service.impl.datasource.DynamicDataSourceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by zhouhao on 16-4-20.
+ */
+@Configuration
+public class DynamicDataSourceAutoConfiguration {
+
+    @Autowired
+    private DataSourceProperties properties;
+
+    @Bean
+    @ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
+    public DataSource dataSource() {
+        DataSourceBuilder factory = DataSourceBuilder
+                .create(this.properties.getClassLoader())
+                .driverClassName(this.properties.getDriverClassName())
+                .url(this.properties.getUrl()).username(this.properties.getUsername())
+                .password(this.properties.getPassword());
+        if (this.properties.getType() != null) {
+            factory.type(this.properties.getType());
+        }
+
+        return new DynamicDataSourceImpl(factory.build());
+    }
+}

+ 8 - 9
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DataSourceServiceImpl.java

@@ -25,19 +25,17 @@ import org.hsweb.web.bean.po.datasource.DataSource;
 import org.hsweb.web.core.exception.BusinessException;
 import org.hsweb.web.dao.datasource.DataSourceMapper;
 import org.hsweb.web.service.config.ConfigService;
-import org.hsweb.web.service.impl.AbstractServiceImpl;
 import org.hsweb.web.service.datasource.DataSourceService;
+import org.hsweb.web.service.impl.AbstractServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
 import org.springframework.jdbc.datasource.DataSourceUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.sql.Connection;
@@ -54,15 +52,15 @@ public class DataSourceServiceImpl extends AbstractServiceImpl<DataSource, Strin
 
     private static final String CACHE_NAME = "datasource";
 
+    @Autowired
+    protected DataSourceProperties properties;
+
     @Resource
     protected DataSourceMapper dataSourceMapper;
 
     @Resource
     protected ConfigService configService;
 
-    @Autowired
-    protected javax.sql.DataSource defaultDataSource;
-
     @Override
     protected DataSourceMapper getMapper() {
         return this.dataSourceMapper;
@@ -76,12 +74,13 @@ public class DataSourceServiceImpl extends AbstractServiceImpl<DataSource, Strin
                 .url(dataSource.getUrl())
                 .username(dataSource.getUsername())
                 .password(dataSource.getPassword())
-                .type(defaultDataSource.getClass());
+                .type(properties.getType());
         return builder.build();
     }
 
     @Override
     @Cacheable(value = CACHE_NAME, key = "'id:'+#id")
+    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
     public DataSource selectByPk(String id) {
         return super.selectByPk(id);
     }

+ 61 - 0
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DynamicDataSourceImpl.java

@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.datasource;
+
+import org.hsweb.web.core.datasource.DynamicDataSource;
+import org.hsweb.web.service.datasource.DynamicDataSourceService;
+import org.springframework.jdbc.datasource.AbstractDataSource;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class DynamicDataSourceImpl extends AbstractDataSource implements DynamicDataSource {
+    private javax.sql.DataSource defaultDataSource;
+
+    private DynamicDataSourceService dynamicDataSourceService;
+
+    public DynamicDataSourceImpl(javax.sql.DataSource defaultDataSource) {
+        this.defaultDataSource = defaultDataSource;
+    }
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        return getActiveDataSource().getConnection();
+    }
+
+    @Override
+    public Connection getConnection(String username, String password) throws SQLException {
+        return getActiveDataSource().getConnection(username, password);
+    }
+
+    public DataSource getActiveDataSource() {
+        String sourceId = DynamicDataSource.getActiveDataSourceId();
+        if (sourceId == null || dynamicDataSourceService == null) return defaultDataSource;
+        DataSource dataSource = dynamicDataSourceService.getDataSource(sourceId);
+        if (dataSource == null) return defaultDataSource;
+        return dataSource;
+    }
+
+    public void setDefaultDataSource(DataSource defaultDataSource) {
+        this.defaultDataSource = defaultDataSource;
+    }
+
+    public void setDynamicDataSourceService(DynamicDataSourceService dynamicDataSourceService) {
+        this.dynamicDataSourceService = dynamicDataSourceService;
+    }
+}

+ 34 - 19
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DynamicDataSourceServiceImpl.java

@@ -19,6 +19,7 @@ package org.hsweb.web.service.impl.datasource;
 import org.hsweb.concurrent.lock.LockFactory;
 import org.hsweb.ezorm.executor.SqlExecutor;
 import org.hsweb.web.bean.po.datasource.DataSource;
+import org.hsweb.web.core.datasource.DynamicDataSource;
 import org.hsweb.web.core.exception.NotFoundException;
 import org.hsweb.web.service.datasource.DataSourceService;
 import org.hsweb.web.service.datasource.DynamicDataSourceService;
@@ -26,6 +27,7 @@ import org.hsweb.web.service.impl.basic.SqlExecutorService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -37,6 +39,9 @@ public class DynamicDataSourceServiceImpl implements DynamicDataSourceService {
     @Resource
     private DataSourceService dataSourceService;
 
+    @Autowired
+    private DynamicDataSource dynamicDataSource;
+
     @Autowired
     private LockFactory lockFactory;
 
@@ -53,31 +58,41 @@ public class DynamicDataSourceServiceImpl implements DynamicDataSourceService {
     }
 
     protected CacheInfo getCache(String id) {
-        DataSource old = dataSourceService.selectByPk(id);
-        if (old == null || old.getEnabled() != 1) throw new NotFoundException("数据源不存在或已禁用");
-        //创建锁
-        ReadWriteLock readWriteLock = lockFactory.createReadWriteLock("datasource.lock." + id);
-        readWriteLock.readLock().tryLock();
+        DynamicDataSource.useDefault();
         try {
-            CacheInfo cacheInfo = cache.get(id);
-            // 缓存存在,并且hash一致
-            if (cacheInfo != null && cacheInfo.getHash() == old.getHash())
+            DataSource old = dataSourceService.selectByPk(id);
+            if (old == null || old.getEnabled() != 1) throw new NotFoundException("数据源不存在或已禁用");
+            //创建锁
+            ReadWriteLock readWriteLock = lockFactory.createReadWriteLock("datasource.lock." + id);
+            readWriteLock.readLock().tryLock();
+            try {
+                CacheInfo cacheInfo = cache.get(id);
+                // 缓存存在,并且hash一致
+                if (cacheInfo != null && cacheInfo.getHash() == old.getHash())
+                    return cacheInfo;
+            } finally {
+                readWriteLock.readLock().unlock();
+            }
+            //加载datasource到缓存
+            readWriteLock.writeLock().tryLock();
+            try {
+                javax.sql.DataSource dataSource = dataSourceService.createDataSource(id);
+                CacheInfo cacheInfo = new CacheInfo(old.getHash(), dataSource);
+                cache.put(id, cacheInfo);
                 return cacheInfo;
+            } finally {
+                readWriteLock.writeLock().unlock();
+            }
         } finally {
-            readWriteLock.readLock().unlock();
-        }
-        //加载datasource到缓存
-        readWriteLock.writeLock().tryLock();
-        try {
-            javax.sql.DataSource dataSource = dataSourceService.createDataSource(id);
-            CacheInfo cacheInfo = new CacheInfo(old.getHash(), dataSource);
-            cache.put(id, cacheInfo);
-            return cacheInfo;
-        } finally {
-            readWriteLock.writeLock().unlock();
+            DynamicDataSource.useLast();
         }
     }
 
+    @PostConstruct
+    public void init() {
+        ((DynamicDataSourceImpl) dynamicDataSource).setDynamicDataSourceService(this);
+    }
+
     class CacheInfo {
         int hash;
 

+ 19 - 50
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/system/DataBaseManagerServiceImpl.java

@@ -15,22 +15,18 @@ import org.hsweb.ezorm.render.dialect.H2DatabaseMeta;
 import org.hsweb.ezorm.render.dialect.MysqlDatabaseMeta;
 import org.hsweb.ezorm.render.dialect.OracleDatabaseMeta;
 import org.hsweb.ezorm.render.support.simple.SimpleSQL;
-import org.hsweb.ezorm.run.simple.SimpleDatabase;
-import org.hsweb.web.core.Install;
+import org.hsweb.web.core.datasource.DynamicDataSource;
 import org.hsweb.web.core.exception.BusinessException;
 import org.hsweb.web.core.exception.NotFoundException;
 import org.hsweb.web.service.datasource.DataSourceService;
-import org.hsweb.web.service.datasource.DynamicDataSourceService;
 import org.hsweb.web.service.impl.DatabaseMetaDataFactoryBean;
 import org.hsweb.web.service.system.DataBaseManagerService;
-import org.hsweb.web.service.system.SqlExecuteProcess;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import javax.sql.DataSource;
 import java.sql.SQLException;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
@@ -51,24 +47,16 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
     @Resource
     private SqlExecutor sqlExecutor;
 
-    @Autowired(required = false)
-    private TableMetaParser tableMetaParser;
-
-    @Autowired
-    private DatabaseMetaDataFactoryBean databaseMetaDataFactoryBean;
-
-    @Resource
-    private DynamicDataSourceService dynamicDataSourceService;
-
     @Resource
     private DataSourceService dataSourceService;
 
+    @Autowired
+    private DataSourceProperties dataSourceProperties;
+
     @Override
+    @Transactional(readOnly = true)
     public List<TableMetaData> getTableList() throws SQLException {
-        if (tableMetaParser == null) {
-            throw new BusinessException("不支持的数据库");
-        }
-        return tableMetaParser.parseAll();
+        return getDBType().getTableMetaParser(sqlExecutor).parseAll();
     }
 
     @Override
@@ -77,6 +65,7 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
         return execSql(sqlExecutor, sqlList);
     }
 
+    @Transactional(rollbackFor = Throwable.class)
     public List<Map<String, Object>> execSql(SqlExecutor sqlExecutor, List<String> sqlList) throws SQLException {
         List<Map<String, Object>> response = new LinkedList<>();
         for (String s : sqlList) {
@@ -115,7 +104,7 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
 
     @Override
     public String createAlterSql(TableMetaData newTable) throws Exception {
-        return createAlterSql(databaseMetaDataFactoryBean.getObject(), tableMetaParser, newTable);
+        return createAlterSql(getDBType().getDatabaseMetaData(), getDBType().getTableMetaParser(sqlExecutor), newTable);
     }
 
     public String createAlterSql(DatabaseMetaData databaseMetaData, TableMetaParser tableMetaParser, TableMetaData newTable) throws Exception {
@@ -131,7 +120,7 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
 
     @Override
     public String createCreateSql(TableMetaData newTable) throws Exception {
-        return createCreateSql(databaseMetaDataFactoryBean.getObject(), newTable);
+        return createCreateSql(getDBType().getDatabaseMetaData(), newTable);
     }
 
     public String createCreateSql(DatabaseMetaData databaseMetaData, TableMetaData newTable) throws Exception {
@@ -144,34 +133,13 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
         return builder.toString();
     }
 
-    @Override
-    public List<TableMetaData> getTableList(String datasourceId) throws SQLException {
-        SqlExecutor sqlExecutor = dynamicDataSourceService.getSqlExecutor(datasourceId);
-        DBType dbType = getDBType(datasourceId);
-        return dbType.getTableMetaParser(sqlExecutor).parseAll();
-    }
-
-    @Override
-    @Transactional(rollbackFor = Throwable.class)
-    public List<Map<String, Object>> execSql(String datasourceId, List<String> sqlList) throws SQLException {
-        return execSql(dynamicDataSourceService.getSqlExecutor(datasourceId), sqlList);
-    }
-
-    @Override
-    public String createAlterSql(String datasourceId, TableMetaData newTable) throws Exception {
-        DBType dbType = getDBType(datasourceId);
-        SqlExecutor sqlExecutor = dynamicDataSourceService.getSqlExecutor(datasourceId);
-        return createAlterSql(dbType.getDatabaseMetaData(), dbType.getTableMetaParser(sqlExecutor), newTable);
-    }
-
-    @Override
-    public String createCreateSql(String datasourceId, TableMetaData newTable) throws Exception {
-        return createCreateSql(getDBType(datasourceId).getDatabaseMetaData(), newTable);
-    }
-
-    public DBType getDBType(String datasourceId) {
-        org.hsweb.web.bean.po.datasource.DataSource dataSource = dataSourceService.selectByPk(datasourceId);
-        String driver = dataSource.getDriver();
+    public DBType getDBType() {
+        String datasourceId = DynamicDataSource.getActiveDataSourceId();
+        String driver = dataSourceProperties.getDriverClassName();
+        if (datasourceId != null) {
+            org.hsweb.web.bean.po.datasource.DataSource dataSource = dataSourceService.selectByPk(datasourceId);
+            driver = dataSource.getDriver();
+        }
         if (driver.contains("mysql")) {
             return DBType.mysql;
         }
@@ -210,7 +178,8 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
                 databaseMetaData.init();
                 return databaseMetaData;
             }
-        }, h2 {
+        },
+        h2 {
             @Override
             public TableMetaParser getTableMetaParser(SqlExecutor sqlExecutor) {
                 return new H2TableMetaParser(sqlExecutor);

+ 0 - 8
hsweb-web-service-interface/src/main/java/org/hsweb/web/service/system/DataBaseManagerService.java

@@ -26,12 +26,4 @@ public interface DataBaseManagerService {
     String createAlterSql(TableMetaData newTable) throws Exception;
 
     String createCreateSql(TableMetaData newTable) throws Exception;
-
-    List<TableMetaData> getTableList(String datasourceId) throws SQLException;
-
-    List<Map<String, Object>> execSql(String datasourceId, List<String> sqlList) throws SQLException;
-
-    String createAlterSql(String datasourceId, TableMetaData newTable) throws Exception;
-
-    String createCreateSql(String datasourceId, TableMetaData newTable) throws Exception;
 }