vran
3 years ago
26 changed files with 719 additions and 41 deletions
@ -1,4 +1,5 @@ |
|||||
.gradle/** |
.gradle/** |
||||
**/build/** |
**/build/** |
||||
.idea/** |
.idea/** |
||||
**/.DS_Store |
**/.DS_Store |
||||
|
drivers/** |
@ -0,0 +1,67 @@ |
|||||
|
package com.databasir.api; |
||||
|
|
||||
|
import com.databasir.common.JsonData; |
||||
|
import com.databasir.core.domain.database.data.*; |
||||
|
import com.databasir.core.domain.database.service.DatabaseTypeService; |
||||
|
import com.databasir.core.domain.log.annotation.Operation; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import org.springframework.data.domain.Page; |
||||
|
import org.springframework.data.domain.Pageable; |
||||
|
import org.springframework.data.web.PageableDefault; |
||||
|
import org.springframework.validation.annotation.Validated; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
|
import javax.validation.Valid; |
||||
|
import java.util.List; |
||||
|
import java.util.Optional; |
||||
|
|
||||
|
import static org.springframework.data.domain.Sort.Direction.DESC; |
||||
|
|
||||
|
@RequiredArgsConstructor |
||||
|
@Validated |
||||
|
@RestController |
||||
|
public class DatabaseTypeController { |
||||
|
|
||||
|
private final DatabaseTypeService databaseTypeService; |
||||
|
|
||||
|
@GetMapping(Routes.DatabaseType.LIST_SIMPLE) |
||||
|
public JsonData<List<String>> listSimpleDatabaseTypes() { |
||||
|
List<String> types = databaseTypeService.listSimpleDatabaseTypes(); |
||||
|
return JsonData.ok(types); |
||||
|
} |
||||
|
|
||||
|
@GetMapping(Routes.DatabaseType.LIST_PAGE) |
||||
|
public JsonData<Page<DatabaseTypePageResponse>> listPage(@PageableDefault(sort = "id", direction = DESC) |
||||
|
Pageable page, |
||||
|
DatabaseTypePageCondition condition) { |
||||
|
Page<DatabaseTypePageResponse> data = databaseTypeService.findByPage(page, condition); |
||||
|
return JsonData.ok(data); |
||||
|
} |
||||
|
|
||||
|
@PostMapping(Routes.DatabaseType.CREATE) |
||||
|
@Operation(module = Operation.Modules.DATABASE_TYPE, name = "创建数据库类型") |
||||
|
public JsonData<Integer> create(@RequestBody @Valid DatabaseTypeCreateRequest request) { |
||||
|
Integer id = databaseTypeService.create(request); |
||||
|
return JsonData.ok(id); |
||||
|
} |
||||
|
|
||||
|
@PatchMapping(Routes.DatabaseType.UPDATE) |
||||
|
@Operation(module = Operation.Modules.DATABASE_TYPE, name = "更新数据库类型") |
||||
|
public JsonData<Void> update(@RequestBody @Valid DatabaseTypeUpdateRequest request) { |
||||
|
databaseTypeService.update(request); |
||||
|
return JsonData.ok(); |
||||
|
} |
||||
|
|
||||
|
@DeleteMapping(Routes.DatabaseType.DELETE_ONE) |
||||
|
@Operation(module = Operation.Modules.DATABASE_TYPE, name = "删除数据库类型") |
||||
|
public JsonData<Void> delete(@PathVariable Integer id) { |
||||
|
databaseTypeService.deleteById(id); |
||||
|
return JsonData.ok(); |
||||
|
} |
||||
|
|
||||
|
@GetMapping(Routes.DatabaseType.GET_ONE) |
||||
|
public JsonData<DatabaseTypeDetailResponse> getOne(@PathVariable Integer id) { |
||||
|
Optional<DatabaseTypeDetailResponse> data = databaseTypeService.selectOne(id); |
||||
|
return JsonData.ok(data); |
||||
|
} |
||||
|
} |
@ -1,10 +1,11 @@ |
|||||
server.port=8080 |
|
||||
logging.level.org.jooq=INFO |
logging.level.org.jooq=INFO |
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver |
|
||||
spring.datasource.username=root |
|
||||
spring.datasource.password=123456 |
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/databasir |
|
||||
spring.jooq.sql-dialect=mysql |
spring.jooq.sql-dialect=mysql |
||||
|
# flyway |
||||
spring.flyway.enabled=true |
spring.flyway.enabled=true |
||||
spring.flyway.baseline-on-migrate=true |
spring.flyway.baseline-on-migrate=true |
||||
spring.flyway.locations=classpath:db/migration |
spring.flyway.locations=classpath:db/migration |
||||
|
# db |
||||
|
databasir.db.url=localhost:3306 |
||||
|
databasir.db.username=root |
||||
|
databasir.db.password=123456 |
||||
|
databasir.db.driver-directory=drivers |
@ -0,0 +1,32 @@ |
|||||
|
package com.databasir.core.config; |
||||
|
|
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.http.client.ClientHttpRequestFactory; |
||||
|
import org.springframework.http.client.SimpleClientHttpRequestFactory; |
||||
|
import org.springframework.http.converter.StringHttpMessageConverter; |
||||
|
import org.springframework.web.client.RestTemplate; |
||||
|
|
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
|
||||
|
@Configuration |
||||
|
public class RestTemplateConfig { |
||||
|
|
||||
|
@Bean |
||||
|
public RestTemplate restTemplate(ClientHttpRequestFactory factory) { |
||||
|
RestTemplate restTemplate = new RestTemplate(factory); |
||||
|
// 支持中文编码
|
||||
|
restTemplate.getMessageConverters().set(1, |
||||
|
new StringHttpMessageConverter(StandardCharsets.UTF_8)); |
||||
|
return restTemplate; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
@Bean |
||||
|
public ClientHttpRequestFactory simpleClientHttpRequestFactory() { |
||||
|
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); |
||||
|
factory.setReadTimeout(1000 * 30);//单位为ms
|
||||
|
factory.setConnectTimeout(1000 * 5);//单位为ms
|
||||
|
return factory; |
||||
|
} |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
package com.databasir.core.domain.database.converter; |
||||
|
|
||||
|
import com.databasir.core.domain.database.data.DatabaseTypeCreateRequest; |
||||
|
import com.databasir.core.domain.database.data.DatabaseTypeDetailResponse; |
||||
|
import com.databasir.core.domain.database.data.DatabaseTypePageResponse; |
||||
|
import com.databasir.core.domain.database.data.DatabaseTypeUpdateRequest; |
||||
|
import com.databasir.dao.tables.pojos.DatabaseTypePojo; |
||||
|
import org.mapstruct.Mapper; |
||||
|
|
||||
|
@Mapper(componentModel = "spring") |
||||
|
public interface DatabaseTypePojoConverter { |
||||
|
|
||||
|
DatabaseTypePojo of(DatabaseTypeCreateRequest request); |
||||
|
|
||||
|
DatabaseTypePojo of(DatabaseTypeUpdateRequest request); |
||||
|
|
||||
|
DatabaseTypeDetailResponse toDetailResponse(DatabaseTypePojo data); |
||||
|
|
||||
|
DatabaseTypePageResponse toPageResponse(DatabaseTypePojo pojo, Integer projectCount); |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
package com.databasir.core.domain.database.data; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import javax.validation.constraints.NotBlank; |
||||
|
|
||||
|
@Data |
||||
|
public class DatabaseTypeCreateRequest { |
||||
|
|
||||
|
@NotBlank |
||||
|
private String databaseType; |
||||
|
|
||||
|
private String icon; |
||||
|
|
||||
|
@NotBlank |
||||
|
private String description; |
||||
|
|
||||
|
@NotBlank |
||||
|
private String jdbcDriverFileUrl; |
||||
|
|
||||
|
@NotBlank |
||||
|
private String jdbcDriverClassName; |
||||
|
|
||||
|
@NotBlank |
||||
|
private String jdbcProtocol; |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
package com.databasir.core.domain.database.data; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.time.LocalDateTime; |
||||
|
|
||||
|
@Data |
||||
|
public class DatabaseTypeDetailResponse { |
||||
|
|
||||
|
private Integer id; |
||||
|
|
||||
|
private String databaseType; |
||||
|
|
||||
|
private String icon; |
||||
|
|
||||
|
private String description; |
||||
|
|
||||
|
private String jdbcDriverFileUrl; |
||||
|
|
||||
|
private String jdbcDriverClassName; |
||||
|
|
||||
|
private String jdbcProtocol; |
||||
|
|
||||
|
private Boolean deleted; |
||||
|
|
||||
|
private Integer deletedToken; |
||||
|
|
||||
|
private LocalDateTime updateAt; |
||||
|
|
||||
|
private LocalDateTime createAt; |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
package com.databasir.core.domain.database.data; |
||||
|
|
||||
|
import com.databasir.dao.Tables; |
||||
|
import lombok.Data; |
||||
|
import org.jooq.Condition; |
||||
|
import org.jooq.impl.DSL; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Data |
||||
|
public class DatabaseTypePageCondition { |
||||
|
|
||||
|
private String databaseTypeContains; |
||||
|
|
||||
|
public Condition toCondition() { |
||||
|
List<Condition> conditions = new ArrayList<>(); |
||||
|
conditions.add(Tables.DATABASE_TYPE.DELETED.eq(false)); |
||||
|
if (databaseTypeContains != null && !databaseTypeContains.trim().equals("")) { |
||||
|
conditions.add(Tables.DATABASE_TYPE.DATABASE_TYPE_.containsIgnoreCase(databaseTypeContains)); |
||||
|
} |
||||
|
return conditions.stream() |
||||
|
.reduce(Condition::and) |
||||
|
.orElse(DSL.trueCondition()); |
||||
|
} |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
package com.databasir.core.domain.database.data; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.time.LocalDateTime; |
||||
|
|
||||
|
@Data |
||||
|
public class DatabaseTypePageResponse { |
||||
|
|
||||
|
private Integer id; |
||||
|
|
||||
|
private String databaseType; |
||||
|
|
||||
|
private String icon; |
||||
|
|
||||
|
private String description; |
||||
|
|
||||
|
private String jdbcDriverFileUrl; |
||||
|
|
||||
|
private String jdbcDriverClassName; |
||||
|
|
||||
|
private String jdbcProtocol; |
||||
|
|
||||
|
private Boolean deleted; |
||||
|
|
||||
|
private Integer deletedToken; |
||||
|
|
||||
|
private Integer projectCount; |
||||
|
|
||||
|
private LocalDateTime updateAt; |
||||
|
|
||||
|
private LocalDateTime createAt; |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
package com.databasir.core.domain.database.data; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import javax.validation.constraints.NotBlank; |
||||
|
import javax.validation.constraints.NotNull; |
||||
|
|
||||
|
@Data |
||||
|
public class DatabaseTypeUpdateRequest { |
||||
|
|
||||
|
@NotNull |
||||
|
private Integer id; |
||||
|
|
||||
|
@NotBlank |
||||
|
private String databaseType; |
||||
|
|
||||
|
private String icon; |
||||
|
|
||||
|
@NotBlank |
||||
|
private String description; |
||||
|
|
||||
|
@NotBlank |
||||
|
private String jdbcDriverFileUrl; |
||||
|
|
||||
|
@NotBlank |
||||
|
private String jdbcDriverClassName; |
||||
|
|
||||
|
@NotBlank |
||||
|
private String jdbcProtocol; |
||||
|
} |
@ -0,0 +1,103 @@ |
|||||
|
package com.databasir.core.domain.database.service; |
||||
|
|
||||
|
import com.databasir.core.domain.DomainErrors; |
||||
|
import com.databasir.core.domain.database.converter.DatabaseTypePojoConverter; |
||||
|
import com.databasir.core.domain.database.data.*; |
||||
|
import com.databasir.core.infrastructure.connection.DatabaseTypes; |
||||
|
import com.databasir.core.infrastructure.driver.DriverResources; |
||||
|
import com.databasir.dao.impl.DatabaseTypeDao; |
||||
|
import com.databasir.dao.impl.ProjectDao; |
||||
|
import com.databasir.dao.tables.pojos.DatabaseTypePojo; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.dao.DuplicateKeyException; |
||||
|
import org.springframework.data.domain.Page; |
||||
|
import org.springframework.data.domain.Pageable; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Objects; |
||||
|
import java.util.Optional; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
@Service |
||||
|
@RequiredArgsConstructor |
||||
|
@Slf4j |
||||
|
public class DatabaseTypeService { |
||||
|
|
||||
|
private final DriverResources driverResources; |
||||
|
|
||||
|
private final DatabaseTypeDao databaseTypeDao; |
||||
|
|
||||
|
private final ProjectDao projectDao; |
||||
|
|
||||
|
private final DatabaseTypePojoConverter databaseTypePojoConverter; |
||||
|
|
||||
|
public Integer create(DatabaseTypeCreateRequest request) { |
||||
|
DatabaseTypePojo pojo = databaseTypePojoConverter.of(request); |
||||
|
try { |
||||
|
return databaseTypeDao.insertAndReturnId(pojo); |
||||
|
} catch (DuplicateKeyException e) { |
||||
|
throw DomainErrors.DATABASE_TYPE_NAME_DUPLICATE.exception(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Transactional |
||||
|
public void update(DatabaseTypeUpdateRequest request) { |
||||
|
databaseTypeDao.selectOptionalById(request.getId()).ifPresent(data -> { |
||||
|
if (DatabaseTypes.has(data.getDatabaseType())) { |
||||
|
throw DomainErrors.MUST_NOT_MODIFY_SYSTEM_DEFAULT_DATABASE_TYPE.exception(); |
||||
|
} |
||||
|
|
||||
|
DatabaseTypePojo pojo = databaseTypePojoConverter.of(request); |
||||
|
try { |
||||
|
databaseTypeDao.updateById(pojo); |
||||
|
} catch (DuplicateKeyException e) { |
||||
|
throw DomainErrors.DATABASE_TYPE_NAME_DUPLICATE.exception(); |
||||
|
} |
||||
|
|
||||
|
// 名称修改,下载地址修改需要删除原有的 driver
|
||||
|
if (!Objects.equals(request.getDatabaseType(), data.getDatabaseType()) |
||||
|
|| !Objects.equals(request.getJdbcDriverFileUrl(), data.getJdbcDriverFileUrl())) { |
||||
|
driverResources.delete(data.getDatabaseType()); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void deleteById(Integer id) { |
||||
|
databaseTypeDao.selectOptionalById(id).ifPresent(data -> { |
||||
|
if (DatabaseTypes.has(data.getDatabaseType())) { |
||||
|
throw DomainErrors.MUST_NOT_MODIFY_SYSTEM_DEFAULT_DATABASE_TYPE.exception(); |
||||
|
} |
||||
|
databaseTypeDao.deleteById(id); |
||||
|
driverResources.delete(data.getDatabaseType()); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public Page<DatabaseTypePageResponse> findByPage(Pageable page, |
||||
|
DatabaseTypePageCondition condition) { |
||||
|
Page<DatabaseTypePojo> pageData = databaseTypeDao.selectByPage(page, condition.toCondition()); |
||||
|
List<String> databaseTypes = pageData.map(DatabaseTypePojo::getDatabaseType).toList(); |
||||
|
Map<String, Integer> projectCountMapByDatabaseType = projectDao.countByDatabaseTypes(databaseTypes); |
||||
|
return pageData |
||||
|
.map(data -> { |
||||
|
Integer count = projectCountMapByDatabaseType.getOrDefault(data.getDatabaseType(), 0); |
||||
|
return databaseTypePojoConverter.toPageResponse(data, count); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public List<String> listSimpleDatabaseTypes() { |
||||
|
return databaseTypeDao.selectAll() |
||||
|
.stream() |
||||
|
.map(DatabaseTypePojo::getDatabaseType) |
||||
|
.collect(Collectors.toList()); |
||||
|
} |
||||
|
|
||||
|
public Optional<DatabaseTypeDetailResponse> selectOne(Integer id) { |
||||
|
return databaseTypeDao.selectOptionalById(id) |
||||
|
.map(databaseTypePojoConverter::toDetailResponse); |
||||
|
} |
||||
|
} |
@ -0,0 +1,80 @@ |
|||||
|
package com.databasir.core.infrastructure.connection; |
||||
|
|
||||
|
import com.databasir.core.domain.DomainErrors; |
||||
|
import com.databasir.core.infrastructure.driver.DriverResources; |
||||
|
import com.databasir.dao.impl.DatabaseTypeDao; |
||||
|
import com.databasir.dao.tables.pojos.DatabaseTypePojo; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.io.File; |
||||
|
import java.io.IOException; |
||||
|
import java.lang.reflect.InvocationTargetException; |
||||
|
import java.net.MalformedURLException; |
||||
|
import java.net.URL; |
||||
|
import java.net.URLClassLoader; |
||||
|
import java.sql.Connection; |
||||
|
import java.sql.Driver; |
||||
|
import java.sql.SQLException; |
||||
|
import java.util.Properties; |
||||
|
|
||||
|
@Component |
||||
|
@RequiredArgsConstructor |
||||
|
@Slf4j |
||||
|
public class CustomDatabaseConnectionFactory implements DatabaseConnectionFactory { |
||||
|
|
||||
|
private final DatabaseTypeDao databaseTypeDao; |
||||
|
|
||||
|
private final DriverResources driverResources; |
||||
|
|
||||
|
@Override |
||||
|
public boolean support(String databaseType) { |
||||
|
return databaseTypeDao.existsByDatabaseType(databaseType); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Connection getConnection(Context context) throws SQLException { |
||||
|
DatabaseTypePojo type = databaseTypeDao.selectByDatabaseType(context.getDatabaseType()); |
||||
|
File driverFile; |
||||
|
try { |
||||
|
driverFile = driverResources.download(context.getDatabaseType(), type.getJdbcDriverFileUrl()); |
||||
|
} catch (IOException e) { |
||||
|
log.error("download driver error " + context, e); |
||||
|
throw DomainErrors.DOWNLOAD_DRIVER_ERROR.exception(e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
URLClassLoader loader = null; |
||||
|
try { |
||||
|
loader = new URLClassLoader( |
||||
|
new URL[]{ |
||||
|
driverFile.toURI().toURL() |
||||
|
}, |
||||
|
this.getClass().getClassLoader() |
||||
|
); |
||||
|
} catch (MalformedURLException e) { |
||||
|
log.error("load driver error " + context, e); |
||||
|
throw DomainErrors.CONNECT_DATABASE_FAILED.exception(e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
Class<?> clazz = null; |
||||
|
Driver driver = null; |
||||
|
try { |
||||
|
clazz = Class.forName(type.getJdbcDriverClassName(), true, loader); |
||||
|
driver = (Driver) clazz.getConstructor().newInstance(); |
||||
|
} catch (ClassNotFoundException e) { |
||||
|
log.error("init driver error", e); |
||||
|
throw DomainErrors.CONNECT_DATABASE_FAILED.exception("驱动初始化异常, 请检查 Driver name:" + e.getMessage()); |
||||
|
} catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) { |
||||
|
log.error("init driver error", e); |
||||
|
throw DomainErrors.CONNECT_DATABASE_FAILED.exception("驱动初始化异常:" + e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
Properties info = new Properties(); |
||||
|
info.put("user", context.getUsername()); |
||||
|
info.put("password", context.getPassword()); |
||||
|
String jdbcUrl = type.getJdbcProtocol() + "://" + context.getUrl() + "/" + context.getSchema(); |
||||
|
return driver.connect(jdbcUrl, info); |
||||
|
} |
||||
|
|
||||
|
} |
@ -1,10 +1,19 @@ |
|||||
package com.databasir.core.infrastructure.connection; |
package com.databasir.core.infrastructure.connection; |
||||
|
|
||||
|
import java.util.Objects; |
||||
|
|
||||
public interface DatabaseTypes { |
public interface DatabaseTypes { |
||||
|
|
||||
String MYSQL = "mysql"; |
String MYSQL = "mysql"; |
||||
|
|
||||
String POSTGRESQL = "postgresql"; |
String POSTGRESQL = "postgresql"; |
||||
|
|
||||
String ORACLE = "oracle"; |
static boolean has(String name) { |
||||
|
if (name == null) { |
||||
|
return false; |
||||
|
} |
||||
|
return Objects.equals(MYSQL, name.toLowerCase()) |
||||
|
|| Objects.equals(POSTGRESQL, name.toLowerCase()); |
||||
|
} |
||||
|
|
||||
} |
} |
||||
|
@ -0,0 +1,84 @@ |
|||||
|
package com.databasir.core.infrastructure.driver; |
||||
|
|
||||
|
import com.databasir.core.domain.DomainErrors; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.http.HttpMethod; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.util.StreamUtils; |
||||
|
import org.springframework.web.client.RestTemplate; |
||||
|
|
||||
|
import java.io.File; |
||||
|
import java.io.FileOutputStream; |
||||
|
import java.io.IOException; |
||||
|
import java.nio.file.Files; |
||||
|
import java.nio.file.Path; |
||||
|
import java.nio.file.Paths; |
||||
|
|
||||
|
@Component |
||||
|
@Slf4j |
||||
|
@RequiredArgsConstructor |
||||
|
public class DriverResources { |
||||
|
|
||||
|
@Value("${databasir.db.driver-directory}") |
||||
|
private String driverBaseDirectory; |
||||
|
|
||||
|
private final RestTemplate restTemplate; |
||||
|
|
||||
|
public File download(String databaseType, String driverFileUrl) throws IOException { |
||||
|
// create parent directory
|
||||
|
if (Files.notExists(Path.of(driverBaseDirectory))) { |
||||
|
Files.createDirectory(Path.of(driverBaseDirectory)); |
||||
|
} |
||||
|
|
||||
|
String filePath = driverPath(databaseType); |
||||
|
Path path = Path.of(filePath); |
||||
|
if (Files.exists(path)) { |
||||
|
// ignore
|
||||
|
log.debug("{} already exists, ignore download from {}", filePath, driverFileUrl); |
||||
|
return path.toFile(); |
||||
|
} else { |
||||
|
// download
|
||||
|
try { |
||||
|
return restTemplate.execute(driverFileUrl, HttpMethod.GET, null, response -> { |
||||
|
if (response.getStatusCode().is2xxSuccessful()) { |
||||
|
File file = path.toFile(); |
||||
|
StreamUtils.copy(response.getBody(), new FileOutputStream(file)); |
||||
|
log.info("{} download success ", filePath); |
||||
|
return file; |
||||
|
} else { |
||||
|
log.error("{} download error from {}: {} ", filePath, driverFileUrl, response); |
||||
|
throw DomainErrors.DOWNLOAD_DRIVER_ERROR.exception("驱动下载失败:" |
||||
|
+ response.getStatusCode() |
||||
|
+ ", " |
||||
|
+ response.getStatusText()); |
||||
|
} |
||||
|
}); |
||||
|
} catch (IllegalArgumentException e) { |
||||
|
log.error(filePath + " download driver error", e); |
||||
|
throw DomainErrors.DOWNLOAD_DRIVER_ERROR.exception(e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void delete(String databaseType) { |
||||
|
Path path = Paths.get(driverPath(databaseType)); |
||||
|
try { |
||||
|
Files.deleteIfExists(path); |
||||
|
} catch (IOException e) { |
||||
|
log.error("delete driver error " + databaseType, e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private String driverPath(String databaseType) { |
||||
|
String fileName = databaseType + ".jar"; |
||||
|
String filePath; |
||||
|
if (driverBaseDirectory.endsWith(File.separator)) { |
||||
|
filePath = driverBaseDirectory + fileName; |
||||
|
} else { |
||||
|
filePath = driverBaseDirectory + File.separator + fileName; |
||||
|
} |
||||
|
return filePath; |
||||
|
} |
||||
|
} |
@ -1,5 +0,0 @@ |
|||||
package com.databasir.core.infrastructure.meta; |
|
||||
|
|
||||
public class DatabaseMetaResolver { |
|
||||
|
|
||||
} |
|
@ -0,0 +1,61 @@ |
|||||
|
package com.databasir.dao.impl; |
||||
|
|
||||
|
import com.databasir.dao.tables.pojos.DatabaseTypePojo; |
||||
|
import lombok.Getter; |
||||
|
import org.jooq.DSLContext; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Repository; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Optional; |
||||
|
|
||||
|
import static com.databasir.dao.Tables.DATABASE_TYPE; |
||||
|
|
||||
|
@Repository |
||||
|
public class DatabaseTypeDao extends BaseDao<DatabaseTypePojo> { |
||||
|
|
||||
|
@Autowired |
||||
|
@Getter |
||||
|
private DSLContext dslContext; |
||||
|
|
||||
|
public DatabaseTypeDao() { |
||||
|
super(DATABASE_TYPE, DatabaseTypePojo.class); |
||||
|
} |
||||
|
|
||||
|
public boolean existsByDatabaseType(String databaseType) { |
||||
|
return exists(DATABASE_TYPE.DATABASE_TYPE_.eq(databaseType) |
||||
|
.and(DATABASE_TYPE.DELETED.eq(false))); |
||||
|
} |
||||
|
|
||||
|
public boolean existsById(Integer id) { |
||||
|
return exists(DATABASE_TYPE.ID.eq(id) |
||||
|
.and(DATABASE_TYPE.DELETED.eq(false))); |
||||
|
} |
||||
|
|
||||
|
public DatabaseTypePojo selectByDatabaseType(String databaseType) { |
||||
|
return this.selectOne(DATABASE_TYPE.DATABASE_TYPE_.eq(databaseType) |
||||
|
.and(DATABASE_TYPE.DELETED.eq(false))); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<DatabaseTypePojo> selectAll() { |
||||
|
return this.getDslContext().selectFrom(DATABASE_TYPE) |
||||
|
.where(DATABASE_TYPE.DELETED.eq(false)) |
||||
|
.orderBy(DATABASE_TYPE.ID.desc()) |
||||
|
.fetchInto(DatabaseTypePojo.class); |
||||
|
} |
||||
|
|
||||
|
public int deleteById(Integer id) { |
||||
|
return this.getDslContext() |
||||
|
.update(DATABASE_TYPE) |
||||
|
.set(DATABASE_TYPE.DELETED, true) |
||||
|
.set(DATABASE_TYPE.DELETED_TOKEN, DATABASE_TYPE.ID) |
||||
|
.where(DATABASE_TYPE.ID.eq(id) |
||||
|
.and(DATABASE_TYPE.DELETED.eq(false))) |
||||
|
.execute(); |
||||
|
} |
||||
|
|
||||
|
public Optional<DatabaseTypePojo> selectOptionalById(Integer id) { |
||||
|
return super.selectOptionalOne(DATABASE_TYPE.DELETED.eq(false).and(DATABASE_TYPE.ID.eq(id))); |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue