Browse Source

基础框架发布: 8.2.37

1. 支持数据库表结构导出成 liquibase 文件

前端核心发布: 8.2.130
main
wangshaoping 5 days ago
parent
commit
1a1a7125be
  1. 0
      app.platformnull/platform/schema/liquibase.xml
  2. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties
  3. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties
  4. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties
  5. 2
      io.sc.platform.developer.frontend/src/components/index.ts
  6. 1
      io.sc.platform.developer.frontend/src/i18n/messages.json
  7. 1
      io.sc.platform.developer.frontend/src/i18n/messages_tw_CN.json
  8. 1
      io.sc.platform.developer.frontend/src/i18n/messages_zh_CN.json
  9. 2
      io.sc.platform.developer.frontend/src/menus/menus.json
  10. 11
      io.sc.platform.developer.frontend/src/routes/routes.json
  11. 185
      io.sc.platform.developer.frontend/src/views/backend/ExportLiquibaseSchema.vue
  12. 76
      io.sc.platform.jdbc.liquibase/src/main/java/io/sc/platform/jdbc/liquibase/exporter/LiquibaseSchemaExporter.java
  13. 55
      io.sc.platform.jdbc.schemacrawler/src/main/java/io/sc/platform/jdbc/schemacrawler/MetaDataLoaderImpl.java
  14. 14
      io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/controller/JdbcDataWebController.java
  15. 38
      io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/controller/support/SchemaExporterThread.java
  16. 4
      io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/exporter/SchemaExporter.java
  17. 2
      io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/service/JdbcDataService.java
  18. 16
      io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/service/impl/JdbcDataServiceImpl.java

0
app.platformnull/platform/schema/liquibase.xml

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties

@ -271,3 +271,4 @@ async=Asynchronous
valueScale=Value Scale valueScale=Value Scale
scale=Scale scale=Scale
clean=Clean clean=Clean
remarks=Remarks

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties

@ -271,3 +271,4 @@ async=\u7570\u6B65
valueScale=\u503C\u7CBE\u5EA6 valueScale=\u503C\u7CBE\u5EA6
scale=\u7CBE\u5EA6 scale=\u7CBE\u5EA6
clean=\u6E05\u9664 clean=\u6E05\u9664
remarks=\u5907\u6CE8

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties

@ -271,3 +271,4 @@ async=\u5F02\u6B65
valueScale=\u503C\u7CBE\u5EA6 valueScale=\u503C\u7CBE\u5EA6
scale=\u7CBE\u5EA6 scale=\u7CBE\u5EA6
clean=\u6E05\u9664 clean=\u6E05\u9664
remarks=\u5099\u8A3B

2
io.sc.platform.developer.frontend/src/components/index.ts

