From efc3a90026d7e44af75109b6ef66b3c509edb503 Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Mon, 11 Sep 2023 17:33:03 +0800
Subject: [PATCH 01/16] =?UTF-8?q?add:=20=E6=96=B0=E5=A2=9E=E5=AF=B9easy-or?=
=?UTF-8?q?m=E5=AF=B9clickhouse=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 112 +++++++++++++
...lickhouseHttpSqlExecutorConfiguration.java | 40 +++++
hsweb-commons-crud/ClickhouseProperties.java | 22 +++
hsweb-commons-crud/EasyormProperties.java | 122 ++++++++++++++
.../clickhouse/ClickhouseDialect.java | 83 ++++++++++
.../ClickhouseRestfulSqlExecutor.java | 135 ++++++++++++++++
.../clickhouse/ClickhouseSchemaMetadata.java | 53 +++++++
.../ClickhouseTableMetadataParser.java | 75 +++++++++
.../ClickhouseDeleteSqlBuilder.java | 87 ++++++++++
.../ClickhouseUpdateSqlBuilder.java | 150 ++++++++++++++++++
10 files changed, 879 insertions(+)
create mode 100644 README.md
create mode 100644 hsweb-commons-crud/ClickhouseHttpSqlExecutorConfiguration.java
create mode 100644 hsweb-commons-crud/ClickhouseProperties.java
create mode 100644 hsweb-commons-crud/EasyormProperties.java
create mode 100644 hsweb-easy-orm/clickhouse/ClickhouseDialect.java
create mode 100644 hsweb-easy-orm/clickhouse/ClickhouseRestfulSqlExecutor.java
create mode 100644 hsweb-easy-orm/clickhouse/ClickhouseSchemaMetadata.java
create mode 100644 hsweb-easy-orm/clickhouse/ClickhouseTableMetadataParser.java
create mode 100644 hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java
create mode 100644 hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..801e082
--- /dev/null
+++ b/README.md
@@ -0,0 +1,112 @@
+# 说明
+
+1. 本仓库需要配合[hsweb-easy-orm](https://github.com/hs-web/hsweb-easy-orm),[hsweb-framework](https://github.com/hs-web/hsweb-framework)使用
+2. 本仓库是针对hsweb-easy-orm 4.X、hsweb-commons-curd 4.X 适配 clickhouse22.X
+
+# 使用
+
+## hsweb-easy-orm编译
+
+1. 首先克隆[hsweb-easy-orm](https://github.com/hs-web/hsweb-easy-orm)至本地
+
+2. hsweb-easy-orm的pom文件中新增依赖
+
+ ```xml
+
+ org.springframework
+ spring-webflux
+ 5.3.25
+
+ ```
+
+3. 将本项目中hsweb-easy-orm的clickhouse目录复制到hsweb-easy-orm的org.hswebframework.ezorm.rdb.supports下,复制后包路径应是org.hswebframework.ezorm.rdb.supports.clickhouse
+
+4. hsweb-easy-orm-rdb\src\main\java\org\hswebframework\ezorm\rdb\metadata\dialect\Dialect.java中新增数据库方言如下
+
+ ```java
+ Dialect CLICKHOUSE =new ClickhouseDialect();
+ ```
+
+5. maven编译
+
+## hsweb-commons-curd编译
+
+1. 首先克隆[hsweb-framework](https://github.com/hs-web/hsweb-framework)至本地
+
+2. 将本项目中hsweb-commons-curd文件夹下ClickhouseHttpSqlExecutorConfiguration.java 、ClickhouseProperties.java放置在hsweb-framework/hsweb-commons-curd模块中org.hswebframework.web.crud.configuration路径下。
+
+3. 在org.hswebframework.web.crud.configuration.EasyormProperties.java文件中插入相关代码如下,**注意注释部分**
+
+ ```java
+
+ @Getter
+ @AllArgsConstructor
+ public enum DialectEnum {
+ mysql(Dialect.MYSQL, "?") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new MysqlSchemaMetadata(name);
+ }
+ },
+ mssql(Dialect.MSSQL, "@arg") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new SqlServerSchemaMetadata(name);
+ }
+ },
+ oracle(Dialect.ORACLE, "?") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new OracleSchemaMetadata(name);
+ }
+ },
+ postgres(Dialect.POSTGRES, "$") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new PostgresqlSchemaMetadata(name);
+ }
+ },
+ h2(Dialect.H2, "$") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new H2SchemaMetadata(name);
+ }
+ }
+ //start
+ //这里是对clickhouse的支持
+ ,
+ clickhouse(Dialect.CLICKHOUSE,"?"){
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new ClickhouseSchemaMetadata(name);
+ }
+ }
+ //end
+ ;
+
+ private Dialect dialect;
+ private String bindSymbol;
+
+ public abstract RDBSchemaMetadata createSchema(String name);
+ ```
+
+4. hsweb-framework/hsweb-commons-curd模块的src/main/resources/META-INF/spring.factories中新增org.hswebframework.web.crud.configuration.ClickhouseHttpSqlExecutorConfiguration,示例如下
+
+ ```
+ # Auto Configure
+ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ org.hswebframework.web.crud.configuration.EasyormConfiguration,\
+ org.hswebframework.web.crud.configuration.JdbcSqlExecutorConfiguration,\
+ org.hswebframework.web.crud.configuration.R2dbcSqlExecutorConfiguration,\
+ org.hswebframework.web.crud.configuration.ClickhouseHttpSqlExecutorConfiguration,\
+ org.hswebframework.web.crud.web.CommonWebFluxConfiguration,\
+ org.hswebframework.web.crud.web.CommonWebMvcConfiguration
+ ```
+
+5. maven编译
+
+# 注意
+
+1. 先编译hsweb-easy-orm再编译hsweb-commons-curd
+2. 编译hsweb-commons-curd时需注意依赖hsweb-easy-orm的版本。
+3. 由于clickhouse各版本系统表差异过大,本仓库暂只支持clickhouse22.X版本
\ No newline at end of file
diff --git a/hsweb-commons-crud/ClickhouseHttpSqlExecutorConfiguration.java b/hsweb-commons-crud/ClickhouseHttpSqlExecutorConfiguration.java
new file mode 100644
index 0000000..afb7364
--- /dev/null
+++ b/hsweb-commons-crud/ClickhouseHttpSqlExecutorConfiguration.java
@@ -0,0 +1,40 @@
+package org.hswebframework.web.crud.configuration;
+
+import org.hswebframework.ezorm.rdb.executor.SyncSqlExecutor;
+import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSqlExecutor;
+import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSyncSqlExecutor;
+import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseRestfulSqlExecutor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.client.WebClient;
+
+
+/**
+ * @author dengpengyu
+ */
+@Configuration
+@EnableConfigurationProperties(ClickhouseProperties.class)
+//@ConditionalOnMissingBean(ConnectionFactory.class)
+public class ClickhouseHttpSqlExecutorConfiguration {
+ @Bean
+ @ConditionalOnMissingBean
+ public ReactiveSqlExecutor reactiveSqlExecutor(ClickhouseProperties properties) {
+
+ WebClient clickhouseWebClient = WebClient
+ .builder()
+ .baseUrl(properties.getUrl())
+ .defaultHeader("X-ClickHouse-User", properties.getUsername())
+ .defaultHeader("X-ClickHouse-Key", properties.getPassword())
+ .build();
+
+ return new ClickhouseRestfulSqlExecutor(clickhouseWebClient);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public SyncSqlExecutor syncSqlExecutor(ReactiveSqlExecutor reactiveSqlExecutor) {
+ return ReactiveSyncSqlExecutor.of(reactiveSqlExecutor);
+ }
+}
\ No newline at end of file
diff --git a/hsweb-commons-crud/ClickhouseProperties.java b/hsweb-commons-crud/ClickhouseProperties.java
new file mode 100644
index 0000000..f99a48b
--- /dev/null
+++ b/hsweb-commons-crud/ClickhouseProperties.java
@@ -0,0 +1,22 @@
+package org.hswebframework.web.crud.configuration;
+
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author dengpengyu
+ * @date 2023/9/6 14:08
+ */
+@Data
+@ConfigurationProperties(prefix = "spring.clickhouse")
+@Component
+public class ClickhouseProperties {
+
+ private String url;
+
+ private String username;
+
+ private String password;
+}
diff --git a/hsweb-commons-crud/EasyormProperties.java b/hsweb-commons-crud/EasyormProperties.java
new file mode 100644
index 0000000..0cac45a
--- /dev/null
+++ b/hsweb-commons-crud/EasyormProperties.java
@@ -0,0 +1,122 @@
+package org.hswebframework.web.crud.configuration;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.SneakyThrows;
+import org.hswebframework.ezorm.rdb.metadata.RDBDatabaseMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
+import org.hswebframework.ezorm.rdb.metadata.dialect.Dialect;
+import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseSchemaMetadata;
+import org.hswebframework.ezorm.rdb.supports.h2.H2SchemaMetadata;
+import org.hswebframework.ezorm.rdb.supports.mssql.SqlServerSchemaMetadata;
+import org.hswebframework.ezorm.rdb.supports.mysql.MysqlSchemaMetadata;
+import org.hswebframework.ezorm.rdb.supports.oracle.OracleSchemaMetadata;
+import org.hswebframework.ezorm.rdb.supports.postgres.PostgresqlSchemaMetadata;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+@ConfigurationProperties(prefix = "easyorm")
+@Data
+public class EasyormProperties {
+
+ private String defaultSchema="PUBLIC";
+
+ private String[] schemas = {};
+
+ private boolean autoDdl = true;
+
+ private boolean allowAlter = false;
+
+ private boolean allowTypeAlter = true;
+
+ private DialectEnum dialect = DialectEnum.h2;
+
+ private Class extends Dialect> dialectType;
+
+ private Class extends RDBSchemaMetadata> schemaType;
+
+ public RDBDatabaseMetadata createDatabaseMetadata() {
+ RDBDatabaseMetadata metadata = new RDBDatabaseMetadata(createDialect());
+
+ Set schemaSet = new HashSet<>(Arrays.asList(schemas));
+ if (defaultSchema != null) {
+ schemaSet.add(defaultSchema);
+ }
+ schemaSet.stream()
+ .map(this::createSchema)
+ .forEach(metadata::addSchema);
+
+ metadata.getSchema(defaultSchema)
+ .ifPresent(metadata::setCurrentSchema);
+
+ return metadata;
+ }
+
+ @SneakyThrows
+ public RDBSchemaMetadata createSchema(String name) {
+ if (schemaType == null) {
+ return dialect.createSchema(name);
+ }
+ return schemaType.getConstructor(String.class).newInstance(name);
+ }
+
+ @SneakyThrows
+ public Dialect createDialect() {
+ if (dialectType == null) {
+ return dialect.getDialect();
+ }
+
+ return dialectType.newInstance();
+ }
+
+ @Getter
+ @AllArgsConstructor
+ public enum DialectEnum {
+ mysql(Dialect.MYSQL, "?") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new MysqlSchemaMetadata(name);
+ }
+ },
+ mssql(Dialect.MSSQL, "@arg") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new SqlServerSchemaMetadata(name);
+ }
+ },
+ oracle(Dialect.ORACLE, "?") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new OracleSchemaMetadata(name);
+ }
+ },
+ postgres(Dialect.POSTGRES, "$") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new PostgresqlSchemaMetadata(name);
+ }
+ },
+ h2(Dialect.H2, "$") {
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new H2SchemaMetadata(name);
+ }
+ },
+ clickhouse(Dialect.CLICKHOUSE,"?"){
+ @Override
+ public RDBSchemaMetadata createSchema(String name) {
+ return new ClickhouseSchemaMetadata(name);
+ }
+ }
+ ;
+
+ private Dialect dialect;
+ private String bindSymbol;
+
+ public abstract RDBSchemaMetadata createSchema(String name);
+ }
+}
diff --git a/hsweb-easy-orm/clickhouse/ClickhouseDialect.java b/hsweb-easy-orm/clickhouse/ClickhouseDialect.java
new file mode 100644
index 0000000..e150312
--- /dev/null
+++ b/hsweb-easy-orm/clickhouse/ClickhouseDialect.java
@@ -0,0 +1,83 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse;
+
+import org.hswebframework.ezorm.core.utils.StringUtils;
+import org.hswebframework.ezorm.rdb.metadata.DataType;
+import org.hswebframework.ezorm.rdb.metadata.JdbcDataType;
+import org.hswebframework.ezorm.rdb.metadata.dialect.DefaultDialect;
+
+import java.sql.Date;
+import java.sql.JDBCType;
+/**
+ * @className ClickhouseDire
+ * @Description TODO
+ * @Author dengpengyu
+ * @Date 2023/9/4 14:53
+ * @Vesion 1.0
+ */
+public class ClickhouseDialect extends DefaultDialect {
+
+ public ClickhouseDialect() {
+ super();
+ addDataTypeBuilder(JDBCType.CHAR, (meta) -> StringUtils.concat("char(", meta.getLength(), ")"));
+ addDataTypeBuilder(JDBCType.VARCHAR, (meta) -> StringUtils.concat("varchar(", meta.getLength(), ")"));
+ addDataTypeBuilder(JDBCType.NVARCHAR, (meta) -> StringUtils.concat("nvarchar(", meta.getLength(), ")"));
+
+ addDataTypeBuilder(JDBCType.TIMESTAMP, (meta) -> "datetime(" + Math.min(6, meta.getLength()) + ")");
+ addDataTypeBuilder(JDBCType.TIME, (meta) -> "time");
+ addDataTypeBuilder(JDBCType.DATE, (meta) -> "date");
+ addDataTypeBuilder(JDBCType.CLOB, (meta) -> "text");
+ addDataTypeBuilder(JDBCType.LONGVARBINARY, (meta) -> "blob");
+ addDataTypeBuilder(JDBCType.LONGVARCHAR, (meta) -> "longtext");
+ addDataTypeBuilder(JDBCType.BLOB, (meta) -> "blob");
+ addDataTypeBuilder(JDBCType.BIGINT, (meta) -> "bigint");
+ addDataTypeBuilder(JDBCType.DOUBLE, (meta) -> "double");
+ addDataTypeBuilder(JDBCType.INTEGER, (meta) -> "int");
+ addDataTypeBuilder(JDBCType.NUMERIC, (meta) -> StringUtils.concat("decimal(", meta.getPrecision(32), ",", meta.getScale(), ")"));
+ addDataTypeBuilder(JDBCType.DECIMAL, (meta) -> StringUtils.concat("decimal(", meta.getPrecision(32), ",", meta.getScale(), ")"));
+ addDataTypeBuilder(JDBCType.TINYINT, (meta) -> "tinyint");
+ addDataTypeBuilder(JDBCType.BOOLEAN, (meta) -> "tinyint");
+ addDataTypeBuilder(JDBCType.BIGINT, (meta) -> "bigint");
+ addDataTypeBuilder(JDBCType.OTHER, (meta) -> "other");
+ addDataTypeBuilder(JDBCType.LONGNVARCHAR, (meta) -> "text");
+
+ addDataTypeBuilder("int", (meta) -> "int");
+ addDataTypeBuilder("json", meta -> "json");
+
+ registerDataType("clob", DataType.builder(JdbcDataType.of(JDBCType.CLOB, String.class), c -> "text"));
+ registerDataType("longnvarchar", DataType.builder(JdbcDataType.of(JDBCType.LONGNVARCHAR, String.class), c -> "longtext"));
+ registerDataType("longvarchar", DataType.builder(JdbcDataType.of(JDBCType.LONGVARCHAR, String.class), c -> "longtext"));
+
+ registerDataType("int", JdbcDataType.of(JDBCType.INTEGER, Integer.class));
+ registerDataType("text", JdbcDataType.of(JDBCType.CLOB, String.class));
+ registerDataType("longtext", JdbcDataType.of(JDBCType.LONGVARCHAR, String.class));
+ registerDataType("year", JdbcDataType.of(JDBCType.DATE, Date.class));
+ registerDataType("text", JdbcDataType.of(JDBCType.CLOB, Date.class));
+ registerDataType("datetime", JdbcDataType.of(JDBCType.TIMESTAMP, Date.class));
+
+ }
+
+ @Override
+ public String getQuoteStart() {
+ return "`";
+ }
+
+ @Override
+ public String getQuoteEnd() {
+ return "`";
+ }
+
+ @Override
+ public boolean isColumnToUpperCase() {
+ return false;
+ }
+
+ @Override
+ public String getId() {
+ return "clickhouse";
+ }
+
+ @Override
+ public String getName() {
+ return "Clickhouse";
+ }
+}
diff --git a/hsweb-easy-orm/clickhouse/ClickhouseRestfulSqlExecutor.java b/hsweb-easy-orm/clickhouse/ClickhouseRestfulSqlExecutor.java
new file mode 100644
index 0000000..37e9747
--- /dev/null
+++ b/hsweb-easy-orm/clickhouse/ClickhouseRestfulSqlExecutor.java
@@ -0,0 +1,135 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.hswebframework.ezorm.rdb.executor.BatchSqlRequest;
+import org.hswebframework.ezorm.rdb.executor.DefaultColumnWrapperContext;
+import org.hswebframework.ezorm.rdb.executor.SqlRequest;
+import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSqlExecutor;
+import org.hswebframework.ezorm.rdb.executor.wrapper.ResultWrapper;
+import org.reactivestreams.Publisher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @className ClickhouseRestfulSqlExecutor
+ * @Description TODO
+ * @Author dengpengyu
+ * @Date 2023/9/4 14:40
+ * @Vesion 1.0
+ */
+public class ClickhouseRestfulSqlExecutor implements ReactiveSqlExecutor {
+ private Logger log = LoggerFactory.getLogger(ClickhouseRestfulSqlExecutor.class);
+ private WebClient client;
+
+ public ClickhouseRestfulSqlExecutor(WebClient client) {
+ this.client = client;
+ }
+
+ @Override
+ public Mono update(Publisher request) {
+ return this
+ .doExecute(request)
+ .then(Mono.just(1));
+ }
+
+ @Override
+ public Mono execute(Publisher request) {
+ return this
+ .doExecute(request)
+ .then();
+ }
+
+ @Override
+ public Flux select(Publisher request, ResultWrapper wrapper) {
+
+ return this
+ .doExecute(request)
+ .flatMap(response -> convertQueryResult(response, wrapper));
+ }
+
+ private Flux doExecute(Publisher requests) {
+ return Flux
+ .from(requests)
+ .expand(request -> {
+ if (request instanceof BatchSqlRequest) {
+ return Flux.fromIterable(((BatchSqlRequest) request).getBatch());
+ }
+ return Flux.empty();
+ })
+
+ .filter(SqlRequest::isNotEmpty)
+ .concatMap(request -> {
+ String sql;
+ if (request.toNativeSql().toUpperCase().startsWith("INSERT")
+ || request.toNativeSql().toUpperCase().startsWith("ALTER")) {
+ sql = request.toNativeSql();
+ } else {
+ sql = request.toNativeSql() + " FORMAT JSON";
+ }
+ log.info("Execute ==> {}", sql);
+ return client
+ .post()
+ .bodyValue(sql)
+ .exchangeToMono(response -> response
+ .bodyToMono(String.class)
+ .map(json -> {
+ checkExecuteResult(sql, json);
+ JSONObject result = JSON.parseObject(json);
+
+ return result;
+ }));
+ });
+ }
+
+ private void checkExecuteResult(String sql, String code) {
+ if (code.startsWith("Code")) {
+ throw new RuntimeException(code);
+ }
+ }
+
+ protected Flux convertQueryResult(JSONObject result, ResultWrapper wrapper) {
+
+ JSONArray head = result.getJSONArray("meta");
+ JSONArray data = result.getJSONArray("data");
+
+ if (CollectionUtils.isEmpty(head) || CollectionUtils.isEmpty(data)) {
+ return Flux.empty();
+ }
+ List columns = head.stream()
+ .map(v -> ((JSONObject) v).get("name").toString())
+ .collect(Collectors.toList());
+
+ return Flux.create(sink -> {
+ wrapper.beforeWrap(() -> columns);
+
+ for (Object rowo : data) {
+ E rowInstance = wrapper.newRowInstance();
+ JSONObject row = (JSONObject) rowo;
+ for (int i = 0; i < columns.size(); i++) {
+ String property = columns.get(i);
+ Object value = row.get(property);
+ DefaultColumnWrapperContext context = new DefaultColumnWrapperContext<>(i, property, value, rowInstance);
+ wrapper.wrapColumn(context);
+ rowInstance = context.getRowInstance();
+ }
+ if (!wrapper.completedWrapRow(rowInstance)) {
+ break;
+ }
+ if (rowInstance != null) {
+ sink.next(rowInstance);
+ }
+ }
+ wrapper.completedWrap();
+ sink.complete();
+ });
+ }
+}
diff --git a/hsweb-easy-orm/clickhouse/ClickhouseSchemaMetadata.java b/hsweb-easy-orm/clickhouse/ClickhouseSchemaMetadata.java
new file mode 100644
index 0000000..4819bcf
--- /dev/null
+++ b/hsweb-easy-orm/clickhouse/ClickhouseSchemaMetadata.java
@@ -0,0 +1,53 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse;
+
+import org.hswebframework.ezorm.rdb.codec.EnumValueCodec;
+import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
+import org.hswebframework.ezorm.rdb.operator.CompositeExceptionTranslation;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.update.DefaultUpdateSqlBuilder;
+import org.hswebframework.ezorm.rdb.supports.clickhouse.sqlBuilder.ClickhouseDeleteSqlBuilder;
+import org.hswebframework.ezorm.rdb.supports.clickhouse.sqlBuilder.ClickhouseUpdateSqlBuilder;
+import org.hswebframework.ezorm.rdb.supports.mysql.*;
+import org.hswebframework.ezorm.rdb.utils.FeatureUtils;
+
+/**
+ * @className ClickhouseSchemaMetadata
+ * @Description TODO
+ * @Author dengpengyu
+ * @Date 2023/9/5 9:36
+ * @Vesion 1.0
+ */
+public class ClickhouseSchemaMetadata extends RDBSchemaMetadata {
+ public ClickhouseSchemaMetadata(String name) {
+ super(name);
+ addFeature(new MysqlPaginator());
+ // TODO 后续增加建表
+ //读取表元数据
+ addFeature(new ClickhouseTableMetadataParser(this));
+ addFeature(new ClickhouseDialect());
+ addFeature(new CompositeExceptionTranslation()
+ .add(FeatureUtils.r2dbcIsAlive(), () -> MysqlR2DBCExceptionTranslation.of(this))
+ .add(MysqlJDBCExceptionTranslation.of(this))
+ );
+ }
+
+ @Override
+ public RDBTableMetadata newTable(String name) {
+ RDBTableMetadata metadata = super.newTable(name);
+ metadata.addFeature(ClickhouseUpdateSqlBuilder.of(metadata));
+ metadata.addFeature(ClickhouseDeleteSqlBuilder.of(metadata));
+ metadata.setOnColumnAdded(column -> {
+ if (column.getValueCodec() instanceof EnumValueCodec && ((EnumValueCodec) column.getValueCodec()).isToMask()) {
+ column.addFeature(MysqlEnumInFragmentBuilder.in);
+ column.addFeature(MysqlEnumInFragmentBuilder.notIn);
+ }
+ });
+ return metadata;
+ }
+
+ @Override
+ public void addTable(RDBTableMetadata metadata) {
+ metadata.addFeature(new MysqlBatchUpsertOperator(metadata));
+ super.addTable(metadata);
+ }
+}
diff --git a/hsweb-easy-orm/clickhouse/ClickhouseTableMetadataParser.java b/hsweb-easy-orm/clickhouse/ClickhouseTableMetadataParser.java
new file mode 100644
index 0000000..a5f956a
--- /dev/null
+++ b/hsweb-easy-orm/clickhouse/ClickhouseTableMetadataParser.java
@@ -0,0 +1,75 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse;
+
+import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
+import org.hswebframework.ezorm.rdb.supports.commons.RDBTableMetadataParser;
+import reactor.core.publisher.Flux;
+
+import java.util.List;
+
+/**
+ * @className Clickhouse
+ * @Description TODO
+ * @Author dengpengyu
+ * @Date 2023/9/4 14:56
+ * @Vesion 1.0
+ */
+public class ClickhouseTableMetadataParser extends RDBTableMetadataParser {
+ private static final String TABLE_META_SQL = String.join(" ",
+ "select",
+ "column_name as `name`,",
+ "data_type as `data_type`,",
+ "character_maximum_length as `data_length`,",
+ "numeric_precision as `data_precision`,",
+ "numeric_scale as `data_scale`,",
+ "column_comment as `comment`,",
+ "table_name as `table_name`,",
+ "case when is_nullable=0 then 0 else 1 end ",
+ "from information_schema.columns where table_schema=#{schema} and table_name like #{table}");
+
+ private static final String TABLE_COMMENT_SQL = String.join(" ",
+ "select ",
+ "`comment`",
+ ",name as `table_name`",
+ "from system.tables where database=#{schema} and name like #{table}");
+
+
+ private static final String ALL_TABLE_SQL = "select table_name as `name` from system.tables where database=#{schema}";
+
+ private static final String TABLE_EXISTS_SQL = "select count() as `total` from system.tables where database=#{schema} and name=#{table}";
+
+ public ClickhouseTableMetadataParser(RDBSchemaMetadata schema) {
+ super(schema);
+ }
+
+ @Override
+ protected String getTableMetaSql(String name) {
+ return TABLE_META_SQL;
+ }
+
+ @Override
+ protected String getTableCommentSql(String name) {
+ return TABLE_COMMENT_SQL;
+ }
+
+ @Override
+ protected String getAllTableSql() {
+ return ALL_TABLE_SQL;
+ }
+
+ @Override
+ public String getTableExistsSql() {
+ return TABLE_EXISTS_SQL;
+ }
+
+ @Override
+ public List parseAll() {
+ return super.fastParseAll();
+ }
+
+ @Override
+ public Flux parseAllReactive() {
+ return super.fastParseAllReactive();
+ }
+
+}
diff --git a/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java b/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java
new file mode 100644
index 0000000..f3899a0
--- /dev/null
+++ b/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java
@@ -0,0 +1,87 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse.sqlBuilder;
+
+import lombok.AllArgsConstructor;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.executor.SqlRequest;
+import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
+import org.hswebframework.ezorm.rdb.metadata.key.ForeignKeyMetadata;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.*;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.delete.DeleteSqlBuilder;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.ForeignKeyTermFragmentBuilder;
+
+import org.hswebframework.ezorm.rdb.operator.dml.delete.DeleteOperatorParameter;
+
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * @className ClickhouseDeleteSqlBuilder
+ * @Description TODO
+ * @Author dengpengyu
+ * @Date 2023/9/6 10:06
+ * @Vesion 1.0
+ */
+@AllArgsConstructor(staticName = "of")
+@SuppressWarnings("all")
+public class ClickhouseDeleteSqlBuilder extends AbstractTermsFragmentBuilder implements DeleteSqlBuilder {
+
+ private RDBTableMetadata table;
+
+ @Override
+ public SqlRequest build(DeleteOperatorParameter parameter) {
+ if (CollectionUtils.isEmpty(parameter.getWhere())) {
+ throw new UnsupportedOperationException("Unsupported No Conditions delete");
+ }
+
+ PrepareSqlFragments fragments = PrepareSqlFragments.of();
+ fragments.addSql("ALTER TABLE", table.getFullName(), "DELETE WHERE");
+
+ SqlFragments where = createTermFragments(parameter, parameter.getWhere());
+ if (where.isEmpty()) {
+ throw new UnsupportedOperationException("Unsupported No Conditions delete");
+ }
+ fragments.addFragments(where);
+
+ return fragments.toRequest();
+ }
+
+ @Override
+ protected SqlFragments createTermFragments(DeleteOperatorParameter parameter, Term term) {
+ String columnName = term.getColumn();
+ if (columnName == null) {
+ return EmptySqlFragments.INSTANCE;
+ }
+
+ if (columnName.contains(".")) {
+ String[] arr = columnName.split("[.]");
+ if (table.equalsNameOrAlias(arr[0])) {
+ columnName = arr[1];
+ } else {
+ return table.getForeignKey(arr[0])
+ .flatMap(key -> table.findFeature(ForeignKeyTermFragmentBuilder.ID)
+ .map(builder -> builder.createFragments(table.getName(), key, createForeignKeyTerm(key, term))))
+ .orElse(EmptySqlFragments.INSTANCE);
+ }
+ }
+
+ return table
+ .getColumn(columnName)
+ .flatMap(column -> column
+ .findFeature(TermFragmentBuilder.createFeatureId(term.getTermType()))
+ .map(termFragment -> termFragment.createFragments(column.getQuoteName(), column, term)))
+ .orElse(EmptySqlFragments.INSTANCE);
+ }
+
+ protected List createForeignKeyTerm(ForeignKeyMetadata keyMetadata, Term term) {
+ Term copy = term.clone();
+ //只要是嵌套到外键表的条件则认为是关联表的条件
+ term.setTerms(new LinkedList<>());
+
+ return Collections.singletonList(copy);
+ }
+}
diff --git a/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java b/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java
new file mode 100644
index 0000000..b2f2b18
--- /dev/null
+++ b/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java
@@ -0,0 +1,150 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse.sqlBuilder;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.apache.commons.collections.CollectionUtils;
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.executor.EmptySqlRequest;
+import org.hswebframework.ezorm.rdb.executor.SqlRequest;
+import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
+import org.hswebframework.ezorm.rdb.metadata.key.ForeignKeyMetadata;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.*;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.ForeignKeyTermFragmentBuilder;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.update.UpdateSqlBuilder;
+import org.hswebframework.ezorm.rdb.operator.dml.update.UpdateColumn;
+import org.hswebframework.ezorm.rdb.operator.dml.update.UpdateOperatorParameter;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import static java.util.Optional.ofNullable;
+import static org.hswebframework.ezorm.rdb.operator.builder.fragments.function.FunctionFragmentBuilder.createFeatureId;
+/**
+ * @author dengpengyu
+ */
+/**
+ * @className ClickhouseUpdateSqlBuilder
+ * @Description TODO
+ * @Author dengpengyu
+ * @Date 2023/9/6 9:56
+ * @Vesion 1.0
+ */
+@AllArgsConstructor(staticName = "of")
+@SuppressWarnings("all")
+public class ClickhouseUpdateSqlBuilder extends AbstractTermsFragmentBuilder implements UpdateSqlBuilder {
+ @Getter
+ private RDBTableMetadata table;
+
+ @Override
+ public SqlRequest build(UpdateOperatorParameter parameter) {
+
+ if (CollectionUtils.isEmpty(parameter.getColumns())) {
+ return EmptySqlRequest.INSTANCE;
+ }
+ if (CollectionUtils.isEmpty(parameter.getWhere())) {
+ throw new UnsupportedOperationException("unsupported no conditions update");
+ }
+
+ PrepareSqlFragments fragments = PrepareSqlFragments.of();
+
+ fragments.addSql("ALTER TABLE", table.getFullName(), "UPDATE");
+
+ int index = 0;
+ for (UpdateColumn column : parameter.getColumns()) {
+ SqlFragments columnFragments = table.getColumn(column.getColumn())
+ .filter(RDBColumnMetadata::isUpdatable)
+ .map(columnMetadata -> {
+ Object value = column.getValue();
+ if (value == null) {
+ return EmptySqlFragments.INSTANCE;
+ }
+
+ PrepareSqlFragments sqlFragments = PrepareSqlFragments.of();
+ sqlFragments.addSql(columnMetadata.getQuoteName(), "=");
+
+ if (column instanceof NativeSql) {
+ return PrepareSqlFragments.of()
+ .addSql(((NativeSql) column).getSql())
+ .addParameter(((NativeSql) column).getParameters());
+ }
+ if (value instanceof NativeSql) {
+ return PrepareSqlFragments.of()
+ .addSql(columnMetadata.getQuoteName(), "=")
+ .addSql(((NativeSql) column.getValue()).getSql())
+ .addParameter(((NativeSql) column.getValue()).getParameters());
+ }
+
+ sqlFragments.addFragments(ofNullable(column.getFunction())
+ .flatMap(function -> columnMetadata.findFeature(createFeatureId(function)))
+ .map(builder -> builder.create(columnMetadata.getName(), columnMetadata, column))
+ .orElseGet(() -> PrepareSqlFragments.of()
+ .addSql("?")
+ .addParameter(columnMetadata.encode(value))));
+
+ return sqlFragments;
+
+ }).orElse(EmptySqlFragments.INSTANCE);
+
+
+ if (columnFragments.isNotEmpty()) {
+ if (index++ != 0) {
+ fragments.addSql(",");
+ }
+ fragments.addFragments(columnFragments);
+
+ }
+ }
+ if (index == 0) {
+ throw new UnsupportedOperationException("No columns are updated");
+ }
+ fragments.addSql("where");
+
+ SqlFragments where = createTermFragments(parameter, parameter.getWhere());
+
+ if (where.isEmpty()) {
+ throw new UnsupportedOperationException("Unsupported No Conditions update");
+ }
+
+ fragments.addFragments(where);
+
+ return fragments.toRequest();
+ }
+
+ @Override
+ protected SqlFragments createTermFragments(UpdateOperatorParameter parameter, Term term) {
+ String columnName = term.getColumn();
+ if (columnName == null) {
+ return EmptySqlFragments.INSTANCE;
+ }
+
+ if (columnName.contains(".")) {
+ String[] arr = columnName.split("[.]");
+ if (table.equalsNameOrAlias(arr[0])) {
+ columnName = arr[1];
+ } else {
+ return table.getForeignKey(arr[0])
+ .flatMap(key -> key.getSource()
+ .findFeature(ForeignKeyTermFragmentBuilder.ID)
+ .map(builder -> builder.createFragments(table.getName(), key, createForeignKeyTerm(key, term))))
+ .orElse(EmptySqlFragments.INSTANCE);
+ }
+ }
+
+ return table
+ .getColumn(columnName)
+ .flatMap(column -> column
+ .findFeature(TermFragmentBuilder.createFeatureId(term.getTermType()))
+ .map(termFragment -> termFragment.createFragments(column.getQuoteName(), column, term)))
+ .orElse(EmptySqlFragments.INSTANCE);
+ }
+
+ protected List createForeignKeyTerm(ForeignKeyMetadata keyMetadata, Term term) {
+ Term copy = term.clone();
+ //只要是嵌套到外键表的条件则认为是关联表的条件
+ term.setTerms(new LinkedList<>());
+
+ return Collections.singletonList(copy);
+ }
+}
From ce44317efaba5dc3d366eacb8272988e0207330c Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Mon, 18 Sep 2023 16:55:20 +0800
Subject: [PATCH 02/16] =?UTF-8?q?fix:=20=E6=8A=8A=E7=BC=96=E8=AF=91?=
=?UTF-8?q?=E8=BF=87=E7=A8=8B=E8=BD=AC=E6=8D=A2=E4=B8=BA=E7=A8=8B=E5=BA=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 112 ------------------
pom.xml | 30 +++++
.../ezorm/rdb/metadata/dialect/Dialect.java | 69 +++++++++++
.../clickhouse/ClickhouseDialect.java | 1 +
.../ClickhouseRestfulSqlExecutor.java | 5 +
.../clickhouse/ClickhouseSchemaMetadata.java | 2 +-
.../ClickhouseTableMetadataParser.java | 0
.../ClickhouseDeleteSqlBuilder.java | 3 -
.../ClickhouseUpdateSqlBuilder.java | 1 +
...lickhouseHttpSqlExecutorConfiguration.java | 1 +
.../configuration}/ClickhouseProperties.java | 6 +-
.../configuration}/EasyormProperties.java | 45 +------
src/main/resources/META-INF/spring.factories | 3 +
13 files changed, 119 insertions(+), 159 deletions(-)
delete mode 100644 README.md
create mode 100644 pom.xml
create mode 100644 src/main/java/org/hswebframework/ezorm/rdb/metadata/dialect/Dialect.java
rename {hsweb-easy-orm => src/main/java/org/hswebframework/ezorm/rdb/supports}/clickhouse/ClickhouseDialect.java (99%)
rename {hsweb-easy-orm => src/main/java/org/hswebframework/ezorm/rdb/supports}/clickhouse/ClickhouseRestfulSqlExecutor.java (95%)
rename {hsweb-easy-orm => src/main/java/org/hswebframework/ezorm/rdb/supports}/clickhouse/ClickhouseSchemaMetadata.java (95%)
rename {hsweb-easy-orm => src/main/java/org/hswebframework/ezorm/rdb/supports}/clickhouse/ClickhouseTableMetadataParser.java (100%)
rename {hsweb-easy-orm => src/main/java/org/hswebframework/ezorm/rdb/supports}/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java (99%)
rename {hsweb-easy-orm => src/main/java/org/hswebframework/ezorm/rdb/supports}/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java (99%)
rename {hsweb-commons-crud => src/main/java/org/hswebframework/web/crud/configuration}/ClickhouseHttpSqlExecutorConfiguration.java (99%)
rename {hsweb-commons-crud => src/main/java/org/hswebframework/web/crud/configuration}/ClickhouseProperties.java (86%)
rename {hsweb-commons-crud => src/main/java/org/hswebframework/web/crud/configuration}/EasyormProperties.java (59%)
create mode 100644 src/main/resources/META-INF/spring.factories
diff --git a/README.md b/README.md
deleted file mode 100644
index 801e082..0000000
--- a/README.md
+++ /dev/null
@@ -1,112 +0,0 @@
-# 说明
-
-1. 本仓库需要配合[hsweb-easy-orm](https://github.com/hs-web/hsweb-easy-orm),[hsweb-framework](https://github.com/hs-web/hsweb-framework)使用
-2. 本仓库是针对hsweb-easy-orm 4.X、hsweb-commons-curd 4.X 适配 clickhouse22.X
-
-# 使用
-
-## hsweb-easy-orm编译
-
-1. 首先克隆[hsweb-easy-orm](https://github.com/hs-web/hsweb-easy-orm)至本地
-
-2. hsweb-easy-orm的pom文件中新增依赖
-
- ```xml
-
- org.springframework
- spring-webflux
- 5.3.25
-
- ```
-
-3. 将本项目中hsweb-easy-orm的clickhouse目录复制到hsweb-easy-orm的org.hswebframework.ezorm.rdb.supports下,复制后包路径应是org.hswebframework.ezorm.rdb.supports.clickhouse
-
-4. hsweb-easy-orm-rdb\src\main\java\org\hswebframework\ezorm\rdb\metadata\dialect\Dialect.java中新增数据库方言如下
-
- ```java
- Dialect CLICKHOUSE =new ClickhouseDialect();
- ```
-
-5. maven编译
-
-## hsweb-commons-curd编译
-
-1. 首先克隆[hsweb-framework](https://github.com/hs-web/hsweb-framework)至本地
-
-2. 将本项目中hsweb-commons-curd文件夹下ClickhouseHttpSqlExecutorConfiguration.java 、ClickhouseProperties.java放置在hsweb-framework/hsweb-commons-curd模块中org.hswebframework.web.crud.configuration路径下。
-
-3. 在org.hswebframework.web.crud.configuration.EasyormProperties.java文件中插入相关代码如下,**注意注释部分**
-
- ```java
-
- @Getter
- @AllArgsConstructor
- public enum DialectEnum {
- mysql(Dialect.MYSQL, "?") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new MysqlSchemaMetadata(name);
- }
- },
- mssql(Dialect.MSSQL, "@arg") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new SqlServerSchemaMetadata(name);
- }
- },
- oracle(Dialect.ORACLE, "?") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new OracleSchemaMetadata(name);
- }
- },
- postgres(Dialect.POSTGRES, "$") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new PostgresqlSchemaMetadata(name);
- }
- },
- h2(Dialect.H2, "$") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new H2SchemaMetadata(name);
- }
- }
- //start
- //这里是对clickhouse的支持
- ,
- clickhouse(Dialect.CLICKHOUSE,"?"){
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new ClickhouseSchemaMetadata(name);
- }
- }
- //end
- ;
-
- private Dialect dialect;
- private String bindSymbol;
-
- public abstract RDBSchemaMetadata createSchema(String name);
- ```
-
-4. hsweb-framework/hsweb-commons-curd模块的src/main/resources/META-INF/spring.factories中新增org.hswebframework.web.crud.configuration.ClickhouseHttpSqlExecutorConfiguration,示例如下
-
- ```
- # Auto Configure
- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- org.hswebframework.web.crud.configuration.EasyormConfiguration,\
- org.hswebframework.web.crud.configuration.JdbcSqlExecutorConfiguration,\
- org.hswebframework.web.crud.configuration.R2dbcSqlExecutorConfiguration,\
- org.hswebframework.web.crud.configuration.ClickhouseHttpSqlExecutorConfiguration,\
- org.hswebframework.web.crud.web.CommonWebFluxConfiguration,\
- org.hswebframework.web.crud.web.CommonWebMvcConfiguration
- ```
-
-5. maven编译
-
-# 注意
-
-1. 先编译hsweb-easy-orm再编译hsweb-commons-curd
-2. 编译hsweb-commons-curd时需注意依赖hsweb-easy-orm的版本。
-3. 由于clickhouse各版本系统表差异过大,本仓库暂只支持clickhouse22.X版本
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..5e7d949
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ org.hswebframework
+ hsweb-incubator-easyorm-clickhouse
+ 1.0-SNAPSHOT
+
+
+ 8
+ 8
+ 4.0.17-SNAPSHOT
+
+
+
+
+ org.hswebframework.web
+ hsweb-commons-crud
+ ${hsweb.framework.version}
+
+
+ org.springframework
+ spring-webflux
+ 5.3.25
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/metadata/dialect/Dialect.java b/src/main/java/org/hswebframework/ezorm/rdb/metadata/dialect/Dialect.java
new file mode 100644
index 0000000..e078e35
--- /dev/null
+++ b/src/main/java/org/hswebframework/ezorm/rdb/metadata/dialect/Dialect.java
@@ -0,0 +1,69 @@
+package org.hswebframework.ezorm.rdb.metadata.dialect;
+
+import org.hswebframework.ezorm.core.meta.Feature;
+import org.hswebframework.ezorm.core.utils.StringUtils;
+import org.hswebframework.ezorm.rdb.metadata.DataType;
+import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBFeatureType;
+import org.hswebframework.ezorm.rdb.metadata.dialect.DataTypeBuilder;
+import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseDialect;
+
+import java.sql.SQLType;
+import java.util.Optional;
+
+/**
+ * @author dengpengyu
+ * @date 2023/9/18 16:14
+ */
+public interface Dialect extends Feature {
+
+ @Override
+ default RDBFeatureType getType() {
+ return RDBFeatureType.dialect;
+ }
+
+ void addDataTypeBuilder(String typeId, DataTypeBuilder mapper);
+
+ String buildColumnDataType(RDBColumnMetadata columnMetaData);
+
+ String getQuoteStart();
+
+ String getQuoteEnd();
+
+ String clearQuote(String string);
+
+ boolean isColumnToUpperCase();
+
+ Optional convertSqlType(Class> type);
+
+ DataType convertDataType(String dataType);
+
+ default String quote(String keyword, boolean changeCase) {
+ if (keyword.startsWith(getQuoteStart()) && keyword.endsWith(getQuoteEnd())) {
+ return keyword;
+ }
+ return StringUtils.concat(
+ getQuoteStart(),
+ isColumnToUpperCase() && changeCase ? keyword.toUpperCase() : keyword,
+ getQuoteEnd()
+ );
+ }
+
+ default String quote(String keyword) {
+ return quote(keyword, true);
+ }
+
+ default String buildColumnFullName(String tableName, String columnName) {
+ if (columnName.contains(".")) {
+ return columnName;
+ }
+ if (StringUtils.isNullOrEmpty(tableName)) {
+ return StringUtils.concat(getQuoteStart(), isColumnToUpperCase() ? columnName.toUpperCase() : columnName, getQuoteEnd());
+ }
+ return StringUtils.concat(tableName, ".", getQuoteStart(), isColumnToUpperCase() ? columnName.toUpperCase() : columnName, getQuoteEnd());
+ }
+
+ ClickhouseDialect CLICKHOUSE = new ClickhouseDialect();
+
+}
+
diff --git a/hsweb-easy-orm/clickhouse/ClickhouseDialect.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
similarity index 99%
rename from hsweb-easy-orm/clickhouse/ClickhouseDialect.java
rename to src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
index e150312..e1e5ee5 100644
--- a/hsweb-easy-orm/clickhouse/ClickhouseDialect.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
@@ -7,6 +7,7 @@
import java.sql.Date;
import java.sql.JDBCType;
+
/**
* @className ClickhouseDire
* @Description TODO
diff --git a/hsweb-easy-orm/clickhouse/ClickhouseRestfulSqlExecutor.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
similarity index 95%
rename from hsweb-easy-orm/clickhouse/ClickhouseRestfulSqlExecutor.java
rename to src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
index 37e9747..9a67cb8 100644
--- a/hsweb-easy-orm/clickhouse/ClickhouseRestfulSqlExecutor.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
@@ -117,6 +117,11 @@ protected Flux convertQueryResult(JSONObject result, ResultWrapper
for (int i = 0; i < columns.size(); i++) {
String property = columns.get(i);
Object value = row.get(property);
+ if ("total".equals(property)) {
+ value = Long.valueOf(row.get(property).toString());
+ } else {
+ value = row.get(property);
+ }
DefaultColumnWrapperContext context = new DefaultColumnWrapperContext<>(i, property, value, rowInstance);
wrapper.wrapColumn(context);
rowInstance = context.getRowInstance();
diff --git a/hsweb-easy-orm/clickhouse/ClickhouseSchemaMetadata.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseSchemaMetadata.java
similarity index 95%
rename from hsweb-easy-orm/clickhouse/ClickhouseSchemaMetadata.java
rename to src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseSchemaMetadata.java
index 4819bcf..6572a41 100644
--- a/hsweb-easy-orm/clickhouse/ClickhouseSchemaMetadata.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseSchemaMetadata.java
@@ -4,7 +4,7 @@
import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
import org.hswebframework.ezorm.rdb.operator.CompositeExceptionTranslation;
-import org.hswebframework.ezorm.rdb.operator.builder.fragments.update.DefaultUpdateSqlBuilder;
+
import org.hswebframework.ezorm.rdb.supports.clickhouse.sqlBuilder.ClickhouseDeleteSqlBuilder;
import org.hswebframework.ezorm.rdb.supports.clickhouse.sqlBuilder.ClickhouseUpdateSqlBuilder;
import org.hswebframework.ezorm.rdb.supports.mysql.*;
diff --git a/hsweb-easy-orm/clickhouse/ClickhouseTableMetadataParser.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseTableMetadataParser.java
similarity index 100%
rename from hsweb-easy-orm/clickhouse/ClickhouseTableMetadataParser.java
rename to src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseTableMetadataParser.java
diff --git a/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java
similarity index 99%
rename from hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java
rename to src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java
index f3899a0..46c2c67 100644
--- a/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/sqlBuilder/ClickhouseDeleteSqlBuilder.java
@@ -1,7 +1,6 @@
package org.hswebframework.ezorm.rdb.supports.clickhouse.sqlBuilder;
import lombok.AllArgsConstructor;
-
import org.apache.commons.collections.CollectionUtils;
import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.ezorm.rdb.executor.SqlRequest;
@@ -10,10 +9,8 @@
import org.hswebframework.ezorm.rdb.operator.builder.fragments.*;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.delete.DeleteSqlBuilder;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.ForeignKeyTermFragmentBuilder;
-
import org.hswebframework.ezorm.rdb.operator.dml.delete.DeleteOperatorParameter;
-
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
diff --git a/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java
similarity index 99%
rename from hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java
rename to src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java
index b2f2b18..9b82886 100644
--- a/hsweb-easy-orm/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/sqlBuilder/ClickhouseUpdateSqlBuilder.java
@@ -24,6 +24,7 @@
/**
* @author dengpengyu
*/
+
/**
* @className ClickhouseUpdateSqlBuilder
* @Description TODO
diff --git a/hsweb-commons-crud/ClickhouseHttpSqlExecutorConfiguration.java b/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseHttpSqlExecutorConfiguration.java
similarity index 99%
rename from hsweb-commons-crud/ClickhouseHttpSqlExecutorConfiguration.java
rename to src/main/java/org/hswebframework/web/crud/configuration/ClickhouseHttpSqlExecutorConfiguration.java
index afb7364..ac99cee 100644
--- a/hsweb-commons-crud/ClickhouseHttpSqlExecutorConfiguration.java
+++ b/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseHttpSqlExecutorConfiguration.java
@@ -3,6 +3,7 @@
import org.hswebframework.ezorm.rdb.executor.SyncSqlExecutor;
import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSqlExecutor;
import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSyncSqlExecutor;
+
import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseRestfulSqlExecutor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
diff --git a/hsweb-commons-crud/ClickhouseProperties.java b/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseProperties.java
similarity index 86%
rename from hsweb-commons-crud/ClickhouseProperties.java
rename to src/main/java/org/hswebframework/web/crud/configuration/ClickhouseProperties.java
index f99a48b..478202e 100644
--- a/hsweb-commons-crud/ClickhouseProperties.java
+++ b/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseProperties.java
@@ -1,18 +1,18 @@
package org.hswebframework.web.crud.configuration;
-
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author dengpengyu
- * @date 2023/9/6 14:08
+ * @date 2023/9/13 15:29
*/
@Data
@ConfigurationProperties(prefix = "spring.clickhouse")
@Component
-public class ClickhouseProperties {
+public class
+ClickhouseProperties {
private String url;
diff --git a/hsweb-commons-crud/EasyormProperties.java b/src/main/java/org/hswebframework/web/crud/configuration/EasyormProperties.java
similarity index 59%
rename from hsweb-commons-crud/EasyormProperties.java
rename to src/main/java/org/hswebframework/web/crud/configuration/EasyormProperties.java
index 0cac45a..9f6b2a1 100644
--- a/hsweb-commons-crud/EasyormProperties.java
+++ b/src/main/java/org/hswebframework/web/crud/configuration/EasyormProperties.java
@@ -7,12 +7,8 @@
import org.hswebframework.ezorm.rdb.metadata.RDBDatabaseMetadata;
import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
import org.hswebframework.ezorm.rdb.metadata.dialect.Dialect;
+import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseDialect;
import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseSchemaMetadata;
-import org.hswebframework.ezorm.rdb.supports.h2.H2SchemaMetadata;
-import org.hswebframework.ezorm.rdb.supports.mssql.SqlServerSchemaMetadata;
-import org.hswebframework.ezorm.rdb.supports.mysql.MysqlSchemaMetadata;
-import org.hswebframework.ezorm.rdb.supports.oracle.OracleSchemaMetadata;
-import org.hswebframework.ezorm.rdb.supports.postgres.PostgresqlSchemaMetadata;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Arrays;
@@ -23,7 +19,7 @@
@Data
public class EasyormProperties {
- private String defaultSchema="PUBLIC";
+ private String defaultSchema = "PUBLIC";
private String[] schemas = {};
@@ -33,7 +29,7 @@ public class EasyormProperties {
private boolean allowTypeAlter = true;
- private DialectEnum dialect = DialectEnum.h2;
+ private DialectEnum dialect = DialectEnum.clickhouse;
private Class extends Dialect> dialectType;
@@ -76,43 +72,12 @@ public Dialect createDialect() {
@Getter
@AllArgsConstructor
public enum DialectEnum {
- mysql(Dialect.MYSQL, "?") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new MysqlSchemaMetadata(name);
- }
- },
- mssql(Dialect.MSSQL, "@arg") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new SqlServerSchemaMetadata(name);
- }
- },
- oracle(Dialect.ORACLE, "?") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new OracleSchemaMetadata(name);
- }
- },
- postgres(Dialect.POSTGRES, "$") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new PostgresqlSchemaMetadata(name);
- }
- },
- h2(Dialect.H2, "$") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new H2SchemaMetadata(name);
- }
- },
- clickhouse(Dialect.CLICKHOUSE,"?"){
+ clickhouse(Dialect.CLICKHOUSE, "?") {
@Override
public RDBSchemaMetadata createSchema(String name) {
return new ClickhouseSchemaMetadata(name);
}
- }
- ;
+ };
private Dialect dialect;
private String bindSymbol;
diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..9460a7e
--- /dev/null
+++ b/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,3 @@
+# Auto Configure
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.hswebframework.web.crud.configuration.ClickhouseHttpSqlExecutorConfiguration
\ No newline at end of file
From c046f58550cd5be02354cac88cb717b3d9cf65b7 Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Mon, 25 Sep 2023 17:47:50 +0800
Subject: [PATCH 03/16] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9clickhouse?=
=?UTF-8?q?=E7=9A=84=E4=BB=8B=E5=85=A5=E6=96=B9=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ezorm/rdb/metadata/dialect/Dialect.java | 69 --------------
.../clickhouse/ClickhouseDialect.java | 14 ++-
.../supports/clickhouse/ClickhouseHelper.java | 47 ++++++++++
.../ClickhouseRestfulSqlExecutor.java | 5 +
.../ezorm/rdb/supports/clickhouse/Helper.java | 92 +++++++++++++++++++
.../ClickhouseReactiveCrudService.java | 26 ++++++
...lickhouseHttpSqlExecutorConfiguration.java | 41 ---------
.../configuration/ClickhouseProperties.java | 2 +
.../crud/configuration/EasyormProperties.java | 87 ------------------
src/main/resources/META-INF/spring.factories | 3 +-
10 files changed, 182 insertions(+), 204 deletions(-)
delete mode 100644 src/main/java/org/hswebframework/ezorm/rdb/metadata/dialect/Dialect.java
create mode 100644 src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseHelper.java
create mode 100644 src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/Helper.java
create mode 100644 src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
delete mode 100644 src/main/java/org/hswebframework/web/crud/configuration/ClickhouseHttpSqlExecutorConfiguration.java
delete mode 100644 src/main/java/org/hswebframework/web/crud/configuration/EasyormProperties.java
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/metadata/dialect/Dialect.java b/src/main/java/org/hswebframework/ezorm/rdb/metadata/dialect/Dialect.java
deleted file mode 100644
index e078e35..0000000
--- a/src/main/java/org/hswebframework/ezorm/rdb/metadata/dialect/Dialect.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.hswebframework.ezorm.rdb.metadata.dialect;
-
-import org.hswebframework.ezorm.core.meta.Feature;
-import org.hswebframework.ezorm.core.utils.StringUtils;
-import org.hswebframework.ezorm.rdb.metadata.DataType;
-import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
-import org.hswebframework.ezorm.rdb.metadata.RDBFeatureType;
-import org.hswebframework.ezorm.rdb.metadata.dialect.DataTypeBuilder;
-import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseDialect;
-
-import java.sql.SQLType;
-import java.util.Optional;
-
-/**
- * @author dengpengyu
- * @date 2023/9/18 16:14
- */
-public interface Dialect extends Feature {
-
- @Override
- default RDBFeatureType getType() {
- return RDBFeatureType.dialect;
- }
-
- void addDataTypeBuilder(String typeId, DataTypeBuilder mapper);
-
- String buildColumnDataType(RDBColumnMetadata columnMetaData);
-
- String getQuoteStart();
-
- String getQuoteEnd();
-
- String clearQuote(String string);
-
- boolean isColumnToUpperCase();
-
- Optional convertSqlType(Class> type);
-
- DataType convertDataType(String dataType);
-
- default String quote(String keyword, boolean changeCase) {
- if (keyword.startsWith(getQuoteStart()) && keyword.endsWith(getQuoteEnd())) {
- return keyword;
- }
- return StringUtils.concat(
- getQuoteStart(),
- isColumnToUpperCase() && changeCase ? keyword.toUpperCase() : keyword,
- getQuoteEnd()
- );
- }
-
- default String quote(String keyword) {
- return quote(keyword, true);
- }
-
- default String buildColumnFullName(String tableName, String columnName) {
- if (columnName.contains(".")) {
- return columnName;
- }
- if (StringUtils.isNullOrEmpty(tableName)) {
- return StringUtils.concat(getQuoteStart(), isColumnToUpperCase() ? columnName.toUpperCase() : columnName, getQuoteEnd());
- }
- return StringUtils.concat(tableName, ".", getQuoteStart(), isColumnToUpperCase() ? columnName.toUpperCase() : columnName, getQuoteEnd());
- }
-
- ClickhouseDialect CLICKHOUSE = new ClickhouseDialect();
-
-}
-
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
index e1e5ee5..c73003a 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
@@ -7,6 +7,7 @@
import java.sql.Date;
import java.sql.JDBCType;
+import java.time.LocalDate;
/**
* @className ClickhouseDire
@@ -18,11 +19,14 @@
public class ClickhouseDialect extends DefaultDialect {
public ClickhouseDialect() {
- super();
- addDataTypeBuilder(JDBCType.CHAR, (meta) -> StringUtils.concat("char(", meta.getLength(), ")"));
- addDataTypeBuilder(JDBCType.VARCHAR, (meta) -> StringUtils.concat("varchar(", meta.getLength(), ")"));
- addDataTypeBuilder(JDBCType.NVARCHAR, (meta) -> StringUtils.concat("nvarchar(", meta.getLength(), ")"));
+
+ addDataTypeBuilder(JDBCType.TINYINT, (meta) -> "Int8");
+ addDataTypeBuilder(JDBCType.BOOLEAN, (meta) -> "Int8");
+
+
+ addDataTypeBuilder(JDBCType.VARCHAR, (meta) -> "string");
+ addDataTypeBuilder(JDBCType.NVARCHAR, (meta) -> StringUtils.concat("nvarchar(", meta.getLength(), ")"));
addDataTypeBuilder(JDBCType.TIMESTAMP, (meta) -> "datetime(" + Math.min(6, meta.getLength()) + ")");
addDataTypeBuilder(JDBCType.TIME, (meta) -> "time");
addDataTypeBuilder(JDBCType.DATE, (meta) -> "date");
@@ -43,7 +47,7 @@ public ClickhouseDialect() {
addDataTypeBuilder("int", (meta) -> "int");
addDataTypeBuilder("json", meta -> "json");
-
+ registerDataType("date", JdbcDataType.of(JDBCType.VARCHAR, String.class));
registerDataType("clob", DataType.builder(JdbcDataType.of(JDBCType.CLOB, String.class), c -> "text"));
registerDataType("longnvarchar", DataType.builder(JdbcDataType.of(JDBCType.LONGNVARCHAR, String.class), c -> "longtext"));
registerDataType("longvarchar", DataType.builder(JdbcDataType.of(JDBCType.LONGVARCHAR, String.class), c -> "longtext"));
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseHelper.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseHelper.java
new file mode 100644
index 0000000..e7c3085
--- /dev/null
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseHelper.java
@@ -0,0 +1,47 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse;
+
+
+import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSqlExecutor;
+
+import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
+import org.hswebframework.ezorm.rdb.metadata.dialect.Dialect;
+import org.hswebframework.web.crud.configuration.ClickhouseProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.client.WebClient;
+
+
+/**
+ * @author dengpengyu
+ * @date 2023/9/21 14:28
+ */
+@Configuration
+@EnableConfigurationProperties(ClickhouseProperties.class)
+public class ClickhouseHelper implements Helper {
+
+ @Autowired
+ ClickhouseProperties properties;
+
+ @Override
+ public RDBSchemaMetadata getRDBSchemaMetadata() {
+ return new ClickhouseSchemaMetadata(properties.getDatabase());
+ }
+
+ @Override
+ public Dialect getDialect() {
+ return new ClickhouseDialect();
+ }
+
+ @Override
+ public ReactiveSqlExecutor getReactiveSqlExecutor() {
+ WebClient clickhouseWebClient = WebClient
+ .builder()
+ .baseUrl(properties.getUrl())
+ .defaultHeader("X-ClickHouse-User", properties.getUsername())
+ .defaultHeader("X-ClickHouse-Key", properties.getPassword())
+ .build();
+
+ return new ClickhouseRestfulSqlExecutor(clickhouseWebClient);
+ }
+}
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
index 9a67cb8..b426483 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
@@ -122,6 +122,11 @@ protected Flux convertQueryResult(JSONObject result, ResultWrapper
} else {
value = row.get(property);
}
+ try{
+ value = Double.valueOf(row.get(property).toString());
+ }catch (Exception e){
+ value = row.get(property);
+ }
DefaultColumnWrapperContext context = new DefaultColumnWrapperContext<>(i, property, value, rowInstance);
wrapper.wrapColumn(context);
rowInstance = context.getRowInstance();
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/Helper.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/Helper.java
new file mode 100644
index 0000000..9f843b1
--- /dev/null
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/Helper.java
@@ -0,0 +1,92 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse;
+
+import lombok.SneakyThrows;
+import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSqlExecutor;
+import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSyncSqlExecutor;
+import org.hswebframework.ezorm.rdb.mapping.EntityColumnMapping;
+import org.hswebframework.ezorm.rdb.mapping.MappingFeatureType;
+import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
+import org.hswebframework.ezorm.rdb.mapping.defaults.DefaultReactiveRepository;
+import org.hswebframework.ezorm.rdb.mapping.jpa.JpaEntityTableMetadataParser;
+import org.hswebframework.ezorm.rdb.mapping.wrapper.EntityResultWrapper;
+import org.hswebframework.ezorm.rdb.metadata.RDBDatabaseMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
+import org.hswebframework.ezorm.rdb.metadata.dialect.Dialect;
+import org.hswebframework.ezorm.rdb.operator.DatabaseOperator;
+import org.hswebframework.ezorm.rdb.operator.DefaultDatabaseOperator;
+
+import java.util.function.Supplier;
+
+/**
+ * @author dengpengyu
+ * @date 2023/9/21 14:20
+ */
+public interface Helper {
+
+ RDBSchemaMetadata getRDBSchemaMetadata();
+
+ Dialect getDialect();
+
+ ReactiveSqlExecutor getReactiveSqlExecutor();
+
+ default RDBDatabaseMetadata getRDBDatabaseMetadata() {
+ RDBDatabaseMetadata metadata = new RDBDatabaseMetadata(getDialect());
+
+ RDBSchemaMetadata schema = getRDBSchemaMetadata();
+
+ ReactiveSqlExecutor sqlExecutor = getReactiveSqlExecutor();
+
+// schema.addFeature((EventListener) (type, context) -> System.out.println(type));
+
+ metadata.setCurrentSchema(schema);
+ metadata.addSchema(schema);
+ metadata.addFeature(sqlExecutor);
+ metadata.addFeature(ReactiveSyncSqlExecutor.of(sqlExecutor));
+
+ return metadata;
+ }
+
+ @SneakyThrows
+ default ReactiveRepository createRepository(Class clazz) {
+ RDBDatabaseMetadata metadata = getRDBDatabaseMetadata();
+ DatabaseOperator operator = DefaultDatabaseOperator.of(metadata);
+
+ JpaEntityTableMetadataParser parser = new JpaEntityTableMetadataParser();
+ parser.setDatabaseMetadata(metadata);
+ /* parser.parseTableMetadata(clazz)
+ .ifPresent(address -> {
+ operator.ddl()
+ .createOrAlter(address)
+ .commit()
+ .reactive()
+ .block();
+ });*/
+
+ RDBTableMetadata table = parser
+ .parseTableMetadata(clazz)
+ .orElseThrow(NullPointerException::new);
+
+// operator.ddl()
+// .createOrAlter(table)
+// .commit()
+// .reactive()
+// .block();
+
+ Supplier supplier = new Supplier() {
+ @SneakyThrows
+ @Override
+ public Object get() {
+ return clazz.newInstance();
+ }
+ };
+ EntityResultWrapper wrapper = new EntityResultWrapper(supplier);
+ wrapper.setMapping(table
+ .getFeature(MappingFeatureType.columnPropertyMapping.createFeatureId(clazz))
+ .orElseThrow(NullPointerException::new));
+
+
+ return new DefaultReactiveRepository<>(operator, table, clazz, wrapper);
+ }
+
+}
diff --git a/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java b/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
new file mode 100644
index 0000000..50a5dda
--- /dev/null
+++ b/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
@@ -0,0 +1,26 @@
+package org.hswebframework.service;
+
+
+import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
+import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseHelper;
+import org.hswebframework.web.crud.service.ReactiveCrudService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author dengpengyu
+ * @date 2023/9/20 11:38
+ */
+public abstract class ClickhouseReactiveCrudService implements ReactiveCrudService {
+
+ private ReactiveRepository repository;
+
+ @Autowired
+ private ClickhouseHelper clickhouseHelper;
+
+ @Override
+ public ReactiveRepository getRepository() {
+ return clickhouseHelper.createRepository(getEntityClass());
+ }
+
+ public abstract Class getEntityClass();
+}
diff --git a/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseHttpSqlExecutorConfiguration.java b/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseHttpSqlExecutorConfiguration.java
deleted file mode 100644
index ac99cee..0000000
--- a/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseHttpSqlExecutorConfiguration.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.hswebframework.web.crud.configuration;
-
-import org.hswebframework.ezorm.rdb.executor.SyncSqlExecutor;
-import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSqlExecutor;
-import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSyncSqlExecutor;
-
-import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseRestfulSqlExecutor;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.reactive.function.client.WebClient;
-
-
-/**
- * @author dengpengyu
- */
-@Configuration
-@EnableConfigurationProperties(ClickhouseProperties.class)
-//@ConditionalOnMissingBean(ConnectionFactory.class)
-public class ClickhouseHttpSqlExecutorConfiguration {
- @Bean
- @ConditionalOnMissingBean
- public ReactiveSqlExecutor reactiveSqlExecutor(ClickhouseProperties properties) {
-
- WebClient clickhouseWebClient = WebClient
- .builder()
- .baseUrl(properties.getUrl())
- .defaultHeader("X-ClickHouse-User", properties.getUsername())
- .defaultHeader("X-ClickHouse-Key", properties.getPassword())
- .build();
-
- return new ClickhouseRestfulSqlExecutor(clickhouseWebClient);
- }
-
- @Bean
- @ConditionalOnMissingBean
- public SyncSqlExecutor syncSqlExecutor(ReactiveSqlExecutor reactiveSqlExecutor) {
- return ReactiveSyncSqlExecutor.of(reactiveSqlExecutor);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseProperties.java b/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseProperties.java
index 478202e..fc77de2 100644
--- a/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseProperties.java
+++ b/src/main/java/org/hswebframework/web/crud/configuration/ClickhouseProperties.java
@@ -16,6 +16,8 @@
private String url;
+ private String database;
+
private String username;
private String password;
diff --git a/src/main/java/org/hswebframework/web/crud/configuration/EasyormProperties.java b/src/main/java/org/hswebframework/web/crud/configuration/EasyormProperties.java
deleted file mode 100644
index 9f6b2a1..0000000
--- a/src/main/java/org/hswebframework/web/crud/configuration/EasyormProperties.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.hswebframework.web.crud.configuration;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.Getter;
-import lombok.SneakyThrows;
-import org.hswebframework.ezorm.rdb.metadata.RDBDatabaseMetadata;
-import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
-import org.hswebframework.ezorm.rdb.metadata.dialect.Dialect;
-import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseDialect;
-import org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseSchemaMetadata;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-@ConfigurationProperties(prefix = "easyorm")
-@Data
-public class EasyormProperties {
-
- private String defaultSchema = "PUBLIC";
-
- private String[] schemas = {};
-
- private boolean autoDdl = true;
-
- private boolean allowAlter = false;
-
- private boolean allowTypeAlter = true;
-
- private DialectEnum dialect = DialectEnum.clickhouse;
-
- private Class extends Dialect> dialectType;
-
- private Class extends RDBSchemaMetadata> schemaType;
-
- public RDBDatabaseMetadata createDatabaseMetadata() {
- RDBDatabaseMetadata metadata = new RDBDatabaseMetadata(createDialect());
-
- Set schemaSet = new HashSet<>(Arrays.asList(schemas));
- if (defaultSchema != null) {
- schemaSet.add(defaultSchema);
- }
- schemaSet.stream()
- .map(this::createSchema)
- .forEach(metadata::addSchema);
-
- metadata.getSchema(defaultSchema)
- .ifPresent(metadata::setCurrentSchema);
-
- return metadata;
- }
-
- @SneakyThrows
- public RDBSchemaMetadata createSchema(String name) {
- if (schemaType == null) {
- return dialect.createSchema(name);
- }
- return schemaType.getConstructor(String.class).newInstance(name);
- }
-
- @SneakyThrows
- public Dialect createDialect() {
- if (dialectType == null) {
- return dialect.getDialect();
- }
-
- return dialectType.newInstance();
- }
-
- @Getter
- @AllArgsConstructor
- public enum DialectEnum {
- clickhouse(Dialect.CLICKHOUSE, "?") {
- @Override
- public RDBSchemaMetadata createSchema(String name) {
- return new ClickhouseSchemaMetadata(name);
- }
- };
-
- private Dialect dialect;
- private String bindSymbol;
-
- public abstract RDBSchemaMetadata createSchema(String name);
- }
-}
diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories
index 9460a7e..ce6376f 100644
--- a/src/main/resources/META-INF/spring.factories
+++ b/src/main/resources/META-INF/spring.factories
@@ -1,3 +1,2 @@
# Auto Configure
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-org.hswebframework.web.crud.configuration.ClickhouseHttpSqlExecutorConfiguration
\ No newline at end of file
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseHelper
\ No newline at end of file
From 8f8b887fb36d612eb1a68b26515a0a75ea58dfaf Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Mon, 25 Sep 2023 22:01:48 +0800
Subject: [PATCH 04/16] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9pom=E6=96=87?=
=?UTF-8?q?=E4=BB=B6=E5=8F=8Agitignore?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 1 +
hsweb-incubator-easyorm-clickhouse.iml | 86 ++++++++++++++++++++++++++
pom.xml | 26 +++++++-
3 files changed, 112 insertions(+), 1 deletion(-)
create mode 100644 .gitignore
create mode 100644 hsweb-incubator-easyorm-clickhouse.iml
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bc8a670
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.idea/*
\ No newline at end of file
diff --git a/hsweb-incubator-easyorm-clickhouse.iml b/hsweb-incubator-easyorm-clickhouse.iml
new file mode 100644
index 0000000..835b7dd
--- /dev/null
+++ b/hsweb-incubator-easyorm-clickhouse.iml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 5e7d949..5d8d83b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
8
8
- 4.0.17-SNAPSHOT
+ 4.0.16
@@ -26,5 +26,29 @@
5.3.25
+
+
+ aliyun-nexus
+ aliyun
+ https://maven.aliyun.com/nexus/content/groups/public/
+
+ false
+
+
+
+
+ hsweb-nexus
+ Nexus Release Repository
+ https://nexus.jetlinks.cn/content/groups/public/
+
+ false
+
+
+ true
+ always
+
+
+
+
\ No newline at end of file
From f855a1d8c8736f9b091126e848cc4cb0c8544ddb Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Tue, 10 Oct 2023 16:35:10 +0800
Subject: [PATCH 05/16] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3clickhouse?=
=?UTF-8?q?=E6=97=A0=E6=B3=95=E8=84=B1=E7=A6=BBeasyorm=E7=9B=B8=E5=85=B3?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E4=BD=BF=E7=94=A8=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 2 +-
...onBeanDefinitionRegistryPostProcessor.java | 46 +++++++++++++++++++
src/main/resources/META-INF/spring.factories | 4 +-
3 files changed, 50 insertions(+), 2 deletions(-)
create mode 100644 src/main/java/org/hswebframework/web/crud/configuration/EasyormConfigurationBeanDefinitionRegistryPostProcessor.java
diff --git a/pom.xml b/pom.xml
index 5d8d83b..f0ff083 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.hswebframework
hsweb-incubator-easyorm-clickhouse
- 1.0-SNAPSHOT
+ 1.1-SNAPSHOT
8
diff --git a/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfigurationBeanDefinitionRegistryPostProcessor.java b/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfigurationBeanDefinitionRegistryPostProcessor.java
new file mode 100644
index 0000000..c68cfe4
--- /dev/null
+++ b/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfigurationBeanDefinitionRegistryPostProcessor.java
@@ -0,0 +1,46 @@
+package org.hswebframework.web.crud.configuration;
+
+import org.hswebframework.ezorm.rdb.mapping.defaults.DefaultReactiveRepository;
+import org.hswebframework.utils.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+
+/**
+ * @className EasyormConfigurationBeanDefinitionRegistryPostProcessor
+ * @Description TODO
+ * @Author zhong
+ * @Date 2023/10/8 14:07
+ * @Vesion 1.0
+ */
+@Component
+public class EasyormConfigurationBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, ApplicationContextAware {
+ private ApplicationContext applicationContext;
+ @Override
+ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
+ Environment environment =applicationContext.getEnvironment();
+ if (StringUtils.isNullOrEmpty(environment.getProperty("easyorm.dialect"))){
+ String[] beanNames = ((DefaultListableBeanFactory) registry).getBeanNamesForType(DefaultReactiveRepository.class);
+ Arrays.stream(beanNames).forEach(item-> registry.removeBeanDefinition(item));
+ registry.removeBeanDefinition("org.hswebframework.web.crud.configuration.AutoDDLProcessor_1");
+ }
+ }
+
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext=applicationContext;
+ }
+}
diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories
index ce6376f..556ddf6 100644
--- a/src/main/resources/META-INF/spring.factories
+++ b/src/main/resources/META-INF/spring.factories
@@ -1,2 +1,4 @@
# Auto Configure
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseHelper
\ No newline at end of file
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ org.hswebframework.ezorm.rdb.supports.clickhouse.ClickhouseHelper,\
+ org.hswebframework.web.crud.configuration.EasyormConfigurationBeanDefinitionRegistryPostProcessor
\ No newline at end of file
From 3b79b74aad13db423caabcb41f6bd8ac1edb4db0 Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Fri, 13 Oct 2023 09:13:05 +0800
Subject: [PATCH 06/16] =?UTF-8?q?add:=20=E5=AF=B9clickhouse=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E7=B1=BB=E5=9E=8B=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 24 ++++++++-
.../clickhouse/ClickhouseDataType.java | 29 +++++++++++
.../clickhouse/ClickhouseDialect.java | 49 ++++---------------
3 files changed, 61 insertions(+), 41 deletions(-)
create mode 100644 src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDataType.java
diff --git a/pom.xml b/pom.xml
index f0ff083..fd6ed2c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,7 +48,29 @@
always
-
+
+
+ sct-releases
+ Nexus Release Repository
+ http://192.168.9.91:81/repository/maven-releases/
+
+
+ sct-snapshots
+ Nexus Snapshot Repository
+ http://192.168.9.91:81/repository/maven-snapshots/
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 2.8.2
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDataType.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDataType.java
new file mode 100644
index 0000000..1d57cea
--- /dev/null
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDataType.java
@@ -0,0 +1,29 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse;
+
+/**
+ * @author dengpengyu
+ * @date 2023/10/12 15:16
+ */
+public interface ClickhouseDataType {
+
+ String INT8 = "Int8";
+
+ String INT16 = "Int16";
+
+ String INT32 = "Int32";
+
+ String INT64 = "Int64";
+
+ String INT128 = "Int128";
+
+ String INT256 = "Int256";
+
+ String STRING = "string";
+
+ String UUID = "UUID";
+
+ String Data = "Data";
+
+ String DATETIME64 = "DateTime64";
+
+}
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
index c73003a..462b6fb 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
@@ -8,6 +8,7 @@
import java.sql.Date;
import java.sql.JDBCType;
import java.time.LocalDate;
+import java.util.UUID;
/**
* @className ClickhouseDire
@@ -19,46 +20,14 @@
public class ClickhouseDialect extends DefaultDialect {
public ClickhouseDialect() {
-
-
- addDataTypeBuilder(JDBCType.TINYINT, (meta) -> "Int8");
- addDataTypeBuilder(JDBCType.BOOLEAN, (meta) -> "Int8");
-
-
- addDataTypeBuilder(JDBCType.VARCHAR, (meta) -> "string");
- addDataTypeBuilder(JDBCType.NVARCHAR, (meta) -> StringUtils.concat("nvarchar(", meta.getLength(), ")"));
- addDataTypeBuilder(JDBCType.TIMESTAMP, (meta) -> "datetime(" + Math.min(6, meta.getLength()) + ")");
- addDataTypeBuilder(JDBCType.TIME, (meta) -> "time");
- addDataTypeBuilder(JDBCType.DATE, (meta) -> "date");
- addDataTypeBuilder(JDBCType.CLOB, (meta) -> "text");
- addDataTypeBuilder(JDBCType.LONGVARBINARY, (meta) -> "blob");
- addDataTypeBuilder(JDBCType.LONGVARCHAR, (meta) -> "longtext");
- addDataTypeBuilder(JDBCType.BLOB, (meta) -> "blob");
- addDataTypeBuilder(JDBCType.BIGINT, (meta) -> "bigint");
- addDataTypeBuilder(JDBCType.DOUBLE, (meta) -> "double");
- addDataTypeBuilder(JDBCType.INTEGER, (meta) -> "int");
- addDataTypeBuilder(JDBCType.NUMERIC, (meta) -> StringUtils.concat("decimal(", meta.getPrecision(32), ",", meta.getScale(), ")"));
- addDataTypeBuilder(JDBCType.DECIMAL, (meta) -> StringUtils.concat("decimal(", meta.getPrecision(32), ",", meta.getScale(), ")"));
- addDataTypeBuilder(JDBCType.TINYINT, (meta) -> "tinyint");
- addDataTypeBuilder(JDBCType.BOOLEAN, (meta) -> "tinyint");
- addDataTypeBuilder(JDBCType.BIGINT, (meta) -> "bigint");
- addDataTypeBuilder(JDBCType.OTHER, (meta) -> "other");
- addDataTypeBuilder(JDBCType.LONGNVARCHAR, (meta) -> "text");
-
- addDataTypeBuilder("int", (meta) -> "int");
- addDataTypeBuilder("json", meta -> "json");
- registerDataType("date", JdbcDataType.of(JDBCType.VARCHAR, String.class));
- registerDataType("clob", DataType.builder(JdbcDataType.of(JDBCType.CLOB, String.class), c -> "text"));
- registerDataType("longnvarchar", DataType.builder(JdbcDataType.of(JDBCType.LONGNVARCHAR, String.class), c -> "longtext"));
- registerDataType("longvarchar", DataType.builder(JdbcDataType.of(JDBCType.LONGVARCHAR, String.class), c -> "longtext"));
-
- registerDataType("int", JdbcDataType.of(JDBCType.INTEGER, Integer.class));
- registerDataType("text", JdbcDataType.of(JDBCType.CLOB, String.class));
- registerDataType("longtext", JdbcDataType.of(JDBCType.LONGVARCHAR, String.class));
- registerDataType("year", JdbcDataType.of(JDBCType.DATE, Date.class));
- registerDataType("text", JdbcDataType.of(JDBCType.CLOB, Date.class));
- registerDataType("datetime", JdbcDataType.of(JDBCType.TIMESTAMP, Date.class));
-
+ addDataTypeBuilder(JDBCType.TINYINT, (meta) -> ClickhouseDataType.INT8);
+ addDataTypeBuilder(JDBCType.BOOLEAN, (meta) -> ClickhouseDataType.INT8);
+ addDataTypeBuilder(JDBCType.SMALLINT, (meta) -> ClickhouseDataType.INT16);
+ addDataTypeBuilder(JDBCType.INTEGER, (meta) -> ClickhouseDataType.INT32);
+ addDataTypeBuilder(JDBCType.BIGINT, (meta) -> ClickhouseDataType.INT64);
+ addDataTypeBuilder(JDBCType.VARCHAR, (meta) -> ClickhouseDataType.STRING);
+ registerDataType("uuid", JdbcDataType.of(JDBCType.VARCHAR, String.class));
+ registerDataType("timestamp", JdbcDataType.of(JDBCType.BIGINT, Long.class));
}
@Override
From 70057e8ca9b4624fce707e551f360d106c117778 Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Fri, 13 Oct 2023 15:37:33 +0800
Subject: [PATCH 07/16] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9date=E5=85=B3?=
=?UTF-8?q?=E9=94=AE=E5=AD=97=E7=9A=84=E7=B1=BB=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 16 +++++++++++++++-
.../supports/clickhouse/ClickhouseDialect.java | 2 ++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index fd6ed2c..392abcb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.hswebframework
hsweb-incubator-easyorm-clickhouse
- 1.1-SNAPSHOT
+ 1.0-RELEASES
8
@@ -71,6 +71,20 @@
maven-deploy-plugin
2.8.2
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.1.2
+
+
+ package
+
+ jar
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
index 462b6fb..6055893 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
@@ -4,6 +4,7 @@
import org.hswebframework.ezorm.rdb.metadata.DataType;
import org.hswebframework.ezorm.rdb.metadata.JdbcDataType;
import org.hswebframework.ezorm.rdb.metadata.dialect.DefaultDialect;
+import org.joda.time.DateTime;
import java.sql.Date;
import java.sql.JDBCType;
@@ -28,6 +29,7 @@ public ClickhouseDialect() {
addDataTypeBuilder(JDBCType.VARCHAR, (meta) -> ClickhouseDataType.STRING);
registerDataType("uuid", JdbcDataType.of(JDBCType.VARCHAR, String.class));
registerDataType("timestamp", JdbcDataType.of(JDBCType.BIGINT, Long.class));
+ registerDataType("date", JdbcDataType.of(JDBCType.VARCHAR, String.class));
}
@Override
From 5a8fa4adedbb235e7f4cba4c34e7fb64fb3bcea9 Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Mon, 16 Oct 2023 15:19:15 +0800
Subject: [PATCH 08/16] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E6=89=A7?=
=?UTF-8?q?=E8=A1=8CSQL=E6=97=A5=E5=BF=97=E7=BA=A7=E5=88=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
index b426483..fc2705e 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
@@ -75,7 +75,7 @@ private Flux doExecute(Publisher requests) {
} else {
sql = request.toNativeSql() + " FORMAT JSON";
}
- log.info("Execute ==> {}", sql);
+ log.trace("Execute ==> {}", sql);
return client
.post()
.bodyValue(sql)
From e39e1d7a0438227b7a802b64a2e74c4d06aa3732 Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Fri, 17 Nov 2023 14:59:43 +0800
Subject: [PATCH 09/16] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E6=A3=80?=
=?UTF-8?q?=E6=9F=A5=E7=BB=93=E6=9E=9C=E7=9A=84=E9=A1=BA=E5=BA=8F=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 2 +-
.../rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index 392abcb..a7709fd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.hswebframework
hsweb-incubator-easyorm-clickhouse
- 1.0-RELEASES
+ 1.0-SNAPSHOT
8
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
index fc2705e..2090b42 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
@@ -82,8 +82,8 @@ private Flux doExecute(Publisher requests) {
.exchangeToMono(response -> response
.bodyToMono(String.class)
.map(json -> {
- checkExecuteResult(sql, json);
JSONObject result = JSON.parseObject(json);
+ checkExecuteResult(sql, json);
return result;
}));
From 6ad7bf0d643ffed43d86e3273ce0b3b8e5f0573a Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Sat, 18 Nov 2023 10:14:19 +0800
Subject: [PATCH 10/16] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E6=8F=92=E5=85=A5=E4=B8=8D=E8=BF=9B=E5=8E=BB=E7=9A=84?=
=?UTF-8?q?=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../service/ClickhouseReactiveCrudService.java | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java b/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
index 50a5dda..6d00afb 100644
--- a/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
+++ b/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
@@ -19,8 +19,11 @@ public abstract class ClickhouseReactiveCrudService implements ReactiveCru
@Override
public ReactiveRepository getRepository() {
- return clickhouseHelper.createRepository(getEntityClass());
+ if (repository == null) {
+ repository = clickhouseHelper.createRepository(getEntityClass());
+ }
+ return repository;
}
- public abstract Class getEntityClass();
+ public abstract Class getEntityClass();
}
From bffd0fc49f111d29f5df765204edaaf127233adc Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Fri, 12 Jan 2024 20:04:13 +0800
Subject: [PATCH 11/16] add .gitignore
---
.gitignore | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index bc8a670..c0fb2d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,27 @@
-.idea/*
\ No newline at end of file
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+*.idea
+*.iml
+target
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+replay_pid*
From 0f2c2d9b90e9377ae02bafcfaa592e956fa1007f Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Sat, 13 Jan 2024 09:54:54 +0800
Subject: [PATCH 12/16] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96Service=E8=8E=B7?=
=?UTF-8?q?=E5=8F=96class?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../service/ClickhouseReactiveCrudService.java | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java b/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
index 6d00afb..f701ed8 100644
--- a/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
+++ b/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
@@ -12,18 +12,24 @@
*/
public abstract class ClickhouseReactiveCrudService implements ReactiveCrudService {
+ private final Class clazz;
+
private ReactiveRepository repository;
@Autowired
private ClickhouseHelper clickhouseHelper;
+ public ClickhouseReactiveCrudService(Class clazz) {
+ this.clazz = clazz;
+ }
+
@Override
public ReactiveRepository getRepository() {
if (repository == null) {
- repository = clickhouseHelper.createRepository(getEntityClass());
+ repository = clickhouseHelper.createRepository(clazz);
}
return repository;
}
- public abstract Class getEntityClass();
+// public abstract Class getEntityClass();
}
From 72d39140dac84f67aa0c4a5cdc3a77a9886acde4 Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Tue, 16 Jan 2024 16:36:08 +0800
Subject: [PATCH 13/16] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=B0=81?=
=?UTF-8?q?=E8=A3=85=E6=9F=A5=E8=AF=A2=E6=95=B0=E6=8D=AE=E5=90=8E=E7=9A=84?=
=?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
hsweb-incubator-easyorm-clickhouse.iml | 38 +++++-----
pom.xml | 2 +-
.../clickhouse/ClickhouseDataType.java | 69 +++++++++++++------
.../clickhouse/ClickhouseDialect.java | 18 ++---
.../ClickhouseRestfulSqlExecutor.java | 53 ++++++++------
.../ClickhouseReactiveCrudService.java | 12 ++--
...onBeanDefinitionRegistryPostProcessor.java | 2 +-
7 files changed, 111 insertions(+), 83 deletions(-)
diff --git a/hsweb-incubator-easyorm-clickhouse.iml b/hsweb-incubator-easyorm-clickhouse.iml
index 835b7dd..4cb7b15 100644
--- a/hsweb-incubator-easyorm-clickhouse.iml
+++ b/hsweb-incubator-easyorm-clickhouse.iml
@@ -15,12 +15,12 @@
-
-
+
+
-
+
-
+
@@ -30,17 +30,17 @@
-
-
-
+
+
+
-
-
-
+
+
+
@@ -50,18 +50,18 @@
-
+
-
-
-
-
-
+
+
+
+
+
@@ -70,13 +70,13 @@
-
-
+
+
-
+
diff --git a/pom.xml b/pom.xml
index a7709fd..0ab5a5f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
8
8
- 4.0.16
+ 4.0.17-SNAPSHOT
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDataType.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDataType.java
index 1d57cea..ad3c289 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDataType.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDataType.java
@@ -1,29 +1,54 @@
package org.hswebframework.ezorm.rdb.supports.clickhouse;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.hswebframework.web.dict.EnumDict;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Array;
+
/**
* @author dengpengyu
* @date 2023/10/12 15:16
*/
-public interface ClickhouseDataType {
-
- String INT8 = "Int8";
-
- String INT16 = "Int16";
-
- String INT32 = "Int32";
-
- String INT64 = "Int64";
-
- String INT128 = "Int128";
-
- String INT256 = "Int256";
-
- String STRING = "string";
-
- String UUID = "UUID";
-
- String Data = "Data";
-
- String DATETIME64 = "DateTime64";
-
+@AllArgsConstructor
+@Getter
+public enum ClickhouseDataType implements EnumDict> {
+
+ INT8(Byte.class),
+ INT16(Short.class),
+ INT32(Integer.class),
+ INT64(Long.class),
+ INT128(BigInteger.class),
+ INT256(BigInteger.class),
+ UINT8(Short.class),
+ UINT16(Integer.class),
+ UINT32(Long.class),
+ UINT64(BigInteger.class),
+ NULLABLE_UINT64(BigInteger.class),
+ FLOAT32(Float.class),
+ FLOAT64(Double.class),
+ STRING(String.class),
+ UUID(String.class),
+ BOOLEAN(Boolean.class),
+ DATE(java.sql.Date.class),
+ DATETIME(java.sql.Timestamp.class),
+ DATETIME64(java.time.LocalDateTime.class),
+ ARRAY(Array.class), // This would be a placeholder, actual implementation depends on the array type
+ ENUM(String.class), // Enums in Clickhouse are typically represented as strings in Java
+ DECIMAL(BigDecimal.class),
+ IP(String.class); // IP address types can be represented as strings
+
+ private final Class> javaType;
+
+ @Override
+ public Class> getValue() {
+ return javaType;
+ }
+
+ @Override
+ public String getText() {
+ return name();
+ }
}
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
index 6055893..ccb020f 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDialect.java
@@ -1,15 +1,9 @@
package org.hswebframework.ezorm.rdb.supports.clickhouse;
-import org.hswebframework.ezorm.core.utils.StringUtils;
-import org.hswebframework.ezorm.rdb.metadata.DataType;
import org.hswebframework.ezorm.rdb.metadata.JdbcDataType;
import org.hswebframework.ezorm.rdb.metadata.dialect.DefaultDialect;
-import org.joda.time.DateTime;
-import java.sql.Date;
import java.sql.JDBCType;
-import java.time.LocalDate;
-import java.util.UUID;
/**
* @className ClickhouseDire
@@ -21,12 +15,12 @@
public class ClickhouseDialect extends DefaultDialect {
public ClickhouseDialect() {
- addDataTypeBuilder(JDBCType.TINYINT, (meta) -> ClickhouseDataType.INT8);
- addDataTypeBuilder(JDBCType.BOOLEAN, (meta) -> ClickhouseDataType.INT8);
- addDataTypeBuilder(JDBCType.SMALLINT, (meta) -> ClickhouseDataType.INT16);
- addDataTypeBuilder(JDBCType.INTEGER, (meta) -> ClickhouseDataType.INT32);
- addDataTypeBuilder(JDBCType.BIGINT, (meta) -> ClickhouseDataType.INT64);
- addDataTypeBuilder(JDBCType.VARCHAR, (meta) -> ClickhouseDataType.STRING);
+ addDataTypeBuilder(JDBCType.TINYINT, (meta) -> ClickhouseDataType.INT8.getText());
+ addDataTypeBuilder(JDBCType.BOOLEAN, (meta) -> ClickhouseDataType.INT8.getText());
+ addDataTypeBuilder(JDBCType.SMALLINT, (meta) -> ClickhouseDataType.INT16.getText());
+ addDataTypeBuilder(JDBCType.INTEGER, (meta) -> ClickhouseDataType.INT32.getText());
+ addDataTypeBuilder(JDBCType.BIGINT, (meta) -> ClickhouseDataType.INT64.getText());
+ addDataTypeBuilder(JDBCType.VARCHAR, (meta) -> ClickhouseDataType.STRING.getText());
registerDataType("uuid", JdbcDataType.of(JDBCType.VARCHAR, String.class));
registerDataType("timestamp", JdbcDataType.of(JDBCType.BIGINT, Long.class));
registerDataType("date", JdbcDataType.of(JDBCType.VARCHAR, String.class));
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
index 2090b42..7f65a71 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
+import lombok.SneakyThrows;
import org.hswebframework.ezorm.rdb.executor.BatchSqlRequest;
import org.hswebframework.ezorm.rdb.executor.DefaultColumnWrapperContext;
import org.hswebframework.ezorm.rdb.executor.SqlRequest;
@@ -16,7 +17,8 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.util.List;
+import java.lang.reflect.Constructor;
+import java.util.*;
import java.util.stream.Collectors;
/**
@@ -98,36 +100,43 @@ private void checkExecuteResult(String sql, String code) {
protected Flux convertQueryResult(JSONObject result, ResultWrapper wrapper) {
- JSONArray head = result.getJSONArray("meta");
- JSONArray data = result.getJSONArray("data");
+ Map columnMeta = new HashMap();
- if (CollectionUtils.isEmpty(head) || CollectionUtils.isEmpty(data)) {
+ JSONArray resultMeta = result.getJSONArray("meta");
+ JSONArray resultEntityList = result.getJSONArray("data");
+
+ if (CollectionUtils.isEmpty(resultMeta) || CollectionUtils.isEmpty(resultEntityList)) {
return Flux.empty();
}
- List columns = head.stream()
- .map(v -> ((JSONObject) v).get("name").toString())
- .collect(Collectors.toList());
+ //把当前列和列类型一一对应
+ for (Object o : resultMeta) {
+ JSONObject e = (JSONObject) o;
+ columnMeta.put(e.getString("name"), ClickhouseDataType.valueOf(e.getString("type").toUpperCase().replace("NULLABLE(", "").replace(")", "")));
+ }
+ //所有的列名
+ ArrayList columns = new ArrayList<>(columnMeta.keySet());
return Flux.create(sink -> {
wrapper.beforeWrap(() -> columns);
- for (Object rowo : data) {
+ for (Object oneObjectEntity : resultEntityList) {
E rowInstance = wrapper.newRowInstance();
- JSONObject row = (JSONObject) rowo;
- for (int i = 0; i < columns.size(); i++) {
- String property = columns.get(i);
- Object value = row.get(property);
- if ("total".equals(property)) {
- value = Long.valueOf(row.get(property).toString());
- } else {
- value = row.get(property);
- }
- try{
- value = Double.valueOf(row.get(property).toString());
- }catch (Exception e){
- value = row.get(property);
+ JSONObject oneJsonObjectEntity = (JSONObject) oneObjectEntity;
+ for (String columnName : columns) {
+// String columnName = columns.get(i);
+ Object value = oneJsonObjectEntity.get(columnName);
+ ClickhouseDataType dataType = columnMeta.get(columnName);
+ try {
+ Class> typeClass = dataType.getJavaType();
+ Constructor> constructor = typeClass.getConstructor(String.class);
+
+ if (Objects.nonNull(value)) {
+ value = constructor.newInstance(value.toString());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
}
- DefaultColumnWrapperContext context = new DefaultColumnWrapperContext<>(i, property, value, rowInstance);
+ DefaultColumnWrapperContext context = new DefaultColumnWrapperContext<>(columns.indexOf(columnName), columnName, value, rowInstance);
wrapper.wrapColumn(context);
rowInstance = context.getRowInstance();
}
diff --git a/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java b/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
index f701ed8..d1a7454 100644
--- a/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
+++ b/src/main/java/org/hswebframework/service/ClickhouseReactiveCrudService.java
@@ -12,24 +12,24 @@
*/
public abstract class ClickhouseReactiveCrudService implements ReactiveCrudService {
- private final Class clazz;
+// private Class clazz;
private ReactiveRepository repository;
@Autowired
private ClickhouseHelper clickhouseHelper;
- public ClickhouseReactiveCrudService(Class clazz) {
- this.clazz = clazz;
- }
+// public ClickhouseReactiveCrudService(Class clazz) {
+// this.clazz = clazz;
+// }
@Override
public ReactiveRepository getRepository() {
if (repository == null) {
- repository = clickhouseHelper.createRepository(clazz);
+ repository = clickhouseHelper.createRepository(getEntityClass());
}
return repository;
}
-// public abstract Class getEntityClass();
+ public abstract Class getEntityClass();
}
diff --git a/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfigurationBeanDefinitionRegistryPostProcessor.java b/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfigurationBeanDefinitionRegistryPostProcessor.java
index c68cfe4..ae89ef5 100644
--- a/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfigurationBeanDefinitionRegistryPostProcessor.java
+++ b/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfigurationBeanDefinitionRegistryPostProcessor.java
@@ -31,7 +31,7 @@ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) t
if (StringUtils.isNullOrEmpty(environment.getProperty("easyorm.dialect"))){
String[] beanNames = ((DefaultListableBeanFactory) registry).getBeanNamesForType(DefaultReactiveRepository.class);
Arrays.stream(beanNames).forEach(item-> registry.removeBeanDefinition(item));
- registry.removeBeanDefinition("org.hswebframework.web.crud.configuration.AutoDDLProcessor_1");
+// registry.removeBeanDefinition("org.hswebframework.web.crud.configuration.AutoDDLProcessor_1");
}
}
From 385ab776907b830fd3549bedbf52bc8b0c4d5f89 Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Wed, 17 Jan 2024 10:37:37 +0800
Subject: [PATCH 14/16] =?UTF-8?q?add:=20=E5=A2=9E=E5=8A=A0clickhouse?=
=?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=89=A7=E8=A1=8C=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../supports/clickhouse/ClickhouseHelper.java | 7 +-
...ava => ClickhouseReactiveSqlExecutor.java} | 9 +-
.../clickhouse/ClickhouseSyncSqlExecutor.java | 177 ++++++++++++++++++
.../ezorm/rdb/supports/clickhouse/Helper.java | 7 +-
4 files changed, 190 insertions(+), 10 deletions(-)
rename src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/{ClickhouseRestfulSqlExecutor.java => ClickhouseReactiveSqlExecutor.java} (94%)
create mode 100644 src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseSyncSqlExecutor.java
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseHelper.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseHelper.java
index e7c3085..2ad3df2 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseHelper.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseHelper.java
@@ -42,6 +42,11 @@ public ReactiveSqlExecutor getReactiveSqlExecutor() {
.defaultHeader("X-ClickHouse-Key", properties.getPassword())
.build();
- return new ClickhouseRestfulSqlExecutor(clickhouseWebClient);
+ return new ClickhouseReactiveSqlExecutor(clickhouseWebClient);
+ }
+
+ @Override
+ public ClickhouseProperties getClickhouseProperties() {
+ return properties;
}
}
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseReactiveSqlExecutor.java
similarity index 94%
rename from src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
rename to src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseReactiveSqlExecutor.java
index 7f65a71..f572cde 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseRestfulSqlExecutor.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseReactiveSqlExecutor.java
@@ -3,7 +3,6 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
-import lombok.SneakyThrows;
import org.hswebframework.ezorm.rdb.executor.BatchSqlRequest;
import org.hswebframework.ezorm.rdb.executor.DefaultColumnWrapperContext;
import org.hswebframework.ezorm.rdb.executor.SqlRequest;
@@ -19,7 +18,6 @@
import java.lang.reflect.Constructor;
import java.util.*;
-import java.util.stream.Collectors;
/**
* @className ClickhouseRestfulSqlExecutor
@@ -28,11 +26,11 @@
* @Date 2023/9/4 14:40
* @Vesion 1.0
*/
-public class ClickhouseRestfulSqlExecutor implements ReactiveSqlExecutor {
- private Logger log = LoggerFactory.getLogger(ClickhouseRestfulSqlExecutor.class);
+public class ClickhouseReactiveSqlExecutor implements ReactiveSqlExecutor {
+ private Logger log = LoggerFactory.getLogger(ClickhouseReactiveSqlExecutor.class);
private WebClient client;
- public ClickhouseRestfulSqlExecutor(WebClient client) {
+ public ClickhouseReactiveSqlExecutor(WebClient client) {
this.client = client;
}
@@ -123,7 +121,6 @@ protected Flux convertQueryResult(JSONObject result, ResultWrapper
E rowInstance = wrapper.newRowInstance();
JSONObject oneJsonObjectEntity = (JSONObject) oneObjectEntity;
for (String columnName : columns) {
-// String columnName = columns.get(i);
Object value = oneJsonObjectEntity.get(columnName);
ClickhouseDataType dataType = columnMeta.get(columnName);
try {
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseSyncSqlExecutor.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseSyncSqlExecutor.java
new file mode 100644
index 0000000..880e64e
--- /dev/null
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseSyncSqlExecutor.java
@@ -0,0 +1,177 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import org.hswebframework.ezorm.core.meta.Feature;
+import org.hswebframework.ezorm.rdb.executor.BatchSqlRequest;
+import org.hswebframework.ezorm.rdb.executor.DefaultColumnWrapperContext;
+import org.hswebframework.ezorm.rdb.executor.SqlRequest;
+import org.hswebframework.ezorm.rdb.executor.SyncSqlExecutor;
+import org.hswebframework.ezorm.rdb.executor.wrapper.ResultWrapper;
+import org.hswebframework.web.crud.configuration.ClickhouseProperties;
+import org.reactivestreams.Publisher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.client.RestTemplate;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.lang.reflect.Constructor;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * @className ClickhouseReactiveSqlExecutor
+ * @Description TODO
+ * @Author zhong
+ * @Date 2024/1/16 14:55
+ * @Vesion 1.0
+ */
+@AllArgsConstructor(staticName = "of")
+public class ClickhouseSyncSqlExecutor implements SyncSqlExecutor {
+ private Logger log = LoggerFactory.getLogger(ClickhouseSyncSqlExecutor.class);
+
+ private RestTemplate restTemplate;
+
+ private String url;
+
+ private HttpHeaders headers;
+
+ public ClickhouseSyncSqlExecutor(ClickhouseProperties clickhouseProperties) {
+ restTemplate =new RestTemplate();
+ this.url=clickhouseProperties.getUrl();
+ headers = new HttpHeaders();
+ headers.add("X-ClickHouse-User", clickhouseProperties.getUsername());
+ headers.add("X-ClickHouse-Key", clickhouseProperties.getPassword());
+ }
+
+ public static Feature of(ClickhouseProperties clickhouseProperties) {
+ return new ClickhouseSyncSqlExecutor(clickhouseProperties);
+ }
+
+
+
+ @Override
+ @SneakyThrows
+ public int update(SqlRequest request) {
+ return this
+ .doExecute(Mono.just(request))
+ .then(Mono.just(1)).toFuture().get(30, TimeUnit.SECONDS);
+
+ }
+
+ @Override
+ @SneakyThrows
+ public void execute(SqlRequest request) {
+
+ this
+ .doExecute(Mono.just(request))
+ .then()
+ .toFuture().get(30,TimeUnit.SECONDS);
+
+ }
+
+ @Override
+ @SneakyThrows
+ public R select(SqlRequest request, ResultWrapper wrapper) {
+ this
+ .doExecute(Mono.just(request))
+ .flatMap(response -> convertQueryResult(response, wrapper))
+ .collectList().toFuture().get(30,TimeUnit.SECONDS);
+
+ return wrapper.getResult();
+
+ }
+
+
+ private Flux doExecute(Publisher requests) {
+ return Flux
+ .from(requests)
+ .expand(request -> {
+ if (request instanceof BatchSqlRequest) {
+ return Flux.fromIterable(((BatchSqlRequest) request).getBatch());
+ }
+ return Flux.empty();
+ })
+
+ .filter(SqlRequest::isNotEmpty)
+ .concatMap(request -> {
+ String sql;
+ if (request.toNativeSql().toUpperCase().startsWith("INSERT")
+ || request.toNativeSql().toUpperCase().startsWith("ALTER")) {
+ sql = request.toNativeSql();
+ } else {
+ sql = request.toNativeSql() + " FORMAT JSON";
+ }
+ log.info("Execute ==> {}", sql);
+ HttpEntity requestEntity = new HttpEntity<>(sql, headers);
+ ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
+ JSONObject result = JSON.parseObject(responseEntity.getBody());
+
+ return Mono.just(result);
+ })
+ ;
+ }
+
+ protected Flux convertQueryResult(JSONObject result, ResultWrapper wrapper) {
+
+ Map columnMeta = new HashMap();
+
+ JSONArray resultMeta = result.getJSONArray("meta");
+ JSONArray resultEntityList = result.getJSONArray("data");
+
+ if (CollectionUtils.isEmpty(resultMeta) || CollectionUtils.isEmpty(resultEntityList)) {
+ return Flux.empty();
+ }
+ //把当前列和列类型一一对应
+ for (Object o : resultMeta) {
+ JSONObject e = (JSONObject) o;
+ columnMeta.put(e.getString("name"), ClickhouseDataType.valueOf(e.getString("type").toUpperCase().replace("NULLABLE(", "").replace(")", "")));
+ }
+ //所有的列名
+ ArrayList columns = new ArrayList<>(columnMeta.keySet());
+
+ return Flux.create(sink -> {
+ wrapper.beforeWrap(() -> columns);
+
+ for (Object oneObjectEntity : resultEntityList) {
+ E rowInstance = wrapper.newRowInstance();
+ JSONObject oneJsonObjectEntity = (JSONObject) oneObjectEntity;
+ for (String columnName : columns) {
+ Object value = oneJsonObjectEntity.get(columnName);
+ ClickhouseDataType dataType = columnMeta.get(columnName);
+ try {
+ Class> typeClass = dataType.getJavaType();
+ Constructor> constructor = typeClass.getConstructor(String.class);
+
+ if (Objects.nonNull(value)) {
+ value = constructor.newInstance(value.toString());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ DefaultColumnWrapperContext context = new DefaultColumnWrapperContext<>(columns.indexOf(columnName), columnName, value, rowInstance);
+ wrapper.wrapColumn(context);
+ rowInstance = context.getRowInstance();
+ }
+ if (!wrapper.completedWrapRow(rowInstance)) {
+ break;
+ }
+ if (rowInstance != null) {
+ sink.next(rowInstance);
+ }
+ }
+ wrapper.completedWrap();
+ sink.complete();
+ });
+ }}
+
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/Helper.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/Helper.java
index 9f843b1..20fb658 100644
--- a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/Helper.java
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/Helper.java
@@ -15,6 +15,7 @@
import org.hswebframework.ezorm.rdb.metadata.dialect.Dialect;
import org.hswebframework.ezorm.rdb.operator.DatabaseOperator;
import org.hswebframework.ezorm.rdb.operator.DefaultDatabaseOperator;
+import org.hswebframework.web.crud.configuration.ClickhouseProperties;
import java.util.function.Supplier;
@@ -30,6 +31,8 @@ public interface Helper {
ReactiveSqlExecutor getReactiveSqlExecutor();
+ ClickhouseProperties getClickhouseProperties();
+
default RDBDatabaseMetadata getRDBDatabaseMetadata() {
RDBDatabaseMetadata metadata = new RDBDatabaseMetadata(getDialect());
@@ -37,12 +40,10 @@ default RDBDatabaseMetadata getRDBDatabaseMetadata() {
ReactiveSqlExecutor sqlExecutor = getReactiveSqlExecutor();
-// schema.addFeature((EventListener) (type, context) -> System.out.println(type));
-
metadata.setCurrentSchema(schema);
metadata.addSchema(schema);
metadata.addFeature(sqlExecutor);
- metadata.addFeature(ReactiveSyncSqlExecutor.of(sqlExecutor));
+ metadata.addFeature(ClickhouseSyncSqlExecutor.of(getClickhouseProperties()));
return metadata;
}
From 9af65be1638be51171767621c899a74e09b26b6a Mon Sep 17 00:00:00 2001
From: PengyuDeng <89559616+PengyuDeng@users.noreply.github.com>
Date: Fri, 19 Jan 2024 11:12:54 +0800
Subject: [PATCH 15/16] =?UTF-8?q?fix:=20=E9=87=8D=E5=86=99=E4=BB=93?=
=?UTF-8?q?=E5=BA=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ClickhouseDefaultRepository.java | 262 ++++++++++++++++++
.../ClickhouseReactiveDefaultRepository.java | 163 +++++++++++
.../ezorm/rdb/supports/clickhouse/Helper.java | 4 +-
3 files changed, 426 insertions(+), 3 deletions(-)
create mode 100644 src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDefaultRepository.java
create mode 100644 src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseReactiveDefaultRepository.java
diff --git a/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDefaultRepository.java b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDefaultRepository.java
new file mode 100644
index 0000000..93e75a3
--- /dev/null
+++ b/src/main/java/org/hswebframework/ezorm/rdb/supports/clickhouse/ClickhouseDefaultRepository.java
@@ -0,0 +1,262 @@
+package org.hswebframework.ezorm.rdb.supports.clickhouse;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.hswebframework.ezorm.core.GlobalConfig;
+import org.hswebframework.ezorm.core.ObjectPropertyOperator;
+import org.hswebframework.ezorm.rdb.events.ContextKeyValue;
+import org.hswebframework.ezorm.rdb.events.ContextKeys;
+import org.hswebframework.ezorm.rdb.executor.wrapper.ResultWrapper;
+import org.hswebframework.ezorm.rdb.mapping.EntityColumnMapping;
+import org.hswebframework.ezorm.rdb.mapping.LazyEntityColumnMapping;
+import org.hswebframework.ezorm.rdb.mapping.MappingFeatureType;
+import org.hswebframework.ezorm.rdb.mapping.events.EventResultOperator;
+import org.hswebframework.ezorm.rdb.mapping.events.MappingContextKeys;
+import org.hswebframework.ezorm.rdb.mapping.events.MappingEventTypes;
+import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
+import org.hswebframework.ezorm.rdb.operator.DatabaseOperator;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.NativeSql;
+import org.hswebframework.ezorm.rdb.operator.dml.insert.InsertOperator;
+import org.hswebframework.ezorm.rdb.operator.dml.insert.InsertResultOperator;
+import org.hswebframework.ezorm.rdb.operator.dml.upsert.SaveResultOperator;
+import org.hswebframework.ezorm.rdb.operator.dml.upsert.UpsertOperator;
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+
+import static org.hswebframework.ezorm.rdb.events.ContextKeys.tableMetadata;
+import static org.hswebframework.ezorm.rdb.mapping.events.MappingContextKeys.*;
+import static org.hswebframework.ezorm.rdb.mapping.events.MappingContextKeys.insert;
+
+/**
+ * @className ClickhouseDefaultRepository
+ * @Description TODO
+ * @Author zhong
+ * @Date 2024/1/19 9:32
+ * @Vesion 1.0
+ */
+public abstract class ClickhouseDefaultRepository {
+ protected DatabaseOperator operator;
+
+ protected ResultWrapper wrapper;
+
+ private volatile String idColumn;
+
+ @Getter
+ protected EntityColumnMapping mapping;
+
+ @Setter
+ protected volatile String[] properties;
+
+ protected Supplier tableSupplier;
+
+ protected final List> defaultContextKeyValue = new ArrayList<>();
+
+ public ClickhouseDefaultRepository(DatabaseOperator operator, Supplier supplier, ResultWrapper wrapper) {
+ this.operator = operator;
+ this.wrapper = wrapper;
+ this.tableSupplier = supplier;
+ defaultContextKeyValue.add(repository.value(this));
+ defaultContextKeyValue.add(ContextKeys.database.value(operator));
+
+ }
+
+ protected RDBTableMetadata getTable() {
+ return tableSupplier.get();
+ }
+
+ protected ContextKeyValue>[] getDefaultContextKeyValue(ContextKeyValue>... kv) {
+ if (kv.length == 0) {
+ return defaultContextKeyValue.toArray(new ContextKeyValue[0]);
+ }
+ List> keyValues = new ArrayList<>(defaultContextKeyValue);
+ keyValues.addAll(Arrays.asList(kv));
+ return keyValues.toArray(new ContextKeyValue[0]);
+ }
+
+ public String[] getProperties() {
+ if (properties == null) {
+ properties = mapping
+ .getColumnPropertyMapping()
+ .entrySet()
+ .stream()
+ .filter(kv -> getTable().getColumn(kv.getKey()).isPresent())
+ .map(Map.Entry::getValue)
+ .toArray(String[]::new);
+ }
+ return properties;
+ }
+
+ protected String getIdColumn() {
+ if (idColumn == null) {
+ this.idColumn = getTable()
+ .getColumns()
+ .stream()
+ .filter(RDBColumnMetadata::isPrimaryKey)
+ .findFirst()
+ .map(RDBColumnMetadata::getName)
+ .orElseThrow(() -> new UnsupportedOperationException("id column not exists"));
+ }
+ return idColumn;
+ }
+
+ protected void initMapping(Class entityType) {
+
+ this.mapping = LazyEntityColumnMapping.of(() -> getTable()
+ .findFeature(MappingFeatureType.columnPropertyMapping.createFeatureId(entityType))
+ .orElseThrow(() -> new UnsupportedOperationException("unsupported columnPropertyMapping feature")));
+ defaultContextKeyValue.add(MappingContextKeys.columnMapping(mapping));
+ }
+
+ protected Collection tryMergeDuplicate(Collection data) {
+ if (data.isEmpty()) {
+ return data;
+ }
+ Map