[Core] [Metadata] [Table] Support create table

This commit is contained in:
qianmoQ 2023-12-14 21:57:57 +08:00
parent 8f2ce41436
commit 3320481802
10 changed files with 144 additions and 32 deletions

View File

@ -2,6 +2,7 @@ package io.edurt.datacap.server.controller;
import io.edurt.datacap.common.response.CommonResponse;
import io.edurt.datacap.service.body.ExportBody;
import io.edurt.datacap.service.body.TableBody;
import io.edurt.datacap.service.body.TableFilter;
import io.edurt.datacap.service.entity.metadata.TableEntity;
import io.edurt.datacap.service.repository.metadata.TableRepository;
@ -54,4 +55,10 @@ public class TableController
{
return this.service.dataDownload(username, filename);
}
@PostMapping(value = "createTable/{id}")
public CommonResponse<Object> createTable(@PathVariable Long id, @RequestBody TableBody configure)
{
return this.service.createTable(id, configure);
}
}

View File

@ -98,5 +98,10 @@
<artifactId>datacap-captcha</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.edurt.datacap</groupId>
<artifactId>datacap-sql</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,23 @@
package io.edurt.datacap.service.body;
import io.edurt.datacap.sql.model.Column;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.List;
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class TableBody
{
private String name;
private String comment;
private String engine;
private List<Column> columns;
}

View File

@ -2,6 +2,7 @@ package io.edurt.datacap.service.service;
import io.edurt.datacap.common.response.CommonResponse;
import io.edurt.datacap.service.body.ExportBody;
import io.edurt.datacap.service.body.TableBody;
import io.edurt.datacap.service.body.TableFilter;
import io.edurt.datacap.service.entity.metadata.TableEntity;
@ -37,4 +38,6 @@ public interface TableService
CommonResponse exportDataById(Long id, ExportBody configure);
Object dataDownload(String username, String filename);
CommonResponse<Object> createTable(Long databaseId, TableBody configure);
}

View File