@ -26,6 +26,7 @@ import component_developer_plugin_Ws from '@/views/plugin/Ws.vue';
import component_developer_plugin_Swagger from '@/views/plugin/Swagger.vue'; import component_developer_plugin_Swagger from '@/views/plugin/Swagger.vue';
import component_developer_plugin_SystemProperties from '@/views/plugin/SystemProperties.vue'; import component_developer_plugin_SystemProperties from '@/views/plugin/SystemProperties.vue';
import component_developer_backend_importLiquibase from '@/views/backend/ImportLiquibase.vue'; import component_developer_backend_importLiquibase from '@/views/backend/ImportLiquibase.vue';
import component_developer_backend_liquibaseSchema from '@/views/backend/ExportLiquibaseSchema.vue';
import component_developer_backend_exportLiquibase from '@/views/backend/ExportLiquibase.vue'; import component_developer_backend_exportLiquibase from '@/views/backend/ExportLiquibase.vue';
import component_developer_backend_sql from '@/views/backend/sql/Sql.vue'; import component_developer_backend_sql from '@/views/backend/sql/Sql.vue';
import component_developer_backend_upload from '@/views/backend/Upload.vue'; import component_developer_backend_upload from '@/views/backend/Upload.vue';
@ -60,6 +61,7 @@ const localComponents = {
'component.developer.plugin.Swagger': component_developer_plugin_Swagger, 'component.developer.plugin.Swagger': component_developer_plugin_Swagger,
'component.developer.plugin.SystemProperties': component_developer_plugin_SystemProperties, 'component.developer.plugin.SystemProperties': component_developer_plugin_SystemProperties,
'component.developer.backend.importLiquibase': component_developer_backend_importLiquibase, 'component.developer.backend.importLiquibase': component_developer_backend_importLiquibase,
'component.developer.backend.liquibaseSchema': component_developer_backend_liquibaseSchema,
'component.developer.backend.exportLiquibase': component_developer_backend_exportLiquibase, 'component.developer.backend.exportLiquibase': component_developer_backend_exportLiquibase,
'component.developer.backend.sql': component_developer_backend_sql, 'component.developer.backend.sql': component_developer_backend_sql,
'component.developer.backend.upload': component_developer_backend_upload, 'component.developer.backend.upload': component_developer_backend_upload,

1
io.sc.platform.developer.frontend/src/i18n/messages.json

@ -29,6 +29,7 @@
"menu.developer.backend": "Back End Tools", "menu.developer.backend": "Back End Tools",
"menu.developer.backend.import.liquibase": "Data Import", "menu.developer.backend.import.liquibase": "Data Import",
"menu.developer.backend.export.liquibaseSchema": "Table Liquibase Schema Export",
"menu.developer.backend.export.liquibase": "Data Export", "menu.developer.backend.export.liquibase": "Data Export",
"menu.developer.backend.sql": "SQL", "menu.developer.backend.sql": "SQL",
"menu.developer.backend.upload": "Upload File", "menu.developer.backend.upload": "Upload File",

1
io.sc.platform.developer.frontend/src/i18n/messages_tw_CN.json

@ -29,6 +29,7 @@
"menu.developer.backend": "後端工具", "menu.developer.backend": "後端工具",
"menu.developer.backend.import.liquibase": "數據導入", "menu.developer.backend.import.liquibase": "數據導入",
"menu.developer.backend.export.liquibaseSchema": "表結構 Liquibase 文件導出",
"menu.developer.backend.export.liquibase": "數據導出", "menu.developer.backend.export.liquibase": "數據導出",
"menu.developer.backend.sql": "SQL", "menu.developer.backend.sql": "SQL",
"menu.developer.backend.upload": "上傳文件", "menu.developer.backend.upload": "上傳文件",

1
io.sc.platform.developer.frontend/src/i18n/messages_zh_CN.json

@ -29,6 +29,7 @@
"menu.developer.backend": "后端工具", "menu.developer.backend": "后端工具",
"menu.developer.backend.import.liquibase": "数据导入", "menu.developer.backend.import.liquibase": "数据导入",
"menu.developer.backend.export.liquibaseSchema": "表结构 Liquibase 文件导出",
"menu.developer.backend.export.liquibase": "数据导出", "menu.developer.backend.export.liquibase": "数据导出",
"menu.developer.backend.sql": "SQL", "menu.developer.backend.sql": "SQL",
"menu.developer.backend.upload": "上传文件", "menu.developer.backend.upload": "上传文件",

2
io.sc.platform.developer.frontend/src/menus/menus.json

@ -75,6 +75,8 @@
{"type":"GROUP", "order":500, "parentId":"menu.developer", "id":"menu.developer.backend", "titleI18nKey":"menu.developer.backend", "icon":"bi-server"}, {"type":"GROUP", "order":500, "parentId":"menu.developer", "id":"menu.developer.backend", "titleI18nKey":"menu.developer.backend", "icon":"bi-server"},
/*//*/ /*//*/
{"type":"ROUTE", "order":100, "parentId":"menu.developer.backend", "id":"menu.developer.backend.import.liquibase", "titleI18nKey":"menu.developer.backend.import.liquibase", "icon":"bi-database-up", "routeName":"route.developer.backend.import.liquibase"}, {"type":"ROUTE", "order":100, "parentId":"menu.developer.backend", "id":"menu.developer.backend.import.liquibase", "titleI18nKey":"menu.developer.backend.import.liquibase", "icon":"bi-database-up", "routeName":"route.developer.backend.import.liquibase"},
/*// Liquibase */
{"type":"ROUTE", "order":150, "parentId":"menu.developer.backend", "id":"menu.developer.backend.export.liquibaseSchema","titleI18nKey":"menu.developer.backend.export.liquibaseSchema","icon":"bi-database-gear", "routeName":"route.developer.backend.export.liquibaseSchema"},
/*//*/ /*//*/
{"type":"ROUTE", "order":200, "parentId":"menu.developer.backend", "id":"menu.developer.backend.export.liquibase", "titleI18nKey":"menu.developer.backend.export.liquibase", "icon":"bi-database-down", "routeName":"route.developer.backend.export.liquibase"}, {"type":"ROUTE", "order":200, "parentId":"menu.developer.backend", "id":"menu.developer.backend.export.liquibase", "titleI18nKey":"menu.developer.backend.export.liquibase", "icon":"bi-database-down", "routeName":"route.developer.backend.export.liquibase"},
/*//SQL*/ /*//SQL*/

11
io.sc.platform.developer.frontend/src/routes/routes.json

@ -309,6 +309,17 @@
"redirect": null, "redirect": null,
"meta": {} "meta": {}
}, },
{
"name": "route.developer.backend.export.liquibaseSchema",
"path": "developer/backend/export/liquibaseSchema",
"parent": "/",
"priority": 0,
"module": "io.sc.platform.developer.frontend",
"component": "component.developer.backend.liquibaseSchema",
"componentPath": "@/views/backend/ExportLiquibaseSchema.vue",
"redirect": null,
"meta": {}
},
{ {
"name": "route.developer.backend.export.liquibase", "name": "route.developer.backend.export.liquibase",
"path": "developer/backend/export/liquibase", "path": "developer/backend/export/liquibase",

185
io.sc.platform.developer.frontend/src/views/backend/ExportLiquibaseSchema.vue

@ -0,0 +1,185 @@
<template>
<div>
<w-form
v-model="valueReactive"
:cols-num="12"
:fields="[
{
colSpan: 2,
name: 'datasource',
label: $t('developer.backend.export.liquibase.datasource'),
type: 'w-select',
options: datasourceOptionsRef,
onUpdateValue: (args) => {
datasourceChanged(args.value);
},
},
{
colSpan: 2,
name: 'catalog',
label: $t('developer.backend.export.liquibase.catalog'),
type: 'w-select',
options: catalogOptionsRef,
onUpdateValue: (args) => {
catalogChanged(valueReactive.datasource, args.value);
},
},
{
colSpan: 2,
name: 'schema',
label: $t('developer.backend.export.liquibase.schema'),
type: 'w-select',
options: schemaOptionsRef,
},
{
colSpan: 6,
name: 'tables',
label: $t('developer.backend.export.liquibase.tables'),
type: 'w-grid-select',
multiple: true,
displayValue: 'name',
grid: {
toolbarConfigure: { noIcon: false },
hideBottom: true,
configButton: true,
checkboxSelection: true,
dataUrl: Environment.apiContextPath(
'/api/jdbc/metadata/getTables?datasource=' +
(valueReactive.datasource || '') +
'&catalog=' +
(valueReactive.catalog || '') +
'&schema=' +
(valueReactive.schema || ''),
),
pageable: false,
sortBy: ['name'],
sortNo: true,
toolbarActions: ['refresh'],
primaryKey: 'name',
columns: [
{ name: 'name', label: $t('name') },
{ name: 'remarks', label: $t('remarks') },
],
},
},
]"
>
</w-form>
<div class="row justify-center q-gutter-md py-2">
<w-progress-btn
ref="progressBtnRef"
icon="bi-database-down"
:label="$t('export')"
data-url="/api/jdbc/data/traceSchemaExporterExecuteProgress"
@click="exportData"
@success="
(progressInfo) => {
Downloader.get(Environment.apiContextPath('/api/mvc/download?filePath=' + encodeURIComponent(progressInfo.result)));
}
"
></w-progress-btn>
</div>
</div>
</template>
<script setup lang="ts">
import 'tailwindcss/utilities.css';
import { ref, reactive, onMounted, onUpdated } from 'vue';
import { t, axios, Environment, DialogManager, Downloader } from 'platform-core';
const progressBtnRef = ref();
const datasourceOptionsRef = ref([]);
const catalogOptionsRef = ref([]);
const schemaOptionsRef = ref([]);
const tablesOptionsRef = ref([]);
const valueReactive = reactive({
datasource: undefined,
catalog: undefined,
schema: undefined,
tables: [],
sql: undefined,
});
const loadDatasource = () => {
axios.get(Environment.apiContextPath('/api/system/datasource?pageable=false&sortBy=name')).then((response) => {
const data = response?.data.content;
const datasourceOptions = [{ label: t('default'), value: '' }];
if (data && data.length > 0) {
for (let item of data) {
datasourceOptions.push({ label: item.name, value: item.name });
}
}
datasourceOptionsRef.value = datasourceOptions;
});
};
const datasourceChanged = (datasource: string) => {
datasource = datasource || '';
axios.get(Environment.apiContextPath('/api/jdbc/metadata/getCatalogs?datasource=' + datasource)).then((response) => {
const data = response?.data;
const catalogOptions = [];
if (data && data.length > 0) {
for (let item of data) {
catalogOptions.push({ label: item.name, value: item.name });
}
}
catalogOptionsRef.value = catalogOptions;
schemaOptionsRef.value = [];
tablesOptionsRef.value = [];
});
};
const catalogChanged = (datasource: string, catalog: string) => {
datasource = datasource || '';
axios.get(Environment.apiContextPath('/api/jdbc/metadata/getSchemas?datasource=' + datasource + '&catalog=' + catalog)).then((response) => {
const data = response?.data;
const schemaOptions = [];
if (data && data.length > 0) {
for (let item of data) {
schemaOptions.push({ label: item.name, value: item.name });
}
}
schemaOptionsRef.value = schemaOptions;
tablesOptionsRef.value = [];
});
};
const schemaChanged = (datasource: string, catalog: string, schema: string) => {
datasource = datasource || '';
catalog = catalog || '';
schema = schema || '';
axios
.get(Environment.apiContextPath('/api/jdbc/metadata/getTables?datasource=' + datasource + '&catalog=' + catalog + '&schema=' + schema))
.then((response) => {
const data = response?.data;
const tablesOptions = [];
if (data && data.length > 0) {
for (let item of data) {
tablesOptions.push({ label: item.name + ' - ' + item.remarks, value: item.name });
}
}
tablesOptionsRef.value = tablesOptions;
});
};
const exportData = (e) => {
DialogManager.confirm(t('developer.backend.export.liquibase.export.tip'), () => {
const data = valueReactive;
const config = {
datasource: data.datasource,
catalog: data.catalog,
schema: data.schema,
tables: data.tables,
};
axios.post(Environment.apiContextPath('/api/jdbc/data/exportSchema'), config).then((response) => {
progressBtnRef.value.start();
});
});
};
onMounted(() => {
loadDatasource();
});
</script>

76
io.sc.platform.jdbc.liquibase/src/main/java/io/sc/platform/jdbc/liquibase/exporter/LiquibaseSchemaExporter.java

@ -2,14 +2,19 @@ package io.sc.platform.jdbc.liquibase.exporter;
import io.sc.platform.core.DirectoryManager; import io.sc.platform.core.DirectoryManager;
import io.sc.platform.core.Environment; import io.sc.platform.core.Environment;
import io.sc.platform.core.enums.ProgressStatus;
import io.sc.platform.core.support.ProgressInfo;
import io.sc.platform.core.util.ZipUtil;
import io.sc.platform.jdbc.exporter.SchemaExporter; import io.sc.platform.jdbc.exporter.SchemaExporter;
import io.sc.platform.jdbc.exporter.support.SchemaExportConfigure; import io.sc.platform.jdbc.exporter.support.SchemaExportConfigure;
import io.sc.platform.jdbc.meta.MetaDataLoader; import io.sc.platform.jdbc.meta.MetaDataLoader;
import io.sc.platform.jdbc.meta.support.Column; import io.sc.platform.jdbc.meta.support.Column;
import io.sc.platform.jdbc.meta.support.Index; import io.sc.platform.jdbc.meta.support.Index;
import io.sc.platform.jdbc.meta.support.Table; import io.sc.platform.jdbc.meta.support.Table;
import io.sc.platform.util.FileUtil;
import io.sc.platform.util.WriterUtil; import io.sc.platform.util.WriterUtil;
import org.springframework.jdbc.support.MetaDataAccessException; import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.util.StringUtils;
import javax.sql.DataSource; import javax.sql.DataSource;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
@ -17,34 +22,53 @@ import javax.xml.stream.XMLStreamWriter;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
public class LiquibaseSchemaExporter implements SchemaExporter { public class LiquibaseSchemaExporter implements SchemaExporter {
private static final String OUTPUT_PATH = DirectoryManager.getInstance().getByName(""); private static final String OUTPUT_PATH = DirectoryManager.getInstance().getByName("dir.work.web.export") + "/liquibase";
@Override @Override
public void export(DataSource dataSource, SchemaExportConfigure configure) { public void export(DataSource dataSource, SchemaExportConfigure configure, ProgressInfo progressInfo, Locale locale) {
try { try {
exportSingleFile(dataSource, configure); exportSingleFile(dataSource, configure,progressInfo,locale);
//exportMultiFile(dataSource, configure); //exportMultiFile(dataSource, configure);
}catch (Exception e){ }catch (Exception e){
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
private void exportSingleFile(DataSource dataSource, SchemaExportConfigure configure) throws XMLStreamException, FileNotFoundException, UnsupportedEncodingException, MetaDataAccessException { private void exportSingleFile(DataSource dataSource, SchemaExportConfigure configure, ProgressInfo progressInfo, Locale locale) throws Exception {
XMLStreamWriter writer = WriterUtil.xmlStreamWriter(OUTPUT_PATH + File.separator + "schema." + configure.getSchema() + ".xml"); progressInfo.setStatus(ProgressStatus.RUNNING);
writeHeader(writer,configure.getSchema()); progressInfo.setStartDatetime(new Date());
List<Table> tables =MetaDataLoader.newInstance().getTables(dataSource,configure.getCatalog(), configure.getSchema()); progressInfo.setTotalWeight(configure.getTables().length);
String outPutDir =OUTPUT_PATH + getPath(configure.getCatalog(),configure.getSchema());
FileUtil.deldirs(outPutDir);
String schemaDir =outPutDir + "/schema";
new File(schemaDir).mkdirs();
XMLStreamWriter writer = WriterUtil.xmlStreamWriter(schemaDir + "/liquibase.xml");
writeHeader(writer,getSchemaName(configure.getCatalog(),configure.getSchema()));
List<Table> tables =MetaDataLoader.newInstance().getTables(dataSource,configure.getCatalog(),configure.getSchema(),configure.getTables());
for(Table table : tables){ for(Table table : tables){
writeTable(table,writer); writeTable(table,writer);
} }
writeTail(writer); writeTail(writer);
writer.flush(); writer.flush();
writer.close(); writer.close();
ZipUtil.zip(outPutDir);
// 设置结果为导出的 zip 文件全路径
progressInfo.setResult(outPutDir + ".zip");
//执行完毕
progressInfo.done();
} }
private void exportMultiFile(DataSource dataSource, SchemaExportConfigure configure) throws MetaDataAccessException, XMLStreamException, FileNotFoundException, UnsupportedEncodingException { private void exportMultiFile(DataSource dataSource, SchemaExportConfigure configure, ProgressInfo progressInfo, Locale locale) throws MetaDataAccessException, XMLStreamException, FileNotFoundException, UnsupportedEncodingException {
List<Table> tables =MetaDataLoader.newInstance().getTables(dataSource, configure.getCatalog(), configure.getSchema()); List<Table> tables =MetaDataLoader.newInstance().getTables(dataSource, configure.getCatalog(), configure.getSchema());
for(Table table : tables){ for(Table table : tables){
XMLStreamWriter writer = WriterUtil.xmlStreamWriter(OUTPUT_PATH + File.separator + "schema." + configure.getSchema() + "." + table.getName() + ".xml"); XMLStreamWriter writer = WriterUtil.xmlStreamWriter(OUTPUT_PATH + File.separator + "schema." + configure.getSchema() + "." + table.getName() + ".xml");
@ -58,6 +82,7 @@ public class LiquibaseSchemaExporter implements SchemaExporter {
private void writeHeader(XMLStreamWriter writer,String changeSetId) throws XMLStreamException { private void writeHeader(XMLStreamWriter writer,String changeSetId) throws XMLStreamException {
writer.writeStartDocument(Environment.DEFAULT_CHARSET_NAME,"1.0"); writer.writeStartDocument(Environment.DEFAULT_CHARSET_NAME,"1.0");
writer.writeStartElement("databaseChangeLog"); //start databaseChangeLog writer.writeStartElement("databaseChangeLog"); //start databaseChangeLog
writer.writeAttribute("xmlns", "http://www.liquibase.org/xml/ns/dbchangelog"); writer.writeAttribute("xmlns", "http://www.liquibase.org/xml/ns/dbchangelog");
writer.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); writer.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
@ -66,6 +91,7 @@ public class LiquibaseSchemaExporter implements SchemaExporter {
writer.writeStartElement("changeSet"); //start changeSet writer.writeStartElement("changeSet"); //start changeSet
writer.writeAttribute("id", changeSetId); writer.writeAttribute("id", changeSetId);
writer.writeAttribute("author", "platform");
} }
private void writeTail(XMLStreamWriter writer) throws XMLStreamException { private void writeTail(XMLStreamWriter writer) throws XMLStreamException {
@ -113,20 +139,50 @@ public class LiquibaseSchemaExporter implements SchemaExporter {
} }
private String getLiquibaseJavaSqlType(Column column) { private String getLiquibaseJavaSqlType(Column column) {
String type ="java.sql.Types." + column.getSqlType(); String type =column.getSqlType();
if("java.sql.Types.VARCHAR".equals(type)) { if("java.sql.Types.VARCHAR".equals(type)) {
if(column.getSize()>10000) { if(column.getSize()>10000) {
type ="java.sql.Types.CLOB"; type ="java.sql.Types.CLOB";
}else { }else {
type =type + "(" + column.getSize() + ")"; type ="NVARCHAR(" + column.getSize() + ")";
} }
}else if("java.sql.Types.LONGVARCHAR".equals(type)){
type ="CLOB";
}else if("java.sql.Types.TIMESTAMP".equals(type)) { }else if("java.sql.Types.TIMESTAMP".equals(type)) {
type ="DATETIME"; type ="DATETIME";
}else if("java.sql.Types.NUMERIC".equals(type)) { }else if("java.sql.Types.NUMERIC".equals(type)) {
type ="java.sql.Types.NUMERIC" + column.getWidth(); type ="java.sql.Types.NUMERIC" + column.getWidth();
}else if("java.sql.Types.DECIMAL".equals(type)) { }else if("java.sql.Types.DECIMAL".equals(type)) {
type ="java.sql.Types.DECIMAL" + column.getWidth(); type ="java.sql.Types.DECIMAL" + column.getWidth();
}else if("java.sql.Types.INTEGER".equals(type)){
type ="INTEGER";
} }
return type; return type;
} }
private String getPath(String catalog,String schema){
String catalogOrSchemaName ="";
if(StringUtils.hasText(catalog)){
catalogOrSchemaName ="/" + catalog;
}
if(StringUtils.hasText(schema)){
catalogOrSchemaName ="/" + schema;
}
return catalogOrSchemaName;
}
private String getSchemaName(String catalog,String schema){
String catalogOrSchemaName ="";
if(StringUtils.hasText(catalog)){
catalogOrSchemaName =catalog;
if(StringUtils.hasText(schema)){
catalogOrSchemaName ="." + schema;
}
return catalogOrSchemaName;
}
if(StringUtils.hasText(schema)){
catalogOrSchemaName =schema;
}
return catalogOrSchemaName;
}
} }

55
io.sc.platform.jdbc.schemacrawler/src/main/java/io/sc/platform/jdbc/schemacrawler/MetaDataLoaderImpl.java

@ -1,5 +1,6 @@
package io.sc.platform.jdbc.schemacrawler; package io.sc.platform.jdbc.schemacrawler;
import com.oceanbase.jdbc.OceanBaseConnection;
import io.sc.platform.jdbc.DatabaseType; import io.sc.platform.jdbc.DatabaseType;
import io.sc.platform.jdbc.meta.MetaDataLoader; import io.sc.platform.jdbc.meta.MetaDataLoader;
import io.sc.platform.jdbc.meta.support.*; import io.sc.platform.jdbc.meta.support.*;
@ -20,10 +21,7 @@ import us.fatehi.utility.datasource.DatabaseConnectionSources;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@Service("io.sc.platform.jdbc.schemacrawler.MetaDataLoaderImpl") @Service("io.sc.platform.jdbc.schemacrawler.MetaDataLoaderImpl")
public class MetaDataLoaderImpl implements MetaDataLoader { public class MetaDataLoaderImpl implements MetaDataLoader {
@ -34,7 +32,7 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
Connection connection =null; Connection connection =null;
ResultSet rs =null; ResultSet rs =null;
try { try {
connection =dataSource.getConnection(); connection =getConnection(dataSource);
DatabaseMetaData databaseMetaData =connection.getMetaData(); DatabaseMetaData databaseMetaData =connection.getMetaData();
rs =databaseMetaData.getCatalogs(); rs =databaseMetaData.getCatalogs();
while (rs.next()){ while (rs.next()){
@ -57,7 +55,7 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
Connection connection =null; Connection connection =null;
ResultSet rs =null; ResultSet rs =null;
try { try {
connection =dataSource.getConnection(); connection =getConnection(dataSource);
DatabaseMetaData databaseMetaData =connection.getMetaData(); DatabaseMetaData databaseMetaData =connection.getMetaData();
rs =databaseMetaData.getSchemas(catalogName,null); rs =databaseMetaData.getSchemas(catalogName,null);
while (rs.next()){ while (rs.next()){
@ -80,7 +78,7 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
Connection connection =null; Connection connection =null;
ResultSet rs =null; ResultSet rs =null;
try { try {
connection =dataSource.getConnection(); connection =getConnection(dataSource);
DatabaseMetaData databaseMetaData =connection.getMetaData(); DatabaseMetaData databaseMetaData =connection.getMetaData();
if(tableNames==null || tableNames.length==0) { if(tableNames==null || tableNames.length==0) {
rs = databaseMetaData.getTables(catalogName, schemaName, null, new String[]{"TABLE"}); rs = databaseMetaData.getTables(catalogName, schemaName, null, new String[]{"TABLE"});
@ -124,7 +122,7 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
Connection connection =null; Connection connection =null;
ResultSet rs =null; ResultSet rs =null;
try { try {
connection =dataSource.getConnection(); connection =getConnection(dataSource);
DatabaseMetaData databaseMetaData =connection.getMetaData(); DatabaseMetaData databaseMetaData =connection.getMetaData();
rs =databaseMetaData.getColumns(catalogName,schemaName,tableName,null); rs =databaseMetaData.getColumns(catalogName,schemaName,tableName,null);
while (rs.next()){ while (rs.next()){
@ -136,6 +134,32 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
try{rs.close();} catch (SQLException e) {} try{rs.close();} catch (SQLException e) {}
try{connection.close();} catch (SQLException e) {} try{connection.close();} catch (SQLException e) {}
} }
Map<String,String> primaryKeys =getPrimaryKeys(dataSource,catalogName,schemaName,tableName);
for(Column column : result){
column.setPartOfPrimaryKey(primaryKeys.containsKey(column.getName()));
}
return result;
}
private Map<String,String> getPrimaryKeys(DataSource dataSource, String catalogName, String schemaName, String tableName) throws MetaDataAccessException {
Map<String,String> result =new HashMap<>();
Connection connection =null;
ResultSet rs =null;
try {
connection =getConnection(dataSource);
DatabaseMetaData databaseMetaData =connection.getMetaData();
rs =databaseMetaData.getPrimaryKeys(catalogName,schemaName,tableName);
while (rs.next()){
String columnName =rs.getString("COLUMN_NAME");
result.put(columnName,columnName);
}
} catch (SQLException e) {
throw new MetaDataAccessException(e);
}finally {
try{rs.close();} catch (SQLException e) {}
try{connection.close();} catch (SQLException e) {}
}
return result; return result;
} }
@ -144,7 +168,7 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
Connection connection =null; Connection connection =null;
ResultSet rs =null; ResultSet rs =null;
try { try {
connection =dataSource.getConnection(); connection =getConnection(dataSource);
DatabaseMetaData databaseMetaData =connection.getMetaData(); DatabaseMetaData databaseMetaData =connection.getMetaData();
rs =databaseMetaData.getIndexInfo(catalogName,schemaName,tableName,false,false); rs =databaseMetaData.getIndexInfo(catalogName,schemaName,tableName,false,false);
while (rs.next()){ while (rs.next()){
@ -182,7 +206,7 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
tableSummary.setRemarks(table.getRemarks()); tableSummary.setRemarks(table.getRemarks());
if(isCount){ if(isCount){
try( try(
Connection connection =dataSource.getConnection(); Connection connection =getConnection(dataSource);
PreparedStatement ps =connection.prepareStatement("select count(1) from " + table.getName()); PreparedStatement ps =connection.prepareStatement("select count(1) from " + table.getName());
ResultSet rs =ps.executeQuery(); ResultSet rs =ps.executeQuery();
){ ){
@ -242,6 +266,7 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
column.setSqlType(SqlTypeUtil.getSqlTypeName(DATA_TYPE)); column.setSqlType(SqlTypeUtil.getSqlTypeName(DATA_TYPE));
column.setJavaType(SqlTypeUtil.getJavaType(DATA_TYPE)); column.setJavaType(SqlTypeUtil.getJavaType(DATA_TYPE));
column.setSize(COLUMN_SIZE); column.setSize(COLUMN_SIZE);
column.setWidth("(" + COLUMN_SIZE + "," + String.valueOf(DECIMAL_DIGITS)+")");
column.setNullable("YES".equalsIgnoreCase(IS_NULLABLE)?true:false); column.setNullable("YES".equalsIgnoreCase(IS_NULLABLE)?true:false);
column.setAutoIncremented("YES".equalsIgnoreCase(IS_AUTOINCREMENT)?true:false); column.setAutoIncremented("YES".equalsIgnoreCase(IS_AUTOINCREMENT)?true:false);
return column; return column;
@ -252,7 +277,7 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
Connection connection =null; Connection connection =null;
ResultSet rs =null; ResultSet rs =null;
try { try {
connection =dataSource.getConnection(); connection =getConnection(dataSource);
DatabaseMetaData databaseMetaData =connection.getMetaData(); DatabaseMetaData databaseMetaData =connection.getMetaData();
rs =databaseMetaData.getImportedKeys(catalogName,schemaName,tableName); rs =databaseMetaData.getImportedKeys(catalogName,schemaName,tableName);
while (rs.next()){ while (rs.next()){
@ -271,4 +296,12 @@ public class MetaDataLoaderImpl implements MetaDataLoader {
} }
return result; return result;
} }
private Connection getConnection(DataSource dataSource) throws SQLException {
Connection connection =dataSource.getConnection();
if(connection instanceof OceanBaseConnection){
((OceanBaseConnection)connection).setRemarksReporting(true);
}
return connection;
}
} }

14
io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/controller/JdbcDataWebController.java

@ -4,8 +4,10 @@ import io.sc.platform.core.service.ProgressableThreadService;
import io.sc.platform.core.support.ProgressInfo; import io.sc.platform.core.support.ProgressInfo;
import io.sc.platform.jdbc.controller.support.ExporterThread; import io.sc.platform.jdbc.controller.support.ExporterThread;
import io.sc.platform.jdbc.controller.support.ImporterThread; import io.sc.platform.jdbc.controller.support.ImporterThread;
import io.sc.platform.jdbc.controller.support.SchemaExporterThread;
import io.sc.platform.jdbc.exporter.support.DataExportConfigure; import io.sc.platform.jdbc.exporter.support.DataExportConfigure;
import io.sc.platform.jdbc.exporter.support.DataImportConfigure; import io.sc.platform.jdbc.exporter.support.DataImportConfigure;
import io.sc.platform.jdbc.exporter.support.SchemaExportConfigure;
import io.sc.platform.jdbc.service.JdbcDataService; import io.sc.platform.jdbc.service.JdbcDataService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -35,6 +37,13 @@ public class JdbcDataWebController {
progressableThreadService.start(thread); progressableThreadService.start(thread);
} }
@PostMapping("exportSchema")
public void exportSchema(@RequestBody SchemaExportConfigure configure, Locale locale) throws Exception {
SchemaExporterThread thread =new SchemaExporterThread(jdbcDataService,configure,locale);
progressableThreadService.start(thread);
}
@PostMapping("exportData") @PostMapping("exportData")
public void exportData(@RequestBody DataExportConfigure configure, Locale locale) throws Exception { public void exportData(@RequestBody DataExportConfigure configure, Locale locale) throws Exception {
ExporterThread thread =new ExporterThread(jdbcDataService,configure,locale); ExporterThread thread =new ExporterThread(jdbcDataService,configure,locale);
@ -50,4 +59,9 @@ public class JdbcDataWebController {
public ProgressInfo traceExporterExecuteProgress(Locale locale) throws Exception{ public ProgressInfo traceExporterExecuteProgress(Locale locale) throws Exception{
return progressableThreadService.getProgressInfo(ExporterThread.class.getName()); return progressableThreadService.getProgressInfo(ExporterThread.class.getName());
} }
@GetMapping("traceSchemaExporterExecuteProgress")
public ProgressInfo traceSchemaExporterExecuteProgress(Locale locale) throws Exception{
return progressableThreadService.getProgressInfo(SchemaExporterThread.class.getName());
}
} }

38
io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/controller/support/SchemaExporterThread.java

@ -0,0 +1,38 @@
package io.sc.platform.jdbc.controller.support;
import io.sc.platform.core.enums.ProgressStatus;
import io.sc.platform.core.support.ProgressableThread;
import io.sc.platform.jdbc.exporter.support.DataExportConfigure;
import io.sc.platform.jdbc.exporter.support.SchemaExportConfigure;
import io.sc.platform.jdbc.service.JdbcDataService;
import io.sc.platform.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Locale;
public class SchemaExporterThread extends ProgressableThread {
private Logger log = LoggerFactory.getLogger(SchemaExporterThread.class);
private JdbcDataService jdbcDataService;
private SchemaExportConfigure configure;
private Locale locale;
public SchemaExporterThread(JdbcDataService jdbcDataService, SchemaExportConfigure configure, Locale locale){
this.jdbcDataService =jdbcDataService;
this.configure =configure;
this.locale =locale;
}
@Override
public void run() {
try {
progressInfo.setStatus(ProgressStatus.RUNNING);
jdbcDataService.exportSchema(configure,progressInfo,locale);
progressInfo.setStatus(ProgressStatus.COMPLETED);
} catch (Exception e) {
log.error("",e);
progressInfo.setStatus(ProgressStatus.ERROR);
progressInfo.setErrorMessage(e.getMessage());
progressInfo.setErrorStackTrace(StringUtil.getStackTrace(e));
}
}
}

4
io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/exporter/SchemaExporter.java

@ -1,13 +1,15 @@
package io.sc.platform.jdbc.exporter; package io.sc.platform.jdbc.exporter;
import io.sc.platform.core.support.ProgressInfo;
import io.sc.platform.jdbc.exporter.support.SchemaExportConfigure; import io.sc.platform.jdbc.exporter.support.SchemaExportConfigure;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale;
import java.util.ServiceLoader; import java.util.ServiceLoader;
public interface SchemaExporter { public interface SchemaExporter {
public void export(DataSource dataSource, SchemaExportConfigure configure); public void export(DataSource dataSource, SchemaExportConfigure configure, ProgressInfo progressInfo, Locale locale);
public static SchemaExporter newInstance(){ public static SchemaExporter newInstance(){
ServiceLoader<SchemaExporter> serviceLoader =ServiceLoader.load(SchemaExporter.class); ServiceLoader<SchemaExporter> serviceLoader =ServiceLoader.load(SchemaExporter.class);

2
io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/service/JdbcDataService.java

@ -3,6 +3,7 @@ package io.sc.platform.jdbc.service;
import io.sc.platform.core.support.ProgressInfo; import io.sc.platform.core.support.ProgressInfo;
import io.sc.platform.jdbc.exporter.support.DataExportConfigure; import io.sc.platform.jdbc.exporter.support.DataExportConfigure;
import io.sc.platform.jdbc.exporter.support.DataImportConfigure; import io.sc.platform.jdbc.exporter.support.DataImportConfigure;
import io.sc.platform.jdbc.exporter.support.SchemaExportConfigure;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -11,4 +12,5 @@ import java.util.Locale;
public interface JdbcDataService { public interface JdbcDataService {
public void importData(DataImportConfigure configure, ProgressInfo progressInfo, Locale locale) throws Exception; public void importData(DataImportConfigure configure, ProgressInfo progressInfo, Locale locale) throws Exception;
public void exportData(DataExportConfigure configure, ProgressInfo progressInfo, Locale locale) throws Exception; public void exportData(DataExportConfigure configure, ProgressInfo progressInfo, Locale locale) throws Exception;
public void exportSchema(SchemaExportConfigure configure, ProgressInfo progressInfo, Locale locale) throws Exception;
} }

16
io.sc.platform.jdbc/src/main/java/io/sc/platform/jdbc/service/impl/JdbcDataServiceImpl.java

@ -2,8 +2,10 @@ package io.sc.platform.jdbc.service.impl;
import io.sc.platform.core.support.ProgressInfo; import io.sc.platform.core.support.ProgressInfo;
import io.sc.platform.jdbc.exporter.DataExporter; import io.sc.platform.jdbc.exporter.DataExporter;
import io.sc.platform.jdbc.exporter.SchemaExporter;
import io.sc.platform.jdbc.exporter.support.DataExportConfigure; import io.sc.platform.jdbc.exporter.support.DataExportConfigure;
import io.sc.platform.jdbc.exporter.support.DataImportConfigure; import io.sc.platform.jdbc.exporter.support.DataImportConfigure;
import io.sc.platform.jdbc.exporter.support.SchemaExportConfigure;
import io.sc.platform.jdbc.importer.DataImporter; import io.sc.platform.jdbc.importer.DataImporter;
import io.sc.platform.jdbc.service.DatasourceService; import io.sc.platform.jdbc.service.DatasourceService;
import io.sc.platform.jdbc.service.JdbcDataService; import io.sc.platform.jdbc.service.JdbcDataService;
@ -45,4 +47,18 @@ public class JdbcDataServiceImpl implements JdbcDataService {
} }
DataExporter.newInstance().exportData(dataSource,configure,progressInfo,locale); DataExporter.newInstance().exportData(dataSource,configure,progressInfo,locale);
} }
@Override
public void exportSchema(SchemaExportConfigure configure, ProgressInfo progressInfo, Locale locale) throws Exception {
if(configure==null){
return;
}
DataSource dataSource =null;
if(StringUtils.hasText(configure.getDatasource())){
dataSource =datasourceService.getDatasource(configure.getDatasource());
}else{
dataSource =datasourceService.getDefaultDatasource();
}
SchemaExporter.newInstance().export(dataSource,configure,progressInfo,locale);
}
} }

Loading…
Cancel
Save