@ -16,6 +16,7 @@ import io.edurt.datacap.fs.Fs;
import io.edurt.datacap.fs.FsRequest;
import io.edurt.datacap.fs.FsResponse;
import io.edurt.datacap.service.body.ExportBody;
import io.edurt.datacap.service.body.TableBody;
import io.edurt.datacap.service.body.TableFilter;
import io.edurt.datacap.service.common.PluginUtils;
import io.edurt.datacap.service.entity.SourceEntity;
@ -24,6 +25,7 @@ import io.edurt.datacap.service.entity.metadata.ColumnEntity;
import io.edurt.datacap.service.entity.metadata.DatabaseEntity;
import io.edurt.datacap.service.entity.metadata.TableEntity;
import io.edurt.datacap.service.initializer.InitializerConfigure;
import io.edurt.datacap.service.repository.metadata.DatabaseRepository;
import io.edurt.datacap.service.repository.metadata.TableRepository;
import io.edurt.datacap.service.security.UserDetailsService;
import io.edurt.datacap.service.service.TableService;
@ -32,6 +34,7 @@ import io.edurt.datacap.spi.Plugin;
import io.edurt.datacap.spi.model.Configure;
import io.edurt.datacap.spi.model.Pagination;
import io.edurt.datacap.spi.model.Response;
import io.edurt.datacap.sql.builder.TableBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
@ -63,13 +66,15 @@ public class TableServiceImpl
{
private final Injector injector;
private final TableRepository repository;
private final DatabaseRepository databaseRepository;
private final InitializerConfigure initializerConfigure;
private final HttpServletRequest request;
public TableServiceImpl(Injector injector, TableRepository repository, InitializerConfigure initializerConfigure, HttpServletRequest request)
public TableServiceImpl(Injector injector, TableRepository repository, DatabaseRepository databaseRepository, InitializerConfigure initializerConfigure, HttpServletRequest request)
{
this.injector = injector;
this.repository = repository;
this.databaseRepository = databaseRepository;
this.initializerConfigure = initializerConfigure;
this.request = request;
}
@ -224,6 +229,29 @@ public class TableServiceImpl
}
}
@Override
public CommonResponse<Object> createTable(Long databaseId, TableBody configure)
{
Optional<DatabaseEntity> optionalDatabase = this.databaseRepository.findById(databaseId);
if (!optionalDatabase.isPresent()) {
return CommonResponse.failure(String.format("Database [ %s ] not found", databaseId));
}
DatabaseEntity database = optionalDatabase.get();
SourceEntity source = database.getSource();
Plugin plugin = PluginUtils.getPluginByNameAndType(this.injector, source.getType(), source.getProtocol()).get();
TableBuilder.Companion.BEGIN();
TableBuilder.Companion.CREATE_TABLE(String.format("`%s`.`%s`", database.getName(), configure.getName()));
TableBuilder.Companion.COLUMNS(configure.getColumns().stream().map(item -> item.toColumnVar()).collect(Collectors.toList()));
String sql = TableBuilder.Companion.SQL();
log.info("Create table sql \n {} \n on database [ {} ]", sql, database.getName());
plugin.connect(source.toConfigure());
Response response = plugin.execute(sql);
response.setContent(sql);
plugin.destroy();
return CommonResponse.success(response);
}
/**
* Fetches the selected data from the specified table in a database.
*

View File

@ -652,7 +652,7 @@ abstract class AbstractSql<T> {
StatementType.TRUNCATE -> truncateSQL(builder)
StatementType.DROP -> dropSQL(builder)
StatementType.CREATE_TABLE -> createTableSQL(builder)
else -> null
else -> throw SqlException("Unsupported statement type: [ $statementType ]")
}
return answer
}

View File

@ -5,6 +5,7 @@ export class DataStructureModel
title: null;
catalog: null;
database: null;
databaseId: null;
table: null;
applyId: null;
type: null;

View File

@ -68,6 +68,11 @@ class TableService
{
return new HttpCommon().post(`${baseUrl}/export/${id}`, configure);
}
createTable(databaseId: number, configure: any): Promise<ResponseModel>
{
return new HttpCommon().post(`${baseUrl}/createTable/${databaseId}`, configure);
}
}
export default new TableService();

View File

@ -308,11 +308,12 @@ export default defineComponent({
type: null;
engine: null;
comment: null;
database: { name: null };
database: { name: null, id: null };
}) => {
const structure = new DataStructureModel();
structure.title = item.name;
structure.database = item.database.name;
structure.databaseId = item.database.id;
structure.catalog = item.catalog;
structure.applyId = item.id;
structure.type = item.type;
@ -360,7 +361,7 @@ export default defineComponent({
engine: null;
isKey: null;
defaultValue: null;
table: { name: null, database: { name: null } };
table: { name: null, database: { name: null, id: null } };
}) => {
const structure = new DataStructureModel();
structure.title = item.name;

View File

@ -33,32 +33,57 @@
<FontAwesomeIcon icon="circle-plus"/>
</Button>
<template #content>
<FormItem :label="$t('source.manager.columnName')">
<Input v-model="item.name"/>
</FormItem>
<FormItem :label="$t('source.manager.columnType')">
<Input v-model="item.type"/>
</FormItem>
<FormItem :label="$t('source.manager.columnLength')">
<InputNumber v-model="item.length"/>
</FormItem>
<FormItem :label="$t('source.manager.columnComment')">
<Input v-model="item.comment"
type="textarea">
</Input>
</FormItem>
<FormItem :label="$t('source.manager.columnDefaultValue')">
<Input v-model="item.defaultValue"/>
</FormItem>
<FormItem :label="$t('source.manager.columnPrimaryKey')">
<Switch v-model="item.primaryKey"/>
</FormItem>
<FormItem :label="$t('source.manager.columnAutoIncrement')">
<Input v-model="item.autoIncrement"/>
</FormItem>
<FormItem :label="$t('source.manager.columnIsNullable')">
<Input v-model="item.isNullable"/>
</FormItem>
<Row>
<Col span="12">
<FormItem :label="$t('source.manager.columnName')"
:label-width="80">
<Input v-model="item.name"/>
</FormItem>
</Col>
<Col span="12">
<FormItem :label="$t('source.manager.columnType')"
:label-width="80">
<Input v-model="item.type"/>
</FormItem>
</Col>
<Col span="12">
<FormItem :label="$t('source.manager.columnLength')"
:label-width="80">
<InputNumber v-model="item.length"/>
</FormItem>
</Col>
<Col span="12">
<FormItem :label="$t('source.manager.columnDefaultValue')"
:label-width="80">
<Input v-model="item.defaultValue"/>
</FormItem>
</Col>
<Col span="12">
<FormItem :label="$t('source.manager.columnPrimaryKey')"
:label-width="80">
<Switch v-model="item.primaryKey"/>
</FormItem>
</Col>
<Col span="12">
<FormItem :label="$t('source.manager.columnAutoIncrement')"
:label-width="80">
<Switch v-model="item.autoIncrement"/>
</FormItem>
</Col>
<Col span="12">
<FormItem :label="$t('source.manager.columnIsNullable')">
<Switch v-model="item.isNullable"/>
</FormItem>
</Col>
<Col span="24">
<FormItem :label="$t('source.manager.columnComment')"
:label-width="80">
<Input v-model="item.comment"
type="textarea">
</Input>
</FormItem>
</Col>
</Row>
</template>
</Panel>
</Collapse>
@ -79,6 +104,7 @@
<script lang="ts">
import {defineComponent} from "vue";
import {DataStructureModel} from "@/model/DataStructure";
import TableService from "@/services/Table";
export default defineComponent({
name: "TableCreate",
@ -99,7 +125,7 @@ export default defineComponent({
name: null,
comment: null,
engine: null,
columns: [{name: 'column_name', type: null, length: 0, comment: null, defaultValue: null, primaryKey: null, autoIncrement: null, isNullable: null}]
columns: [{name: 'column_name', type: null, length: 0, comment: null, defaultValue: null, primaryKey: false, autoIncrement: null, isNullable: false}]
}
}
},
@ -107,10 +133,23 @@ export default defineComponent({
handlerSave()
{
this.loading = true;
TableService.createTable(this.data.databaseId, this.formState)
.then(response => {
if (response.data) {
if (response.data.isSuccessful) {
this.$Message.success(this.$t('common.success'));
this.handlerCancel();
}
else {
this.$Message.error(response.data?.message);
}
}
})
.finally(() => this.loading = false)
},
handlerAdd()
{
const newColumn = {name: 'column_name', type: null, length: 0, comment: null, defaultValue: null, primaryKey: null, autoIncrement: null, isNullable: null}
const newColumn = {name: 'column_name', type: null, length: 0, comment: null, defaultValue: null, primaryKey: false, autoIncrement: null, isNullable: false}
this.formState.columns.push(newColumn);
},
handlerRemove(index: number)