diff --git a/README.md b/README.md index d234e464..a8b99b07 100644 --- a/README.md +++ b/README.md @@ -2,26 +2,26 @@ # 概述 -uno('u:no,读wu no)提供基础的组件,来构建大型复杂应用的能力,截止于2023-07-06目前包含如下组件库: +uno('u:no,读wu no)提供基础的组件,来构建大型复杂应用的能力。 -- core:核心库,提供通用的工具、事件总线、简易的类型系统、元数据转换,通用链式接口声明、简易的Task、Cache机制。 -- data:数据处理,包含通用查询模块、orm框架。 -- rule:规则引擎。 -- web:简易的web工具集,提供系统默认的HTTP请求端点。 -- test:基于spring环境方便使用的测试工具集。 +- core:核心库,提供通用的工具、事件总线、简易的类型系统、元数据转换,通用链式接口声明、简易的Task、Cache机制。 +- data:数据处理,包含通用查询模块、orm框架。 +- rule:规则引擎。 +- web:简易的web工具集,提供系统默认的HTTP请求端点。 +- test:基于spring环境方便使用的测试工具集。 - gis:构建mybatis的空间数据转换、jackson -> 标准geojson的转换、坐标系转换。 - auto:自动生成spi文件、还包括spring.factories。 - bom:项目包依赖集。 - plugins(未实现):通用的插件工具,包含微内核模式接口声明、jar包等第三方插件包加载与执行。 - components: 组件集合。 - - http: 构建openapi工具,响应式的http请求响应框架。 + - http: 构建openapi工具,响应式的http请求响应框架。 - kafka:基于响应式背压封装的kafka。 - media:多媒体组件,基于命令模式提供通用api。 - netty:封装netty,构建无集群模式的RPC框架。 - sequential:时序数据的处理,包含数据接收、转换、处理,基于响应式,背压特性高性能的数据处理。 - websocket:封装websocket,具有数据批推,发布订阅模式,客户端可以使用Topic的路径树化。 -- starter:为各个组件编写spring-starter包。 +- starter:为各个组件编写spring-starter包。 diff --git a/pom.xml b/pom.xml index 853c4747..85a1ae13 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ cc.allio uno pom - 1.1.5.RELEASE + 1.1.6-beta.1 构建大型应用需要的基本能力 --- all in one https://github.com/b6688c/uno @@ -36,7 +36,7 @@ 21 2020.0.12 - 3.2.0 + 3.2.1 3.2.1 3.8.1 3.1.0 @@ -200,50 +200,4 @@ - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - true - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - snapshots - https://oss.sonatype.org/content/repositories/snapshots/ - - true - - - true - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - true - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - \ No newline at end of file diff --git a/uno-auto/pom.xml b/uno-auto/pom.xml index c0c40516..20ea35b4 100644 --- a/uno-auto/pom.xml +++ b/uno-auto/pom.xml @@ -5,18 +5,12 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-auto - - 8 - 8 - UTF-8 - - diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/AbstractUnoProcessor.java b/uno-auto/src/main/java/cc/allio/uno/auto/AbstractUnoProcessor.java index a3a866a3..18832b36 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/AbstractUnoProcessor.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/AbstractUnoProcessor.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto; import javax.annotation.processing.AbstractProcessor; diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/BootAutoType.java b/uno-auto/src/main/java/cc/allio/uno/auto/BootAutoType.java index a28f17d9..0e488cb8 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/BootAutoType.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/BootAutoType.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto; /** diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/factories/AutoFactoriesProcessor.java b/uno-auto/src/main/java/cc/allio/uno/auto/factories/AutoFactoriesProcessor.java index e7e8c482..81d1fb09 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/factories/AutoFactoriesProcessor.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/factories/AutoFactoriesProcessor.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto.factories; import cc.allio.uno.auto.AbstractUnoProcessor; @@ -47,15 +31,13 @@ @SupportedAnnotationTypes("*") @SupportedOptions("debug") public class AutoFactoriesProcessor extends AbstractUnoProcessor { - /** - * The location to look for factories. - *

Can be present in multiple JAR files. - */ - private static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; /** * devtools,有 Configuration 注解的 jar 一般需要 devtools 配置文件 */ private static final String DEVTOOLS_RESOURCE_LOCATION = "META-INF/spring-devtools.properties"; + // Auto Configuration location + private static final String AUTO_CONFIGURATION_LOCATION = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports"; + /** * 数据承载 */ @@ -123,10 +105,10 @@ private void generateFactoriesFiles() { } Filer filer = processingEnv.getFiler(); try { - // 1. spring.factories - FileObject factoriesFile = filer.createResource(StandardLocation.CLASS_OUTPUT, "", FACTORIES_RESOURCE_LOCATION); - FactoriesFiles.writeFactoriesFile(factories, factoriesFile.openOutputStream()); - String classesPath = factoriesFile.toUri().toString().split("classes")[0]; + // 1. auto configuration file + FileObject autoConfigurationFile = filer.createResource(StandardLocation.CLASS_OUTPUT, "", AUTO_CONFIGURATION_LOCATION); + FactoriesFiles.writeFactoriesFile(factories, autoConfigurationFile.openOutputStream()); + String classesPath = autoConfigurationFile.toUri().toString().split("classes")[0]; Path projectPath = Paths.get(new URI(classesPath)).getParent(); // 2. devtools 配置,因为有 @Configuration 注解的需要 devtools String projectName = projectPath.getFileName().toString(); diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/factories/FactoriesFiles.java b/uno-auto/src/main/java/cc/allio/uno/auto/factories/FactoriesFiles.java index c75cd23e..e653c278 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/factories/FactoriesFiles.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/factories/FactoriesFiles.java @@ -1,22 +1,5 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto.factories; - import cc.allio.uno.auto.model.MultiSetMap; import java.io.BufferedWriter; @@ -34,48 +17,48 @@ * @author L.cm */ class FactoriesFiles { - private static final Charset UTF_8 = StandardCharsets.UTF_8; + private static final Charset UTF_8 = StandardCharsets.UTF_8; - /** - * 写出 spring.factories 文件 - * @param factories factories 信息 - * @param output 输出流 - * @throws IOException 异常信息 - */ - static void writeFactoriesFile(MultiSetMap factories, - OutputStream output) throws IOException { - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, UTF_8)); - Set keySet = factories.keySet(); - for (String key : keySet) { - Set values = factories.get(key); - if (values == null || values.isEmpty()) { - continue; - } - writer.write(key); - writer.write("=\\\n "); - StringJoiner joiner = new StringJoiner(",\\\n "); - for (String value : values) { - joiner.add(value); - } - writer.write(joiner.toString()); - writer.newLine(); - } - writer.flush(); - output.close(); - } + /** + * 写出 spring.factories 文件 + * + * @param factories factories 信息 + * @param output 输出流 + * @throws IOException 异常信息 + */ + static void writeFactoriesFile(MultiSetMap factories, + OutputStream output) throws IOException { + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, UTF_8)); + Set keySet = factories.keySet(); + for (String key : keySet) { + Set values = factories.get(key); + if (values == null || values.isEmpty()) { + continue; + } + StringJoiner joiner = new StringJoiner("\n"); + for (String value : values) { + joiner.add(value); + } + writer.write(joiner.toString()); + writer.newLine(); + } + writer.flush(); + output.close(); + } - /** - * 写出 spring-devtools.properties - * @param projectName 项目名 - * @param output 输出流 - * @throws IOException 异常信息 - */ - static void writeDevToolsFile(String projectName, - OutputStream output) throws IOException { - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, UTF_8)); - String format = "restart.include.%s=/%s[\\\\w-]+\\.jar"; - writer.write(String.format(format, projectName, projectName)); - writer.flush(); - output.close(); - } + /** + * 写出 spring-devtools.properties + * + * @param projectName 项目名 + * @param output 输出流 + * @throws IOException 异常信息 + */ + static void writeDevToolsFile(String projectName, + OutputStream output) throws IOException { + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, UTF_8)); + String format = "restart.include.%s=/%s[\\\\w-]+\\.jar"; + writer.write(String.format(format, projectName, projectName)); + writer.flush(); + output.close(); + } } diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/model/MultiSetMap.java b/uno-auto/src/main/java/cc/allio/uno/auto/model/MultiSetMap.java index c5d7dcec..b9caef01 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/model/MultiSetMap.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/model/MultiSetMap.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto.model; import java.util.*; diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/model/Sets.java b/uno-auto/src/main/java/cc/allio/uno/auto/model/Sets.java index 339acf31..794b3301 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/model/Sets.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/model/Sets.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto.model; import java.util.Objects; diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/model/TypeHelper.java b/uno-auto/src/main/java/cc/allio/uno/auto/model/TypeHelper.java index 7c572d1d..76359e3c 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/model/TypeHelper.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/model/TypeHelper.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto.model; import javax.annotation.processing.ProcessingEnvironment; diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/service/AutoService.java b/uno-auto/src/main/java/cc/allio/uno/auto/service/AutoService.java index 96fa4c90..5bf34afb 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/service/AutoService.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/service/AutoService.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto.service; import java.lang.annotation.*; diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/service/AutoServiceProcessor.java b/uno-auto/src/main/java/cc/allio/uno/auto/service/AutoServiceProcessor.java index b1441c42..807fa689 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/service/AutoServiceProcessor.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/service/AutoServiceProcessor.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto.service; import cc.allio.uno.auto.AbstractUnoProcessor; diff --git a/uno-auto/src/main/java/cc/allio/uno/auto/service/ServicesFiles.java b/uno-auto/src/main/java/cc/allio/uno/auto/service/ServicesFiles.java index 1302dbf3..21942622 100644 --- a/uno-auto/src/main/java/cc/allio/uno/auto/service/ServicesFiles.java +++ b/uno-auto/src/main/java/cc/allio/uno/auto/service/ServicesFiles.java @@ -1,19 +1,3 @@ -/* - * Copyright (c) 2018-2028, DreamLu All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * Author: DreamLu 卢春梦 (596392912@qq.com) - */ package cc.allio.uno.auto.service; import java.io.*; diff --git a/uno-bom/pom.xml b/uno-bom/pom.xml index f75aa6af..ca43b684 100644 --- a/uno-bom/pom.xml +++ b/uno-bom/pom.xml @@ -5,19 +5,19 @@ org.springframework.boot spring-boot-starter-parent - 3.2.0 + 3.2.2 4.0.0 cc.allio uno-bom - 1.1.5.RELEASE + 1.1.6-beta.1 pom - 1.1.5.RELEASE + 1.1.6-beta.1 1.5.9 @@ -34,16 +34,15 @@ 2.2.17 1.6.2 3.0.0 - - 3.0.3-SNAPSHOT - 3.5.3 + 3.0.3 + 3.5.5 1.2.20 8.0.22 12.2.0.1 42.2.22 8.4.1.jre8 - 4.1.3 + 4.3.0 27.0 3.7.0 @@ -117,11 +116,6 @@ uno-starter-kafka ${uno.version} - - cc.allio - uno-starter-liquibase - ${uno.version} - cc.allio uno-starter-websocket @@ -143,6 +137,51 @@ uno-data ${uno.version} + + cc.allio + uno-data-test + ${uno.version} + + + cc.allio + uno-data-api + ${uno.version} + + + cc.allio + uno-data-db + ${uno.version} + + + cc.allio + uno-data-elasticsearch + ${uno.version} + + + cc.allio + uno-data-influxdb + ${uno.version} + + + cc.allio + uno-data-mongodb + ${uno.version} + + + cc.allio + uno-data-neo4j + ${uno.version} + + + cc.allio + uno-data-redis + ${uno.version} + + + cc.allio + uno-data-sql + ${uno.version} + cc.allio uno-web diff --git a/uno-components/pom.xml b/uno-components/pom.xml index 84f65179..a893d9af 100644 --- a/uno-components/pom.xml +++ b/uno-components/pom.xml @@ -5,7 +5,7 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 @@ -20,11 +20,6 @@ uno-component-netty - - 8 - 8 - - cc.allio diff --git a/uno-components/uno-component-http/pom.xml b/uno-components/uno-component-http/pom.xml index 5a189766..e9632cde 100644 --- a/uno-components/uno-component-http/pom.xml +++ b/uno-components/uno-component-http/pom.xml @@ -5,7 +5,7 @@ uno-components cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 ../pom.xml 4.0.0 diff --git a/uno-components/uno-component-http/src/test/java/cc/allio/uno/component/http/api/OpenApiV3AssemblyTest.java b/uno-components/uno-component-http/src/test/java/cc/allio/uno/component/http/api/OpenApiV3AssemblyTest.java index f03aceb6..d254ae10 100644 --- a/uno-components/uno-component-http/src/test/java/cc/allio/uno/component/http/api/OpenApiV3AssemblyTest.java +++ b/uno-components/uno-component-http/src/test/java/cc/allio/uno/component/http/api/OpenApiV3AssemblyTest.java @@ -36,7 +36,7 @@ protected void onInit() throws Throwable { @Test void testFindByPath() { - StepVerifier.create(converter.find("/user/get")) + StepVerifier.create(converter.find("/user/getValue")) .expectNextCount(1) .verifyComplete(); } @@ -72,7 +72,7 @@ void testAll() { @Test void testSwap() { StepVerifier.create( - converter.find("/user/get") + converter.find("/user/getValue") .flatMap(swapper -> swapper .addParameter("id", "1") .swap() @@ -85,7 +85,7 @@ void testSwap() { @Test void testAddToken() { StepVerifier.create( - converter.find("/user/get") + converter.find("/user/getValue") .flatMap(swapper -> swapper .addParameter("id", "1") .swap() diff --git a/uno-components/uno-component-kafka/pom.xml b/uno-components/uno-component-kafka/pom.xml index a51878a2..0b634a1d 100644 --- a/uno-components/uno-component-kafka/pom.xml +++ b/uno-components/uno-component-kafka/pom.xml @@ -5,18 +5,12 @@ uno-components cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-component-kafka - - 8 - 8 - UTF-8 - - io.projectreactor.kafka diff --git a/uno-components/uno-component-kafka/src/main/java/cc/allio/uno/component/kafka/UnoKafkaReceiver.java b/uno-components/uno-component-kafka/src/main/java/cc/allio/uno/component/kafka/UnoKafkaReceiver.java index 6aeb94a8..7b325a8f 100644 --- a/uno-components/uno-component-kafka/src/main/java/cc/allio/uno/component/kafka/UnoKafkaReceiver.java +++ b/uno-components/uno-component-kafka/src/main/java/cc/allio/uno/component/kafka/UnoKafkaReceiver.java @@ -121,7 +121,7 @@ public Flux doSubscribe(int bufferSize) { /** * {@link org.apache.kafka.clients.consumer.Consumer#assignment()} * - * @return The set of partitions currently assigned to this consumer + * @return The setValue of partitions currently assigned to this consumer */ public Flux assignment() { return receiver.doOnConsumer(org.apache.kafka.clients.consumer.Consumer::assignment) diff --git a/uno-components/uno-component-netty/pom.xml b/uno-components/uno-component-netty/pom.xml index 0fc3fe93..c0ff9195 100644 --- a/uno-components/uno-component-netty/pom.xml +++ b/uno-components/uno-component-netty/pom.xml @@ -6,17 +6,11 @@ uno-components cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 uno-component-netty - - 8 - 8 - UTF-8 - - cc.allio diff --git a/uno-components/uno-component-netty/src/main/java/cc/allio/uno/component/netty/AbstractNettyService.java b/uno-components/uno-component-netty/src/main/java/cc/allio/uno/component/netty/AbstractNettyService.java index e4e70b76..e8b6f7da 100644 --- a/uno-components/uno-component-netty/src/main/java/cc/allio/uno/component/netty/AbstractNettyService.java +++ b/uno-components/uno-component-netty/src/main/java/cc/allio/uno/component/netty/AbstractNettyService.java @@ -44,7 +44,7 @@ public abstract class AbstractNettyService implements RemoteService { /** * 请求-响应,他们使用的id都是相同的 * 当请求来到时,根据请求的id put这个promisor对象 - * 当响应到来时,根据响应的id,get这个promisor对象并向 set promise对象 + * 当响应到来时,根据响应的id,get这个promisor对象并向 setValue promise对象 */ private final ConcurrentHashMap promises = new ConcurrentHashMap<>(); /** diff --git a/uno-components/uno-component-sequential/pom.xml b/uno-components/uno-component-sequential/pom.xml index 9cffbd4e..da635e60 100644 --- a/uno-components/uno-component-sequential/pom.xml +++ b/uno-components/uno-component-sequential/pom.xml @@ -5,18 +5,12 @@ uno-components cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-component-sequential - - 8 - 8 - UTF-8 - - cc.allio @@ -29,7 +23,7 @@ cc.allio - uno-data + uno-data-elasticsearch org.springframework diff --git a/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/context/DefaultSequentialContext.java b/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/context/DefaultSequentialContext.java index 29662296..dc9fbc07 100644 --- a/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/context/DefaultSequentialContext.java +++ b/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/context/DefaultSequentialContext.java @@ -6,7 +6,7 @@ import cc.allio.uno.core.bus.DefaultEventContext; import cc.allio.uno.core.util.id.IdGenerator; import cc.allio.uno.component.sequential.Sequential; -import cc.allio.uno.core.util.CoreBeanUtil; +import cc.allio.uno.core.util.BeanUtils; import org.springframework.context.ApplicationContext; import java.util.*; @@ -71,7 +71,7 @@ public Long getContextId() { @Override public Sequential getSequential() { - return CoreBeanUtil.copy(sequential, sequential.getClass()); + return BeanUtils.copy(sequential, sequential.getClass()); } @Override diff --git a/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/process/handle/AppendProcessHandler.java b/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/process/handle/AppendProcessHandler.java index 4483f29d..eb802dd0 100644 --- a/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/process/handle/AppendProcessHandler.java +++ b/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/process/handle/AppendProcessHandler.java @@ -32,7 +32,7 @@ public interface AppendProcessHandler extends Comparable { * is less than, equal to, or greater than the specified object. * @throws NullPointerException if the specified object is null * @throws ClassCastException if the specified object's type prevents it - * from being compared to this object. + * xxxx being compared to this object. * @see Comparable#compareTo(Object) */ @Override diff --git a/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/washer/WashMachine.java b/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/washer/WashMachine.java index d2f58efd..5c24312f 100644 --- a/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/washer/WashMachine.java +++ b/uno-components/uno-component-sequential/src/main/java/cc/allio/uno/component/sequential/washer/WashMachine.java @@ -3,8 +3,9 @@ import cc.allio.uno.component.sequential.context.SequentialContext; import cc.allio.uno.component.sequential.Sequential; import cc.allio.uno.core.reactive.BufferRate; -import cc.allio.uno.data.orm.executor.SQLCommandExecutor; -import cc.allio.uno.data.orm.executor.SQLCommandExecutorFactory; +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.CommandExecutorFactory; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; import com.google.common.collect.Lists; import jakarta.persistence.Id; import jakarta.persistence.Table; @@ -42,7 +43,7 @@ public class WashMachine { this.recorderDisposable = BufferRate.create(Flux.create(sink -> recorder = sink)) .doOnNext(records -> { - SQLCommandExecutor sqlExecutor = SQLCommandExecutorFactory.getSQLExecutor(SQLCommandExecutor.ELASTICSEARCH_SQL_COMMAND_EXECUTOR_KEY); + CommandExecutor sqlExecutor = CommandExecutorFactory.getDSLExecutor(ExecutorKey.ELASTICSEARCH); if (sqlExecutor != null) { sqlExecutor.batchInsertPojos(records); } diff --git a/uno-components/uno-component-sequential/src/test/java/cc/allio/uno/component/sequential/dispatch/DispatchDispatcherTest.java b/uno-components/uno-component-sequential/src/test/java/cc/allio/uno/component/sequential/dispatch/DispatchDispatcherTest.java index 2ba1cf99..3e38e4d9 100644 --- a/uno-components/uno-component-sequential/src/test/java/cc/allio/uno/component/sequential/dispatch/DispatchDispatcherTest.java +++ b/uno-components/uno-component-sequential/src/test/java/cc/allio/uno/component/sequential/dispatch/DispatchDispatcherTest.java @@ -3,7 +3,7 @@ import cc.allio.uno.component.sequential.*; import cc.allio.uno.component.sequential.bus.SequentialEventBus; import cc.allio.uno.component.sequential.process.DefaultProcessor; -import cc.allio.uno.core.util.CoreBeanUtil; +import cc.allio.uno.core.util.BeanUtils; import cc.allio.uno.test.RunTest; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -12,7 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -@RunTest(components = {DefaultProcessor.class, SequentialEventBus.class, CoreBeanUtil.class, SubscriptionProperties.class, SubscriptionPropertiesTypeManager.class}) +@RunTest(components = {DefaultProcessor.class, SequentialEventBus.class, BeanUtils.class, SubscriptionProperties.class, SubscriptionPropertiesTypeManager.class}) @Slf4j class DispatchDispatcherTest { diff --git a/uno-components/uno-component-websocket/pom.xml b/uno-components/uno-component-websocket/pom.xml index 818ee4a2..79e399b7 100644 --- a/uno-components/uno-component-websocket/pom.xml +++ b/uno-components/uno-component-websocket/pom.xml @@ -5,7 +5,7 @@ uno-components cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 @@ -13,12 +13,6 @@ 提供封装的websocket,包含鉴权、心跳、连接管理、实现方只需要关注消息的处理 - - 8 - 8 - UTF-8 - - org.springframework.boot diff --git a/uno-components/uno-component-websocket/src/main/java/cc/allio/uno/component/websocket/WebSocketEndpoint.java b/uno-components/uno-component-websocket/src/main/java/cc/allio/uno/component/websocket/WebSocketEndpoint.java index b6cb63c1..0732c923 100644 --- a/uno-components/uno-component-websocket/src/main/java/cc/allio/uno/component/websocket/WebSocketEndpoint.java +++ b/uno-components/uno-component-websocket/src/main/java/cc/allio/uno/component/websocket/WebSocketEndpoint.java @@ -69,10 +69,10 @@ public interface WebSocketEndpoint { * * @return WebSocketProperties实例对象 * @throws NoSuchBeanDefinitionException 没有找到{@link WebSocketProperties}的定义抛出 - * @throws NullPointerException {@link CoreBeanUtil#getContext()}为空时抛出 + * @throws NullPointerException {@link BeanUtils#getContext()}为空时抛出 */ default WebSocketProperties getProperties() { - return CoreBeanUtil.getBean(WebSocketProperties.class); + return BeanUtils.getBean(WebSocketProperties.class); } diff --git a/uno-core/pom.xml b/uno-core/pom.xml index dd1ef514..d0f933bc 100644 --- a/uno-core/pom.xml +++ b/uno-core/pom.xml @@ -5,7 +5,7 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 @@ -73,6 +73,10 @@ com.fasterxml.jackson.core jackson-annotations + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + io.projectreactor reactor-core diff --git a/uno-core/src/main/java/cc/allio/uno/core/api/Adapter.java b/uno-core/src/main/java/cc/allio/uno/core/api/Adapter.java new file mode 100644 index 00000000..8d97e5f4 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/api/Adapter.java @@ -0,0 +1,27 @@ +package cc.allio.uno.core.api; + +/** + * 通用适配器定义 + * + * @author jiangwei + * @date 2024/1/9 16:04 + * @since 1.1.6 + */ +public interface Adapter { + + /** + * 根据原始的类型获取目标转换的类型 + * + * @param o 原始类型 + * @return 转换类型 + */ + R adapt(O o); + + /** + * 根据目标的类型获取原始的类型 + * + * @param r 目标类型 + * @return 原始类型 + */ + O reverse(R r); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/api/EqualsTo.java b/uno-core/src/main/java/cc/allio/uno/core/api/EqualsTo.java new file mode 100644 index 00000000..d8cd4369 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/api/EqualsTo.java @@ -0,0 +1,20 @@ +package cc.allio.uno.core.api; + +/** + * Java中接口类型不存在{@link Object#equals(Object)}方法,该接口的定义为了能够使得Java接口能够有类似的方法。 + *

另外一个目的是提供显示的接口来实现{@code equals}方法,避免在调试环节不知道为何两个对象相等。

+ * + * @author jiangwei + * @date 2024/2/16 20:17 + * @since 1.1.6 + */ +public interface EqualsTo { + + /** + * 类似于{@link Object#equals(Object)} + * + * @param other other + * @return ture if equivalent + */ + boolean equalsTo(T other); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/api/Key.java b/uno-core/src/main/java/cc/allio/uno/core/api/Key.java index b7a89545..b4c617f0 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/api/Key.java +++ b/uno-core/src/main/java/cc/allio/uno/core/api/Key.java @@ -21,5 +21,5 @@ public interface Key { * * @return key */ - String getKey(); + String key(); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/api/OptionalContext.java b/uno-core/src/main/java/cc/allio/uno/core/api/OptionalContext.java index af097008..f420616b 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/api/OptionalContext.java +++ b/uno-core/src/main/java/cc/allio/uno/core/api/OptionalContext.java @@ -1,9 +1,12 @@ package cc.allio.uno.core.api; +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.core.util.id.IdGenerator; +import com.google.common.collect.Maps; import org.springframework.context.ApplicationContext; -import java.util.Map; -import java.util.Optional; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; /** * 定义Uno上下文模版方法 @@ -58,26 +61,6 @@ default Optional get(String key, Class clazz) { return get(key).map(clazz::cast); } - /** - * 放入新的属性数据 - * - * @param key 属性key - * @param obj 属性值 - * @throws NullPointerException obj为空时抛出 - */ - void putAttribute(String key, Object obj); - - /** - * 放入其他所有的属性数据 - * - * @param otherAttributes 其他属性数据 - */ - default void putAll(Map otherAttributes) { - for (Map.Entry attribute : otherAttributes.entrySet()) { - putAttribute(attribute.getKey(), attribute.getValue()); - } - } - /** * 获取Spring应用的上下文 * @@ -109,6 +92,51 @@ default T getOrThrows(String key, Class type) { return type.cast(target); } + /** + * 给定一个类型,获取第一个匹配的属性 + * + * @param typeClass typeClass + * @param 类型 + * @return option + */ + default Optional getTypeFirst(Class typeClass) { + Map all = getAll(); + Collection values = all.values(); + return values.stream() + .filter(value -> typeClass.isAssignableFrom(value.getClass())) + .findFirst() + .map(typeClass::cast); + } + + /** + * 如果没有获取到则返回null + * + * @see #getTypeFirst(Class) + */ + default T getTypeFirstForce(Class typeClass) { + return getTypeFirst(typeClass).orElse(null); + } + + /** + * 放入新的属性数据 + * + * @param key 属性key + * @param obj 属性值 + * @throws NullPointerException obj为空时抛出 + */ + void putAttribute(String key, Object obj); + + /** + * 放入其他所有的属性数据 + * + * @param otherAttributes 其他属性数据 + */ + default void putAll(Map otherAttributes) { + for (Map.Entry attribute : otherAttributes.entrySet()) { + putAttribute(attribute.getKey(), attribute.getValue()); + } + } + /** * 判断是否包含key * @@ -118,4 +146,111 @@ default T getOrThrows(String key, Class type) { default boolean containsKey(String key) { return get(key).isPresent(); } + + /** + * 返回基于给定的可变餐values参数创建一个{@link ImmutableOptionalContext} + * + * @param values values + * @return OptionalContext + */ + static ImmutableOptionalContext immutable(Object... values) { + return new ImmutableOptionalContext(values); + } + + /** + * 基于{@link OptionalContext}与给定的可变餐values参数创建一个{@link ImmutableOptionalContext} + * + * @param other other optional context + * @param values values + * @return OptionalContext + */ + static ImmutableOptionalContext immutable(OptionalContext other, Object... values) { + return new ImmutableOptionalContext(other, values); + } + + /** + * 基于给定的values参数创建一个{@link ImmutableOptionalContext} + * + * @param values values + * @return OptionalContext + */ + static ImmutableOptionalContext immutable(Map values) { + return new ImmutableOptionalContext(values); + } + + /** + * 基于{@link OptionalContext}与给定的values参数创建一个{@link ImmutableOptionalContext} + * + * @param other other optional context + * @param values values + * @return OptionalContext + */ + static ImmutableOptionalContext immutable(OptionalContext other, Map values) { + return new ImmutableOptionalContext(other, values); + } + + /** + * 不可变的{@link OptionalContext} + */ + class ImmutableOptionalContext implements OptionalContext { + + private final Map context; + private final AtomicInteger randomCounter = new AtomicInteger(); + + public ImmutableOptionalContext(Object[] values) { + if (values != null) { + this.context = new HashMap<>(values.length); + for (Object value : values) { + putSingleValue(value); + } + } else { + this.context = Collections.emptyMap(); + } + } + + public ImmutableOptionalContext(Map values) { + this.context = new HashMap<>(values); + } + + public ImmutableOptionalContext(OptionalContext other, Map values) { + this.context = new HashMap<>(other.getAll()); + this.context.putAll(values); + } + + public ImmutableOptionalContext(OptionalContext other, Object[] values) { + this.context = new HashMap<>(other.getAll()); + if (values != null) { + for (Object value : values) { + putSingleValue(value); + } + } + } + + @Override + public Optional get(String key) { + return Optional.ofNullable(context.get(key)); + } + + @Override + public Optional getApplicationContext() { + throw Exceptions.unOperate("getApplicationContext"); + } + + @Override + public Map getAll() { + return Collections.unmodifiableMap(context); + } + + @Override + public void putAttribute(String key, Object obj) { + throw Exceptions.unOperate("putAttribute"); + } + + void putSingleValue(Object value) { + if (value != null) { + String name = value.getClass().getName(); + this.context.put(name + randomCounter.getAndIncrement(), value); + } + } + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Operator.java b/uno-core/src/main/java/cc/allio/uno/core/api/Self.java similarity index 70% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/Operator.java rename to uno-core/src/main/java/cc/allio/uno/core/api/Self.java index 2a917784..5543100b 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Operator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/api/Self.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.core.api; /** * 数据操作接口 @@ -7,7 +7,7 @@ * @date 2023/1/5 10:37 * @since 1.1.4 */ -public interface Operator> { +public interface Self> { /** * self对象 diff --git a/uno-core/src/main/java/cc/allio/uno/core/api/Step.java b/uno-core/src/main/java/cc/allio/uno/core/api/Step.java new file mode 100644 index 00000000..5f5a654d --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/api/Step.java @@ -0,0 +1,66 @@ +package cc.allio.uno.core.api; + +import cc.allio.uno.core.util.ObjectUtils; + +import java.util.LinkedList; +import java.util.function.Supplier; + +/** + * 执行步骤。步骤将会按照{@link #then(Supplier)}一步一步执行下去,直到获取的值不为null或者走完步骤。 + * + * @author jiangwei + * @date 2024/2/6 23:38 + * @since 1.1.6 + */ +public interface Step { + + /** + * 开始并获取{@link Step}实例 + * + * @param 数据类型 + * @return Step + */ + static Step start() { + return new StepImpl<>(); + } + + /** + * 步骤 + * + * @param provider provider + * @return Step + */ + Step then(Supplier provider); + + /** + * 终止 + * + * @return 获取的结果 + */ + T stop(); + + + class StepImpl implements Step, Self> { + + LinkedList> providers = new LinkedList<>(); + + @Override + public Step then(Supplier provider) { + this.providers.add(provider); + return self(); + } + + @Override + public T stop() { + Supplier provider; + while ((provider = providers.pollFirst()) != null) { + T value = provider.get(); + if (ObjectUtils.isNotEmpty(value)) { + return value; + } + } + return null; + } + } + +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/BeanCopier.java b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanCopier.java index 5e9d9af8..158778c5 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bean/BeanCopier.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanCopier.java @@ -2,7 +2,7 @@ import cc.allio.uno.core.util.ClassUtils; -import cc.allio.uno.core.util.CoreBeanUtil; +import cc.allio.uno.core.util.BeanUtils; import cc.allio.uno.core.util.StringUtils; import org.springframework.asm.ClassVisitor; import org.springframework.asm.Label; @@ -36,7 +36,7 @@ public abstract class BeanCopier { private static final Type BEAN_MAP = TypeUtils.parseType(Map.class.getName()); private static final Signature COPY = new Signature("copy", Type.VOID_TYPE, new Type[]{Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER}); private static final Signature CONVERT = TypeUtils.parseSignature("Object convert(Object, Class, Object)"); - private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object get(Object)"); + private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object getValue(Object)"); private static final Type CLASS_UTILS = TypeUtils.parseType(org.springframework.util.ClassUtils.class.getName()); private static final Signature IS_ASSIGNABLE_VALUE = TypeUtils.parseSignature("boolean isAssignableValue(Class, Object)"); /** @@ -50,7 +50,7 @@ public static BeanCopier create(Class source, Class target, boolean useConverter public static BeanCopier create(Class source, Class target, boolean useConverter, boolean nonNull) { BeanCopierKey copierKey = new BeanCopierKey(source, target, useConverter, nonNull); - // 利用 ConcurrentMap 缓存 提高性能,接近 直接 get set + // 利用 ConcurrentMap 缓存 提高性能,接近 直接 getValue setValue return BEAN_COPIER_MAP.computeIfAbsent(copierKey, key -> { Generator gen = new Generator(); gen.setSource(key.getSource()); @@ -162,7 +162,7 @@ public void generateClass(ClassVisitor v) { String propName = setter.getName(); CopyProperty targetIgnoreCopy = cc.allio.uno.core.util.ReflectUtils.getAnnotation(target, propName, CopyProperty.class); - // set 上有忽略的 注解 + // setValue 上有忽略的 注解 if (targetIgnoreCopy != null) { if (targetIgnoreCopy.ignore()) { continue; @@ -173,9 +173,9 @@ public void generateClass(ClassVisitor v) { propName = aliasTargetPropName; } } - // 找到对应的 get + // 找到对应的 getValue PropertyDescriptor getter = names.get(propName); - // 没有 get 跳出 + // 没有 getValue 跳出 if (getter == null) { continue; } @@ -188,7 +188,7 @@ public void generateClass(ClassVisitor v) { Class getterPropertyType = getter.getPropertyType(); Class setterPropertyType = setter.getPropertyType(); - // L.cm 2019.01.12 优化逻辑,先判断类型,类型一致直接 set,不同再判断 是否 类型转换 + // L.cm 2019.01.12 优化逻辑,先判断类型,类型一致直接 setValue,不同再判断 是否 类型转换 // nonNull Label Label l0 = e.make_label(); // 判断类型是否一致,包括 包装类型 @@ -213,17 +213,17 @@ public void generateClass(ClassVisitor v) { // 需要落栈,强制拆箱 e.unbox_or_zero(setterType); } else { - // 如果 get 为原始类型,需要装箱 + // 如果 getValue 为原始类型,需要装箱 if (getterIsPrimitive && !setterIsPrimitive) { e.box(returnType); } - // 如果 set 为原始类型,需要拆箱 + // 如果 setValue 为原始类型,需要拆箱 if (!getterIsPrimitive && setterIsPrimitive) { e.unbox_or_zero(setterType); } } - // 构造 set 方法 + // 构造 setValue 方法 invokeWrite(e, write, writeMethod, nonNull, l0); } else if (useConverter) { e.load_local(targetLocal); @@ -243,12 +243,12 @@ public void generateClass(ClassVisitor v) { } EmitUtils.load_class(e, setterType); - // 更改成了属性名,之前是 set 方法名 + // 更改成了属性名,之前是 setValue 方法名 e.push(propName); e.invoke_interface(CONVERTER, CONVERT); e.unbox_or_zero(setterType); - // 构造 set 方法 + // 构造 setValue 方法 invokeWrite(e, write, writeMethod, nonNull, l0); } } @@ -272,7 +272,7 @@ private static void invokeWrite(CodeEmitter e, MethodInfo write, Method writeMet @Override protected Object firstInstance(Class type) { - return CoreBeanUtil.newInstance(type); + return BeanUtils.newInstance(type); } @Override @@ -306,7 +306,7 @@ public void generateClassFormMap(ClassEmitter ce, CodeEmitter e, Type sourceType for (PropertyDescriptor setter : setters) { String propName = setter.getName(); - // set 上有忽略的 注解 + // setValue 上有忽略的 注解 CopyProperty targetIgnoreCopy = cc.allio.uno.core.util.ReflectUtils.getAnnotation(target, propName, CopyProperty.class); if (targetIgnoreCopy != null) { if (targetIgnoreCopy.ignore()) { @@ -327,7 +327,7 @@ public void generateClassFormMap(ClassEmitter ce, CodeEmitter e, Type sourceType e.load_local(sourceLocal); e.push(propName); - // 执行 map get + // 执行 map getValue e.invoke_interface(BEAN_MAP, BEAN_MAP_GET); // box 装箱,避免 array[] 数组问题 e.box(mapBox); diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/BeanInfoWrapper.java b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanInfoWrapper.java index dcd1521d..50e9e5a8 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bean/BeanInfoWrapper.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanInfoWrapper.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.units.qual.K; import org.springframework.util.Assert; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -15,6 +16,7 @@ import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Array; +import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Stream; @@ -74,8 +76,8 @@ public Mono findByName(String name) { .switchIfEmpty(Mono.empty()) .single() .onErrorResume(error -> { - if (log.isDebugEnabled()) { - log.debug("get field {} descriptor error", name); + if (log.isWarnEnabled()) { + log.warn("getValue field {} descriptor error", name); } return Mono.empty(); }); @@ -160,6 +162,13 @@ public F getForce(Object target, String name, Class fieldType) { return ref.get(); } + /** + * @see #setCoverage(Object, String, boolean, Object...) + */ + public synchronized K setForce(K target, String name, Object... value) { + return setCoverageForce(target, name, true, value); + } + /** * 向目标对象设置字段的值,目标字段如果存在值则不进行设置. * @@ -170,10 +179,18 @@ public F getForce(Object target, String name, Class fieldType) { * @throws NullPointerException 当值集合存在null时抛出异常 * @see #setCoverage(Object, String, boolean, Object...) */ - public synchronized Mono set(T target, String name, Object... value) { + public synchronized Mono set(K target, String name, Object... value) { return setCoverage(target, name, false, value); } + /** + * @see #setCoverage(Object, String, boolean, Object...) + */ + public synchronized K setCoverageForce(K target, String name, boolean forceCoverage, Object... value) { + setCoverage(target, name, forceCoverage, value).subscribe(); + return target; + } + /** * 向目标对象设置字段的值,目标字段如果存在值则不进行设置 * @@ -185,14 +202,14 @@ public synchronized Mono set(T target, String name, Object... value) { * @throws NullPointerException 当值集合存在null时抛出异常 * @see #write(Object, PropertyDescriptor, boolean, Object...) */ - public synchronized Mono setCoverage(T target, String name, boolean forceCoverage, Object... value) { + public synchronized Mono setCoverage(K target, String name, boolean forceCoverage, Object... value) { Assert.notNull(name, "target must not null"); return findByName(name) .flatMap(descriptor -> write(target, descriptor, forceCoverage, value) .onErrorContinue((error, o) -> { - if (log.isDebugEnabled()) { - log.debug("target {} set field {} value error set empty", target.getClass().getSimpleName(), name); + if (log.isWarnEnabled()) { + log.warn("target {} setValue field {} value error setValue empty", target.getClass().getSimpleName(), name); } })); } @@ -208,17 +225,22 @@ private Mono read(Object target, PropertyDescriptor descriptor) { return Mono.justOrEmpty(descriptor.getReadMethod()) .flatMap(readMethod -> { try { - return Mono.justOrEmpty(readMethod.invoke(target)); + Object result = readMethod.invoke(target); + return Mono.just(Objects.requireNonNullElse(result, ValueWrapper.EMPTY_VALUE)); } catch (Throwable ex) { return Mono.error(ex); } }) - .onErrorContinue((err, o) -> log.info("Target {} get field {} value error", target.getClass().getSimpleName(), descriptor.getName(), err)); + .onErrorContinue((err, o) -> { + if (log.isWarnEnabled()) { + log.warn("Target {} getValue field {} value error", target.getClass().getSimpleName(), descriptor.getName(), err); + } + }); } /** * 调用指定bean{@link PropertyDescriptor}的WriteMethod方法,进行字段赋值。 - *

根据配置的forceCoverage参数,判断是否进行强行覆盖值(如果字段不为空的化)

+ *

根据配置的forceCoverage参数,判断是否进行强行覆盖值(如果字段不为空)

* * @param target 写入指定bean * @param descriptor 字段对象 @@ -226,8 +248,8 @@ private Mono read(Object target, PropertyDescriptor descriptor) { * @param args 写入参数 * @return 指定bean */ - private Mono write(T target, PropertyDescriptor descriptor, boolean forceCoverage, Object... args) { - Mono writeMono = Mono.justOrEmpty(descriptor.getWriteMethod()) + private Mono write(K target, PropertyDescriptor descriptor, boolean forceCoverage, Object... args) { + Mono writeMono = Mono.justOrEmpty(descriptor.getWriteMethod()) .flatMap(writeMethod -> TypeValue.of(writeMethod.getParameterTypes(), args) .map(TypeValue::tryTransfer) @@ -254,8 +276,8 @@ private Mono write(T target, PropertyDescriptor descriptor, boolean forceCove writeMethod.invoke(target, values.toArray()); } } catch (Throwable err) { - if (log.isDebugEnabled()) { - log.debug("Target {} set field {} value error set empty", target.getClass().getSimpleName(), descriptor.getName()); + if (log.isWarnEnabled()) { + log.warn("Target {} setValue field {} value error setValue empty", target.getClass().getSimpleName(), descriptor.getName()); } } return Mono.just(target); @@ -264,6 +286,28 @@ private Mono write(T target, PropertyDescriptor descriptor, boolean forceCove if (forceCoverage) { return writeMono; } - return read(target, descriptor).switchIfEmpty(writeMono).then(Mono.just(target)); + return read(target, descriptor) + .flatMap(v -> { + if (ValueWrapper.EMPTY_VALUE.equals(v)) { + return writeMono; + } + return Mono.just(target); + }); + } + + /** + * 基于class对象创建{@link BeanInfoWrapper}实例 + * + * @param clazz clazz + * @param 实例类型 + * @return BeanInfoWrapper + */ + public static BeanInfoWrapper of(Class clazz) { + try { + return new BeanInfoWrapper<>(clazz); + } catch (IntrospectionException e) { + // ignore + return null; + } } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/BeanMap.java b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanMap.java index ec20bf1e..2a8022bd 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bean/BeanMap.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanMap.java @@ -48,7 +48,7 @@ public BladeGenerator() { /** * Set the bean that the generated map should reflect. The bean may be swapped * out for another bean of the same type using {@link #setBean}. - * Calling this method overrides any value previously set using {@link #setBeanClass}. + * Calling this method overrides any value previously setValue using {@link #setBeanClass}. * You must call either this method or {@link #setBeanClass} before {@link #create}. * * @param bean the initial bean diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/BeanMapEmitter.java b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanMapEmitter.java index 5eb0dfcf..60075603 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bean/BeanMapEmitter.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/BeanMapEmitter.java @@ -20,7 +20,7 @@ class BeanMapEmitter extends ClassEmitter { private static final Type FIXED_KEY_SET = TypeUtils.parseType("org.springframework.cglib.beans.FixedKeySet"); private static final Signature CSTRUCT_OBJECT = TypeUtils.parseConstructor("Object"); private static final Signature CSTRUCT_STRING_ARRAY = TypeUtils.parseConstructor("String[]"); - private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object get(Object, Object)"); + private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object getValue(Object, Object)"); private static final Signature BEAN_MAP_PUT = TypeUtils.parseSignature("Object put(Object, Object, Object)"); private static final Signature KEY_SET = TypeUtils.parseSignature("java.util.Set keySet()"); private static final Signature NEW_INSTANCE = new Signature("newInstance", BEAN_MAP, new Type[]{Constants.TYPE_OBJECT}); diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/Empty.java b/uno-core/src/main/java/cc/allio/uno/core/bean/Empty.java new file mode 100644 index 00000000..b3a43bce --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/Empty.java @@ -0,0 +1,11 @@ +package cc.allio.uno.core.bean; + +/** + * 标识空对象 + * + * @author jiangwei + * @date 2024/1/9 18:56 + * @since 1.1.6 + */ +public final class Empty { +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/MapWrapper.java b/uno-core/src/main/java/cc/allio/uno/core/bean/MapWrapper.java index 8ec8d966..5e0c49c0 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bean/MapWrapper.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/MapWrapper.java @@ -1,6 +1,7 @@ package cc.allio.uno.core.bean; import cc.allio.uno.core.util.ObjectUtils; +import com.google.common.collect.Maps; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -9,7 +10,6 @@ import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.util.Map; -import java.util.stream.Collectors; /** * value = map的wrapper @@ -22,6 +22,10 @@ public class MapWrapper implements ValueWrapper { private final Map instance; + public MapWrapper() { + this.instance = Maps.newConcurrentMap(); + } + public MapWrapper(Map value) { this.instance = value; } @@ -78,10 +82,10 @@ public Mono setCoverage(String name, boolean forceCoverage, Object... va *
  • 多值作为数组存入
  • * * - * @param name the key + * @param name the key * @param values the values myabe array */ - private void putMultiValues(String name, Object... values) { + private void putMultiValues(String name, Object... values) { if (ObjectUtils.isNotEmpty(values)) { if (values.length == 1) { instance.put(name, values[0]); @@ -97,16 +101,15 @@ public Flux findAll() { instance.keySet() .stream() .map(this::find) - .collect(Collectors.toList())); + .toList()); } @Override - public Flux> findAllValues() { + public Flux> findTupleValues() { return Flux.fromIterable( instance.entrySet().stream() .map(entry -> Tuples.of(entry.getKey(), entry.getValue())) - .collect(Collectors.toList()) - ); + .toList()); } @Override diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/ObjectWrapper.java b/uno-core/src/main/java/cc/allio/uno/core/bean/ObjectWrapper.java index 348003be..343f8daa 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bean/ObjectWrapper.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/ObjectWrapper.java @@ -1,6 +1,8 @@ package cc.allio.uno.core.bean; +import cc.allio.uno.core.exception.Exceptions; import cc.allio.uno.core.util.CollectionUtils; +import com.google.common.collect.Maps; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -9,11 +11,9 @@ import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.util.*; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; /** - * POJO对象包装器,作用是反射设置获取该对象的字段值,并可以获取这个类中所有方法等 + * Object包装器,作用是反射设置获取该对象的字段值,并可以获取这个类中所有方法等 * * @author jiangwei * @date 2022/5/21 10:17 @@ -25,7 +25,6 @@ public class ObjectWrapper implements ValueWrapper { * 解析的目标对象 */ private final Object instance; - private final BeanInfoWrapper wrapper; public ObjectWrapper(Object instance) { @@ -35,8 +34,8 @@ public ObjectWrapper(Object instance) { try { this.wrapper = new BeanInfoWrapper<>((Class) instance.getClass()); this.instance = instance; - } catch (IntrospectionException e) { - throw new RuntimeException(e); + } catch (IntrospectionException ex) { + throw Exceptions.unchecked(ex); } } @@ -47,8 +46,8 @@ public ObjectWrapper(Class instanceClass) { try { this.wrapper = new BeanInfoWrapper<>(instanceClass); this.instance = null; - } catch (IntrospectionException e) { - throw new RuntimeException(e); + } catch (IntrospectionException ex) { + throw Exceptions.unchecked(ex); } } @@ -124,11 +123,10 @@ public Flux findAll() { * @return tuple2 */ @Override - public Flux> findAllValues() { + public Flux> findTupleValues() { return findAll() .flatMap(propertyDescriptor -> - get(propertyDescriptor.getName()) - .map(value -> Tuples.of(propertyDescriptor.getName(), value))); + get(propertyDescriptor.getName()).map(value -> Tuples.of(propertyDescriptor.getName(), value))); } /** @@ -137,16 +135,21 @@ public Flux> findAllValues() { * @return Map */ @Override - public Map findAllValuesForce() { - AtomicReference>> ref = new AtomicReference<>(); - findAllValues().collectList().subscribe(ref::set); - List> allValues = ref.get(); + public Map findMapValuesForce() { + List> allValues = findTupleValues().collectList().block(); if (CollectionUtils.isEmpty(allValues)) { return Collections.emptyMap(); } - return allValues - .stream() - .collect(Collectors.toMap(Tuple2::getT1, Tuple2::getT2)); + Map result = Maps.newHashMap(); + for (Tuple2 allValue : allValues) { + String key = allValue.getT1(); + Object value = allValue.getT2(); + if (EMPTY_VALUE.equals(value)) { + value = null; + } + result.put(key, value); + } + return result; } /** @@ -158,4 +161,48 @@ public Map findAllValuesForce() { public Object getTarget() { return instance; } + + /** + * 设置字段值,如果字段值不存在,则不抛出异常 + * + * @param instance instance + * @param name name + * @param value value + */ + public static void setValue(Object instance, String name, Object... value) { + ObjectWrapper wrapper = new ObjectWrapper(instance); + if (Boolean.TRUE.equals(wrapper.contains(name))) { + wrapper.setForce(name, value); + } + } + + /** + * 获取字段值 + * + * @param instance instance + * @param name name + * @return value or null + */ + public static Object getValue(Object instance, String name) { + ObjectWrapper wrapper = new ObjectWrapper(instance); + if (Boolean.TRUE.equals(wrapper.contains(name))) { + return wrapper.getForce(name); + } + return null; + } + + /** + * 获取字段值 + * + * @param instance instance + * @param name name + * @return value or null + */ + public static T getValue(Object instance, String name, Class fieldType) { + ObjectWrapper wrapper = new ObjectWrapper(instance); + if (Boolean.TRUE.equals(wrapper.contains(name))) { + return wrapper.getForce(name, fieldType); + } + return null; + } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/bean/ValueWrapper.java b/uno-core/src/main/java/cc/allio/uno/core/bean/ValueWrapper.java index 021824e9..11ca95cc 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bean/ValueWrapper.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bean/ValueWrapper.java @@ -1,7 +1,10 @@ package cc.allio.uno.core.bean; +import cc.allio.uno.core.exception.Exceptions; import cc.allio.uno.core.type.Types; import cc.allio.uno.core.util.CollectionUtils; +import cc.allio.uno.core.util.FieldUtils; +import com.google.common.collect.Lists; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -9,10 +12,7 @@ import java.beans.BeanInfo; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -28,6 +28,8 @@ */ public interface ValueWrapper { + Empty EMPTY_VALUE = new Empty(); + /** * 给定字段判断是否包含当前bean中是否包含该字段 * @@ -61,7 +63,7 @@ default PropertyDescriptor find(String name) { * 获取对象某个字段的值 * * @param field 字段 - * @return 单数据源对象 + * @return 单数据源对象,如果原始数据为null,则返回{@link #EMPTY_VALUE},需要使用方进行判断 * @see BeanInfoWrapper#get(Object, String) */ default Mono get(Field field) { @@ -207,16 +209,16 @@ default List findAllForce() { * * @return tuple2 */ - Flux> findAllValues(); + Flux> findTupleValues(); /** * 强制获取该pojo所有的值 * * @return Map */ - default Map findAllValuesForce() { + default Map findMapValuesForce() { AtomicReference>> ref = new AtomicReference<>(); - findAllValues().collectList().subscribe(ref::set); + findTupleValues().collectList().subscribe(ref::set); List> values = ref.get(); if (CollectionUtils.isNotEmpty(values)) { return values.stream().collect(Collectors.toMap(Tuple2::getT1, Tuple2::getT2)); @@ -224,6 +226,46 @@ default Map findAllValuesForce() { return Collections.emptyMap(); } + /** + * 获取引用的目标实体的所有值 + */ + default Flux findValues() { + return findTupleValues().map(Tuple2::getT2); + } + + /** + * @see #findValues() + */ + default List findValuesForce() { + List fields = findNamesForce(); + List values = Lists.newArrayList(); + for (String field : fields) { + Object value = getForce(field); + if (value == null) { + value = EMPTY_VALUE; + } + values.add(value); + } + return values; + } + + /** + * 获取引用的目标实体的所有字段名称 + */ + default Flux findNames() { + return findTupleValues().map(Tuple2::getT1); + } + + /** + * @see #findNames() + */ + default List findNamesForce() { + Object target = getTarget(); + return Arrays.stream(FieldUtils.getAllFields(target.getClass())) + .map(Field::getName) + .toList(); + } + /** * 获取引用的目标实体 * @@ -231,6 +273,19 @@ default Map findAllValuesForce() { */ Object getTarget(); + /** + * 给定一个对象,判断该对象是否是{@link #EMPTY_VALUE},如果是,则返回null,否则返回原始对象 + * + * @param ori ori + * @return null or ori + */ + static Object restore(Object ori) { + if (EMPTY_VALUE.equals(ori)) { + return null; + } + return ori; + } + /** * 根据给定的对象获取ValueWrapper实例 * @@ -243,6 +298,6 @@ static ValueWrapper get(Object o) { } else if (Types.isMap(o.getClass())) { return new MapWrapper((Map) o); } - throw new UnsupportedOperationException(String.format("unsupport %s value wrapper", o.getClass())); + throw Exceptions.unOperate(String.format("unsupport %s value wrapper", o.getClass())); } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/bus/BaseEventBus.java b/uno-core/src/main/java/cc/allio/uno/core/bus/BaseEventBus.java index dfb7e864..db769438 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bus/BaseEventBus.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bus/BaseEventBus.java @@ -58,6 +58,9 @@ public Flux> publishOnFlux(String path, C context) { topics.lookup(path) .publishOn(Schedulers.boundedElastic()) .doOnNext(topic -> { + if (log.isDebugEnabled()) { + log.debug("Topic path {} is finder, now publish", path); + } // 存入 上下文数据 context.putAttribute(EventContext.TOPIC_PATH_KEY, path); context.putAttribute(EventContext.TOPIC_KEY, topic); diff --git a/uno-core/src/main/java/cc/allio/uno/core/bus/EventBus.java b/uno-core/src/main/java/cc/allio/uno/core/bus/EventBus.java index bcd50ab7..e6befb31 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bus/EventBus.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bus/EventBus.java @@ -19,6 +19,32 @@ */ public interface EventBus { + /** + * @see #hasTopic(Subscription) + */ + default boolean hasTopic(TopicKey topicKey) { + return hasTopic(topicKey.getSubscription()); + } + + /** + * @see #hasTopic(Subscription) + */ + default boolean hasTopic(String path) { + return hasTopic(Subscription.of(path)); + } + + /** + * 根据指定的订阅信息判断是否存在订阅的主题 + * + * @param subscription subscription + * @return true if exist, false otherwise + * @see #findTopic(Subscription) + */ + default boolean hasTopic(Subscription subscription) { + Long topicCount = findTopic(subscription).count().block(); + return topicCount != null && topicCount != 0; + } + /** * 根据主题路径获取指定的主题实例 * diff --git a/uno-core/src/main/java/cc/allio/uno/core/bus/Subscription.java b/uno-core/src/main/java/cc/allio/uno/core/bus/Subscription.java index e5bcee75..88a567d4 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bus/Subscription.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bus/Subscription.java @@ -76,7 +76,7 @@ public static List ofList(List topics) { } /** - * 基于{@link SubscriptionProperties#getCustomize()}构建订阅信息 + * 构建订阅信息 * * @param customize 多值Map,从配置文件中获取 * @param except 期望获取的订阅分组key diff --git a/uno-core/src/main/java/cc/allio/uno/core/bus/TopicKey.java b/uno-core/src/main/java/cc/allio/uno/core/bus/TopicKey.java index d90f6ab8..12a849fe 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/bus/TopicKey.java +++ b/uno-core/src/main/java/cc/allio/uno/core/bus/TopicKey.java @@ -71,7 +71,7 @@ static TopicKey create(Class clazz, String[] appends) { */ static TopicKey create(String prefix, Object pojo) { ObjectWrapper wrapper = new ObjectWrapper(pojo); - return create(prefix, wrapper.findAllValuesForce().values().stream().map(Object::toString).toArray(String[]::new)); + return create(prefix, wrapper.findMapValuesForce().values().stream().map(Object::toString).toArray(String[]::new)); } /** diff --git a/uno-core/src/main/java/cc/allio/uno/core/chain/ChainContext.java b/uno-core/src/main/java/cc/allio/uno/core/chain/ChainContext.java index 5c5d95ff..ca913d58 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/chain/ChainContext.java +++ b/uno-core/src/main/java/cc/allio/uno/core/chain/ChainContext.java @@ -1,5 +1,6 @@ package cc.allio.uno.core.chain; +import java.util.Collections; import java.util.Map; /** @@ -24,6 +25,8 @@ public interface ChainContext { * * @return Map实例数据 */ - Map getAttribute(); + default Map getAttribute() { + return Collections.emptyMap(); + } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/chain/DefaultChain.java b/uno-core/src/main/java/cc/allio/uno/core/chain/DefaultChain.java index c95fc413..16ecc334 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/chain/DefaultChain.java +++ b/uno-core/src/main/java/cc/allio/uno/core/chain/DefaultChain.java @@ -40,19 +40,28 @@ private DefaultChain(Chain parent, int index) { @Override public Mono proceed(ChainContext context) { return Mono.defer(() -> { - if (index < nodes.size()) { - Node node = nodes.get(index); - DefaultChain nextChain = new DefaultChain<>(this, this.index + 1); - try { - return node.execute(nextChain, context); - } catch (Throwable e) { - return Mono.error(e); - } - } else { - return Mono.empty(); + if (index < nodes.size()) { + Node node = nodes.get(index); + DefaultChain nextChain = new DefaultChain<>(this, this.index + 1); + Mono out; + try { + out = node.execute(nextChain, context); + } catch (Throwable ex) { + if (log.isWarnEnabled()) { + log.warn("execute node error", ex); } - }) - .onErrorContinue((err, obj) -> log.info("Chain Proceed error", err)); + // 避免后续结点不能执行 + out = nextChain.proceed(context); + } + return out.onErrorContinue((err, o) -> { + if (log.isWarnEnabled()) { + log.warn("Chain execute error", err); + } + }); + } else { + return Mono.empty(); + } + }); } @Override diff --git a/uno-core/src/main/java/cc/allio/uno/core/chain/Node.java b/uno-core/src/main/java/cc/allio/uno/core/chain/Node.java index 3454d232..809a236e 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/chain/Node.java +++ b/uno-core/src/main/java/cc/allio/uno/core/chain/Node.java @@ -20,7 +20,7 @@ * @author jiangwei * @date 2022/8/22 18:46 * @see org.springframework.core.annotation.Order - * @see javax.annotation.Priority + * @see jakarta.annotation.Priority * @see org.springframework.core.Ordered * @since 1.0 */ diff --git a/uno-core/src/main/java/cc/allio/uno/core/concurrent/LockContext.java b/uno-core/src/main/java/cc/allio/uno/core/concurrent/LockContext.java new file mode 100644 index 00000000..e7c2caf2 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/concurrent/LockContext.java @@ -0,0 +1,301 @@ +package cc.allio.uno.core.concurrent; + +import cc.allio.uno.core.api.OptionalContext; +import cc.allio.uno.core.api.Self; +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.core.function.ConsumerAction; +import cc.allio.uno.core.function.VoidConsumer; +import com.google.common.collect.Maps; +import org.springframework.context.ApplicationContext; + +import java.util.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * 基于{@link java.util.concurrent.locks.ReentrantLock}的函数式锁上下文的类。 + *

    在其作用域内部的的动作都会进行加锁

    + *

    其内部的的action返回的参数都会放在进行存放

    + * + * @author jiangwei + * @date 2024/2/6 20:17 + * @since 1.1.6 + */ +public class LockContext implements Self, OptionalContext { + + private final InternalParameterContext optionalContext; + private final Lock lock; + + private final LinkedList> actions; + private final LinkedList> functions; + + private Consumer startOf; + private Consumer endOf; + + LockContext() { + this(Collections.emptyMap()); + } + + LockContext(Map parameter) { + this.optionalContext = new InternalParameterContext(); + this.optionalContext.putAll(parameter); + this.lock = new ReentrantLock(); + this.actions = new LinkedList<>(); + this.functions = new LinkedList<>(); + } + + /** + * 创建 LockContext实例 + * + * @return LockContext + */ + public static LockContext lock() { + return new LockContext(); + } + + /** + * 创建 LockContext实例 + * + * @return LockContext + */ + public static LockContext lock(Map parameter) { + return new LockContext(parameter); + } + + /** + * 创建 LockContext实例 + * + * @return LockContext + */ + public static LockContext lock(Consumer lockStatOf) { + LockContext lockContext = new LockContext(); + lockContext.startOf = lockStatOf; + return lockContext; + } + + /** + * 添加动作 如果操作内发生异常则向外抛出 + * + * @param acceptor acceptor + * @return LockContext + */ + public LockContext then(ConsumerAction acceptor) { + this.actions.add(acceptor); + return self(); + } + + /** + * 加锁后继续执行,不返回任何值。如果操作内发生异常则向外抛出 + * + * @param func func + * @return LockContext + */ + public LockContext then(Function func) { + this.functions.add(func); + return self(); + } + + /** + * 加锁后直接返回,该操作是一个终止操作,会把之前加入缓存的操作一并执行。如果操作内发生异常则向外抛出 + * + * @param func func + * @param 返回值类型 + * @return v + */ + public V lockReturn(Function func) { + // 初始 + if (startOf != null) { + tryLockAndUnlock(() -> startOf.accept(this)); + } + return tryLockAndUnlock( + () -> { + doRelease(); + return func.apply(optionalContext); + }, + () -> { + if (endOf != null) { + endOf.accept(this); + } + }); + } + + /** + * 设置参数 + * + * @param key key + * @param value value + * @return LockContext + */ + public LockContext put(String key, Object value) { + this.actions.add(context -> this.putAttribute(key, value)); + return self(); + } + + /** + * 执行完操作之后的执行 + * + * @param endOf endOf + * @return LockContext + */ + public LockContext lockEnd(Consumer endOf) { + this.endOf = endOf; + return self(); + } + + /** + * 释放 + */ + public void release() { + release(null); + } + + /** + * 释放 + */ + public void release(Consumer endOf) { + lockEnd(endOf); + if (startOf != null) { + tryLockAndUnlock(() -> startOf.accept(this)); + } + if (endOf != null) { + tryLockAndUnlock(() -> endOf.accept(this), this::doRelease); + } else { + doRelease(); + } + } + + /** + * 触发缓存的{@link #actions}、{@link #functions}操作 + */ + private void doRelease() { + // 非值锁操作 + tryLockAndUnlock(() -> { + ConsumerAction action; + while ((action = actions.pollFirst()) != null) { + action.accept(optionalContext); + } + }); + // 值锁操作 + tryLockAndUnlock(() -> { + Function func; + while ((func = functions.pollFirst()) != null) { + Object value = func.apply(optionalContext); + optionalContext.putPreviousValue(value); + } + }); + } + + /** + * 优化 try-lock-finally-unlock + * + * @param acceptor acceptor + */ + private void tryLockAndUnlock(VoidConsumer acceptor) { + tryLockAndUnlock(acceptor, null); + } + + /** + * 优化 try-lock-finally-unlock + * + * @param actor actor + * @param finisher 在finally语句执行的语句 + */ + private void tryLockAndUnlock(VoidConsumer actor, VoidConsumer finisher) { + if (actor != null) { + lock.lock(); + try { + actor.doAccept(); + } finally { + if (finisher != null) { + finisher.doAccept(); + } + lock.unlock(); + } + } + } + + /** + * 优化 try-lock-finally-unlock + * + * @param actor actor + * @param finisher 在finally语句执行的语句 + */ + private V tryLockAndUnlock(Supplier actor, VoidConsumer finisher) { + if (actor != null) { + lock.lock(); + try { + return actor.get(); + } finally { + if (finisher != null) { + finisher.doAccept(); + } + lock.unlock(); + } + } + return null; + } + + @Override + public Optional get(String key) { + return optionalContext.get(key); + } + + @Override + public void putAttribute(String key, Object obj) { + optionalContext.putAttribute(key, obj); + } + + @Override + public Optional getApplicationContext() { + return optionalContext.getApplicationContext(); + } + + @Override + public Map getAll() { + return optionalContext.getAll(); + } + + public static class InternalParameterContext implements OptionalContext { + + private final Map parameter = Maps.newConcurrentMap(); + // 记录上一步执行的函数名称 + private Object previousObject; + + @Override + public Optional get(String key) { + return Optional.ofNullable(parameter.get(key)); + } + + @Override + public void putAttribute(String key, Object obj) { + parameter.put(key, obj); + } + + @Override + public Optional getApplicationContext() { + throw Exceptions.unOperate("getApplicationContext"); + } + + @Override + public Map getAll() { + return parameter; + } + + void putPreviousValue(Object value) { + this.previousObject = value; + } + + /** + * 获取上一步的操作的返回参数 + * + * @return value + */ + public Object getPreviousValue() { + return previousObject; + } + } + +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/BreadthTraversalMode.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/BreadthTraversalMode.java index 0f9f10bd..1a88a3f1 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/BreadthTraversalMode.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/BreadthTraversalMode.java @@ -15,14 +15,14 @@ public class BreadthTraversalMode implements TraversalMode { @Override - public void doTraversal(TraversalElement e, Visitor visitor) { - Queue bfsQueue = new LinkedList<>(); + public > void doTraversal(T e, Visitor visitor) { + Queue> bfsQueue = new LinkedList<>(); bfsQueue.add(e); while (!bfsQueue.isEmpty()) { - TraversalElement element = bfsQueue.poll(); + TraversalElement element = bfsQueue.poll(); element.doAccept(visitor); if (CollectionUtils.isNotEmpty(element.getChildren())) { - element.getChildren().forEach(chd -> bfsQueue.offer((TraversalElement) chd)); + element.getChildren().forEach(bfsQueue::offer); } } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/ComparableElement.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/ComparableElement.java index 8e72420c..c238273b 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/ComparableElement.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/ComparableElement.java @@ -1,21 +1,19 @@ package cc.allio.uno.core.datastructure.tree; -import lombok.NonNull; - import java.io.Serializable; import java.util.Comparator; -public class ComparableElement> extends DefaultElement { +public class ComparableElement> extends DefaultElement { private final Comparator comparator; - public ComparableElement(@NonNull Serializable id, Comparator comparator) { + public ComparableElement(Serializable id, Comparator comparator) { super(id); this.comparator = comparator; } @Override - public void addChildren(Element element) { + public void addChildren(T element) { super.addChildren(element); if (comparator != null) { getChildren().sort((o1, o2) -> comparator.compare((T) o1, (T) o2)); diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/DeepTraversalMode.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/DeepTraversalMode.java index ae431419..afd9770a 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/DeepTraversalMode.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/DeepTraversalMode.java @@ -16,19 +16,19 @@ public class DeepTraversalMode implements TraversalMode { @Override - public void doTraversal(TraversalElement e, Visitor visitor) { + public > void doTraversal(T e, Visitor visitor) { // 深度优先 - Deque dfsStack = new ArrayDeque<>(); + Deque dfsStack = new ArrayDeque<>(); dfsStack.push(e); - List childrens = e.getChildren(); + List childrens = e.getChildren(); deepAccept(childrens, dfsStack); while (!dfsStack.isEmpty()) { - TraversalElement element = dfsStack.pollLast(); + T element = dfsStack.pollLast(); element.doAccept(visitor); } } - private void deepAccept(List childrens, Deque dfsStack) { + private > void deepAccept(List childrens, Deque dfsStack) { if (CollectionUtils.isNotEmpty(childrens)) { childrens.forEach(dfsStack::offerLast); childrens.forEach(e -> deepAccept(e.getChildren(), dfsStack)); diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/DefaultElement.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/DefaultElement.java index 952006c1..303f0906 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/DefaultElement.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/DefaultElement.java @@ -2,11 +2,9 @@ import com.google.common.collect.Lists; import lombok.Getter; -import lombok.NonNull; import lombok.Setter; import java.io.Serializable; -import java.util.Collections; import java.util.List; /** @@ -17,40 +15,108 @@ * @since 1.1.5 */ @Getter -public class DefaultElement extends TraversalElement { +public class DefaultElement> extends TraversalElement { private final Serializable id; + + @Getter + private Serializable parentId; @Setter private int depth; @Setter - private Element parent; + private T parent; - private List children; + private List children; - public DefaultElement(@NonNull Serializable id) { + public DefaultElement(Serializable id) { this.id = id; this.children = Lists.newArrayList(); } - public DefaultElement(@NonNull Serializable id, int depth) { + public DefaultElement(Serializable id, Integer depth) { this.id = id; this.depth = depth; this.children = Lists.newArrayList(); } + public DefaultElement(Serializable id, Serializable parentId) { + this.id = id; + this.parentId = parentId; + this.children = Lists.newArrayList(); + } + + public DefaultElement(Serializable id, Serializable parentId, int depth) { + this.id = id; + this.parentId = parentId; + this.depth = depth; + this.children = Lists.newArrayList(); + } + + @Override + public void setParentId(Serializable parentId) { + this.parentId = parentId; + } + @Override public boolean isLeaf() { return children.isEmpty(); } + /** + * 根据指定的id获取某个子结点 + * + * @param id id + * @return element or null + */ + @Override + public T findChildren(Serializable id) { + for (T child : children) { + if (id.equals(child.getId())) { + return child; + } + T findChild = child.findChildren(id); + if (findChild != null) { + return findChild; + } + } + return null; + } + + /** + * 根据指定的id移除某个子结点 + * + * @param id id + * @return true if success + */ + @Override + public boolean removeChildren(Serializable id) { + boolean removed = children.removeIf(child -> id.equals(child.getId())); + if (removed) { + return true; + } + // 没有移除尝试在从字节中再次移除 + for (T child : children) { + removed = child.removeChildren(id); + if (removed) { + return true; + } + } + return false; + } + + @Override + public void setChildren(List children) { + this.children = children; + } + @Override - public void setChildren(List children) { - this.children = Collections.singletonList(children); + public List getChildren() { + return children; } @Override - public void addChildren(Element element) { + public void addChildren(T element) { this.children.add(element); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Element.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Element.java index c9f6aca9..5990f9a6 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Element.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Element.java @@ -16,9 +16,9 @@ * @date 2023/4/26 11:31 * @since 1.1.4 */ -public interface Element extends Serializable { +public interface Element> extends Serializable { - Element ROOT_SENTINEL = new DefaultElement(-1, -1); + Element ROOT_SENTINEL = new DefaultElement<>(-1, -1); /** * 定义根节点 @@ -51,19 +51,34 @@ default String getPath() { return getParent() != null ? getParent().getPath() + StringPool.ORIGIN_DOT + getId() : String.valueOf(getId()); } + /** + * 获取父节点Id + * + * @return Element + * @since 1.1.6 + */ + default Serializable getParentId() { + return getParent() != null ? getParent().getId() : null; + } + + /** + * 设置父节点Id + */ + void setParentId(Serializable parentId); + /** * 获取父节点 * * @return Element */ - T getParent(); + T getParent(); /** * 设置父节点 * * @param parent parent node */ - void setParent(T parent); + void setParent(T parent); /** * 是否为根节点 @@ -81,24 +96,40 @@ default boolean isRoot() { */ boolean isLeaf(); + /** + * 根据指定的id获取某个子结点 + * + * @param id id + * @return element or null + */ + T findChildren(Serializable id); + + /** + * 根据指定的id移除某个子结点 + * + * @param id id + * @return true if success + */ + boolean removeChildren(Serializable id); + /** * 获取子节点 * * @return element list */ - List getChildren(); + List getChildren(); /** * 添加子结点 */ - void addChildren(T element); + void addChildren(T element); /** * 覆盖并设置子结点 * * @param children children */ - void setChildren(List children); + void setChildren(List children); /** * 清除children数据 @@ -110,7 +141,7 @@ default boolean isRoot() { * * @param visitor visitor */ - default void accept(Visitor visitor) { + default void accept(Visitor visitor) { accept(visitor, Traversal.NONE); } @@ -120,5 +151,12 @@ default void accept(Visitor visitor) { * @param visitor visitor * @param traversal 遍历原则 */ - void accept(Visitor visitor, Traversal traversal); + void accept(Visitor visitor, Traversal traversal); + + /** + * 获取Sentinel结点 + */ + static Element getRootSentinel() { + return new DefaultElement<>(-1, -1); + } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Expand.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Expand.java index 2f2c8eb0..703bf651 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Expand.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Expand.java @@ -9,7 +9,7 @@ * @date 2023/11/9 11:32 * @since 1.1.5 */ -public interface Expand { +public interface Expand extends Serializable { /** * 获取当前结点的标识 diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/NoneTraversalMode.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/NoneTraversalMode.java index 5cbe5ae3..7aae799d 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/NoneTraversalMode.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/NoneTraversalMode.java @@ -12,7 +12,7 @@ public class NoneTraversalMode implements TraversalMode { NoneTraversalMode() {} @Override - public void doTraversal(TraversalElement e, Visitor visitor) { + public > void doTraversal(T e, Visitor visitor) { e.doAccept(visitor); e.getChildren().forEach(c -> c.accept(visitor, getMode())); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TraversalElement.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TraversalElement.java index c489d14c..f63b3eb0 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TraversalElement.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TraversalElement.java @@ -7,11 +7,11 @@ * @date 2023/4/26 15:18 * @since 1.1.4 */ -public abstract class TraversalElement implements Element { +public abstract class TraversalElement> implements Element { @Override - public void accept(Visitor visitor, Traversal traversal) { - TraversalMode.get(traversal).doTraversal(this, visitor); + public void accept(Visitor visitor, Traversal traversal) { + TraversalMode.get(traversal).doTraversal((T) this, visitor); } /** @@ -19,7 +19,7 @@ public void accept(Visitor visitor, Traversal traversal) { * * @param visitor visitor访问器 */ - protected void doAccept(Visitor visitor) { - visitor.visit(this); + protected void doAccept(Visitor visitor) { + visitor.visit((T) this); } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TraversalMode.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TraversalMode.java index 36a218e4..9776c80d 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TraversalMode.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TraversalMode.java @@ -37,7 +37,7 @@ static TraversalMode get(Traversal traversal) { * @param e e * @param visitor visitor */ - void doTraversal(TraversalElement e, Visitor visitor); + > void doTraversal(T e, Visitor visitor); /** * 获取遍历的模式 diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TreeSupport.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TreeSupport.java index 22d19303..0fa00dc2 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TreeSupport.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TreeSupport.java @@ -24,17 +24,11 @@ private TreeSupport() { * @see #treeify(List, Function) */ public static List treeify(List expandTrees) { - return treeify(expandTrees, e -> new DefaultElement(e.getId())); + return treeify(expandTrees, e -> new DefaultElement<>(e.getId())); } /** * 把平展的树转换为具有层次性的树。 - *

    算法明细如下:

    - *
      - *
    1. 构建已{@link Element#getId()}为key的散列表结构
    2. - *
    3. 循环{@link Expand}列表,每一次循环根据散列表结构找到对应父与当前{@link Element}的结构,然后进行添加
    4. - *
    - *

    时间复杂度将会是O(n)

    * * @param expandTrees 平展的树 * @param treeFunc 平展结构转换为树结构 @@ -42,18 +36,45 @@ public static List treeify(List expandTree * @param 继承于{@link Element}的泛型 * @return hierarchy filter expand tree depth == 0的结点 */ - public static synchronized List treeify(List expandTrees, Function treeFunc) { + public static synchronized > List treeify(List expandTrees, Function treeFunc) { if (CollectionUtils.isEmpty(expandTrees)) { return Collections.emptyList(); } - // transfer expand id must not null - Map idElement = + return adjust( expandTrees.stream() - .map(treeFunc) - .collect(Collectors.toMap(Element::getId, e -> e)); + .map(expand -> { + R element = treeFunc.apply(expand); + if (element != null && element.getParentId() == null) { + element.setParentId(expand.getParentId()); + } + return element; + }) + .toList() + ); + } + + /** + * 对给定的Tree Element进行调整,使得可以进行树化 + *

    算法明细如下:

    + *
      + *
    1. 构建已{@link Element#getId()}为key的散列表结构
    2. + *
    3. 循环{@link Element}列表,每一次循环根据散列表结构找到对应父与当前{@link Element}的结构,然后进行添加
    4. + *
    + *

    时间复杂度将会是O(n)

    + * + * @param elements elements + * @param Tree Element + * @return 调整完成的树 + */ + public static > List adjust(List elements) { + if (CollectionUtils.isEmpty(elements)) { + return elements; + } + // transfer expand id must not null + Map idElement = elements.stream().collect(Collectors.toMap(Element::getId, e -> e)); // 已散列表为基础循环设置添加子结点 - for (T e : expandTrees) { + for (R e : elements) { Serializable parentId = e.getParentId(); R parent = idElement.get(parentId); if (parent != null) { @@ -64,9 +85,7 @@ public static synchronized List treeify } } - T fake = expandTrees.getFirst(); - - R sentinel = treeFunc.apply(fake); + Element sentinel = Element.getRootSentinel(); for (R virtual : idElement.values()) { if (virtual.getDepth() == Element.ROOT_NODE) { // 触发Element添加结点的特性,如排序 @@ -80,7 +99,7 @@ public static synchronized List treeify /** * @see #expand(List, Function, Comparator) */ - public static List expand(List forest) { + public static > List expand(List forest) { return expand( forest, r -> new DefaultExpand(r.getId(), r.getParent() != null ? r.getParent().getId() : null), @@ -98,7 +117,7 @@ public static List expand(List forest) { * @param 继承于{@link Element}的泛型 * @return expand */ - public static synchronized List expand(List forest, Function expandFunc, Comparator comparator) { + public static synchronized > List expand(List forest, Function expandFunc, Comparator comparator) { List expands = Lists.newArrayList(); try { Element.ROOT_SENTINEL.setChildren(Lists.newArrayList(forest)); diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Visitor.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Visitor.java index 7e34a8b2..8b94b251 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Visitor.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/Visitor.java @@ -8,12 +8,12 @@ * @since 1.1.4 */ @FunctionalInterface -public interface Visitor { +public interface Visitor> { /** * visit the given element * * @param e element */ - void visit(Element e); + void visit(T e); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/exception/Exceptions.java b/uno-core/src/main/java/cc/allio/uno/core/exception/Exceptions.java index f806b364..5291e65b 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/exception/Exceptions.java +++ b/uno-core/src/main/java/cc/allio/uno/core/exception/Exceptions.java @@ -8,9 +8,12 @@ /** * 异常处理工具类 * - * @author L.cm + * @author jiangwei */ -public class Exceptions { +public abstract class Exceptions { + + private Exceptions() { + } /** * 将CheckedException转换为UncheckedException. @@ -104,4 +107,23 @@ public static Throwable unwrap(Throwable wrapped) { } } + /** + * 创建{@link NullPointerException}异常 + * + * @param message 异常消息 + * @return message + */ + public static NullPointerException unNull(String message) { + return new NullPointerException(message); + } + + /** + * 创建{@link UnsupportedOperationException}异常 + * + * @param message 异常消息 + * @return message + */ + public static UnsupportedOperationException unOperate(String message) { + return new UnsupportedOperationException(message); + } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/Action.java b/uno-core/src/main/java/cc/allio/uno/core/function/Action.java new file mode 100644 index 00000000..1b865a57 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/Action.java @@ -0,0 +1,11 @@ +package cc.allio.uno.core.function; + +/** + * 标识接口,表示一系列函数式行为。 + * + * @author jiangwei + * @date 2024/1/9 15:54 + * @since 1.1.6 + */ +public interface Action { +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/ConsumerAction.java b/uno-core/src/main/java/cc/allio/uno/core/function/ConsumerAction.java new file mode 100644 index 00000000..980cadea --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/ConsumerAction.java @@ -0,0 +1,13 @@ +package cc.allio.uno.core.function; + +import java.util.function.Consumer; + +/** + * consumer action + * + * @author jiangwei + * @date 2024/1/9 16:00 + * @since 1.1.6 + */ +public interface ConsumerAction extends Consumer, Action { +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/SupplierAction.java b/uno-core/src/main/java/cc/allio/uno/core/function/SupplierAction.java new file mode 100644 index 00000000..e517a9de --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/SupplierAction.java @@ -0,0 +1,13 @@ +package cc.allio.uno.core.function; + +import java.util.function.Supplier; + +/** + * supplier 动作 + * + * @author jiangwei + * @date 2024/1/9 15:58 + * @since 1.1.6 + */ +public interface SupplierAction extends Supplier, Action { +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/TernaryConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/TernaryConsumer.java new file mode 100644 index 00000000..f4503963 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/TernaryConsumer.java @@ -0,0 +1,13 @@ +package cc.allio.uno.core.function; + +/** + * 拓展Consumer函数式接口,用于接收三元参数 + * + * @author jiangwei + * @date 2024/1/9 15:51 + * @since 1.1.6 + */ +@FunctionalInterface +public interface TernaryConsumer { + void accept(T t, Q q, P p); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/VoidConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/VoidConsumer.java new file mode 100644 index 00000000..d4aecb49 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/VoidConsumer.java @@ -0,0 +1,21 @@ +package cc.allio.uno.core.function; + +import java.util.function.Consumer; + +/** + * 不接收如何参数的消费者 + * + * @author jiangwei + * @date 2024/1/9 15:57 + * @since 1.1.6 + */ +@FunctionalInterface +public interface VoidConsumer extends Consumer, Action { + + @Override + default void accept(Object o) { + doAccept(); + } + + void doAccept(); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/LambdaMethod.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/LambdaMethod.java new file mode 100644 index 00000000..1fa4f48f --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/LambdaMethod.java @@ -0,0 +1,34 @@ +package cc.allio.uno.core.function.lambda; + +/** + * 继承或实现都需要实现{@link java.io.Serializable},{@link java.io.NotSerializableException} 当实体没有实现{@link java.io.Serializable}时抛出 + * + * @author jiangwei + * @date 2024/1/26 18:26 + * @since 1.1.6 + */ +public interface LambdaMethod { + + /** + * 获取Method名称 + * + * @return Column名称 + */ + default String getMethodName() { + return getLambda().getMethodName(); + } + + /** + * 获取字段名 + */ + default String getFieldName() { + return getLambda().getFieldName(); + } + + /** + * 获取 lambda实例 + */ + default SerializedLambda getLambda() { + return SerializedLambda.of(this); + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodBiConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodBiConsumer.java new file mode 100644 index 00000000..cef58d2c --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodBiConsumer.java @@ -0,0 +1,18 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * 基于函数式接口的Lambda实现,如this::getName。 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * + * @author jiangwei + * @date 2024/1/26 18:34 + * @see java.util.function.BiConsumer + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodBiConsumer extends Serializable, LambdaMethod { + + void accept(T t, K k); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodBiFunction.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodBiFunction.java new file mode 100644 index 00000000..844f4ff0 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodBiFunction.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * 基于函数式接口的Lambda实现 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * @author jiangwei + * @date 2024/1/26 18:39 + * @see java.util.function.BiFunction + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodBiFunction extends Serializable, LambdaMethod { + + R apply(T t, U u); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodBiPredicate.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodBiPredicate.java new file mode 100644 index 00000000..20c34831 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodBiPredicate.java @@ -0,0 +1,16 @@ +package cc.allio.uno.core.function.lambda; + +import java.util.function.BiPredicate; + +/** + * 基于函数式接口的Lambda实现 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * + * @author jiangwei + * @date 2024/2/11 10:48 + * @see BiPredicate + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodBiPredicate extends BiPredicate, LambdaMethod { +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodConsumer.java new file mode 100644 index 00000000..0d54593c --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodConsumer.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * 基于函数式接口的Lambda实现,如this::getName + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * @author jiangwei + * @date 2024/1/26 18:26 + * @see java.util.function.Consumer + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodConsumer extends Serializable, LambdaMethod { + + void accept(T t); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodFunction.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodFunction.java new file mode 100644 index 00000000..d72f7126 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodFunction.java @@ -0,0 +1,32 @@ +package cc.allio.uno.core.function.lambda; + +import cc.allio.uno.core.util.ReflectTool; + +import java.io.Serializable; + +/** + * 基于函数式接口的Lambda实现,如this::getName + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * @author jiangwei + * @date 2024/1/26 18:31 + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodFunction extends Serializable, LambdaMethod { + + K apply(T t); + + /** + * 获取参数值的类型 + */ + default Class getParameterType() { + return (Class) ReflectTool.getGenericType(this, MethodFunction.class, 0); + } + + /** + * 获取返回值的类型 + */ + default Class getReturnType() { + return (Class) ReflectTool.getGenericType(this, MethodFunction.class, 1); + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodPredicate.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodPredicate.java new file mode 100644 index 00000000..ef97e651 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodPredicate.java @@ -0,0 +1,16 @@ +package cc.allio.uno.core.function.lambda; + +import java.util.function.Predicate; + +/** + * 基于函数式接口的Lambda实现 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * + * @author jiangwei + * @date 2024/2/11 10:44 + * @see Predicate + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodPredicate extends Predicate, LambdaMethod { +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodQueConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodQueConsumer.java new file mode 100644 index 00000000..b8e7e2d3 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodQueConsumer.java @@ -0,0 +1,16 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * 基于函数式接口的Lambda实现,四元消费者 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * @author jiangwei + * @date 2024/1/26 18:37 + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodQueConsumer extends Serializable, LambdaMethod { + + void accept(T t, K k, U u, L l); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodQueFunction.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodQueFunction.java new file mode 100644 index 00000000..14e270fb --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodQueFunction.java @@ -0,0 +1,16 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * 基于函数式接口的Lambda实现,四元函数 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * @author jiangwei + * @date 2024/1/26 18:41 + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodQueFunction extends Serializable, LambdaMethod { + + R apply(T1 t1, T2 t2, T3 t3, T4 t4); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/MethodReference.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodReference.java similarity index 88% rename from uno-core/src/main/java/cc/allio/uno/core/function/MethodReference.java rename to uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodReference.java index 6f1ec6c9..60f9d930 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/function/MethodReference.java +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodReference.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.function; +package cc.allio.uno.core.function.lambda; import java.io.Serializable; import java.util.function.Supplier; diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodReferenceColumn.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodReferenceColumn.java new file mode 100644 index 00000000..e73575f7 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodReferenceColumn.java @@ -0,0 +1,59 @@ +package cc.allio.uno.core.function.lambda; + +import cc.allio.uno.core.StringPool; +import org.apache.commons.lang3.reflect.FieldUtils; + +import java.lang.reflect.Field; + +/** + * 可以通过静态方法引用来获取实体(需要实例实现{@link java.io.Serializable})的字段名称: + *
    + *     select(User::getName).eq(User::getAge, 2)...
    + * 
    + * + * @author jiangwei + * @date 2023/1/5 15:36 + * @since 1.1.4 + */ +public interface MethodReferenceColumn extends StaticMethodReference { + + /** + * 获取实体类型 + * + * @return class or empty + */ + default Class getEntityType() { + SerializedLambda serializedLambda = SerializedLambda.of(this); + String implClass = serializedLambda.getImplClass(); + try { + return (Class) Class.forName(implClass.replace(StringPool.SLASH, StringPool.ORIGIN_DOT)); + } catch (ClassNotFoundException e) { + // ignore + return null; + } + } + + /** + * 获取Column名称 + * + * @return Column名称 + * @throws java.io.NotSerializableException 当实体没有实现{@link java.io.Serializable}时抛出 + */ + default String getColumn() { + return SerializedLambda.of(this).getFieldName(); + } + + /** + * 获取实体的{@link Field}实例 + * + * @return field 实例 or empty + */ + default Field getField() { + Class entityType = getEntityType(); + if (entityType != null) { + return FieldUtils.getField(entityType, getColumn(), true); + } else { + return null; + } + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodSupplier.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodSupplier.java new file mode 100644 index 00000000..24b43698 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodSupplier.java @@ -0,0 +1,26 @@ +package cc.allio.uno.core.function.lambda; + +import cc.allio.uno.core.util.ReflectTool; + +import java.io.Serializable; + +/** + * 基于函数式接口的Lambda实现,如this::setName + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * @author jiangwei + * @date 2024/1/26 18:29 + * @see java.util.function.Supplier + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodSupplier extends Serializable, LambdaMethod { + + T get(); + + /** + * 获取类型 + */ + default Class getType() { + return (Class) ReflectTool.getGenericType(this, MethodSupplier.class); + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodTerConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodTerConsumer.java new file mode 100644 index 00000000..839ea774 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodTerConsumer.java @@ -0,0 +1,16 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * 基于函数式接口的Lambda实现,三元消费者 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * @author jiangwei + * @date 2024/1/26 18:36 + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodTerConsumer extends Serializable, LambdaMethod { + + void accept(T t, K k, U u); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodTerFunction.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodTerFunction.java new file mode 100644 index 00000000..72b41507 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodTerFunction.java @@ -0,0 +1,16 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * 基于函数式接口的Lambda实现,三元函数 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * @author jiangwei + * @date 2024/1/26 18:40 + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodTerFunction extends Serializable, LambdaMethod { + + R apply(T t, U u, L l); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodTerPredicate.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodTerPredicate.java new file mode 100644 index 00000000..718cfd17 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodTerPredicate.java @@ -0,0 +1,23 @@ +package cc.allio.uno.core.function.lambda; + +/** + * 基于函数式接口的Lambda实现 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * + * @author jiangwei + * @date 2024/2/11 10:48 + * @since 1.1.6 + */ +public interface MethodTerPredicate extends LambdaMethod { + + /** + * Evaluates this predicate on the given arguments. + * + * @param t the first input argument + * @param u the second input argument + * @param p the third input argument + * @return {@code true} if the input arguments match the predicate, + * otherwise {@code false} + */ + boolean test(T t, U u, P p); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodVoid.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodVoid.java new file mode 100644 index 00000000..c9678795 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodVoid.java @@ -0,0 +1,15 @@ +package cc.allio.uno.core.function.lambda; + +import cc.allio.uno.core.function.VoidConsumer; + +/** + * 基于函数式接口的Lambda实现 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * + * @author jiangwei + * @date 2024/2/11 10:46 + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodVoid extends VoidConsumer, LambdaMethod { +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodVoidPredicate.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodVoidPredicate.java new file mode 100644 index 00000000..8312a46f --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/MethodVoidPredicate.java @@ -0,0 +1,15 @@ +package cc.allio.uno.core.function.lambda; + +/** + * 基于函数式接口的Lambda实现 + *

    该接口包含能够获取Lambda方法名、字段名、Lambda方法的序列化信息等。

    + * + * @author jiangwei + * @date 2024/2/11 10:53 + * @since 1.1.6 + */ +@FunctionalInterface +public interface MethodVoidPredicate extends LambdaMethod { + + boolean test(); +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/SerializedLambda.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/SerializedLambda.java similarity index 99% rename from uno-core/src/main/java/cc/allio/uno/core/function/SerializedLambda.java rename to uno-core/src/main/java/cc/allio/uno/core/function/lambda/SerializedLambda.java index f5f61cd5..650190c7 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/function/SerializedLambda.java +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/SerializedLambda.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.function; +package cc.allio.uno.core.function.lambda; import cc.allio.uno.core.util.ClassUtils; import cc.allio.uno.core.util.StringUtils; diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/StaticMethodReference.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/StaticMethodReference.java similarity index 88% rename from uno-core/src/main/java/cc/allio/uno/core/function/StaticMethodReference.java rename to uno-core/src/main/java/cc/allio/uno/core/function/lambda/StaticMethodReference.java index ea56c5fa..fd2394f2 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/function/StaticMethodReference.java +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/StaticMethodReference.java @@ -1,4 +1,4 @@ -package cc.allio.uno.core.function; +package cc.allio.uno.core.function.lambda; import java.io.Serializable; import java.util.function.Function; diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodBiConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodBiConsumer.java new file mode 100644 index 00000000..83b563b4 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodBiConsumer.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for bi consumer accept method + * + * @author jiangwei + * @date 2024/2/18 15:46 + * @see MethodBiConsumer + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodBiConsumer extends Serializable, LambdaMethod { + + void accept(T t, K k) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodBiFunction.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodBiFunction.java new file mode 100644 index 00000000..c8e4307e --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodBiFunction.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for bi function apply method + * + * @author jiangwei + * @date 2024/2/18 15:49 + * @see MethodBiFunction + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodBiFunction extends Serializable, LambdaMethod { + + R apply(T t, U u) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodBiPredicate.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodBiPredicate.java new file mode 100644 index 00000000..db8e0bd5 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodBiPredicate.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for predicate test method + * + * @author jiangwei + * @date 2024/2/18 15:53 + * @see MethodBiPredicate + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodBiPredicate extends Serializable, LambdaMethod { + + boolean test(T t, U u) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodConsumer.java new file mode 100644 index 00000000..e0498062 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodConsumer.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for consumer accept method + * + * @author jiangwei + * @date 2024/2/18 15:54 + * @see MethodConsumer + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodConsumer extends Serializable, LambdaMethod { + + void accept(T t) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodFunction.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodFunction.java new file mode 100644 index 00000000..f1db5c8a --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodFunction.java @@ -0,0 +1,16 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for function apply method + * + * @author jiangwei + * @date 2024/2/18 15:56 + * @see MethodFunction + * @since 1.1.6 + */ +public interface ThrowingMethodFunction extends Serializable, LambdaMethod { + + K apply(T t) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodPredicate.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodPredicate.java new file mode 100644 index 00000000..5d6b4cf0 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodPredicate.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for predicate test method + * + * @author jiangwei + * @date 2024/2/18 15:57 + * @see MethodPredicate + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodPredicate extends Serializable, LambdaMethod { + + boolean test(T t) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodQueConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodQueConsumer.java new file mode 100644 index 00000000..c6b7408e --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodQueConsumer.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for que consumer accept method + * + * @author jiangwei + * @date 2024/2/18 15:57 + * @see MethodQueConsumer + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodQueConsumer extends Serializable, LambdaMethod { + + void accept(T t, K k, U u, L l) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodQueFunction.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodQueFunction.java new file mode 100644 index 00000000..321b4491 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodQueFunction.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for que function apply method + * + * @author jiangwei + * @date 2024/2/18 15:58 + * @see MethodQueFunction + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodQueFunction extends Serializable, LambdaMethod { + + R apply(T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodSupplier.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodSupplier.java new file mode 100644 index 00000000..b592c7d5 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodSupplier.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for supplier get method + * + * @author jiangwei + * @date 2024/2/18 15:59 + * @see MethodSupplier + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodSupplier extends Serializable, LambdaMethod { + + T get() throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodTerConsumer.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodTerConsumer.java new file mode 100644 index 00000000..1ffb2638 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodTerConsumer.java @@ -0,0 +1,16 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for ter consumer accept method + * + * @author jiangwei + * @date 2024/2/18 16:00 + * @see MethodTerConsumer + * @since 1.1.6 + */ +public interface ThrowingMethodTerConsumer extends Serializable, LambdaMethod { + + void accept(T t, K k, U u) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodTerFunction.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodTerFunction.java new file mode 100644 index 00000000..4885e6ac --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodTerFunction.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for ter function apply method + * + * @author jiangwei + * @date 2024/2/18 16:01 + * @see MethodTerFunction + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodTerFunction extends Serializable, LambdaMethod { + + R apply(T t, U u, L l) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodTerPredicate.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodTerPredicate.java new file mode 100644 index 00000000..ed05cf2d --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodTerPredicate.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for ter predicate test method + * + * @author jiangwei + * @date 2024/2/18 16:02 + * @see MethodTerPredicate + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodTerPredicate extends Serializable, LambdaMethod { + + boolean test(T t, U u, P p) throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodVoid.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodVoid.java new file mode 100644 index 00000000..a4deac31 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodVoid.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for void method + * + * @author jiangwei + * @date 2024/2/18 16:03 + * @see MethodVoid + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodVoid extends Serializable, LambdaMethod { + + void accept() throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodVoidPredicate.java b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodVoidPredicate.java new file mode 100644 index 00000000..166b8bbc --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/function/lambda/ThrowingMethodVoidPredicate.java @@ -0,0 +1,17 @@ +package cc.allio.uno.core.function.lambda; + +import java.io.Serializable; + +/** + * exception for predicate test method + * + * @author jiangwei + * @date 2024/2/18 16:04 + * @see MethodVoidPredicate + * @since 1.1.6 + */ +@FunctionalInterface +public interface ThrowingMethodVoidPredicate extends Serializable, LambdaMethod { + + boolean test() throws Throwable; +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/metadata/mapping/DefaultMappingMetadata.java b/uno-core/src/main/java/cc/allio/uno/core/metadata/mapping/DefaultMappingMetadata.java index 18713e63..8d6dd8b7 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/metadata/mapping/DefaultMappingMetadata.java +++ b/uno-core/src/main/java/cc/allio/uno/core/metadata/mapping/DefaultMappingMetadata.java @@ -38,7 +38,7 @@ public void addMapping(MappingField source, MappingField target) { @Override public MappingField get(String sourceFieldName) { return Optional.ofNullable(get(MappingField.builder().name(sourceFieldName).build())) - .orElseThrow(() -> new NullPointerException(String.format("According to %s get Mapping relationship Failed, does not exist", sourceFieldName))); + .orElseThrow(() -> new NullPointerException(String.format("According to %s getValue Mapping relationship Failed, does not exist", sourceFieldName))); } @Override diff --git a/uno-core/src/main/java/cc/allio/uno/core/proxy/CglibProxyInvocation.java b/uno-core/src/main/java/cc/allio/uno/core/proxy/CglibProxyInvocation.java index 21caa8be..62d317d4 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/proxy/CglibProxyInvocation.java +++ b/uno-core/src/main/java/cc/allio/uno/core/proxy/CglibProxyInvocation.java @@ -21,8 +21,8 @@ public T proxyInstance(ClassLoader classLoader, Class target, InvocationI Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target); enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> { - if (interceptor instanceof CglibInvocationInterceptor) { - return ((CglibInvocationInterceptor) interceptor).invoke(obj, method, args1, proxy); + if (interceptor instanceof CglibInvocationInterceptor cglibInvocationInterceptor) { + return cglibInvocationInterceptor.invoke(obj, method, args1, proxy); } return interceptor.invoke(obj, method, args1); }); @@ -49,7 +49,7 @@ public Class[] objectToClass(Object[] args) { return Arrays.stream(args) .filter(Objects::nonNull) .map(Object::getClass) - .collect(Collectors.toList()) + .toList() .toArray(new Class[]{}); } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/proxy/ComposeOrigin.java b/uno-core/src/main/java/cc/allio/uno/core/proxy/ComposeOrigin.java index 87888a47..4861fd93 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/proxy/ComposeOrigin.java +++ b/uno-core/src/main/java/cc/allio/uno/core/proxy/ComposeOrigin.java @@ -7,14 +7,14 @@ *
    *
      *     class Test {
    - *         void get(@ComposeOrigin Object obj);
    + *         void getValue(@ComposeOrigin Object obj);
      *     }
      *     class ComposeTest extends Test {
      *     	   Test[] tests;
      *         ComposeTes(Test... tests) {
      *             this.tests = tests;
      *         }
    - *         void get(@ComposeOrigin Object obj) {
    + *         void getValue(@ComposeOrigin Object obj) {
      *             ...
      *         }
      *     }
    diff --git a/uno-core/src/main/java/cc/allio/uno/core/proxy/ComposeSharable.java b/uno-core/src/main/java/cc/allio/uno/core/proxy/ComposeSharable.java
    index 1c26b924..607fcfc7 100644
    --- a/uno-core/src/main/java/cc/allio/uno/core/proxy/ComposeSharable.java
    +++ b/uno-core/src/main/java/cc/allio/uno/core/proxy/ComposeSharable.java
    @@ -4,18 +4,18 @@
     
     /**
      * 使用于代理对象。标记于方法上,表示当前方法可以使用组合类型的方法。
    - * 比如说:Test的实例将使用ComposeTest#get()方法 + * 比如说:Test的实例将使用ComposeTest#getValue()方法 *
    *
      *     class Test {
    - *         void get();
    + *         void getValue();
      *     }
      *     class ComposeTest extends Test {
      *     	   Test[] tests;
      *         ComposeTest(Test... tests) {
      *             this.tests = tests;
      *         }
    - *         void get();
    + *         void getValue();
      *     }
      * 
    *
    diff --git a/uno-core/src/main/java/cc/allio/uno/core/serializer/JsonNodeEnhancer.java b/uno-core/src/main/java/cc/allio/uno/core/serializer/JsonNodeEnhancer.java index 3d2b410c..b52f8e53 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/serializer/JsonNodeEnhancer.java +++ b/uno-core/src/main/java/cc/allio/uno/core/serializer/JsonNodeEnhancer.java @@ -1,6 +1,6 @@ package cc.allio.uno.core.serializer; -import cc.allio.uno.core.util.BigDecimalUtil; +import cc.allio.uno.core.util.BigDecimalUtils; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.JsonNodeType; import lombok.extern.slf4j.Slf4j; @@ -78,7 +78,7 @@ public BigDecimal asBigDecimal(String fieldName) { */ public BigDecimal asBigDecimal(String fieldName, Supplier defaultValue) { String maybeBigDecimal = asString(fieldName); - BigDecimal maybe = BigDecimalUtil.creator(maybeBigDecimal); + BigDecimal maybe = BigDecimalUtils.creator(maybeBigDecimal); if (Objects.isNull(maybe)) { return defaultValue.get(); } @@ -115,7 +115,7 @@ public String asString(String fieldName, Supplier defaultValue) { return fieldNode.asText(defaultValue.get()); } } catch (Throwable e) { - log.error("get {} asString failed", fieldName, e); + log.error("getValue {} asString failed", fieldName, e); return defaultValue.get(); } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/spi/AutoTypeLoader.java b/uno-core/src/main/java/cc/allio/uno/core/spi/AutoTypeLoader.java index ddc992f3..72845a54 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/spi/AutoTypeLoader.java +++ b/uno-core/src/main/java/cc/allio/uno/core/spi/AutoTypeLoader.java @@ -10,7 +10,7 @@ import java.util.stream.Collectors; /** - * 使用google{@link AutoService}与{@link Type}数据类型加载单例对象,提供的静态方法获取实例数据不做缓存 + * {@link AutoService}与{@link Type}数据类型加载单例对象,提供的静态方法获取实例数据不做缓存 * * @author jiangwei * @date 2022/5/20 10:42 diff --git a/uno-core/src/main/java/cc/allio/uno/core/task/CronExpression.java b/uno-core/src/main/java/cc/allio/uno/core/task/CronExpression.java index 1c02b632..3dd0c15e 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/task/CronExpression.java +++ b/uno-core/src/main/java/cc/allio/uno/core/task/CronExpression.java @@ -908,7 +908,7 @@ protected void addToSet(int val, int end, int incr, int type) // ie: there's no max to overflow over set.add(i); } else { - // take the modulus to get the real value + // take the modulus to getValue the real value int i2 = i % max; // 1-indexed ranges should not include 0, and should include their max @@ -1019,7 +1019,7 @@ public Date getTimeAfter(Date afterTime) { int sec = cl.get(Calendar.SECOND); int min = cl.get(Calendar.MINUTE); - // get second................................................. + // getValue second................................................. st = seconds.tailSet(sec); if (st != null && st.size() != 0) { sec = st.first(); @@ -1034,7 +1034,7 @@ public Date getTimeAfter(Date afterTime) { int hr = cl.get(Calendar.HOUR_OF_DAY); t = -1; - // get minute................................................. + // getValue minute................................................. st = minutes.tailSet(min); if (st != null && st.size() != 0) { t = min; @@ -1055,7 +1055,7 @@ public Date getTimeAfter(Date afterTime) { int day = cl.get(Calendar.DAY_OF_MONTH); t = -1; - // get hour................................................... + // getValue hour................................................... st = hours.tailSet(hr); if (st != null && st.size() != 0) { t = hr; @@ -1080,10 +1080,10 @@ public Date getTimeAfter(Date afterTime) { t = -1; int tmon = mon; - // get day................................................... + // getValue day................................................... boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC); boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC); - if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule + if (dayOfMSpec && !dayOfWSpec) { // getValue day by day of month rule st = daysOfMonth.tailSet(day); if (lastdayOfMonth) { if (!nearestWeekday) { @@ -1196,7 +1196,7 @@ public Date getTimeAfter(Date afterTime) { // are 1-based continue; } - } else if (dayOfWSpec && !dayOfMSpec) { // get day by day of week rule + } else if (dayOfWSpec && !dayOfMSpec) { // getValue day by day of week rule if (lastdayOfWeek) { // are we looking for the last XXX day of // the month? int dow = daysOfWeek.first(); // desired @@ -1341,7 +1341,7 @@ public Date getTimeAfter(Date afterTime) { return null; } - // get month................................................... + // getValue month................................................... st = months.tailSet(mon); if (st != null && st.size() != 0) { t = mon; @@ -1368,7 +1368,7 @@ public Date getTimeAfter(Date afterTime) { year = cl.get(Calendar.YEAR); t = -1; - // get year................................................... + // getValue year................................................... st = years.tailSet(year); if (st != null && st.size() != 0) { t = year; @@ -1401,7 +1401,7 @@ public Date getTimeAfter(Date afterTime) { * to daylight saving problems. * * @param cal the calendar to operate on - * @param hour the hour to set + * @param hour the hour to setValue */ protected void setCalendarHour(Calendar cal, int hour) { cal.set(Calendar.HOUR_OF_DAY, hour); diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/BigDecimalTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/BigDecimalTypeOperator.java index c00fc02b..41972991 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/BigDecimalTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/BigDecimalTypeOperator.java @@ -10,55 +10,45 @@ * @date 2021/12/23 20:18 * @since 1.0 */ -public class BigDecimalTypeOperator implements TypeOperator { +public class BigDecimalTypeOperator implements TypeOperator { @Override - public Object convert(Object target, Class maybeType) { - return new BigDecimal(target.toString()); + public BigDecimal convert(Object target, Class maybeType) { + return Types.parseBigDecimal(target); } @Override public int signum(Object target) { - BigDecimal bigDecimal = new BigDecimal(target.toString()); - return bigDecimal.signum(); + return convert(target).signum(); } @Override public String fromString(Object target) { - BigDecimal bigDecimal = new BigDecimal(target.toString()); - return bigDecimal.toString(); + return convert(target).toString(); } @Override - public Object add(Object origin, Object passive) { - return new BigDecimal(origin.toString()) - .add(new BigDecimal(passive.toString())) - .setScale(2, RoundingMode.UP); + public BigDecimal add(BigDecimal origin, BigDecimal passive) { + return origin.add(passive).setScale(2, RoundingMode.UP); } @Override - public Object subtract(Object origin, Object passive) { - return new BigDecimal(origin.toString()) - .subtract(new BigDecimal(passive.toString())) - .setScale(2, RoundingMode.UP); + public BigDecimal subtract(BigDecimal origin, BigDecimal passive) { + return origin.subtract(passive).setScale(2, RoundingMode.UP); } @Override - public Object multiply(Object origin, Object passive) { - return new BigDecimal(origin.toString()) - .multiply(new BigDecimal(origin.toString())) - .setScale(2, RoundingMode.UP); + public BigDecimal multiply(BigDecimal origin, BigDecimal passive) { + return origin.multiply(passive).setScale(2, RoundingMode.UP); } @Override - public Object divide(Object origin, Object passive) { - return new BigDecimal(origin.toString()) - .divide(new BigDecimal(passive.toString())) - .setScale(2, RoundingMode.UP); + public BigDecimal divide(BigDecimal origin, BigDecimal passive) { + return origin.divide(passive, 2, RoundingMode.UP); } @Override - public Object defaultValue() { + public BigDecimal defaultValue() { return BigDecimal.ZERO; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/BooleanCalculateOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/BooleanCalculateOperator.java index e6e54877..6c2a09ac 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/BooleanCalculateOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/BooleanCalculateOperator.java @@ -7,19 +7,19 @@ * @date 2021/12/23 20:10 * @since 1.0 */ -public class BooleanCalculateOperator extends UnsupportedCalculateOperator { +public class BooleanCalculateOperator extends UnsupportedCalculateOperator { @Override - public Object convert(Object target, Class maybeType) { - return Boolean.parseBoolean(target.toString()); + public Boolean convert(Object target, Class maybeType) { + return Types.parseBoolean(target); } @Override public String fromString(Object target) { - return convert(target, Boolean.class).toString(); + return convert(target).toString(); } @Override - public Object defaultValue() { + public Boolean defaultValue() { return Boolean.FALSE; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/ByteTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/ByteTypeOperator.java index d587fb74..ba60f1af 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/ByteTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/ByteTypeOperator.java @@ -7,20 +7,20 @@ * @date 2021/12/23 20:16 * @since 1.0 */ -public class ByteTypeOperator extends UnsupportedCalculateOperator { +public class ByteTypeOperator extends UnsupportedCalculateOperator { @Override - public Object convert(Object target, Class maybeType) { - return Byte.parseByte(target.toString()); + public Byte convert(Object target, Class maybeType) { + return Types.parseByte(target); } @Override public String fromString(Object target) { - return convert(target, Byte.class).toString(); + return convert(target).toString(); } @Override - public Object defaultValue() { + public Byte defaultValue() { return Byte.valueOf("0"); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/CalculateOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/CalculateOperator.java index f738caac..6f570a10 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/CalculateOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/CalculateOperator.java @@ -7,7 +7,7 @@ * @date 2022/10/10 22:19 * @since 1.1.0 */ -public interface CalculateOperator { +public interface CalculateOperator { /** * 加动作 @@ -15,7 +15,7 @@ public interface CalculateOperator { * @param origin 原始数据 * @param passive 被加数 */ - Object add(Object origin, Object passive); + T add(T origin, T passive); /** * 减动作 @@ -23,7 +23,7 @@ public interface CalculateOperator { * @param origin 原始数据 * @param passive 被减数 */ - Object subtract(Object origin, Object passive); + T subtract(T origin, T passive); /** * 乘动作 @@ -31,7 +31,7 @@ public interface CalculateOperator { * @param origin 原始数据 * @param passive 被乘数 */ - Object multiply(Object origin, Object passive); + T multiply(T origin, T passive); /** * 除动作 @@ -39,5 +39,5 @@ public interface CalculateOperator { * @param origin 原始数据 * @param passive 被除数 */ - Object divide(Object origin, Object passive); + T divide(T origin, T passive); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/DateCalculateOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/DateCalculateOperator.java index 61db42fd..8158567d 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/DateCalculateOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/DateCalculateOperator.java @@ -3,7 +3,6 @@ import cc.allio.uno.core.util.DateUtil; import org.springframework.util.ObjectUtils; -import java.text.ParseException; import java.util.Date; /** @@ -13,31 +12,27 @@ * @date 2021/12/23 20:24 * @since 1.0 */ -public class DateCalculateOperator extends UnsupportedCalculateOperator { +public class DateCalculateOperator extends UnsupportedCalculateOperator { @Override - public Object convert(Object target, Class maybeType) { - try { - if (target instanceof Date) { - return target; - } - if (ObjectUtils.isEmpty(target)) { - return defaultValue(); - } else { - return DateUtil.DATETIME_FORMAT.parse(target.toString()); - } - } catch (ParseException e) { - throw new NullPointerException(e.getMessage()); + public Date convert(Object target, Class maybeType) { + if (Types.isDate(target.getClass())) { + return (Date) target; + } + if (ObjectUtils.isEmpty(target)) { + return defaultValue(); + } else { + return DateUtil.parse(target.toString()); } } @Override public String fromString(Object target) { - return DateUtil.format((Date) convert(target, Date.class), DateUtil.PATTERN_DATETIME); + return DateUtil.format(convert(target, Date.class), DateUtil.PATTERN_DATETIME); } @Override - public Object defaultValue() { + public Date defaultValue() { return new Date(); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/DefaultTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/DefaultTypeOperator.java index 8cbdf853..196ea58e 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/DefaultTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/DefaultTypeOperator.java @@ -7,7 +7,7 @@ * @date 2021/12/23 20:32 * @since 1.0 */ -public class DefaultTypeOperator extends UnsupportedCalculateOperator { +public class DefaultTypeOperator extends UnsupportedCalculateOperator { @Override public Object convert(Object target, Class maybeType) { return target; @@ -15,7 +15,7 @@ public Object convert(Object target, Class maybeType) { @Override public String fromString(Object target) { - return convert(target, Object.class).toString(); + return convert(target).toString(); } @Override diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/DoubleTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/DoubleTypeOperator.java index 51ddd465..0b0fb4fb 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/DoubleTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/DoubleTypeOperator.java @@ -7,45 +7,45 @@ * @date 2021/12/23 20:15 * @since 1.0 */ -public class DoubleTypeOperator implements TypeOperator { +public class DoubleTypeOperator implements TypeOperator { @Override - public Object convert(Object target, Class maybeType) { - return Double.parseDouble(target.toString()); + public Double convert(Object target, Class maybeType) { + return Types.parseDouble(target); } @Override public int signum(Object target) { - double aDouble = Double.parseDouble(target.toString()); + double aDouble = convert(target); return Double.compare(aDouble, Double.NaN); } @Override public String fromString(Object target) { - return convert(target, Double.class).toString(); + return convert(target).toString(); } @Override - public Object add(Object origin, Object passive) { - return Double.parseDouble(origin.toString()) + Double.parseDouble(passive.toString()); + public Double add(Double origin, Double passive) { + return origin + passive; } @Override - public Object subtract(Object origin, Object passive) { - return Double.parseDouble(origin.toString()) - Double.parseDouble(passive.toString()); + public Double subtract(Double origin, Double passive) { + return origin - passive; } @Override - public Object multiply(Object origin, Object passive) { - return Double.parseDouble(origin.toString()) * Double.parseDouble(passive.toString()); + public Double multiply(Double origin, Double passive) { + return origin * passive; } @Override - public Object divide(Object origin, Object passive) { - return Double.parseDouble(origin.toString()) / Double.parseDouble(passive.toString()); + public Double divide(Double origin, Double passive) { + return origin / passive; } @Override - public Object defaultValue() { + public Double defaultValue() { return 0d; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/EnumTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/EnumTypeOperator.java index 5a7fbf37..d83a8e33 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/EnumTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/EnumTypeOperator.java @@ -1,21 +1,107 @@ package cc.allio.uno.core.type; +import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.function.lambda.MethodReferenceColumn; + import java.util.Arrays; +import java.util.Set; /** - * Enum类型转化,以枚举类型的名称作为比较条件,获取对应的枚举类型。比如:EXAMPLE("name"),EXAMPLE就是枚举类型名称 + * Enum类型转化,包含以下几种转换方法: + *
      + *
    • 以枚举类型的名称作为比较条件,获取对应的枚举类型。比如:EXAMPLE("name"),EXAMPLE就是枚举类型名称
    • + *
    • 如果第一种不匹配,则按照枚举类里面可能为值的字段名称作比较,如:value、label...
    • + *
    • {@link #convert(Object, Class, String)}采用该方法,给定值
    • + *
    * * @author jiangwei * @date 2021/12/24 00:59 * @since 1.0 */ -public class EnumTypeOperator extends UnsupportedCalculateOperator { +public class EnumTypeOperator> extends UnsupportedCalculateOperator { + + private static final Set maybeValueTexts = Set.of("value", "label"); + + private final Class enumType; + + public EnumTypeOperator(Class enumType) { + this.enumType = enumType; + } @Override - public Object convert(Object target, Class maybeType) { + public T convert(Object target, Class maybeType) { + Object[] enumConstants = maybeType.getEnumConstants(); + if (enumConstants == null) { + return null; + } + return (T) Arrays.stream(enumConstants) + .filter(constant -> { + String name = ((Enum) constant).name(); + if (target.equals(name)) { + return true; + } + ObjectWrapper constantWrapper = new ObjectWrapper(constant); + for (String maybeValueText : maybeValueTexts) { + Object force = constantWrapper.getForce(maybeValueText); + if (target.equals(force)) { + return true; + } + } + return false; + }) + .findFirst() + .orElseGet(() -> target); + } + + /** + * 通过给定取值的字段名称,进行枚举类型的转化 + * + * @param target target + * @param valueText 给定取值的字段 + * @return enum + */ + public T convert(Object target, String valueText) { + return convert(target, getType(), valueText); + } + + /** + * 通过给定取值的字段名称,进行枚举类型的转化 + * + * @param target target + * @param valueText 给定取值的字段 + * @return enum + */ + public T convert(Object target, MethodReferenceColumn valueText) { + return convert(target, getType(), valueText.getColumn()); + } + + /** + * 通过给定取值的字段名称,进行枚举类型的转化 + * + * @param target target + * @param maybeType maybeType + * @param valueText 给定取值的字段 + * @return enum + */ + public T convert(Object target, Class maybeType, MethodReferenceColumn valueText) { + return convert(target, maybeType, valueText.getColumn()); + } + + /** + * 通过给定取值的字段名称,进行枚举类型的转化 + * + * @param target target + * @param maybeType maybeType + * @param valueText 给定取值的字段 + * @return enum + */ + public T convert(Object target, Class maybeType, String valueText) { Object[] enumConstants = maybeType.getEnumConstants(); - return Arrays.stream(enumConstants) - .filter(constant -> ((Enum) constant).name().equals(target.toString())) + return (T) Arrays.stream(enumConstants) + .filter(constant -> { + Object force = new ObjectWrapper(constant).getForce(valueText); + return target.equals(force); + }) .findFirst() .orElse(target); } @@ -27,11 +113,11 @@ public int signum(Object target) { @Override public String fromString(Object target) { - return convert(target, Enum.class).toString(); + return convert(target, getType()).toString(); } @Override public Class getType() { - return Types.ENUM; + return enumType; } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/FloatTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/FloatTypeOperator.java index 0e4c15e4..60f5c840 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/FloatTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/FloatTypeOperator.java @@ -7,45 +7,45 @@ * @date 2021/12/23 20:11 * @since 1.0 */ -public class FloatTypeOperator implements TypeOperator { +public class FloatTypeOperator implements TypeOperator { @Override - public Object convert(Object target, Class maybeType) { - return Float.parseFloat(target.toString()); + public Float convert(Object target, Class maybeType) { + return Types.parseFloat(target); } @Override public int signum(Object target) { - float aFloat = Float.parseFloat(target.toString()); + float aFloat = convert(target); return Float.compare(aFloat, Float.NaN); } @Override public String fromString(Object target) { - return convert(target, Float.class).toString(); + return convert(target).toString(); } @Override - public Object add(Object origin, Object passive) { - return Float.parseFloat(origin.toString()) + Float.parseFloat(passive.toString()); + public Float add(Float origin, Float passive) { + return origin + passive; } @Override - public Object subtract(Object origin, Object passive) { - return Float.parseFloat(origin.toString()) - Float.parseFloat(passive.toString()); + public Float subtract(Float origin, Float passive) { + return origin - passive; } @Override - public Object multiply(Object origin, Object passive) { - return Float.parseFloat(origin.toString()) * Float.parseFloat(passive.toString()); + public Float multiply(Float origin, Float passive) { + return origin * passive; } @Override - public Object divide(Object origin, Object passive) { - return Float.parseFloat(origin.toString()) / Float.parseFloat(passive.toString()); + public Float divide(Float origin, Float passive) { + return origin / passive; } @Override - public Object defaultValue() { + public Float defaultValue() { return 0f; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/IntegerTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/IntegerTypeOperator.java index fd90e97e..d81cb7cd 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/IntegerTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/IntegerTypeOperator.java @@ -7,52 +7,53 @@ * @date 2021/12/23 20:08 * @since 1.0 */ -public class IntegerTypeOperator implements TypeOperator { +public class IntegerTypeOperator implements TypeOperator { @Override - public Object convert(Object target, Class maybeType) { - Object tryToNumeric = Types.tryToNumeric(target); - if (Types.isDouble(tryToNumeric.getClass())) { - return ((Double) tryToNumeric).intValue(); - } else if (Types.isInteger(tryToNumeric.getClass())) { - return tryToNumeric; + public Integer convert(Object target, Class maybeType) { + if (target instanceof Integer i) { + return i; + } else if (target instanceof Double d) { + return d.intValue(); + } else if (target instanceof Float f) { + return f.intValue(); } throw new IllegalArgumentException(String.format("target %s can't cast type %s", target, maybeType)); } @Override public int signum(Object target) { - int anInt = Integer.parseInt(target.toString()); + int anInt = convert(target); return Integer.signum(anInt); } @Override public String fromString(Object target) { - return convert(target, Integer.class).toString(); + return convert(target).toString(); } @Override - public Object add(Object origin, Object passive) { - return Integer.parseInt(origin.toString()) + Integer.parseInt(passive.toString()); + public Integer add(Integer origin, Integer passive) { + return origin + passive; } @Override - public Object subtract(Object origin, Object passive) { - return Integer.parseInt(origin.toString()) - Integer.parseInt(passive.toString()); + public Integer subtract(Integer origin, Integer passive) { + return origin - passive; } @Override - public Object multiply(Object origin, Object passive) { - return Integer.parseInt(origin.toString()) * Integer.parseInt(passive.toString()); + public Integer multiply(Integer origin, Integer passive) { + return origin * passive; } @Override - public Object divide(Object origin, Object passive) { - return Integer.parseInt(origin.toString()) / Integer.parseInt(passive.toString()); + public Integer divide(Integer origin, Integer passive) { + return origin / passive; } @Override - public Object defaultValue() { + public Integer defaultValue() { return 0; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/LongTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/LongTypeOperator.java index 0fc5c9b6..393cf7b0 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/LongTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/LongTypeOperator.java @@ -7,46 +7,46 @@ * @date 2021/12/24 15:42 * @since 1.0 */ -public class LongTypeOperator implements TypeOperator { +public class LongTypeOperator implements TypeOperator { @Override - public Object convert(Object target, Class maybeType) { - return Long.parseLong(target.toString()); + public Long convert(Object target, Class maybeType) { + return Types.parseLong(target); } @Override public int signum(Object target) { - long aLong = Long.parseLong(target.toString()); + long aLong = convert(target); return Long.signum(aLong); } @Override public String fromString(Object target) { - return convert(target, Long.class).toString(); + return convert(target).toString(); } @Override - public Object add(Object origin, Object passive) { - return Long.parseLong(origin.toString()) + Long.parseLong(passive.toString()); + public Long add(Long origin, Long passive) { + return origin + passive; } @Override - public Object subtract(Object origin, Object passive) { - return Long.parseLong(origin.toString()) - Long.parseLong(passive.toString()); + public Long subtract(Long origin, Long passive) { + return origin - passive; } @Override - public Object multiply(Object origin, Object passive) { - return Long.parseLong(passive.toString()) * Long.parseLong(passive.toString()); + public Long multiply(Long origin, Long passive) { + return origin * passive; } @Override - public Object divide(Object origin, Object passive) { - return Long.parseLong(origin.toString()) / Long.parseLong(passive.toString()); + public Long divide(Long origin, Long passive) { + return origin / passive; } @Override - public Object defaultValue() { + public Long defaultValue() { return 0L; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/ShortTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/ShortTypeOperator.java index d1843728..6124a6b9 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/ShortTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/ShortTypeOperator.java @@ -9,45 +9,45 @@ * @date 2021/12/23 20:11 * @since 1.0 */ -public class ShortTypeOperator implements TypeOperator { +public class ShortTypeOperator implements TypeOperator { @Override - public Object convert(Object target, Class maybeType) { - return Short.parseShort(target.toString()); + public Short convert(Object target, Class maybeType) { + return Types.parseShort(target); } @Override public int signum(Object target) { - short aShort = Short.parseShort(target.toString()); - return Short.compare(aShort, Short.parseShort(StringPool.ZERO)); + short aShort = convert(target); + return Short.compare(aShort, defaultValue()); } @Override public String fromString(Object target) { - return convert(target, Short.class).toString(); + return convert(target).toString(); } @Override - public Object add(Object origin, Object passive) { - return Short.parseShort(origin.toString()); + public Short add(Short origin, Short passive) { + return (short) (origin + passive); } @Override - public Object subtract(Object origin, Object passive) { - return null; + public Short subtract(Short origin, Short passive) { + return (short) (origin - passive); } @Override - public Object multiply(Object origin, Object passive) { - return null; + public Short multiply(Short origin, Short passive) { + return (short) (origin * passive); } @Override - public Object divide(Object origin, Object passive) { - return null; + public Short divide(Short origin, Short passive) { + return (short) (origin / passive); } @Override - public Object defaultValue() { + public Short defaultValue() { return 0; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/StringTypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/StringTypeOperator.java index 89e3a7e1..f8d34ed2 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/StringTypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/StringTypeOperator.java @@ -7,15 +7,15 @@ * @date 2021/12/23 20:14 * @since 1.0 */ -public class StringTypeOperator extends UnsupportedCalculateOperator { +public class StringTypeOperator extends UnsupportedCalculateOperator { @Override - public Object convert(Object target, Class maybeType) { - return String.valueOf(target); + public String convert(Object target, Class maybeType) { + return target.toString(); } @Override public String fromString(Object target) { - return convert(target, String.class).toString(); + return convert(target); } @Override diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/TypeOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/TypeOperator.java index 7812998c..7b6be943 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/TypeOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/TypeOperator.java @@ -3,19 +3,20 @@ /** * 类型操作 * + * @param 具体操作的类型实体 * @author jiangwei * @date 2021/12/23 20:06 * @since 1.0 */ -public interface TypeOperator extends CalculateOperator { +public interface TypeOperator extends CalculateOperator { /** * 转换动作 * - * @param target 目标对象 + * @param target 目标对象 * @return 转换后的对象,可能也为原对象 */ - default Object convert(Object target) { + default T convert(Object target) { return convert(target, getType()); } @@ -26,7 +27,7 @@ default Object convert(Object target) { * @param maybeType 目标对象可能的类型 * @return 转换后的对象,可能也为原对象 */ - Object convert(Object target, Class maybeType); + T convert(Object target, Class maybeType); /** * 判断数字为正数、0或负数 @@ -48,7 +49,7 @@ default Object convert(Object target) { * * @return 默认返回为null, 由实现类实现 */ - default Object defaultValue() { + default T defaultValue() { return null; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/TypeOperatorFactory.java b/uno-core/src/main/java/cc/allio/uno/core/type/TypeOperatorFactory.java index cc5802b9..da7ea9e5 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/TypeOperatorFactory.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/TypeOperatorFactory.java @@ -6,31 +6,45 @@ import java.util.Date; import java.util.Map; import java.util.Optional; +import java.util.function.Function; /** * @author jiangwei * @date 2021/12/23 20:35 - * @since 1.0 + * @modifyDate 2024/01/13 18:32 + * @since 1.1.6 */ public class TypeOperatorFactory { private TypeOperatorFactory() { } - private static final Map, TypeOperator> TRANSLATOR_MAP = Maps.newConcurrentMap(); - private static final TypeOperator DEFAULT_TYPE_OPERATOR = new DefaultTypeOperator(); + private static final Map, Function, TypeOperator>> TRANSLATOR_FUNC_MAP = Maps.newConcurrentMap(); + private static final TypeOperator DEFAULT_TYPE_OPERATOR = new DefaultTypeOperator(); + + private static final TypeOperator BIG_DECIMAL_TYPE_OPERATOR = new BigDecimalTypeOperator(); + private static final TypeOperator INTEGER_TYPE_OPERATOR = new IntegerTypeOperator(); + private static final TypeOperator BOOLEAN_TYPE_OPERATOR = new BooleanCalculateOperator(); + private static final TypeOperator BYTE_TYPE_OPERATOR = new ByteTypeOperator(); + private static final TypeOperator DOUBLE_TYPE_OPERATOR = new DoubleTypeOperator(); + private static final TypeOperator SHORT_TYPE_OPERATOR = new ShortTypeOperator(); + private static final TypeOperator STRING_TYPE_OPERATOR = new StringTypeOperator(); + private static final TypeOperator DATE_TYPE_OPERATOR = new DateCalculateOperator(); + private static final TypeOperator LONG_TYPE_OPERATOR = new LongTypeOperator(); + private static final TypeOperator FLOAT_TYPE_OPERATOR = new FloatTypeOperator(); + static { - addTypeOperator(BigDecimal.class, new BigDecimalTypeOperator()); - addTypeOperator(Integer.class, new IntegerTypeOperator()); - addTypeOperator(Boolean.class, new BooleanCalculateOperator()); - addTypeOperator(Byte.class, new ByteTypeOperator()); - addTypeOperator(Double.class, new DoubleTypeOperator()); - addTypeOperator(Short.class, new ShortTypeOperator()); - addTypeOperator(String.class, new StringTypeOperator()); - addTypeOperator(Date.class, new DateCalculateOperator()); - addTypeOperator(Enum.class, new EnumTypeOperator()); - addTypeOperator(Long.class, new LongTypeOperator()); + addTypeOperator(Types.BIG_DECIMAL, type -> BIG_DECIMAL_TYPE_OPERATOR); + addTypeOperator(Types.INTEGER, type -> INTEGER_TYPE_OPERATOR); + addTypeOperator(Types.BOOLEAN, type -> BOOLEAN_TYPE_OPERATOR); + addTypeOperator(Types.BYTE, type -> BYTE_TYPE_OPERATOR); + addTypeOperator(Types.DOUBLE, type -> DOUBLE_TYPE_OPERATOR); + addTypeOperator(Types.SHORT, type -> SHORT_TYPE_OPERATOR); + addTypeOperator(Types.STRING, type -> STRING_TYPE_OPERATOR); + addTypeOperator(Types.DATE, type -> DATE_TYPE_OPERATOR); + addTypeOperator(Types.LONG, type -> LONG_TYPE_OPERATOR); + addTypeOperator(Types.FLOAT, type -> FLOAT_TYPE_OPERATOR); } /** @@ -39,22 +53,27 @@ private TypeOperatorFactory() { * @param type 某个指定类型 * @return 转换器实例 */ - public static synchronized TypeOperator translator(Class type) { - return Optional - .ofNullable(TRANSLATOR_MAP.get(type)) - .orElseGet(() -> - Optional.ofNullable(type.getSuperclass()) - .map(TRANSLATOR_MAP::get) - .orElse(DEFAULT_TYPE_OPERATOR)); + public static synchronized TypeOperator translator(Class type) { + if (type.isEnum()) { + return (TypeOperator) new EnumTypeOperator(type); + } + Function, TypeOperator> func = TRANSLATOR_FUNC_MAP.get(type); + if (func == null) { + return (TypeOperator) DEFAULT_TYPE_OPERATOR; + } else { + TypeOperator typeOperator = func.apply(type); + return Optional.ofNullable((TypeOperator) typeOperator) + .orElseGet(() -> (TypeOperator) DEFAULT_TYPE_OPERATOR); + } } /** * 添加{@link TypeOperator} * - * @param type 类型 - * @param typeOperator 类型操作 + * @param type 类型 + * @param func func */ - public static synchronized void addTypeOperator(Class type, TypeOperator typeOperator) { - TRANSLATOR_MAP.put(type, typeOperator); + public static synchronized void addTypeOperator(Class type, Function, TypeOperator> func) { + TRANSLATOR_FUNC_MAP.put(type, func); } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/TypeValue.java b/uno-core/src/main/java/cc/allio/uno/core/type/TypeValue.java index 54fc64ca..6294797a 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/TypeValue.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/TypeValue.java @@ -39,13 +39,13 @@ public class TypeValue { /** * 转换器 */ - private final TypeOperator maybeTypeOperator; + private final TypeOperator maybeTypeOperator; public TypeValue(Class maybeType, Object value) { this(maybeType, value, TypeOperatorFactory.translator(maybeType)); } - public TypeValue(Class maybeType, Object value, TypeOperator typeOperator) { + public TypeValue(Class maybeType, Object value, TypeOperator typeOperator) { this.maybeType = maybeType; this.value = value; this.maybeTypeOperator = typeOperator; @@ -84,8 +84,8 @@ public Object tryTransfer() { try { maybeType.cast(maybeActual); } catch (ClassCastException e) { - if (log.isDebugEnabled()) { - log.debug("Try cast current value {} for type {} failed", value, maybeType.getName()); + if (log.isTraceEnabled()) { + log.trace("Try cast current value {} for type {} failed", value, maybeType.getName()); } if (Types.isArray(maybeType)) { return arrayTransfer(); @@ -97,7 +97,9 @@ public Object tryTransfer() { try { maybeActual = maybeTypeOperator.convert(maybeActual, maybeType); } catch (NullPointerException | NumberFormatException e2) { - log.debug("user translator {} get actual value {} type failed", maybeTypeOperator.getClass().getName(), value); + if (log.isTraceEnabled()) { + log.trace("user translator {} getValue actual value {} type failed", maybeTypeOperator.getClass().getName(), value); + } return value; } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/Types.java b/uno-core/src/main/java/cc/allio/uno/core/type/Types.java index b342887c..115bd6fb 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/Types.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/Types.java @@ -2,9 +2,11 @@ import cc.allio.uno.core.StringPool; import com.google.common.collect.Sets; +import jakarta.annotation.Nonnull; import java.math.BigDecimal; import java.util.*; +import java.util.function.Consumer; /** * 类型公共方法集 @@ -26,7 +28,6 @@ protected Types() { public static final Short SHORT_EMPTY = 0; public static final String STRING_EMPTY = StringPool.EMPTY; - public static final Class LONG = Long.class; public static final Class BOOLEAN = Boolean.class; public static final Class CHARACTER = Character.class; @@ -50,7 +51,7 @@ protected Types() { private static final Set> COLLECTION_TYPES = Sets.newHashSet( LIST, SET, MAP, STACK, QUEUE); - // ==================== is operator ==================== + // ==================== is operate ==================== /** * 判断放给定的class是否是{@link Long} @@ -162,6 +163,17 @@ public static boolean isString(Class clazz) { return STRING.isAssignableFrom(clazz); } + /** + * 判断放给定的class是否是{@link BigDecimal} + * + * @param clazz class对象实例 + * @return true BigDecimal false not BigDecimal + */ + public static boolean isBigDecimal(Class clazz) { + return BIG_DECIMAL.isAssignableFrom(clazz); + } + + /** * 判断给定的class是否是{@link java.util.Map} * @@ -212,6 +224,16 @@ public static boolean isQueue(Class clazz) { return QUEUE.isAssignableFrom(clazz); } + /** + * 判断给定的class是否是{@link java.util.Collection} + * + * @param clazz class对象实例 + * @return true Queue false not Queue + */ + public static boolean isCollection(Class clazz) { + return Collection.class.isAssignableFrom(clazz); + } + /** * 判断给定的class是否是{@link java.util.Queue} * @@ -255,7 +277,7 @@ public static int signum(Object value) { return typeOperator.signum(value); } - // ==================== to operator ==================== + // ==================== to operate ==================== /** * 返回给定对象字符串数据 @@ -288,8 +310,26 @@ public static Boolean toBoolean(Integer i) { } } + // ==================== parse operate ==================== + /** - * 整形数据转换为bool + * 解析为long + * + * @param o o + * @return null or long + */ + public static Long parseLong(Object o) { + if (o == null) { + return null; + } + if (Types.isLong(o.getClass())) { + return (Long) o; + } + return Long.parseLong(toString(o)); + } + + /** + * 解析为bool * * @param o o * @return i为null 则返回 false > 1 -> true 、0 = false or false @@ -318,6 +358,150 @@ public static Boolean parseBoolean(Object o) { return Boolean.FALSE; } + /** + * 解析为char + * + * @param o o + * @return null or char + */ + public static Character parseChar(Object o) { + if (o == null) { + return null; + } + if (Types.isChar(o.getClass())) { + return (Character) o; + } + return toString(o).toCharArray()[0]; + } + + /** + * 解析为byte + * + * @param o o + * @return null or byte + */ + public static Byte parseByte(Object o) { + if (o == null) { + return null; + } + if (Types.isByte(o.getClass())) { + return (Byte) o; + } + return Byte.parseByte(toString(o)); + } + + /** + * 解析为short + * + * @param o o + * @return null or short + */ + public static Short parseShort(Object o) { + if (o == null) { + return null; + } + if (Types.isShort(o.getClass())) { + return (Short) o; + } + return Short.parseShort(toString(o)); + } + + /** + * 解析为Float + * + * @param o o + * @return null or float + */ + public static Float parseFloat(Object o) { + if (o == null) { + return null; + } + if (Types.isFloat(o.getClass())) { + return (Float) o; + } + return Float.parseFloat(toString(o)); + } + + /** + * 解析为String + * + * @param o o + * @return null or string + */ + public static String parseString(Object o) { + if (o == null) { + return null; + } + if (Types.isString(o.getClass())) { + return (String) o; + } + return toString(o); + } + + /** + * 解析为Integer + * + * @param o o + * @return null or integer + */ + public static Integer parseInteger(Object o) { + if (o == null) { + return null; + } + if (Types.isInteger(o.getClass())) { + return (Integer) o; + } + return Integer.parseInt(toString(o)); + } + + /** + * 解析为Double + * + * @param o o + * @return null or double + */ + public static Double parseDouble(Object o) { + if (o == null) { + return null; + } + if (Types.isDouble(o.getClass())) { + return (Double) o; + } + return Double.parseDouble(toString(o)); + } + + /** + * 解析为Double + * + * @param o o + * @return null or double + */ + public static BigDecimal parseBigDecimal(Object o) { + if (o == null) { + return null; + } + if (Types.isBigDecimal(o.getClass())) { + return (BigDecimal) o; + } + return new BigDecimal(toString(o)); + } + + /** + * 解析为Date + * + * @param o o + * @return null or double + */ + public static Date parseDate(Object o) { + if (o == null) { + return null; + } + if (Types.isDate(o.getClass())) { + return (Date) o; + } + return TypeOperatorFactory.translator(DATE).convert(o); + } + /** * 判断给定的值是否为类型空值 * @@ -340,7 +524,7 @@ public static boolean isEmpty(Object value) { return true; } else if (value instanceof Short && Types.SHORT_EMPTY.equals(value)) { return true; - } else if (value instanceof String && Types.STRING_EMPTY.equals(value)) { + } else if (Types.STRING_EMPTY.equals(value)) { return true; } else if (value.getClass().isArray()) { return ((Object[]) value).length > 0; @@ -358,7 +542,7 @@ public static boolean isNotEmpty(Object value) { return !isEmpty(value); } - // ==================== get operator ==================== + // ==================== getValue operate ==================== /** * 获取Integer类型的数据 @@ -428,7 +612,7 @@ public static Boolean getBoolean(Object value) { if (isBoolean(value.getClass())) { return (Boolean) value; } - return null; + return Boolean.TRUE.equals(value); } /** @@ -493,7 +677,7 @@ public static Object tryToNumeric(Object o) { Object tryToValue = null; // 尝试转换为数字类型 try { - tryToValue = new Integer(toString(o)); + tryToValue = Integer.parseInt(toString(o)); } catch (NumberFormatException err) { // ignore } @@ -501,7 +685,7 @@ public static Object tryToNumeric(Object o) { return tryToValue; } try { - tryToValue = new Double(toString(o)); + tryToValue = Double.parseDouble(toString(o)); } catch (NumberFormatException err) { // ignore } @@ -510,4 +694,18 @@ public static Object tryToNumeric(Object o) { } return o; } + + /** + * 类型转换并通过调用acceptor消费转换后的数据 + * + * @param obj obj + * @param clazz clazz + * @param acceptor acceptor + * @param 转换的类型 + */ + public static void cast(@Nonnull Object obj, @Nonnull Class clazz, @Nonnull Consumer acceptor) { + if (clazz.isAssignableFrom(obj.getClass())) { + acceptor.accept(clazz.cast(obj)); + } + } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/type/UnsupportedCalculateOperator.java b/uno-core/src/main/java/cc/allio/uno/core/type/UnsupportedCalculateOperator.java index ee79e512..d201ebf1 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/type/UnsupportedCalculateOperator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/type/UnsupportedCalculateOperator.java @@ -7,25 +7,25 @@ * @date 2022/10/10 22:21 * @since 1.1.0 */ -public abstract class UnsupportedCalculateOperator implements TypeOperator { +public abstract class UnsupportedCalculateOperator implements TypeOperator { @Override - public Object add(Object origin, Object passive) { + public T add(T origin, T passive) { throw new UnsupportedOperationException("Unsupported Operation 'add'"); } @Override - public Object subtract(Object origin, Object passive) { + public T subtract(T origin, T passive) { throw new UnsupportedOperationException("Unsupported Operation 'subtract'"); } @Override - public Object multiply(Object origin, Object passive) { + public T multiply(T origin, T passive) { throw new UnsupportedOperationException("Unsupported Operation 'multiply'"); } @Override - public Object divide(Object origin, Object passive) { + public T divide(T origin, T passive) { throw new UnsupportedOperationException("Unsupported Operation 'divide'"); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/CoreBeanUtil.java b/uno-core/src/main/java/cc/allio/uno/core/util/BeanUtils.java similarity index 92% rename from uno-core/src/main/java/cc/allio/uno/core/util/CoreBeanUtil.java rename to uno-core/src/main/java/cc/allio/uno/core/util/BeanUtils.java index 8cb47d71..4925c7da 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/CoreBeanUtil.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/BeanUtils.java @@ -1,13 +1,14 @@ package cc.allio.uno.core.util; +import cc.allio.uno.core.exception.Exceptions; import cc.allio.uno.core.util.convert.UnoConverter; import cc.allio.uno.core.bean.BeanCopier; import cc.allio.uno.core.bean.BeanMap; import cc.allio.uno.core.bean.BeanProperty; import cc.allio.uno.core.type.Types; import com.google.common.collect.Maps; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyAccessorFactory; @@ -29,13 +30,16 @@ * @since 1.0 */ @Slf4j -public class CoreBeanUtil extends BeanUtils implements ApplicationContextAware { +public final class BeanUtils extends org.springframework.beans.BeanUtils implements ApplicationContextAware { private static ApplicationContext context; + public BeanUtils() { + } + @Override public void setApplicationContext(ApplicationContext context) throws BeansException { - CoreBeanUtil.context = context; + BeanUtils.context = context; } public static T getBean(Class clazz) { @@ -59,7 +63,7 @@ public static T getBean(String beanName, Class clazz) { if (clazz == null) { return null; } - return (T) context.getBean(beanName, clazz); + return context.getBean(beanName, clazz); } public static T getBeanOrDefault(Class clazz, T defaultValue) { @@ -69,7 +73,7 @@ public static T getBeanOrDefault(Class clazz, T defaultValue) { try { return context.getBean(clazz); } catch (NullPointerException | NoSuchBeanDefinitionException e) { - log.error("get bean failed, return default value"); + log.error("getValue bean failed, return default value"); return defaultValue; } } @@ -156,8 +160,8 @@ public static String getProperties(String name, String defaultValue) { * @param expectType 期望类型的Class对象 * @param 期望的类型 * @return 获取的期望类型的配置 - * @see org.springframework.core.env.Environment#getProperty(String, Class) * @throws NullPointerException {@link ApplicationContext}对象为null抛出 + * @see org.springframework.core.env.Environment#getProperty(String, Class) */ public static T getProperties(String name, Class expectType) { return getProperties(name, expectType, null); @@ -223,7 +227,7 @@ public static T clone(@Nullable T source) { if (source == null) { return null; } - return (T) CoreBeanUtil.copy(source, source.getClass()); + return (T) BeanUtils.copy(source, source.getClass()); } /** @@ -242,16 +246,17 @@ public static T clone(@Nullable T source) { * @param clazz 类名 * @param 泛型标记 * @return T + * @throws NullPointerException 当source为null时抛出 */ @Nullable public static T copy(@Nullable Object source, Class clazz) { if (source == null) { - return null; + throw Exceptions.unNull("source is empty"); } if (Types.isMap(clazz)) { - return (T) Maps.newHashMap((Map)source); + return (T) Maps.newHashMap((Map) source); } - return CoreBeanUtil.copy(source, source.getClass(), clazz); + return BeanUtils.copy(source, source.getClass(), clazz); } /** @@ -266,11 +271,12 @@ public static T copy(@Nullable Object source, Class clazz) { * @param targetClazz 转换成的类型 * @param 泛型标记 * @return T + * @throws NullPointerException 当source为null时抛出 */ @Nullable - public static T copy(@Nullable Object source, Class sourceClazz, Class targetClazz) { + public static @NonNull T copy(@Nullable Object source, Class sourceClazz, Class targetClazz) { if (source == null) { - return null; + throw Exceptions.unNull("source is empty"); } BeanCopier copier = BeanCopier.create(sourceClazz, targetClazz, false); T to = newInstance(targetClazz); @@ -303,7 +309,7 @@ public static List copy(@Nullable Collection sourceList, Class targ if (sourceClazz == null) { sourceClazz = source.getClass(); } - T bean = CoreBeanUtil.copy(source, sourceClazz, targetClazz); + T bean = BeanUtils.copy(source, sourceClazz, targetClazz); outList.add(bean); } return outList; @@ -366,7 +372,7 @@ public static T copyWithConvert(@Nullable Object source, Class targetClaz if (source == null) { return null; } - return CoreBeanUtil.copyWithConvert(source, source.getClass(), targetClazz); + return BeanUtils.copyWithConvert(source, source.getClass(), targetClazz); } /** @@ -418,7 +424,7 @@ public static List copyWithConvert(@Nullable Collection sourceList, Cl if (sourceClazz == null) { sourceClazz = source.getClass(); } - T bean = CoreBeanUtil.copyWithConvert(source, sourceClazz, targetClazz); + T bean = BeanUtils.copyWithConvert(source, sourceClazz, targetClazz); outList.add(bean); } return outList; @@ -443,7 +449,7 @@ public static T copyProperties(@Nullable Object source, Class targetClazz return null; } T to = newInstance(targetClazz); - CoreBeanUtil.copyProperties(source, to); + BeanUtils.copyProperties(source, to); return to; } @@ -469,7 +475,7 @@ public static List copyProperties(@Nullable Collection sourceList, Cla if (source == null) { continue; } - T bean = CoreBeanUtil.copyProperties(source, targetClazz); + T bean = BeanUtils.copyProperties(source, targetClazz); outList.add(bean); } return outList; @@ -503,7 +509,7 @@ public static T toBean(Map beanMap, Class valueType) { if (beanMap.isEmpty()) { return to; } - CoreBeanUtil.copy(beanMap, to); + BeanUtils.copy(beanMap, to); return to; } @@ -521,7 +527,7 @@ public static Object generator(@Nullable Object superBean, BeanProperty... props } Class superclass = superBean.getClass(); Object genBean = generator(superclass, props); - CoreBeanUtil.copy(superBean, genBean); + BeanUtils.copy(superBean, genBean); return genBean; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/BigDecimalUtil.java b/uno-core/src/main/java/cc/allio/uno/core/util/BigDecimalUtils.java similarity index 97% rename from uno-core/src/main/java/cc/allio/uno/core/util/BigDecimalUtil.java rename to uno-core/src/main/java/cc/allio/uno/core/util/BigDecimalUtils.java index d455c8f5..b4ec5455 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/BigDecimalUtil.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/BigDecimalUtils.java @@ -12,7 +12,7 @@ * @since 1.0 */ @Slf4j -public class BigDecimalUtil { +public class BigDecimalUtils { /** * 创建BigDecimal对象 diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/CalendarUtil.java b/uno-core/src/main/java/cc/allio/uno/core/util/CalendarUtils.java similarity index 99% rename from uno-core/src/main/java/cc/allio/uno/core/util/CalendarUtil.java rename to uno-core/src/main/java/cc/allio/uno/core/util/CalendarUtils.java index a0d83936..26fa765c 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/CalendarUtil.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/CalendarUtils.java @@ -11,7 +11,7 @@ * @date 2022/7/6 14:18 * @since 1.0 */ -public class CalendarUtil { +public class CalendarUtils { public static final String PATTERN_DATESTART = "yyyy-MM-dd 00:00:00"; public static final String PATTERN_DATEEND = "yyyy-MM-dd 23:59:59"; diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/ClassUtils.java b/uno-core/src/main/java/cc/allio/uno/core/util/ClassUtils.java index 1b81ea4a..df89bb88 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/ClassUtils.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/ClassUtils.java @@ -17,7 +17,7 @@ import java.util.stream.Stream; /** - * Class的一些操作 + * 与{@link Class}有关的工具集 * * @author jw * @date 2021/12/5 11:00 @@ -100,13 +100,14 @@ public static Class getArrayClassType(Class arrayClass) { */ public static Class getSingleActualGenericType(Class clazz) throws ClassNotFoundException { String expectClassname = getSingleGenericClassName(clazz); - Object exceptType = AccessController.doPrivileged((PrivilegedAction) () -> { - try { - return Class.forName(expectClassname, false, Thread.currentThread().getContextClassLoader()); - } catch (ClassNotFoundException e) { - return e; - } - }); + Object exceptType = AccessController.doPrivileged( + (PrivilegedAction) () -> { + try { + return Class.forName(expectClassname, false, Thread.currentThread().getContextClassLoader()); + } catch (ClassNotFoundException e) { + return e; + } + }); if (exceptType instanceof ClassNotFoundException notfound) { throw new ClassNotFoundException(notfound.getMessage()); } @@ -152,7 +153,6 @@ public static Type[] getFieldGenericType(Field field) { return new Type[]{}; } - /** * {@code Object}类型的参数转为Class对象 * @@ -371,25 +371,20 @@ public static List newInstanceList(Collection> classes } /** - * 根据class对象创建新实例 - * - * @param clazz clazz,非空 - * @param constructorParameters 创建实例传递的构造参数 - * @param 参数类型 - * @return 实例结果 or null + * @see #newInstanceIfErrorDefault(Class, Object[], Supplier) */ public static T newInstance(@NonNull Class clazz, Object... constructorParameters) { return newInstanceIfErrorDefault(clazz, constructorParameters, () -> null); } /** - * 根据class对象创建新实例,当实例化时产生错误,则根据给定参数的值返回结果 + * 根据class对象创建新实例,当实例化时产生错误,则根据给定参数的值返回结果。该方法创建实例不会抛出任何异常 * * @param clazz class,非空 * @param constructorParameters 创建实例传递的构造参数 * @param errorDefault 错误时给的默认值 * @param 参数类型 - * @return 实例 + * @return instance or null */ public static T newInstanceIfErrorDefault(@NonNull Class clazz, Object[] constructorParameters, Supplier errorDefault) { InstantiationBuilder instantiationBuilder = instantiationBuilder(); @@ -694,9 +689,7 @@ public static class DeDuplicationFeature implements Feature { @Override public void execute(Instantiation instantiation) { Class[] waitForInstanceClasses = instantiation.getWaitForInstanceClasses(); - instantiation.rewriteInstanceClasses( - Stream.of(waitForInstanceClasses).distinct().toArray(Class[]::new) - ); + instantiation.rewriteInstanceClasses(Stream.of(waitForInstanceClasses).distinct().toArray(Class[]::new)); } } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/CollectionUtils.java b/uno-core/src/main/java/cc/allio/uno/core/util/CollectionUtils.java index 091a6cce..6f7b5686 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/CollectionUtils.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/CollectionUtils.java @@ -1,5 +1,7 @@ package cc.allio.uno.core.util; +import com.google.common.collect.Sets; + import java.util.*; /** @@ -109,23 +111,6 @@ public static boolean isNotEmpty(Map map) { return !isEmpty(map); } - /** - * 根据对象的equals过滤数据 - */ - @SafeVarargs - public static Collection filter(Collection collection, V... filters) throws IllegalAccessException, InstantiationException { - Collection copyCollection = collection.getClass().newInstance(); - copyCollection.addAll(collection); - Collection filterCollection = collection.getClass().newInstance(); - for (V filter : filters) { - if (collection.contains(filter)) { - filterCollection.add(filter); - } - } - copyCollection.removeAll(filterCollection); - return copyCollection; - } - /** * Map集合转换Properties实例 * @@ -142,20 +127,55 @@ public static Properties mapToProperties(Map map) { /** * 两个集合求并集 + * + * @param c1 c1 + * @param c2 c2 + * @param 集合元素类型 + * @return 求并集后的集合 */ - public static boolean union(Collection source, Collection target) { - if (isEmpty(target) || isEmpty(source)) { - return false; + public static Collection union(Collection c1, Collection c2) { + if (isEmpty(c2) || isEmpty(c1)) { + return Collections.emptyList(); } - boolean changed = false; - for (V o : target) { - boolean contains = source.contains(o); - if (!contains) { - source.add(o); - changed = true; + Set union = Sets.newHashSet(); + union.addAll(c1); + union.addAll(c2); + return union; + } + + /** + * 两个集合求交集 + * + * @param c1 c1 + * @param c2 c2 + * @param 集合元素类型 + * @return 求交集后的元素集合 + */ + public static Collection intersection(Collection c1, Collection c2) { + Set intersection = Sets.newHashSet(); + for (V v : c1) { + if (c2.contains(v)) { + intersection.add(v); } } - return changed; + return intersection; } + /** + * 以c1作为源求与c2的差集 + * + * @param c1 c1 + * @param c2 c2 + * @param 集合中的元素 + * @return 求差集后的集合 + */ + public static Collection complement(Collection c1, Collection c2) { + Set complement = Sets.newHashSet(); + for (V v : c1) { + if (!c2.contains(v)) { + complement.add(v); + } + } + return complement; + } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/ConvertUtil.java b/uno-core/src/main/java/cc/allio/uno/core/util/ConvertUtils.java similarity index 99% rename from uno-core/src/main/java/cc/allio/uno/core/util/ConvertUtil.java rename to uno-core/src/main/java/cc/allio/uno/core/util/ConvertUtils.java index d2ddcb20..7e2285dd 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/ConvertUtil.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/ConvertUtils.java @@ -11,7 +11,7 @@ * @author L.cm */ @SuppressWarnings("unchecked") -public class ConvertUtil { +public class ConvertUtils { /** * Convenience operation for converting a source object to the specified targetType. diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/DateUtil.java b/uno-core/src/main/java/cc/allio/uno/core/util/DateUtil.java index c021ba6a..20a768be 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/DateUtil.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/DateUtil.java @@ -14,12 +14,13 @@ import java.time.temporal.TemporalQuery; import java.util.*; import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** * 日期工具类 * - * @author L.cm + * @author j.x */ public class DateUtil { @@ -32,6 +33,13 @@ public class DateUtil { public static final String PATTERN_TIME = "HH:mm:ss"; + // ISO + public static final String ISO_PATTERN_DATE = "yyyy-MM-dd"; + public static final String ISO_PATTERN_TIME = "HH:mm:ss.SSSXXX"; + public static final String ISO_PATTERN_DATE_TIME = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; + // 匹配ISO的时间 如 + public static Pattern ISO_PATTERN = Pattern.compile(".*T.*|.*T.*\\..*|.*\\.."); + /** * 老 date 格式化 */ @@ -399,30 +407,81 @@ public static String format(TemporalAccessor temporal, String pattern) { /** * 尝试按照不同时间格式解析给定的字符串数据 + *
      + *
    • ISO时间格式解析
    • + *
    • 标准的时间格式解析
    • + *
    * * @param dateStr 时间字符串 * @return Date or null + * @see #tryIsoParse(String) + * @see #tryUniParse(String) */ public static Date parse(String dateStr) { + Date parseDate; + if (ISO_PATTERN.matcher(dateStr).matches()) { + parseDate = tryIsoParse(dateStr); + } else { + parseDate = tryUniParse(dateStr); + } + return parseDate; + } + + /** + * 尽最有可能的匹配对iso时间解析,顺序为: + *
      + *
    1. {@link #ISO_PATTERN_DATE_TIME}
    2. + *
    3. {@link #ISO_PATTERN_DATE}
    4. + *
    + * + * @param dateStr 时间子串 + * @return Date or null + */ + public static Date tryIsoParse(String dateStr) { Date parseDate = null; try { - parseDate = DateUtil.parse(dateStr, DateUtil.PATTERN_DATETIME); - } catch (Throwable ex) { + parseDate = DateUtil.parse(dateStr, ISO_PATTERN_DATE_TIME); + } catch (Throwable e1) { + // ignore + try { + parseDate = DateUtil.parse(dateStr, ISO_PATTERN_DATE); + } catch (Throwable e2) { + // ignore + } } - if (parseDate == null) { + return parseDate; + } + + /** + * 尽最可能匹配对通用时间格式进行解析。顺序为 + *
      + *
    1. {@link #PATTERN_DATETIME}
    2. + *
    3. {@link #PATTERN_HOUR}
    4. + *
    5. {@link #PATTERN_DATE}
    6. + *
    + * + * @param dateStr 时间子串 + * @return Date or null + */ + public static Date tryUniParse(String dateStr) { + Date parseDate = null; + try { + parseDate = DateUtil.parse(dateStr, DateUtil.PATTERN_DATETIME); + } catch (Throwable e1) { + // ignore try { parseDate = DateUtil.parse(dateStr, DateUtil.PATTERN_HOUR); - } catch (Throwable ex) { + } catch (Throwable e2) { + // ignore } } - if (parseDate == null) { try { parseDate = DateUtil.parse(dateStr, DateUtil.PATTERN_DATE); } catch (Throwable ex) { + // ignore } } - return parseDate; } @@ -664,7 +723,7 @@ public static String time() { * @return 时间 */ public static Integer hour() { - return NumberUtil.toInt(format(new Date(), "HH")); + return NumberUtils.toInt(format(new Date(), "HH")); } /** @@ -673,7 +732,7 @@ public static Integer hour() { * @return 当日24条数据 */ public static Collection getHourDataSet() { - Date dayBegin = CalendarUtil.getFirstSecondOfDay(DateUtil.now()); + Date dayBegin = CalendarUtils.getFirstSecondOfDay(DateUtil.now()); Calendar cal = Calendar.getInstance(); cal.setTime(dayBegin); PriorityQueue dataSets = new PriorityQueue<>(Date::compareTo); diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/FieldUtils.java b/uno-core/src/main/java/cc/allio/uno/core/util/FieldUtils.java new file mode 100644 index 00000000..9065cc5a --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/util/FieldUtils.java @@ -0,0 +1,52 @@ +package cc.allio.uno.core.util; + +import org.apache.commons.lang3.ArrayUtils; + +import java.lang.reflect.Field; +import java.util.*; + +/** + * field util + * + * @author jiangwei + * @date 2024/1/9 16:12 + * @since 1.1.6 + */ +public class FieldUtils extends org.apache.commons.lang3.reflect.FieldUtils { + + /** + * Gets all fields of the given class and its parents (if any). + * + * @param cls the {@link Class} to query + * @return an array of Fields (possibly empty). + * @throws NullPointerException if the class is {@code null} + * @since 3.2 + */ + public static Field[] getAllFields(final Class cls) { + return getAllFieldsList(cls).toArray(ArrayUtils.EMPTY_FIELD_ARRAY); + } + + /** + * Gets all fields of the given class and its parents (if any). + * + * @param cls the {@link Class} to query + * @return a list of Fields (possibly empty). + * @throws NullPointerException if the class is {@code null} + * @since 3.2 + */ + public static List getAllFieldsList(final Class cls) { + Objects.requireNonNull(cls, "cls"); + final List allFields = new ArrayList<>(); + recursionGetAllField(cls, allFields); + return allFields; + } + + private static void recursionGetAllField(Class cls, List fieldSet) { + Class superclass = cls.getSuperclass(); + if (superclass != null) { + recursionGetAllField(superclass, fieldSet); + } + final Field[] declaredFields = cls.getDeclaredFields(); + Collections.addAll(fieldSet, declaredFields); + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/IoUtil.java b/uno-core/src/main/java/cc/allio/uno/core/util/IoUtils.java similarity index 90% rename from uno-core/src/main/java/cc/allio/uno/core/util/IoUtil.java rename to uno-core/src/main/java/cc/allio/uno/core/util/IoUtils.java index 36559da5..f43827ba 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/IoUtil.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/IoUtils.java @@ -12,7 +12,7 @@ * * @author L.cm */ -public class IoUtil extends org.springframework.util.StreamUtils { +public class IoUtils extends org.springframework.util.StreamUtils { /** * closeQuietly @@ -56,21 +56,21 @@ public static String readToString(InputStream input) { */ public static String readToString(@Nullable InputStream input, Charset charset) { try { - return IoUtil.copyToString(input, charset); + return IoUtils.copyToString(input, charset); } catch (IOException e) { throw Exceptions.unchecked(e); } finally { - IoUtil.closeQuietly(input); + IoUtils.closeQuietly(input); } } public static byte[] readToByteArray(@Nullable InputStream input) { try { - return IoUtil.copyToByteArray(input); + return IoUtils.copyToByteArray(input); } catch (IOException e) { throw Exceptions.unchecked(e); } finally { - IoUtil.closeQuietly(input); + IoUtils.closeQuietly(input); } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/JsonUtils.java b/uno-core/src/main/java/cc/allio/uno/core/util/JsonUtils.java index 501408ab..2c08f3cd 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/JsonUtils.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/JsonUtils.java @@ -13,6 +13,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.type.CollectionLikeType; import com.fasterxml.jackson.databind.type.MapType; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.extern.slf4j.Slf4j; import org.springframework.lang.Nullable; @@ -33,7 +34,7 @@ @Slf4j public class JsonUtils { - private static final ObjectMapper INSTANCE = newJsonMapper(); + private static ObjectMapper instance = newJsonMapper(); private JsonUtils() { @@ -45,7 +46,7 @@ private JsonUtils() { * @return 空json数据 object node */ public static ObjectNode empty() { - return INSTANCE.createObjectNode(); + return instance.createObjectNode(); } /** @@ -54,7 +55,7 @@ public static ObjectNode empty() { * @return array node */ public static ArrayNode arrayEmpty() { - return INSTANCE.createArrayNode(); + return instance.createArrayNode(); } /** @@ -241,7 +242,7 @@ public static List readList(@Nullable String content, Class elementCla * @param 每一个元素泛型 * @param bytes 字节数组 * @param elementClass 元素Class对象 - * @return Set实例 set + * @return Set实例 setValue */ public static Set readSet(byte[] bytes, Class elementClass) { if (ObjectUtils.isEmpty(bytes)) { @@ -387,14 +388,14 @@ public static T toPojo(Map fromValue, Class toValueType) { * @return 单实例对象 json mapper */ public static ObjectMapper getJsonMapper() { - return INSTANCE; + return instance; } /** * 封装 Set type * * @param elementClass 集合值类型 - * @return CollectionLikeType set type + * @return CollectionLikeType setValue type */ public static CollectionLikeType getSetType(Class elementClass) { return getJsonMapper().getTypeFactory().constructCollectionLikeType(Set.class, elementClass); @@ -448,6 +449,15 @@ public static ObjectMapper newJsonMapper() { mapper.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 单引号处理 mapper.configure(JsonReadFeature.ALLOW_SINGLE_QUOTES.mappedFeature(), true); + // 解决时间序列化问题 + mapper.registerModule(new JavaTimeModule()); return mapper; } + + /** + * 由外部传递{@link ObjectMapper}进行使用 + */ + public static void reset(ObjectMapper objectMapper) { + JsonUtils.instance = objectMapper; + } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/NumberUtil.java b/uno-core/src/main/java/cc/allio/uno/core/util/NumberUtils.java similarity index 98% rename from uno-core/src/main/java/cc/allio/uno/core/util/NumberUtil.java rename to uno-core/src/main/java/cc/allio/uno/core/util/NumberUtils.java index 3a67d870..70e819e1 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/NumberUtil.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/NumberUtils.java @@ -24,7 +24,7 @@ * * @author L.cm */ -public class NumberUtil extends org.springframework.util.NumberUtils { +public class NumberUtils extends org.springframework.util.NumberUtils { //----------------------------------------------------------------------- diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/ReflectTool.java b/uno-core/src/main/java/cc/allio/uno/core/util/ReflectTool.java new file mode 100644 index 00000000..b39340d2 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/util/ReflectTool.java @@ -0,0 +1,77 @@ +package cc.allio.uno.core.util; + +import lombok.NonNull; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.stream.Stream; + +/** + * 反射相关的工具集合 + * + * @author j.x + * @date 2023/11/30 11:57 + * @since 1.0.0 + */ +public class ReflectTool { + + private ReflectTool() { + } + + /** + * 获取某个实体的泛型 + * + * @throws NullPointerException obj or superClassOrInterface is null then throws + * @see #getGenericType(Object, Class, int) + */ + public static Class getGenericType(@NonNull Object obj, @NonNull Class superClassOrInterface) { + return getGenericType(obj, superClassOrInterface, 0); + } + + /** + * 获取某个实体的泛型。给定{@param obj}必须是实现的子类,如果是lambda则不能无法获取 + * + * @param obj 实体 + * @param superClassOrInterface 声明的类或接口 + * @param index 声明泛型的顺序 + * @return class or null + * @throws NullPointerException obj or superClassOrInterface is null then throws + */ + public static Class getGenericType(@NonNull Object obj, @NonNull Class superClassOrInterface, int index) { + Class clazz = obj.getClass(); + + Stream.Builder genericTypeBuilder = Stream.builder(); + + Type genericSuperclass = clazz.getGenericSuperclass(); + if (genericSuperclass != null) { + genericTypeBuilder.add(genericSuperclass); + } + + Type[] genericInterfaces = clazz.getGenericInterfaces(); + + if (ObjectUtils.isNotEmpty(genericInterfaces)) { + for (Type genericInterface : genericInterfaces) { + genericTypeBuilder.add(genericInterface); + } + } + + Type superType = genericTypeBuilder.build() + .filter(type -> { + if (type instanceof ParameterizedType parameterizedType + && parameterizedType.getRawType() instanceof Class rawClass) { + return superClassOrInterface.isAssignableFrom(rawClass); + } + return false; + }) + .findFirst() + .orElse(null); + + if (superType != null) { + Type[] actualTypeArguments = ((ParameterizedType) superType).getActualTypeArguments(); + if (actualTypeArguments.length > index) { + return (Class) actualTypeArguments[index]; + } + } + return null; + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/ReflectUtils.java b/uno-core/src/main/java/cc/allio/uno/core/util/ReflectUtils.java index 22d3fe5c..f4ba7d67 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/ReflectUtils.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/ReflectUtils.java @@ -16,7 +16,6 @@ */ package cc.allio.uno.core.util; -import com.google.common.collect.Streams; import org.springframework.beans.BeansException; import org.springframework.cglib.core.CodeGenerationException; import org.springframework.core.convert.Property; @@ -29,10 +28,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; /** * 反射工具类 @@ -71,7 +67,7 @@ public static PropertyDescriptor[] getBeanSetters(Class type) { */ public static PropertyDescriptor[] getPropertiesHelper(Class type, boolean read, boolean write) { try { - PropertyDescriptor[] all = CoreBeanUtil.getPropertyDescriptors(type); + PropertyDescriptor[] all = BeanUtils.getPropertyDescriptors(type); if (read && write) { return all; } else { @@ -99,7 +95,7 @@ public static PropertyDescriptor[] getPropertiesHelper(Class type, boolean re */ @Nullable public static Property getProperty(Class propertyType, String propertyName) { - PropertyDescriptor propertyDescriptor = CoreBeanUtil.getPropertyDescriptor(propertyType, propertyName); + PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(propertyType, propertyName); if (propertyDescriptor == null) { return null; } @@ -151,41 +147,6 @@ public static TypeDescriptor getTypeDescriptor(Class propertyType, PropertyDe return new TypeDescriptor(property); } - /** - * 获取当前class所有的field,包含其父类 - * - * @param clazz the clazz - * @return all field of class - */ - public static List getAllField(Class clazz) { - Stream allField = Stream.empty(); - while (clazz != Object.class) { - Field[] declaredFields = clazz.getDeclaredFields(); - allField = Streams.concat(Arrays.stream(declaredFields), allField); - clazz = clazz.getSuperclass(); - } - return allField.collect(Collectors.toList()); - } - - /** - * 获取 类属性 - * - * @param clazz 类信息 - * @param fieldName 属性名 - * @return Field - */ - @Nullable - public static Field getField(Class clazz, String fieldName) { - while (clazz != Object.class) { - try { - return clazz.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - clazz = clazz.getSuperclass(); - } - } - return null; - } - /** * 获取 所有 field 属性上的注解 * @@ -197,7 +158,7 @@ public static Field getField(Class clazz, String fieldName) { */ @Nullable public static T getAnnotation(Class clazz, String fieldName, Class annotationClass) { - Field field = ReflectUtils.getField(clazz, fieldName); + Field field = FieldUtils.getField(clazz, fieldName); if (field == null) { return null; } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/ResourceUtil.java b/uno-core/src/main/java/cc/allio/uno/core/util/ResourceUtils.java similarity index 55% rename from uno-core/src/main/java/cc/allio/uno/core/util/ResourceUtil.java rename to uno-core/src/main/java/cc/allio/uno/core/util/ResourceUtils.java index c573d006..ff164ed1 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/ResourceUtil.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/ResourceUtils.java @@ -1,13 +1,11 @@ package cc.allio.uno.core.util; -import org.springframework.util.ResourceUtils; - /** - * 用于将资源位置解析为文件系统中文件的实用方法,基于{@link ResourceUtils} + * 用于将资源位置解析为文件系统中文件的实用方法,基于{@link org.springframework.util.ResourceUtils} * * @author jiangwei * @date 2022/1/29 16:21 * @since 1.0 */ -public class ResourceUtil extends ResourceUtils { +public class ResourceUtils extends org.springframework.util.ResourceUtils { } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/StringUtils.java b/uno-core/src/main/java/cc/allio/uno/core/util/StringUtils.java index 18514aaf..cb4652ff 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/StringUtils.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/StringUtils.java @@ -30,7 +30,6 @@ public class StringUtils extends org.springframework.util.StringUtils { private StringUtils() { - } public static boolean isNotEmpty(String s) { diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/Values.java b/uno-core/src/main/java/cc/allio/uno/core/util/Values.java new file mode 100644 index 00000000..55b2934c --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/util/Values.java @@ -0,0 +1,66 @@ +package cc.allio.uno.core.util; + +import cc.allio.uno.core.type.Types; + +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Stream; + +/** + * 与值相关的操作 + * + * @author jiangwei + * @date 2024/2/19 17:42 + * @since 1.1.6 + */ +public class Values { + + /** + * 返回数组 + * + * @see #streamExpand(Object[]) + */ + public static V[] expand(V... values) { + return (V[]) streamExpand(values).toArray(Object[]::new); + } + + /** + * 返回{@link Collection} + * + * @see #streamExpand(Object[]) + */ + public static Collection collectionExpand(V... values) { + return streamExpand(values).toList(); + } + + /** + * 给定values可变参数,如果里面存在: + *
      + *
    • 数组
    • + *
    • {@link java.util.Collection}
    • + *
    + * 则把数据进行转换。返回流数据 + * + * @param values values + * @param 值类型 + * @return value of stream + */ + public static Stream streamExpand(V... values) { + return Arrays.stream(values) + .flatMap(v -> { + Class valueClass = (Class) v.getClass(); + if (Types.isArray(valueClass)) { + Stream.Builder builder = Stream.builder(); + for (V o : ((V[]) v)) { + builder.add(o); + } + return builder.build(); + } else if (Types.isCollection(valueClass)) { + Stream.Builder builder = Stream.builder(); + ((Collection) v).forEach(builder::add); + return builder.build(); + } + return Stream.of(v); + }); + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/comparator/CollectionComparator.java b/uno-core/src/main/java/cc/allio/uno/core/util/comparator/CollectionComparator.java index fe8be502..e0753dac 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/comparator/CollectionComparator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/comparator/CollectionComparator.java @@ -1,10 +1,18 @@ package cc.allio.uno.core.util.comparator; +import cc.allio.uno.core.function.lambda.MethodBiFunction; + import java.util.Collection; import java.util.Comparator; /** * Collection Comparator + *

    该方法将比较如下事项:

    + *
      + *
    • 两个集合元素数量是否相等,不相等则返回
    • + *
    • 以集合o1为基准,遍历它,通过{@link #finder}寻找在集合o2中的元素,如果o2元素存在则进行下一步,否则返回-1(说明两者不一致)
    • + *
    • 基于{@link ObjectComparator}进行比较获取最后结果
    • + *
    * * @author jiangwei * @date 2022/7/10 16:01 @@ -12,8 +20,41 @@ */ public class CollectionComparator implements Comparator> { + private final MethodBiFunction, T> finder; + + public CollectionComparator() { + this.finder = (bench, comparable) -> comparable.stream().filter(bench::equals).findFirst().orElse(null); + } + + /** + * 参数包含三个范型参数: + *
      + *
    1. 用于比较的基准元素
    2. + *
    3. 用于比较的集合
    4. + *
    5. 从比较集合中查找出来的元素
    6. + *
    + * + * @param finder 元素基准记录寻找器 + */ + public CollectionComparator(MethodBiFunction, T> finder) { + this.finder = finder; + } + + @Override public int compare(Collection c1, Collection c2) { - return new ObjectComparator().compare(c1, c2); + if (c1.size() != c2.size()) { + return -1; + } + boolean compared = c1.stream() + .anyMatch(benchElement -> { + T testElement = finder.apply(benchElement, c2); + if (testElement != null) { + return false; + } + int compare = Comparators.objects().compare(c1, c2); + return compare >= 0; + }); + return compared ? 0 : -1; } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/comparator/ComparatorGenerator.java b/uno-core/src/main/java/cc/allio/uno/core/util/comparator/ComparatorGenerator.java deleted file mode 100644 index 39efa436..00000000 --- a/uno-core/src/main/java/cc/allio/uno/core/util/comparator/ComparatorGenerator.java +++ /dev/null @@ -1,45 +0,0 @@ -package cc.allio.uno.core.util.comparator; - -import java.math.BigDecimal; -import java.util.Collection; -import java.util.Comparator; - -/** - * 比较器生成器 - * - * @author jiangwei - * @date 2022/7/10 16:13 - * @since 1.0 - */ -public class ComparatorGenerator { - - /** - * 更具类型生成Comparator - * - * @param clazz class类型 - * @param 范型 - * @return Comparator实例 - */ - public static Comparator generator(Class clazz) { - if (clazz.isAssignableFrom(Integer.class)) { - return (Comparator) new IntegerComparator(); - } else if (clazz.isAssignableFrom(Byte.class)) { - return (Comparator) new ByteComparator(); - } else if (clazz.isAssignableFrom(Boolean.class)) { - return (Comparator) new BooleanComparator(); - } else if (clazz.isAssignableFrom(Long.class)) { - return (Comparator) new LongComparator(); - } else if (clazz.isAssignableFrom(Short.class)) { - return (Comparator) new ShortComparator(); - } else if (clazz.isAssignableFrom(String.class)) { - return (Comparator) new StringComparator(); - } else if (clazz.isAssignableFrom(BigDecimal.class)) { - return (Comparator) new BigDecimalComparator(); - } else if (clazz.isAssignableFrom(Collection.class)) { - return (Comparator) new CollectionComparator<>(); - } else if (clazz.isAssignableFrom(Float.class)) { - return (Comparator) new FloatComparator(); - } - return (Comparator) new ObjectComparator(); - } -} diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/comparator/Comparators.java b/uno-core/src/main/java/cc/allio/uno/core/util/comparator/Comparators.java new file mode 100644 index 00000000..2402300d --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/util/comparator/Comparators.java @@ -0,0 +1,106 @@ +package cc.allio.uno.core.util.comparator; + +import cc.allio.uno.core.function.lambda.MethodBiFunction; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.Comparator; + +/** + * {@link java.util.Comparator}常用类型比较器 + * + * @author jiangwei + * @date 2024/2/13 14:54 + * @since 1.1.6 + */ +public final class Comparators extends org.springframework.util.comparator.Comparators { + + private static final Comparator STRING_COMPARATOR = new StringComparator(); + private static final Comparator INTEGER_COMPARATOR = new IntegerComparator(); + private static final Comparator LONG_COMPARATOR = new LongComparator(); + private static final Comparator FLOAT_COMPARATOR = new FloatComparator(); + private static final Comparator DOUBLE_COMPARATOR = new DoubleComparator(); + private static final Comparator BOOLEAN_COMPARATOR = new BooleanComparator(); + private static final Comparator SHORT_COMPARATOR = new ShortComparator(); + private static final Comparator BIG_DECIMAL_COMPARATOR = new BigDecimalComparator(); + private static final Comparator OBJECT_COMPARATOR = new ObjectComparator(); + + private Comparators() { + } + + /** + * as string comparator + */ + public static Comparator strings() { + return STRING_COMPARATOR; + } + + /** + * as integer comparator + */ + public static Comparator integers() { + return INTEGER_COMPARATOR; + } + + /** + * as long comparator + */ + public static Comparator longs() { + return LONG_COMPARATOR; + } + + public static Comparator doubles() { + return DOUBLE_COMPARATOR; + } + + /** + * as float comparator + */ + public static Comparator floats() { + return FLOAT_COMPARATOR; + } + + /** + * as boolean comparator + */ + public static Comparator booleans() { + return BOOLEAN_COMPARATOR; + } + + /** + * as short comparator + */ + public static Comparator shorts() { + return SHORT_COMPARATOR; + } + + /** + * as big decimal comparator + */ + public static Comparator bigDecimals() { + return BIG_DECIMAL_COMPARATOR; + } + + /** + * as object comparator + */ + public static Comparator objects() { + return OBJECT_COMPARATOR; + } + + /** + * as collection comparator + */ + public static Comparator> collections() { + return new CollectionComparator<>(); + } + + /** + * as collection comparator + * + * @see CollectionComparator#CollectionComparator(MethodBiFunction) + */ + public static Comparator> collections(MethodBiFunction, T> finder) { + return new CollectionComparator<>(finder); + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/comparator/EqualsComparator.java b/uno-core/src/main/java/cc/allio/uno/core/util/comparator/EqualsComparator.java index 261813e1..6534bd98 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/comparator/EqualsComparator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/comparator/EqualsComparator.java @@ -3,7 +3,7 @@ import java.util.Comparator; /** - * Equals Comparator + * Equals Comparator。基于{@link Object#equals(Object)} * * @author jiangwei * @date 2022/7/10 16:16 @@ -13,6 +13,9 @@ public class EqualsComparator implements Comparator { @Override public int compare(Object o1, Object o2) { + if (o1 == null || o2 == null) { + return -1; + } return o1.equals(o2) ? 0 : -1; } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/comparator/ObjectComparator.java b/uno-core/src/main/java/cc/allio/uno/core/util/comparator/ObjectComparator.java index b88a9748..538d5864 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/comparator/ObjectComparator.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/comparator/ObjectComparator.java @@ -14,12 +14,17 @@ @Slf4j public class ObjectComparator implements Comparator { + private static final Comparator EQUALS_COMPARATOR = new EqualsComparator(); + @Override public int compare(Object o1, Object o2) { + if (o1 == null || o2 == null) { + return -1; + } // 两者类型不一致,返回-1 if (!o1.getClass().isAssignableFrom(o2.getClass())) { return -1; } - return new EqualsComparator().compare(o1, o2); + return EQUALS_COMPARATOR.compare(o1, o2); } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/convert/EnumToStringConverter.java b/uno-core/src/main/java/cc/allio/uno/core/util/convert/EnumToStringConverter.java index a4d4c71c..88262501 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/convert/EnumToStringConverter.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/convert/EnumToStringConverter.java @@ -1,6 +1,6 @@ package cc.allio.uno.core.util.convert; -import cc.allio.uno.core.util.ConvertUtil; +import cc.allio.uno.core.util.ConvertUtils; import com.fasterxml.jackson.annotation.JsonValue; import lombok.extern.slf4j.Slf4j; import org.springframework.core.convert.TypeDescriptor; @@ -77,7 +77,7 @@ public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDe return ((Enum) source).name(); } int ordinal = ((Enum) source).ordinal(); - return ConvertUtil.convert(ordinal, targetClazz); + return ConvertUtils.convert(ordinal, targetClazz); } try { return EnumToStringConverter.invoke(sourceClazz, accessibleObject, source, targetClazz); @@ -98,12 +98,12 @@ private static Object invoke(Class clazz, AccessibleObject accessibleObject, Method method = (Method) accessibleObject; Class paramType = method.getParameterTypes()[0]; // 类型转换 - Object object = ConvertUtil.convert(source, paramType); + Object object = ConvertUtils.convert(source, paramType); value = method.invoke(clazz, object); } if (value == null) { return null; } - return ConvertUtil.convert(value, targetClazz); + return ConvertUtils.convert(value, targetClazz); } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/convert/StringToEnumConverter.java b/uno-core/src/main/java/cc/allio/uno/core/util/convert/StringToEnumConverter.java index 5b7e45df..3060fdb2 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/convert/StringToEnumConverter.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/convert/StringToEnumConverter.java @@ -1,6 +1,6 @@ package cc.allio.uno.core.util.convert; -import cc.allio.uno.core.util.ConvertUtil; +import cc.allio.uno.core.util.ConvertUtils; import cc.allio.uno.core.util.StringUtils; import com.fasterxml.jackson.annotation.JsonCreator; import lombok.extern.slf4j.Slf4j; @@ -93,14 +93,14 @@ private static Object invoke(Class clazz, AccessibleObject accessibleObject, Constructor constructor = (Constructor) accessibleObject; Class paramType = constructor.getParameterTypes()[0]; // 类型转换 - Object object = ConvertUtil.convert(value, paramType); + Object object = ConvertUtils.convert(value, paramType); return constructor.newInstance(object); } if (accessibleObject instanceof Method) { Method method = (Method) accessibleObject; Class paramType = method.getParameterTypes()[0]; // 类型转换 - Object object = ConvertUtil.convert(value, paramType); + Object object = ConvertUtils.convert(value, paramType); return method.invoke(clazz, object); } return null; diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/convert/UnoConverter.java b/uno-core/src/main/java/cc/allio/uno/core/util/convert/UnoConverter.java index e0d95449..4f139902 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/convert/UnoConverter.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/convert/UnoConverter.java @@ -3,7 +3,8 @@ import cc.allio.uno.core.function.CheckedFunction; import cc.allio.uno.core.function.Unchecked; import cc.allio.uno.core.util.ClassUtils; -import cc.allio.uno.core.util.ConvertUtil; +import cc.allio.uno.core.util.ConvertUtils; +import cc.allio.uno.core.util.FieldUtils; import cc.allio.uno.core.util.ReflectUtils; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -33,7 +34,7 @@ public class UnoConverter implements Converter { * * @param value 源对象属性 * @param target 目标对象属性类 - * @param fieldName 目标的field名,原为 set 方法名,BladeBeanCopier 里做了更改 + * @param fieldName 目标的field名,原为 setValue 方法名,BladeBeanCopier 里做了更改 * @return {Object} */ @Override @@ -50,10 +51,10 @@ public Object convert(Object value, Class target, final Object fieldName) { TypeDescriptor targetDescriptor = UnoConverter.getTypeDescriptor(targetClazz, (String) fieldName); // 1. 判断 sourceClazz 为 Map if (Map.class.isAssignableFrom(sourceClazz)) { - return ConvertUtil.convert(value, targetDescriptor); + return ConvertUtils.convert(value, targetDescriptor); } else { TypeDescriptor sourceDescriptor = UnoConverter.getTypeDescriptor(sourceClazz, (String) fieldName); - return ConvertUtil.convert(value, sourceDescriptor, targetDescriptor); + return ConvertUtils.convert(value, sourceDescriptor, targetDescriptor); } } catch (Throwable e) { log.warn("BladeConverter error", e); @@ -66,7 +67,7 @@ private static TypeDescriptor getTypeDescriptor(final Class clazz, final Stri // 忽略抛出异常的函数,定义完整泛型,避免编译问题 CheckedFunction uncheckedFunction = (key) -> { // 这里 property 理论上不会为 null - Field field = ReflectUtils.getField(clazz, fieldName); + Field field = FieldUtils.getField(clazz, fieldName); if (field == null) { throw new NoSuchFieldException(fieldName); } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplate.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplate.java index 5c6181f0..acd49126 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplate.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/ExpressionTemplate.java @@ -1,6 +1,6 @@ package cc.allio.uno.core.util.template; -import cc.allio.uno.core.util.IoUtil; +import cc.allio.uno.core.util.IoUtils; import com.google.common.collect.Maps; import org.springframework.core.io.UrlResource; import reactor.util.function.Tuple2; @@ -14,7 +14,7 @@ import java.net.URL; import java.util.Collections; import java.util.Map; - + /** * Express模版。基于模版文件解析内容
    * @@ -137,7 +137,7 @@ default String parseFileTemplate(String file, Object target) throws IOException URL url = Thread.currentThread().getContextClassLoader().getResource(file); if (url != null) { UrlResource resource = new UrlResource(url); - String template = IoUtil.readToString(resource.getInputStream()); + String template = IoUtils.readToString(resource.getInputStream()); return parseTemplate(template, target); } throw new FileNotFoundException(String.format("%s file not found", file)); @@ -180,4 +180,14 @@ static ExpressionTemplate createTemplate(Tokenizer tokenizer) { static ExpressionTemplate createTemplate(Tokenizer tokenizer, boolean langsym) { return new PlaceholderExpressionTemplate(tokenizer, langsym); } + + /** + * 根据指定的{@link Tokenizer}创建{@link TokenParser}实例 + * + * @param tokenizer tokenizer + * @return TokenParser + */ + static TokenParser createParse(Tokenizer tokenizer) { + return new GenericTokenParser(tokenizer); + } } diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BaseInterchange.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BaseInterchange.java index f65f9386..9661da63 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BaseInterchange.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/BaseInterchange.java @@ -30,8 +30,7 @@ public Object change(String text, Object value, boolean langsym) throws Throwabl */ protected Object reValue(Object value, boolean langsym) { // 如果值类型为语言值则其判断的优先级大于参数langsym - if (value instanceof LangValue) { - LangValue langValue = (LangValue) value; + if (value instanceof LangValue langValue) { Object or = langValue.getValue(); if (langValue.isLangsym()) { return getTypeValue(or); diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListInterchange.java b/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListInterchange.java index 56feafa9..265d3a2b 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListInterchange.java +++ b/uno-core/src/main/java/cc/allio/uno/core/util/template/expression/ListInterchange.java @@ -22,7 +22,7 @@ public class ListInterchange extends BaseInterchange implements ListableIntercha @Override protected Object onChange(String text, Object value, boolean langsym) { List listable = (List) value; - // get index + // getValue index AtomicReference indexRef = new AtomicReference<>(); tokenParser.parse(text, content -> { indexRef.set(Integer.valueOf(content)); diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-class.png b/uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-class.png deleted file mode 100644 index e7fb170e..00000000 Binary files a/uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-class.png and /dev/null differ diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-sequence.png b/uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-sequence.png deleted file mode 100644 index c6b55566..00000000 Binary files a/uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-sequence.png and /dev/null differ diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-class.puml b/uno-core/src/main/resources/template-uml-class.puml similarity index 100% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-class.puml rename to uno-core/src/main/resources/template-uml-class.puml diff --git a/uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-sequence.puml b/uno-core/src/main/resources/template-uml-sequence.puml similarity index 100% rename from uno-core/src/main/java/cc/allio/uno/core/util/template/template-uml-sequence.puml rename to uno-core/src/main/resources/template-uml-sequence.puml diff --git a/uno-core/src/test/java/cc/allio/uno/core/bean/BeanInfoWrapperTest.java b/uno-core/src/test/java/cc/allio/uno/core/bean/BeanInfoWrapperTest.java index c10a11b0..a7b7e0e5 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/bean/BeanInfoWrapperTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/bean/BeanInfoWrapperTest.java @@ -88,7 +88,7 @@ void testSetList() throws IntrospectionException { void testSetSet() throws IntrospectionException { TestComplex testComplex = new TestComplex(); BeanInfoWrapper infoWrapper = new BeanInfoWrapper<>(TestComplex.class); - infoWrapper.set(testComplex, "set", Lists.newArrayList("2", "2")).subscribe(); + infoWrapper.set(testComplex, "setValue", Lists.newArrayList("2", "2")).subscribe(); assertEquals(1, testComplex.getSet().size()); } diff --git a/uno-core/src/test/java/cc/allio/uno/core/bean/ObjectWrapperTest.java b/uno-core/src/test/java/cc/allio/uno/core/bean/ObjectWrapperTest.java index 99ee759c..6eb7b1ff 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/bean/ObjectWrapperTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/bean/ObjectWrapperTest.java @@ -53,8 +53,13 @@ void testGetAllValues() { user.setName("name"); user.setType("type"); ObjectWrapper wrapper = new ObjectWrapper(user); - Map allValuesForce = wrapper.findAllValuesForce(); + Map allValuesForce = wrapper.findMapValuesForce(); System.out.println(allValuesForce); + wrapper.get("id") + .as(StepVerifier::create) + .expectNext(ValueWrapper.EMPTY_VALUE) + .verifyComplete(); + } } diff --git a/uno-core/src/test/java/cc/allio/uno/core/bus/EventBusTest.java b/uno-core/src/test/java/cc/allio/uno/core/bus/EventBusTest.java index 48c39692..78090dfe 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/bus/EventBusTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/bus/EventBusTest.java @@ -171,4 +171,16 @@ void testConcurrent() throws InterruptedException { } counter.await(); } + + @Test + void testHasTopic() { + bus.subscribe("/t1").subscribe(); + assertTrue(bus.hasTopic("/t1")); + + bus.subscribe("/t1/t2").subscribe(); + assertTrue(bus.hasTopic("/t1/**")); + + assertFalse(bus.hasTopic("/t2/**")); + + } } diff --git a/uno-core/src/test/java/cc/allio/uno/core/bus/SubscriptionTest.java b/uno-core/src/test/java/cc/allio/uno/core/bus/SubscriptionTest.java index ffe8cad7..771d36bb 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/bus/SubscriptionTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/bus/SubscriptionTest.java @@ -44,8 +44,4 @@ void testCustomizeIsEmptyWithSubscription() { assertEquals(0, empty.size()); } - @Override - protected void onDown() throws Throwable { - - } } diff --git a/uno-core/src/test/java/cc/allio/uno/core/chain/DefaultChainTest.java b/uno-core/src/test/java/cc/allio/uno/core/chain/DefaultChainTest.java index 4d75a50f..79103ff4 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/chain/DefaultChainTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/chain/DefaultChainTest.java @@ -46,4 +46,14 @@ void testNodeContext() throws Throwable { .verifyComplete(); } + @Test + void testErrorContinue() throws Throwable { + ErrorNode errorNode = new ErrorNode(); + SetDefaultValueNode defaultValueNode = new SetDefaultValueNode(); + DefaultChain chain = new DefaultChain<>(Arrays.asList(errorNode, defaultValueNode)); + TestChainContext context = new TestChainContext(); + chain.proceed(context).subscribe(); + assertEquals("default", context.getAttribute().get("test")); + } + } diff --git a/uno-core/src/test/java/cc/allio/uno/core/chain/ErrorNode.java b/uno-core/src/test/java/cc/allio/uno/core/chain/ErrorNode.java new file mode 100644 index 00000000..333d5cb2 --- /dev/null +++ b/uno-core/src/test/java/cc/allio/uno/core/chain/ErrorNode.java @@ -0,0 +1,11 @@ +package cc.allio.uno.core.chain; + +import reactor.core.publisher.Mono; + +public class ErrorNode implements Node { + @Override + public Mono execute(Chain chain, ChainContext context) throws Throwable { + int i = 1 / 0; + return chain.proceed(context); + } +} diff --git a/uno-core/src/test/java/cc/allio/uno/core/chain/SetDefaultValueNode.java b/uno-core/src/test/java/cc/allio/uno/core/chain/SetDefaultValueNode.java new file mode 100644 index 00000000..7f84b396 --- /dev/null +++ b/uno-core/src/test/java/cc/allio/uno/core/chain/SetDefaultValueNode.java @@ -0,0 +1,12 @@ +package cc.allio.uno.core.chain; + +import reactor.core.publisher.Mono; + +public class SetDefaultValueNode implements Node { + + @Override + public Mono execute(Chain chain, ChainContext context) throws Throwable { + context.getAttribute().put("test", "default"); + return chain.proceed(context); + } +} diff --git a/uno-core/src/test/java/cc/allio/uno/core/datastructure/tree/TreeSupportTest.java b/uno-core/src/test/java/cc/allio/uno/core/datastructure/tree/TreeSupportTest.java index 716fffee..c5dbbbcd 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/datastructure/tree/TreeSupportTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/datastructure/tree/TreeSupportTest.java @@ -36,15 +36,15 @@ void testTreeifyAndExpand() { @Test void testComparatorTreeify() { - List treeify = + List treeify = TreeSupport.treeify( testData, expand -> new Role(expand.getId(), Comparator.comparingInt(Role::getSort)) ); assertEquals(3, treeify.size()); - Element element = treeify.get(1); + Role element = treeify.get(1); assertNotNull(element); - Element sort = element.getChildren().get(0); + Role sort = element.getChildren().get(0); assertNotNull(sort); assertEquals(5, sort.getId()); } diff --git a/uno-core/src/test/java/cc/allio/uno/core/function/MethodReferenceColumnTest.java b/uno-core/src/test/java/cc/allio/uno/core/function/MethodReferenceColumnTest.java new file mode 100644 index 00000000..e9ce68e2 --- /dev/null +++ b/uno-core/src/test/java/cc/allio/uno/core/function/MethodReferenceColumnTest.java @@ -0,0 +1,20 @@ +package cc.allio.uno.core.function; + +import cc.allio.uno.core.BaseTestCase; +import cc.allio.uno.core.function.lambda.MethodReferenceColumn; +import lombok.Data; +import org.junit.jupiter.api.Test; + +public class MethodReferenceColumnTest extends BaseTestCase { + + @Test + void testGetEntityType() { + MethodReferenceColumn methodReferenceColumn = User::getId; + assertEquals(User.class, methodReferenceColumn.getEntityType()); + } + + @Data + public static class User { + private String id; + } +} diff --git a/uno-core/src/test/java/cc/allio/uno/core/function/SerializedLambdaTest.java b/uno-core/src/test/java/cc/allio/uno/core/function/SerializedLambdaTest.java index 2da73f33..437ab337 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/function/SerializedLambdaTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/function/SerializedLambdaTest.java @@ -2,6 +2,9 @@ import cc.allio.uno.core.BaseTestCase; import cc.allio.uno.core.User; +import cc.allio.uno.core.function.lambda.MethodReference; +import cc.allio.uno.core.function.lambda.SerializedLambda; +import cc.allio.uno.core.function.lambda.StaticMethodReference; import org.junit.jupiter.api.Test; class SerializedLambdaTest extends BaseTestCase { diff --git a/uno-core/src/test/java/cc/allio/uno/core/function/ThrowingFunctionTest.java b/uno-core/src/test/java/cc/allio/uno/core/function/ThrowingFunctionTest.java new file mode 100644 index 00000000..5d929218 --- /dev/null +++ b/uno-core/src/test/java/cc/allio/uno/core/function/ThrowingFunctionTest.java @@ -0,0 +1,39 @@ +package cc.allio.uno.core.function; + +import cc.allio.uno.core.BaseTestCase; +import cc.allio.uno.core.function.lambda.ThrowingMethodBiConsumer; +import cc.allio.uno.core.function.lambda.ThrowingMethodVoid; +import org.junit.jupiter.api.Test; + +public class ThrowingFunctionTest extends BaseTestCase { + + @Test + void testDemoThrowing() { + Demo demo = new Demo() { + @Override + public void f1(String s1, String s2) throws Throwable { + + } + + @Override + public void f2() { + + } + }; + + ThrowingMethodBiConsumer throwing = demo::f1; + String m1 = throwing.getMethodName(); + assertEquals("f1", m1); + + ThrowingMethodVoid throwing2 = demo::f2; + String m2 = throwing2.getMethodName(); + assertEquals("f2", m2); + } + + public interface Demo { + + void f1(String s1, String s2) throws Throwable; + + void f2(); + } +} diff --git a/uno-core/src/test/java/cc/allio/uno/core/type/EnumTypeTest.java b/uno-core/src/test/java/cc/allio/uno/core/type/EnumTypeTest.java index 5aec1c6a..fe3867d7 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/type/EnumTypeTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/type/EnumTypeTest.java @@ -1,6 +1,8 @@ package cc.allio.uno.core.type; import cc.allio.uno.core.BaseTestCase; +import lombok.AllArgsConstructor; +import lombok.Getter; import org.junit.jupiter.api.Test; public class EnumTypeTest extends BaseTestCase { @@ -12,6 +14,30 @@ void testEnumOperator() { System.out.println(convert); } + @Test + void testGuessEnum() { + TypeOperator translator1 = TypeOperatorFactory.translator(Named.class); + + assertInstanceOf(EnumTypeOperator.class, translator1); + + Named name = translator1.convert("name"); + + assertNotNull(name); + + TypeOperator translator2 = TypeOperatorFactory.translator(NameValued.class); + + NameValued value = translator2.convert("value"); + assertNotNull(value); + + NameValued label = translator2.convert("label"); + assertNotNull(label); + + NameValued value1 = ((EnumTypeOperator) translator2).convert("value", NameValued::getValue); + + assertNotNull(value); + } + + public class User { private TestA testA; } @@ -20,4 +46,22 @@ public enum TestA { A, B } + + @Getter + @AllArgsConstructor + public enum Named { + + NAME("name"); + + private final String label; + } + + @Getter + @AllArgsConstructor + public enum NameValued { + + NAME("value", "label"); + private final String value; + private final String label; + } } diff --git a/uno-core/src/test/java/cc/allio/uno/core/util/CollectionUtilsTest.java b/uno-core/src/test/java/cc/allio/uno/core/util/CollectionUtilsTest.java new file mode 100644 index 00000000..83988948 --- /dev/null +++ b/uno-core/src/test/java/cc/allio/uno/core/util/CollectionUtilsTest.java @@ -0,0 +1,40 @@ +package cc.allio.uno.core.util; + +import cc.allio.uno.core.BaseTestCase; +import com.google.common.collect.Lists; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Collection; + +public class CollectionUtilsTest extends BaseTestCase { + + @Test + void testUnion() { + ArrayList c1 = Lists.newArrayList("1", "2", "3"); + ArrayList c2 = Lists.newArrayList("1", "4"); + Collection union = CollectionUtils.union(c1, c2); + + assertEquals(4, union.size()); + } + + @Test + void testIntersection() { + ArrayList c1 = Lists.newArrayList("1", "2", "3"); + ArrayList c2 = Lists.newArrayList("1", "4"); + + Collection intersection = CollectionUtils.intersection(c1, c2); + + assertEquals(1, intersection.size()); + } + + @Test + void testComplement() { + ArrayList c1 = Lists.newArrayList("1", "2", "3"); + ArrayList c2 = Lists.newArrayList("1", "4"); + + Collection complement = CollectionUtils.complement(c1, c2); + + assertEquals(2, complement.size()); + } +} diff --git a/uno-core/src/test/java/cc/allio/uno/core/util/DateUtilTest.java b/uno-core/src/test/java/cc/allio/uno/core/util/DateUtilTest.java index a2ea9e3d..b62ae753 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/util/DateUtilTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/util/DateUtilTest.java @@ -55,13 +55,23 @@ void testIsBetween() { } - @Override - protected void onInit() throws Throwable { - + @Test + void testIsoParse() { + String isoStr = "2023-11-30T08:48:19.304+08:00"; + Date parse = DateUtil.parse(isoStr); + assertNotNull(parse); } - @Override - protected void onDown() throws Throwable { - + @Test + void testUniParse() { + String str1 = "2023-11-30 08:48:19"; + Date d1 = DateUtil.parse(str1); + assertNotNull(d1); + String str2 = "2x23-11-30 08:48:19d"; + Date d2 = DateUtil.parse(str2); + assertNull(d2); + String str3 = "2023-11-30"; + Date d3 = DateUtil.parse(str3); + assertNotNull(d3); } } diff --git a/uno-core/src/test/java/cc/allio/uno/core/util/ReflectToolTest.java b/uno-core/src/test/java/cc/allio/uno/core/util/ReflectToolTest.java new file mode 100644 index 00000000..4e60a38e --- /dev/null +++ b/uno-core/src/test/java/cc/allio/uno/core/util/ReflectToolTest.java @@ -0,0 +1,60 @@ +package cc.allio.uno.core.util; + +import cc.allio.uno.core.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class ReflectToolTest extends BaseTestCase { + + @Test + void testGenericType() { + + // 接口测试 + Class genericType1 = ReflectTool.getGenericType(new AImpl(), A.class); + + assertEquals(String.class, genericType1); + + Class genericType2 = ReflectTool.getGenericType(new Object(), Object.class); + assertNull(genericType2); + + + Class genericType3 = ReflectTool.getGenericType(new BImpl(), B.class, 1); + assertEquals(Integer.class, genericType3); + + // 类测试 + Class genericType4 = ReflectTool.getGenericType(new CImpl(), C.class); + assertEquals(String.class, genericType4); + + Class genericType5 = ReflectTool.getGenericType(new AAPenetrateImpl(), A.class); + assertEquals(String.class, genericType5); + } + + + interface A { + } + + interface B { + } + + static abstract class C { + + } + + static class AImpl implements A { + } + + static class BImpl implements B { + } + + static class CImpl extends C { + } + + + interface APenetrate extends A { + } + + abstract class APenetrateImpl implements APenetrate { + } + + class AAPenetrateImpl extends APenetrateImpl { + } +} diff --git a/uno-core/src/test/java/cc/allio/uno/core/util/StringUtilBaseTest.java b/uno-core/src/test/java/cc/allio/uno/core/util/StringUtilBaseTest.java index 108c1b0e..696a7a30 100644 --- a/uno-core/src/test/java/cc/allio/uno/core/util/StringUtilBaseTest.java +++ b/uno-core/src/test/java/cc/allio/uno/core/util/StringUtilBaseTest.java @@ -237,7 +237,7 @@ void testGetApiPath() { templateUrl = "https://blog.csdn.net:8081/gerald2008/article/details/107116526/get?id=1&name=2"; StepVerifier.create(StringUtils.getApiUrl(templateUrl)) - .expectNext("/gerald2008/article/details/107116526/get?id=1&name=2") + .expectNext("/gerald2008/article/details/107116526/getValue?id=1&name=2") .verifyComplete(); templateUrl = ""; @@ -246,9 +246,9 @@ void testGetApiPath() { .verifyComplete(); // 如果不是http、https等存在的将返回 - templateUrl = "wasd://blog.csdn.net:8081/gerald2008/article/details/107116526/get?id=1&name=2"; + templateUrl = "wasd://blog.csdn.net:8081/gerald2008/article/details/107116526/getValue?id=1&name=2"; StepVerifier.create(StringUtils.getApiUrl(templateUrl)) - .expectNext("//blog.csdn.net:8081/gerald2008/article/details/107116526/get?id=1&name=2") + .expectNext("//blog.csdn.net:8081/gerald2008/article/details/107116526/getValue?id=1&name=2") .verifyComplete(); } diff --git a/uno-data/pom.xml b/uno-data/pom.xml index e081571e..44d22227 100644 --- a/uno-data/pom.xml +++ b/uno-data/pom.xml @@ -5,22 +5,29 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 + pom 4.0.0 uno-data - 1.1.5.RELEASE + 1.1.6-beta.1 - summary: uno数据层操作,包含于数据源、mybatis-plus、reactive-jpa、elasticsearch、influxdb等(依赖包于provide) + summary: uno数据层操作,包含于数据源、mybatis-plus、reactive-jpa、elasticsearch、influxdb等 features: 提供数据聚合等操作 - - 8 - 8 - UTF-8 - + + uno-data-api + uno-data-db + uno-data-elasticsearch + uno-data-influxdb + uno-data-mongodb + uno-data-neo4j + uno-data-redis + uno-data-test + uno-data-sql + @@ -33,131 +40,12 @@ uno-auto provided - - - - com.baomidou - mybatis-plus-boot-starter - provided - - - org.mybatis.spring.boot - mybatis-spring-boot-starter - provided - - - - co.elastic.clients - elasticsearch-java - provided - - - org.elasticsearch.client - elasticsearch-rest-client - provided - - - jakarta.persistence - jakarta.persistence-api - - - - com.influxdb - influxdb-client-java - provided - - - - com.taosdata.jdbc - taos-jdbcdriver - provided - - - org.springframework.boot - spring-boot-starter-data-jpa - provided - - - org.springframework.boot - spring-boot-starter-data-r2dbc - provided - - - com.alibaba - druid-spring-boot-starter - provided - + cc.allio uno-test test - - org.postgresql - postgresql - provided - - - mysql - mysql-connector-java - provided - - - com.microsoft.sqlserver - mssql-jdbc - provided - - - com.h2database - h2 - provided - - - io.asyncer - r2dbc-mysql - - - io.r2dbc - r2dbc-mssql - provided - - - org.postgresql - r2dbc-postgresql - - - io.r2dbc - r2dbc-h2 - provided - - - com.oracle.database.r2dbc - oracle-r2dbc - provided - - - - org.apache.shardingsphere - shardingsphere-sql-parser-mysql - - - org.apache.shardingsphere - shardingsphere-sql-parser-postgresql - - - org.apache.shardingsphere - shardingsphere-sql-parser-sqlserver - - - org.apache.shardingsphere - shardingsphere-sql-parser-oracle - - - - com.alibaba - druid - - org.springframework.boot spring-boot-starter-test @@ -169,11 +57,5 @@ - - org.springframework - spring-webmvc - test - - \ No newline at end of file diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/ORMProperties.java b/uno-data/src/main/java/cc/allio/uno/data/orm/ORMProperties.java deleted file mode 100644 index a08f68ab..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/ORMProperties.java +++ /dev/null @@ -1,56 +0,0 @@ -package cc.allio.uno.data.orm; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.Getter; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * ORM Properties - * - * @author jiangwei - * @date 2023/4/16 23:42 - * @since 1.1.4 - */ -@Data -@ConfigurationProperties(prefix = "allio.uno.data.orm") -public class ORMProperties { - - private SQL sql = new SQL(); - private Executor executor = new Executor(); - - @Data - public static class SQL { - private SQLOperatorMetadata operator = SQLOperatorMetadata.DRUID; - private SQLFormat format = SQLFormat.UNDERLINE; - } - - @Data - public static class Executor { - private SQLExecutor type = SQLExecutor.MYBATIS; - } - - @Getter - @AllArgsConstructor - public enum SQLOperatorMetadata { - DRUID("druid"), - LOCAL("local"), - SHARDING_SPHERE("sharding-sphere"); - private final String name; - } - - @Getter - @AllArgsConstructor - public enum SQLExecutor { - MYBATIS("mybatis"); - private final String name; - } - - @Getter - @AllArgsConstructor - public enum SQLFormat { - UNDERLINE("underline"), - HUMP("HUMP_FEATURE"); - private final String name; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/SQLAdapter.java b/uno-data/src/main/java/cc/allio/uno/data/orm/SQLAdapter.java deleted file mode 100644 index da668729..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/SQLAdapter.java +++ /dev/null @@ -1,29 +0,0 @@ -package cc.allio.uno.data.orm; - -/** - * SQL适配器定义 - * - * @param 转换的类型 - * @param 原始类型 - * @author jiangwei - * @date 2023/4/13 13:14 - * @since 1.1.4 - */ -public interface SQLAdapter { - - /** - * 根据原始的类型获取目标转换的类型 - * - * @param o 原始类型实例 - * @return 转换的实例 - */ - R get(O o); - - /** - * 根据目标的类型获取原始的类型 - * - * @param r 目标类型 - * @return 原始类型 - */ - O reversal(R r); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/config/DataBaseAutoConfiguration.java b/uno-data/src/main/java/cc/allio/uno/data/orm/config/DataBaseAutoConfiguration.java deleted file mode 100644 index 7ae391c9..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/config/DataBaseAutoConfiguration.java +++ /dev/null @@ -1,113 +0,0 @@ -package cc.allio.uno.data.orm.config; - -import cc.allio.uno.data.orm.ORMProperties; -import cc.allio.uno.data.orm.sql.*; -import com.alibaba.druid.DbType; -import com.alibaba.druid.pool.DruidDataSource; -import cc.allio.uno.core.env.Envs; -import cc.allio.uno.data.orm.executor.SQLCommandExecutor; -import cc.allio.uno.data.orm.executor.SQLCommandExecutorFactory; -import cc.allio.uno.data.orm.executor.mybatis.MybatisSQLCommandExecutor; -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.microsoft.sqlserver.jdbc.SQLServerDataSource; -import com.mysql.cj.jdbc.MysqlDataSource; -import com.zaxxer.hikari.HikariDataSource; -import org.apache.ibatis.session.SqlSessionFactory; -import org.postgresql.ds.PGSimpleDataSource; -import org.springframework.beans.BeansException; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.sql.DataSource; - -import static cc.allio.uno.data.orm.executor.SQLCommandExecutor.MYBATIS_SQL_COMMAND_EXECUTOR_KEY; - -@Configuration(proxyBeanMethods = false) -@AutoConfigureAfter({DataSourceAutoConfiguration.class}) -@ConditionalOnClass({DruidDataSource.class, HikariDataSource.class}) -@EnableConfigurationProperties(ORMProperties.class) -public class DataBaseAutoConfiguration implements ApplicationContextAware { - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - DataSource dataSource = applicationContext.getBean(DataSource.class); - // druid - if (dataSource instanceof DruidDataSource) { - String dbType = ((DruidDataSource) dataSource).getDbType(); - DbType druidDbType = DbType.of(dbType); - DBType systemDbType = DruidDbTypeAdapter.getInstance().reversal(druidDbType); - Envs.setProperty(DBType.DB_TYPE_CONFIG_KEY, systemDbType.getName()); - } - // hikari - if (dataSource instanceof HikariDataSource) { - String driverClassName = ((HikariDataSource) dataSource).getDriverClassName(); - Envs.setProperty(DBType.DB_TYPE_CONFIG_KEY, parseDriveClassNameForDBtype(driverClassName).getName()); - } - // pg - if (dataSource instanceof PGSimpleDataSource) { - Envs.setProperty(DBType.DB_TYPE_CONFIG_KEY, DBType.POSTGRESQL.getName()); - } - // mysql - if (dataSource instanceof MysqlDataSource) { - Envs.setProperty(DBType.DB_TYPE_CONFIG_KEY, DBType.MYSQL.getName()); - } - // mssql - if (dataSource instanceof SQLServerDataSource) { - Envs.setProperty(DBType.DB_TYPE_CONFIG_KEY, DBType.SQLSERVER.getName()); - } - } - - @Bean - @ConditionalOnProperty(name = OperatorMetadata.OPERATOR_METADATA_KEY, havingValue = "druid") - public DruidOperatorMetadata druidOperatorMetadata() { - Envs.setProperty(OperatorMetadata.OPERATOR_METADATA_KEY, OperatorMetadata.DRUID_OPERATOR_KEY.getKey()); - return SQLOperatorFactory.getSystemOperatorMetadata(); - } - - @Bean - @ConditionalOnProperty(name = OperatorMetadata.OPERATOR_METADATA_KEY, havingValue = "local") - @ConditionalOnMissingBean - public LocalOperatorMetadata localOperatorMetadata() { - Envs.setProperty(OperatorMetadata.OPERATOR_METADATA_KEY, OperatorMetadata.LOCAL_OPERATOR_KEY.getKey()); - return SQLOperatorFactory.getSystemOperatorMetadata(); - } - - @Bean - @ConditionalOnProperty(name = OperatorMetadata.OPERATOR_METADATA_KEY, havingValue = "sharding-sphere") - @ConditionalOnMissingBean - public ShardingSphereOperatorMetadata shardingSphereOperatorMetadata() { - Envs.setProperty(OperatorMetadata.OPERATOR_METADATA_KEY, OperatorMetadata.SHARDING_SPHERE_KEY.getKey()); - return SQLOperatorFactory.getSystemOperatorMetadata(); - } - - @Bean - @ConditionalOnClass(SqlSessionFactory.class) - @ConditionalOnMissingBean - public MybatisSQLCommandExecutor mybatisSQLCommandExecutor(SqlSessionFactory sqlSessionFactory) { - Envs.setProperty(SQLCommandExecutor.SQL_EXECUTOR_TYPE_KEY, MYBATIS_SQL_COMMAND_EXECUTOR_KEY.getKey()); - return SQLCommandExecutorFactory.create(MYBATIS_SQL_COMMAND_EXECUTOR_KEY, new Object[]{sqlSessionFactory.getConfiguration()}); - } - - /** - * 解析driveClassName为DBType - * - * @param driveClassName driveClassName - * @return DBType or default h2 - */ - private DBType parseDriveClassNameForDBtype(String driveClassName) { - if ("com.mysql.cj.jdbc.Driver".equals(driveClassName) || "com.mysql.jdbc.Driver".equals(driveClassName)) { - return DBType.MYSQL; - } else if ("org.postgresql.Driver".equals(driveClassName)) { - return DBType.POSTGRESQL; - } - return DBType.H2; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/config/ElasticSearchAutoConfiguration.java b/uno-data/src/main/java/cc/allio/uno/data/orm/config/ElasticSearchAutoConfiguration.java deleted file mode 100644 index 24ad6552..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/config/ElasticSearchAutoConfiguration.java +++ /dev/null @@ -1,23 +0,0 @@ -package cc.allio.uno.data.orm.config; - -import cc.allio.uno.data.orm.executor.SQLCommandExecutorFactory; -import cc.allio.uno.data.orm.executor.elasticsearch.EsSQLCommandExecutor; -import org.elasticsearch.client.RestClientBuilder; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; -import org.springframework.context.annotation.*; - -import static cc.allio.uno.data.orm.executor.SQLCommandExecutor.ELASTICSEARCH_SQL_COMMAND_EXECUTOR_KEY; - -@Configuration(proxyBeanMethods = false) -@AutoConfigureAfter(ElasticsearchRestClientAutoConfiguration.class) -@ConditionalOnClass(RestClientBuilder.class) -public class ElasticSearchAutoConfiguration { - - @Bean - public EsSQLCommandExecutor esSQLCommandExecutor(RestClientBuilder builder) { - return SQLCommandExecutorFactory.create(ELASTICSEARCH_SQL_COMMAND_EXECUTOR_KEY, new Object[]{builder}); - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/AbstractDialect.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/AbstractDialect.java deleted file mode 100644 index f5299cdc..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/AbstractDialect.java +++ /dev/null @@ -1,52 +0,0 @@ -package cc.allio.uno.data.orm.dialect; - -import cc.allio.uno.data.orm.dialect.func.FuncRegistry; -import cc.allio.uno.data.orm.dialect.func.ReuseFuncFactory; -import cc.allio.uno.data.orm.type.TypeRegistry; - -/** - * dialect抽象层 - * - * @author jiangwei - * @date 2023/1/5 18:49 - * @since 1.1.4 - */ -public abstract class AbstractDialect implements Dialect { - - protected final TypeRegistry typeRegistry = TypeRegistry.getInstance(); - protected final FuncRegistry funcRegistry; - - protected AbstractDialect() { - this.funcRegistry = new FuncRegistry(); - // registry general func - funcRegistry.register(ReuseFuncFactory.count(this)); - funcRegistry.register(ReuseFuncFactory.min(this)); - funcRegistry.register(ReuseFuncFactory.max(this)); - funcRegistry.register(ReuseFuncFactory.avg(this)); - funcRegistry.register(ReuseFuncFactory.sum(this)); - // 触发子类 func - triggerInitFunc(); - // 初始化type - triggerInitType(); - } - - @Override - public FuncRegistry getFuncRegistry() { - return funcRegistry; - } - - @Override - public TypeRegistry getTypeRegistry() { - return typeRegistry; - } - - /** - * 触发初始化Func实例 - */ - protected abstract void triggerInitFunc(); - - /** - * 触发初始化Type实例 - */ - protected abstract void triggerInitType(); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/Dialect.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/Dialect.java deleted file mode 100644 index 9cc2fbb1..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/Dialect.java +++ /dev/null @@ -1,35 +0,0 @@ -package cc.allio.uno.data.orm.dialect; - -import cc.allio.uno.data.orm.dialect.func.FuncRegistry; -import cc.allio.uno.data.orm.type.TypeRegistry; - -/** - * 定义数据库方言对象 - * - * @author jiangwei - * @date 2023/1/5 18:27 - * @since 1.1.4 - */ -public interface Dialect { - - /** - * 获取数据库版本号 - * - * @return Version实例 - */ - Version getVersion(); - - /** - * 获取Func registry - * - * @return FuncRegistry - */ - FuncRegistry getFuncRegistry(); - - /** - * 获取Type registry - * - * @return TypeRegistry - */ - TypeRegistry getTypeRegistry(); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/H2Dialect.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/H2Dialect.java deleted file mode 100644 index f3205e0f..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/H2Dialect.java +++ /dev/null @@ -1,26 +0,0 @@ -package cc.allio.uno.data.orm.dialect; - -/** - * H2 dialect - * - * @author jiangwei - * @date 2023/1/5 18:49 - * @since 1.1.4 - */ -public class H2Dialect extends AbstractDialect { - - @Override - public Version getVersion() { - return null; - } - - @Override - protected void triggerInitFunc() { - - } - - @Override - protected void triggerInitType() { - - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/Version.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/Version.java deleted file mode 100644 index c9590008..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/Version.java +++ /dev/null @@ -1,55 +0,0 @@ -package cc.allio.uno.data.orm.dialect; - -import lombok.AllArgsConstructor; -import lombok.Data; - -/** - * 数据库版本号 - * - * @author jiangwei - * @date 2023/1/12 18:17 - * @since 1.1.4 - */ -@Data -@AllArgsConstructor -public class Version { - - private final Integer major; - private final Integer minor; - private final Integer micro; - - /** - * 创建数据库版本实例 minor = 0 - * - * @param major major version - * @return Version 实例 - */ - public static Version make(Integer major) { - return make(major, 0); - } - - /** - * 创建数据库版本实例 micro = 0 - * - * @param major major version - * @param minor minor version - * @return Version 实例 - */ - public static Version make(Integer major, Integer minor) { - return make(major, minor, 0); - } - - /** - * 创建数据库版本实例 - * - * @param major major version - * @param minor minor version - * @param micro micro version - * @return Version 实例 - */ - public static Version make(Integer major, Integer minor, Integer micro) { - return new Version(major, minor, micro); - } - - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncDescriptor.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncDescriptor.java deleted file mode 100644 index 7c43a72a..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncDescriptor.java +++ /dev/null @@ -1,58 +0,0 @@ -package cc.allio.uno.data.orm.dialect.func; - -import cc.allio.uno.data.orm.dialect.Dialect; - -/** - * 描述某个指定的SQL aggregate - * - * @author jiangwei - * @date 2023/1/12 15:39 - * @since 1.1.4 - */ -public interface FuncDescriptor { - - /** - * 获取Func name - * - * @return func name - */ - String getFuncName(); - - /** - * 创建Func实例 - * - * @return Func实例 - */ - Func createFunc(); - - /** - * 获取func签名 - * - * @return 签名 - */ - String getSignature(); - - /** - * 获取func 类型 - * - * @return 函数类型 - */ - FuncType getFuncType(); - - /** - * 获取数据库方言对象 - * - * @return dialect instance - */ - Dialect getDialect(); - - /** - * 渲染当前函数为表达式字符串 - * - * @param arguments 渲染过程中动态参数 - * @return 表达式 - * @see FuncRendering#render(FuncDescriptor, Object[]) - */ - String render(Object[] arguments); - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncRegistry.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncRegistry.java deleted file mode 100644 index cdf71575..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncRegistry.java +++ /dev/null @@ -1,172 +0,0 @@ -package cc.allio.uno.data.orm.dialect.func; - -import cc.allio.uno.data.orm.dialect.Dialect; -import com.google.common.collect.Lists; - -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.function.Supplier; - -/** - * {@link FuncDescriptor} registry - * - * @author jiangwei - * @date 2023/1/12 18:07 - * @since 1.1.4 - */ -public class FuncRegistry { - - private final Map funcMap; - - public FuncRegistry() { - this.funcMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - } - - /** - * 获取Func的列表数据 - * - * @return Func list - */ - public List getFuncs() { - return Lists.newArrayList(funcMap.values()); - } - - /** - * 获取当前注册表所有的函数名称 - * - * @return 函数名称List - */ - public List getFuncNames() { - return Lists.newArrayList(funcMap.keySet()); - } - - /** - * 向注册表中注册func实例 - * - * @param funcName func name - * @param func func instance - * @return FuncDescriptor - */ - public FuncDescriptor register(String funcName, FuncDescriptor func) { - return funcMap.put(funcName, func); - } - - /** - * 向func registry中注册FuncDescriptor实例 - * - * @param func FuncDescriptor实例 - * @return FuncDescriptor - */ - public FuncDescriptor register(FuncDescriptor func) { - return register(func.getFuncName(), func); - } - - /** - * 从注册表中查找Func实例 - * - * @param funcName func name - * @return FuncDescriptor or null - */ - public FuncDescriptor findFunc(String funcName) { - return funcMap.get(funcName); - } - - /** - * {@link NamedFuncDescriptorBuilder}构造器 - * - * @param funcName func name - * @return NamedFuncDescriptorBuilder实例 - */ - public NamedFuncDescriptorBuilder namedFuncDescriptorBuilder(String funcName) { - return NamedFuncDescriptorBuilder.builder().setFuncName(funcName); - } - - public static class NamedFuncDescriptorBuilder { - - private String funcName; - private String signature; - private FuncType funcType; - private Dialect dialect; - private FuncRendering rendering; - - public static NamedFuncDescriptorBuilder builder() { - return new NamedFuncDescriptorBuilder(); - } - - /** - * 设置函数名称 - * - * @param funcName func name - * @return NamedFuncDescriptorBuilder - */ - public NamedFuncDescriptorBuilder setFuncName(String funcName) { - this.funcName = funcName; - return this; - } - - /** - * 设置函数签名 - * - * @param signature 签名 - * @return NamedFuncDescriptorBuilder - */ - public NamedFuncDescriptorBuilder setSignature(String signature) { - this.signature = signature; - return this; - } - - /** - * 设置函数类型 - * - * @param funcType 函数类型 - * @return NamedFuncDescriptorBuilder - */ - public NamedFuncDescriptorBuilder setFuncType(FuncType funcType) { - this.funcType = funcType; - return this; - } - - /** - * 设置方言 - * - * @param dialect dialect instance - * @return NamedFuncDescriptorBuilder - */ - public NamedFuncDescriptorBuilder setDialect(Dialect dialect) { - this.dialect = dialect; - return this; - } - - /** - * 设置func rendering - * - * @param rendering FuncRendering - * @return NamedFuncDescriptorBuilder - */ - public NamedFuncDescriptorBuilder setRendering(FuncRendering rendering) { - this.rendering = rendering; - return this; - } - - /** - * 设置func rendering - * - * @param rendering FuncRendering - * @return NamedFuncDescriptorBuilder - */ - public NamedFuncDescriptorBuilder setRendering(Supplier rendering) { - this.rendering = rendering.get(); - return this; - } - - /** - * 构建 FuncDescriptor对象 - * - * @return NamedFuncDescriptor - */ - public NamedFuncDescriptor build() { - return new NamedFuncDescriptor(funcName, signature, funcType, dialect, rendering); - } - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncRendering.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncRendering.java deleted file mode 100644 index fd5512d3..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncRendering.java +++ /dev/null @@ -1,62 +0,0 @@ -package cc.allio.uno.data.orm.dialect.func; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -/** - * func实例转换为SQL功能接口 - * - * @author jiangwei - * @date 2023/1/12 16:38 - * @since 1.1.4 - */ -@FunctionalInterface -public interface FuncRendering { - - /** - * 渲染当前函数为表达式字符串 - * - * @param descriptor func descriptor - * @param arguments 渲染过程中动态参数 - * @return 表达式 - */ - String render(FuncDescriptor descriptor, Object[] arguments); - - - /** - * 根据给定类型查找参数中是否含有,如果有则返回。 - * - * @param type 给定的类型 - * @param 类型 - * @return List - */ - static List getArgument(Object[] arguments, Class type) { - return Arrays.stream(arguments).filter(a -> type.isAssignableFrom(a.getClass())).map(type::cast).collect(Collectors.toList()); - } - - /** - * 根据给定类型查找参数中是否含有,如果有则返回单个实例 - * - * @param type 给定的类型 - * @param 类型 - * @return 实例 - */ - static Optional getSingleArgument(Object[] arguments, Class type) { - if (containsTypeArgument(arguments, type)) { - return Arrays.stream(arguments).filter(a -> type.isAssignableFrom(a.getClass())).map(type::cast).findFirst(); - } - return Optional.empty(); - } - - /** - * 判断是否包含指定类型的参数 - * - * @param type 类型 - * @return true 包含 false 不包含 - */ - static boolean containsTypeArgument(Object[] arguments, Class type) { - return Arrays.stream(arguments).anyMatch(a -> type.isAssignableFrom(a.getClass())); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncType.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncType.java deleted file mode 100644 index bb87f72c..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/FuncType.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.allio.uno.data.orm.dialect.func; - -/** - * 描述Func类型,比如 normal、aggregate... - * - * @author jiangwei - * @date 2023/1/12 15:41 - * @since 1.1.4 - */ -public enum FuncType { - NORMAL, AGGREGATE, WINDOW; -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/NamedFuncDescriptor.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/NamedFuncDescriptor.java deleted file mode 100644 index 27f41c13..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/NamedFuncDescriptor.java +++ /dev/null @@ -1,56 +0,0 @@ -package cc.allio.uno.data.orm.dialect.func; - -import cc.allio.uno.data.orm.dialect.Dialect; -import lombok.Getter; - -import java.util.Optional; - -/** - * 指定函数名称name - * - * @author jiangwei - * @date 2023/1/12 15:37 - * @since 1.1.4 - */ -public class NamedFuncDescriptor implements FuncDescriptor { - - // 函数名称 - private final String funcName; - // 函数类型 - private final FuncType funcType; - // dialect - @Getter - private final Dialect dialect; - private final FuncRendering rendering; - - @Getter - private final String signature; - - protected NamedFuncDescriptor(String funcName, String signature, FuncType funcType, Dialect dialect, FuncRendering rendering) { - this.funcName = funcName; - this.signature = signature; - this.funcType = funcType; - this.dialect = dialect; - this.rendering = rendering; - } - - @Override - public String getFuncName() { - return funcName; - } - - @Override - public Func createFunc() { - return null; - } - - @Override - public FuncType getFuncType() { - return funcType; - } - - @Override - public String render(Object[] arguments) { - return rendering.render(this, Optional.ofNullable(arguments).orElse(new Object[]{})); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/ReuseFuncFactory.java b/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/ReuseFuncFactory.java deleted file mode 100644 index 50741268..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/ReuseFuncFactory.java +++ /dev/null @@ -1,137 +0,0 @@ -package cc.allio.uno.data.orm.dialect.func; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.dialect.Dialect; -import cc.allio.uno.data.orm.sql.Alias; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.word.Distinct; -import cc.allio.uno.data.orm.sql.word.KeyWord; -import cc.allio.uno.data.orm.sql.word.KeyWords; - -import static cc.allio.uno.data.orm.dialect.func.FuncRendering.getSingleArgument; - -/** - * 对于不同数据库而言,即使存在差异,也还有可以复用的部分。当前类把那些可以进行复用的函数进行维护 - * - * @author jiangwei - * @date 2023/1/12 19:06 - * @since 1.1.4 - */ -public class ReuseFuncFactory { - - private ReuseFuncFactory() { - } - - /** - * count func - * - * @param dialect dialect instance - * @return FuncDescriptor instance - * @see mysql - * @see mssql - * @see pgsql - */ - public static FuncDescriptor count(Dialect dialect) { - return dialect.getFuncRegistry() - .namedFuncDescriptorBuilder(Func.COUNT_FUNCTION.getName()) - .setFuncType(FuncType.AGGREGATE) - .setDialect(dialect) - .setSignature("COUNT(expr) [over_clause]") - .setRendering(GeneralAggregateFunctionRendering::new) - .build(); - } - - /** - * min func - * - * @param dialect dialect instance - * @return FuncDescriptor instance - * @see mysql - * @see mssql - * @see pgsql - */ - public static FuncDescriptor min(Dialect dialect) { - return dialect.getFuncRegistry() - .namedFuncDescriptorBuilder(Func.MIN_FUNCTION.getName()) - .setFuncType(FuncType.AGGREGATE) - .setDialect(dialect) - .setSignature("MIN([DISTINCT] expr) [over_clause]") - .setRendering(GeneralAggregateFunctionRendering::new) - .build(); - } - - /** - * max func - * - * @param dialect dialect instance - * @return FuncDescriptor instance - * @see mysql - * @see mssql - * @see pgsql - */ - public static FuncDescriptor max(Dialect dialect) { - return dialect.getFuncRegistry() - .namedFuncDescriptorBuilder(Func.MAX_FUNCTION.getName()) - .setFuncType(FuncType.AGGREGATE) - .setDialect(dialect) - .setSignature("MAX([DISTINCT] expr) [over_clause]") - .setRendering(GeneralAggregateFunctionRendering::new) - .build(); - } - - /** - * avg func - * - * @param dialect dialect instance - * @return FuncDescriptor instance - * @see mysql - * @see mssql - * @see pgsql - */ - public static FuncDescriptor avg(Dialect dialect) { - return dialect.getFuncRegistry() - .namedFuncDescriptorBuilder(Func.AVG_FUNCTION.getName()) - .setFuncType(FuncType.AGGREGATE) - .setDialect(dialect) - .setSignature("AVG([DISTINCT] expr) [over_clause]") - .setRendering(GeneralAggregateFunctionRendering::new) - .build(); - } - - /** - * sum func - * - * @param dialect dialect instance - * @return FuncDescriptor - * @see mysql - * @see mssql - * @see pgsql - */ - public static FuncDescriptor sum(Dialect dialect) { - return dialect.getFuncRegistry() - .namedFuncDescriptorBuilder(Func.SUM_FUNCTION.getName()) - .setFuncType(FuncType.AGGREGATE) - .setDialect(dialect) - .setSignature("AVG([DISTINCT] expr) [over_clause]") - .setRendering(GeneralAggregateFunctionRendering::new) - .build(); - } - - /** - * 通用的AggregateFunction - */ - static class GeneralAggregateFunctionRendering implements FuncRendering { - - @Override - public String render(FuncDescriptor descriptor, Object[] arguments) { - KeyWord keyWord = KeyWords.get(descriptor.getFuncName()); - StringBuilder sql = new StringBuilder(); - sql.append(keyWord.get()).append(StringPool.LEFT_BRACKET); - getSingleArgument(arguments, Distinct.class).ifPresent(distinct -> sql.append(distinct.get()).append(StringPool.SPACE)); - getSingleArgument(arguments, RuntimeColumn.class).ifPresent(column -> sql.append(column.getName())); - sql.append(StringPool.RIGHT_BRACKET); - getSingleArgument(arguments, Alias.class).ifPresent(alias -> sql.append(StringPool.SPACE).append(alias.getAlias())); - return sql.toString(); - } - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/DefaultResultSetHandler.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/DefaultResultSetHandler.java deleted file mode 100644 index 88cdb69d..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/DefaultResultSetHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.allio.uno.data.orm.executor; - -/** - * 不经任何处理 - * - * @author jiangwei - * @date 2023/4/18 13:25 - * @since 1.1.4 - */ -public class DefaultResultSetHandler implements ResultSetHandler { - - @Override - public ResultGroup apply(ResultGroup resultGroup) { - return resultGroup; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/IdMethodReferenceColumn.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/IdMethodReferenceColumn.java deleted file mode 100644 index 4f6c94fa..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/IdMethodReferenceColumn.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.allio.uno.data.orm.executor; - -import cc.allio.uno.data.orm.sql.MethodReferenceColumn; -import cc.allio.uno.data.orm.sql.PojoWrapper; - -/** - * pojo的id方法 - * - * @author jiangwei - * @date 2023/7/11 12:34 - * @since 1.1.4 - */ -public class IdMethodReferenceColumn

    implements MethodReferenceColumn

    { - - private final PojoWrapper

    wrapper; - - public IdMethodReferenceColumn(P pojo) { - this.wrapper = new PojoWrapper<>(pojo); - } - - @Override - public String getColumn() { - return wrapper.findByIdColumn().getSqlName().getName(); - } - - @Override - public Object apply(P p) { - return null; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/MapResultSetHandler.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/MapResultSetHandler.java deleted file mode 100644 index 3fb409f4..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/MapResultSetHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.allio.uno.data.orm.executor; - -import java.util.Map; - -/** - * ResultGroup -> map - * - * @author jiangwei - * @date 2023/4/18 13:24 - * @since 1.1.4 - */ -public class MapResultSetHandler implements ResultSetHandler> { - - @Override - public Map apply(ResultGroup resultGroup) { - return resultGroup.toMap(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultGroup.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultGroup.java deleted file mode 100644 index b96d8c88..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultGroup.java +++ /dev/null @@ -1,117 +0,0 @@ -package cc.allio.uno.data.orm.executor; - -import cc.allio.uno.core.bean.ObjectWrapper; -import cc.allio.uno.core.util.ClassUtils; -import cc.allio.uno.core.util.JsonUtils; -import cc.allio.uno.data.orm.sql.MethodReferenceColumn; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import lombok.Data; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * 结果集。保持顺序一致性 - * - * @author jiangwei - * @date 2023/4/14 18:02 - * @since 1.1.4 - */ -@Data -public class ResultGroup { - - private List resultRows = Lists.newArrayList(); - private Map resultRowMap = Maps.newHashMap(); - - /** - * 添加{@link ResultRow} - * - * @param row row - */ - public void addRow(ResultRow row) { - resultRows.add(row.getIndex(), row); - resultRowMap.put(row.getColumn().format(), row); - } - - /** - * 添加{@link ResultRow}集合 - * - * @param resultRows the resultRows - */ - public void addAllRows(Collection resultRows) { - resultRows.forEach(this::addRow); - } - - /** - * 根据结果集索引 - * - * @param index index - */ - public ResultRow getRow(int index) { - return resultRows.get(index); - } - - /** - * 根据字段名称获取ResultRow - * - * @param columnName 字段名称 - * @return ResultRow - */ - public ResultRow getRow(String columnName) { - return resultRowMap.get(columnName); - } - - /** - * 根据方法索引获取字段名 - * - * @param ref ref - * @return ResultRow - */ - public ResultRow getRow(MethodReferenceColumn ref) { - return getRow(ref.getColumn()); - } - - /** - * 返回实体对象 - * - * @param entity 实体类型 - * @param 实体范型 - * @return T - */ - public T toEntity(Class entity) { - T metadata = ClassUtils.newInstance(entity); - ObjectWrapper wrapper = new ObjectWrapper(metadata); - for (ResultRow resultRow : resultRows) { - Object value = resultRow.getValue(); - if (value != null) { - wrapper.setForce( - resultRow.getColumn().format(), resultRow.getValue()); - } - } - return metadata; - } - - /** - * 返回map数据 - * - * @return map - */ - public Map toMap() { - Map valuesMap = Maps.newHashMap(); - for (Map.Entry entry : resultRowMap.entrySet()) { - valuesMap.put(entry.getKey(), entry.getValue().getValue()); - } - return valuesMap; - } - - /** - * 返回json数据 - * - * @return json 字符串 - */ - public String toJson() { - return JsonUtils.toJson(toMap()); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLColumnDefListResultSetHandler.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLColumnDefListResultSetHandler.java deleted file mode 100644 index f432b6fb..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLColumnDefListResultSetHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.allio.uno.data.orm.executor; - -import cc.allio.uno.core.type.Types; -import cc.allio.uno.data.orm.sql.SQLColumnDef; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.type.DataType; -import cc.allio.uno.data.orm.type.GenericSQLType; -import com.google.common.collect.Lists; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * {@link SQLColumnDef}结果集处理器 - * - * @author jiangwei - * @date 2023/7/4 14:54 - * @since 1.1.4 - */ -public class SQLColumnDefListResultSetHandler implements ListResultSetHandler { - - /** - * 用于保存字段名称 - */ - public static final String ROW_FIELD_NAME = "field"; - - @Override - public List apply(ResultSet resultGroups) { - return Lists.newArrayList(resultGroups) - .stream() - .map(r -> { - ResultRow field = r.getRow(ROW_FIELD_NAME); - return SQLColumnDef.builder() - .sqlName(SQLName.of(Types.toString(field.getValue()), SQLName.PLAIN_FEATURE)) - .dataType(DataType.create(GenericSQLType.getByJdbcCode(field.getJdbcType().getVendorTypeNumber()))) - .build(); - }) - .collect(Collectors.toList()); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandExecutor.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandExecutor.java deleted file mode 100644 index 03797d7d..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandExecutor.java +++ /dev/null @@ -1,904 +0,0 @@ -package cc.allio.uno.data.orm.executor; - -import cc.allio.uno.core.api.Key; -import cc.allio.uno.core.env.Envs; -import cc.allio.uno.core.util.CollectionUtils; -import cc.allio.uno.data.orm.executor.elasticsearch.EsSQLCommandExecutor; -import cc.allio.uno.data.orm.executor.mybatis.MybatisSQLCommandExecutor; -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLDropTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLExistTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.dml.SQLDeleteOperator; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.SQLUpdateOperator; - -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; -import java.util.function.UnaryOperator; -import java.util.stream.Collectors; - -/** - * SQL执行器定义 - * TODO 应该考虑采用拦截器做些特殊的事项(如自动赋值id) - * - * @author jiangwei - * @date 2023/4/14 13:43 - * @since 1.1.4 - */ -public interface SQLCommandExecutor { - - // sql executor - String SQL_EXECUTOR_TYPE_KEY = "allio.uno.data.orm.executor.type"; - ExecutorKey MYBATIS_SQL_COMMAND_EXECUTOR_KEY = () -> "mybatis"; - ExecutorKey ELASTICSEARCH_SQL_COMMAND_EXECUTOR_KEY = () -> "elasticsearch"; - ExecutorKey REDIS_SQL_COMMAND_KEY = () -> "redis"; - ExecutorKey MONGODB_SQL_COMMAND_KEY = () -> "mongodb"; - ExecutorKey INFLUXDB_SQL_COMMAND_KEY = () -> "influxdb"; - ExecutorKey NEO4J_SQL_COMMAND_KEY = () -> "neo4j"; - - interface ExecutorKey extends Key { - @Override - default String getProperties() { - return SQL_EXECUTOR_TYPE_KEY; - } - } - - /** - * 获取系统默认executor key - * - * @return ExecutorKey - */ - static ExecutorKey getSystemExecutorKey() { - String executorKey = Envs.getProperty(SQL_EXECUTOR_TYPE_KEY); - if (MYBATIS_SQL_COMMAND_EXECUTOR_KEY.getKey().equals(executorKey)) { - return MYBATIS_SQL_COMMAND_EXECUTOR_KEY; - } else if (ELASTICSEARCH_SQL_COMMAND_EXECUTOR_KEY.getKey().equals(executorKey)) { - return ELASTICSEARCH_SQL_COMMAND_EXECUTOR_KEY; - } else if (REDIS_SQL_COMMAND_KEY.getKey().equals(executorKey)) { - return REDIS_SQL_COMMAND_KEY; - } else if (MONGODB_SQL_COMMAND_KEY.getKey().equals(executorKey)) { - return MONGODB_SQL_COMMAND_KEY; - } else if (INFLUXDB_SQL_COMMAND_KEY.getKey().equals(executorKey)) { - return INFLUXDB_SQL_COMMAND_KEY; - } else if (NEO4J_SQL_COMMAND_KEY.getKey().equals(executorKey)) { - return NEO4J_SQL_COMMAND_KEY; - } - return MYBATIS_SQL_COMMAND_EXECUTOR_KEY; - } - - /** - * 根据pojo class创建表 - * - * @param pojoClass the pojoClass - * @return true 成功 false 失败 - */ - default

    boolean createTable(Class

    pojoClass) { - PojoWrapper

    pojoWrapper = new PojoWrapper<>(pojoClass); - return createTable(o -> o.from(pojoWrapper.getTable()).columns(pojoWrapper.getSQLColumnDef())); - } - - /** - * 创表 - * - * @param func the func - * @return true 成功 false 失败 - */ - default boolean createTable(UnaryOperator func) { - return createTable(func.apply(getOperatorMetadata().createTable())); - } - - /** - * 创表 - * - * @param createTableOperator SQLCreateTableOperator - * @return true 成功 false 失败 - */ - default boolean createTable(SQLCreateTableOperator createTableOperator) { - return bool(createTableOperator, SQLCommandType.CREATE_TABLE); - } - - /** - * 创表 - * - * @param createTableOperator SQLCreateTableOperator - * @param resultSetHandler resultSetHandler - * @return true 成功 false 失败 - */ - default boolean createTable(SQLCreateTableOperator createTableOperator, ResultSetHandler resultSetHandler) { - return bool(createTableOperator, SQLCommandType.CREATE_TABLE, resultSetHandler); - } - - /** - * 根据pojo class删除表 - * - * @param tableName the tableName - * @return true 成功 false 失败 - */ - default boolean dropTable(String tableName) { - return dropTable(o -> o.from(tableName)); - } - - /** - * 根据pojo class删除表 - * - * @param table the table - * @return true 成功 false 失败 - */ - default boolean dropTable(Table table) { - return dropTable(o -> o.from(table)); - } - - /** - * 根据pojo class删除表 - * - * @param pojoClass the pojoClass - * @return true 成功 false 失败 - */ - default

    boolean dropTable(Class

    pojoClass) { - PojoWrapper

    pojoWrapper = new PojoWrapper<>(pojoClass); - return dropTable(o -> o.from(pojoWrapper.getTable())); - } - - /** - * 删表 - * - * @param func func - * @return true 成功 false 失败 - */ - default boolean dropTable(UnaryOperator func) { - return dropTable(func.apply(getOperatorMetadata().dropTable())); - } - - /** - * 删表 - * - * @param dropTableOperator dropTableOperator - * @return true 成功 false 失败 - */ - default boolean dropTable(SQLDropTableOperator dropTableOperator) { - return bool(dropTableOperator, SQLCommandType.DELETE_TABLE); - } - - /** - * 删表 - * - * @param dropTableOperator dropTableOperator - * @param resultSetHandler resultSetHandler - * @return true 成功 false 失败 - */ - default boolean dropTable(SQLDropTableOperator dropTableOperator, ResultSetHandler resultSetHandler) { - return bool(dropTableOperator, SQLCommandType.DELETE, resultSetHandler); - } - - /** - * 判断表是否存在 - * - * @param tableName the tableName - * @return true 成功 false 失败 - */ - default boolean existTable(String tableName) { - return existTable(o -> o.from(tableName)); - } - - /** - * 判断表是否存在 - * - * @param table the table - * @return true 成功 false 失败 - */ - default boolean existTable(Table table) { - return existTable(o -> o.from(table)); - } - - /** - * 根据pojoClass判断是否存在 - * - * @param pojoClass pojoClass - * @return true 成功 false 失败 - */ - default

    boolean existTable(Class

    pojoClass) { - PojoWrapper

    pojoWrapper = new PojoWrapper<>(pojoClass); - return existTable(o -> o.from(pojoWrapper.getTable())); - } - - /** - * 判断表是否存在 - * - * @param func the func - * @return true 成功 false 失败 - */ - default boolean existTable(UnaryOperator func) { - return existTable(func.apply(getOperatorMetadata().existTable())); - } - - /** - * 判断表是否存在 - * - * @param existTableOperator SQLExistTableOperator - * @return true 成功 false 失败 - */ - default boolean existTable(SQLExistTableOperator existTableOperator) { - return bool(existTableOperator, SQLCommandType.EXIST_TABLE); - } - - /** - * 判断表是否存在 - * - * @param existTableOperator SQLExistTableOperator - * @param resultSetHandler resultSetHandler - * @return true 成功 false 失败 - */ - default boolean existTable(SQLExistTableOperator existTableOperator, ResultSetHandler resultSetHandler) { - return bool(existTableOperator, SQLCommandType.EXIST_TABLE, resultSetHandler); - } - - /** - * 插入数据 - * - * @param pojo pojo - * @return true 成功 false 失败 - */ - default

    boolean insertPojo(P pojo) { - PojoWrapper

    pojoWrapper = new PojoWrapper<>(pojo); - return insert(o -> o.from(pojoWrapper.getTable()).insertPojo(pojoWrapper.getPojoValue())); - } - - /** - * 插入数据(认定为同一个表数据) - * - * @param pojos pojos - * @return true 成功 false 失败 - */ - default

    boolean batchInsertPojos(List

    pojos) { - if (CollectionUtils.isEmpty(pojos)) { - return false; - } - P thePojo = pojos.get(0); - PojoWrapper

    pojoWrapper = new PojoWrapper<>(thePojo); - // values - List

    pojoValues = pojos.stream().map(pojo -> new PojoWrapper<>(pojo).getPojoValue()).collect(Collectors.toList()); - return insert(o -> o.from(pojoWrapper.getTable()).batchInsertPojos(pojoValues)); - } - - /** - * 插入数据 - * - * @param func the func - * @return true 成功 false 失败 - */ - default boolean insert(UnaryOperator func) { - return insert(func.apply(getOperatorMetadata().insert())); - } - - /** - * 插入数据 - * - * @param sqlInsertOperator SQLInsertOperator - * @return true 成功 false 失败 - */ - default boolean insert(SQLInsertOperator sqlInsertOperator) { - return bool(sqlInsertOperator, SQLCommandType.INSERT); - } - - /** - * 插入数据 - * - * @param sqlInsertOperator SQLInsertOperator - * @param resultSetHandler resultSetHandler - * @return true 成功 false 失败 - */ - default boolean insert(SQLInsertOperator sqlInsertOperator, ResultSetHandler resultSetHandler) { - return bool(sqlInsertOperator, SQLCommandType.INSERT, resultSetHandler); - } - - /** - * 更新数据 - * - * @param pojo the pojo - * @return true 成功 false 失败 - */ - default

    boolean updatePojo(P pojo) { - PojoWrapper

    pojoWrapper = new PojoWrapper<>(pojo); - return update(o -> o.from(pojoWrapper.getTable()).updatePojo(pojo)); - } - - /** - * 更新数据 - * - * @param pojo the pojo - * @return true 成功 false 失败 - */ - default

    boolean updatePojoById(P pojo, Object id) { - PojoWrapper

    pojoWrapper = new PojoWrapper<>(pojo); - SQLColumnDef theId = pojoWrapper.findByIdColumn(); - return updatePojoByCondition(pojo, condition -> condition.eq(theId.getSqlName(), id)); - } - - /** - * 更新数据根据条件 - * - * @param pojo the pojo - * @return true 成功 false 失败 - */ - default

    boolean updatePojoByCondition(P pojo, UnaryOperator> condition) { - return update(o -> { - PojoWrapper

    pojoWrapper = new PojoWrapper<>(pojo); - SQLUpdateOperator updateOperator = o.from(pojoWrapper.getTable()).updatePojo(pojo); - condition.apply(updateOperator); - return updateOperator; - }); - } - - /** - * 更新数据 - * - * @param func the func - * @return true 成功 false 失败 - */ - default boolean update(UnaryOperator func) { - return update(func.apply(getOperatorMetadata().update())); - } - - /** - * 更新数据 - * - * @param updateOperator SQLUpdateOperator - * @return true 成功 false 失败 - */ - default boolean update(SQLUpdateOperator updateOperator) { - return bool(updateOperator, SQLCommandType.UPDATE); - } - - /** - * 更新数据 - * - * @param updateOperator SQLUpdateOperator - * @param resultSetHandler resultSetHandler - * @return true 成功 false 失败 - */ - default boolean update(SQLUpdateOperator updateOperator, ResultSetHandler resultSetHandler) { - return bool(updateOperator, SQLCommandType.UPDATE, resultSetHandler); - } - - /** - * 删除数据 - * - * @param func the func - * @return true 成功 false 失败 - */ - default boolean delete(UnaryOperator func) { - return delete(func.apply(getOperatorMetadata().delete())); - } - - /** - * 删除数据 - * - * @param deleteOperator SQLUpdateOperator - * @return true 成功 false 失败 - */ - default boolean delete(SQLDeleteOperator deleteOperator) { - return bool(deleteOperator, SQLCommandType.DELETE); - } - - /** - * 删除数据 - * - * @param deleteOperator SQLUpdateOperator - * @param resultSetHandler resultSetHandler - * @return true 成功 false 失败 - */ - default boolean delete(SQLDeleteOperator deleteOperator, ResultSetHandler resultSetHandler) { - return bool(deleteOperator, SQLCommandType.DELETE, resultSetHandler); - } - - /** - * bool操作,包含创建、更新、删除、插入表、删除表... - * - * @param operator SQLOperator操作 - * @param sqlCommand sql命令 - * @return true 成功 false 失败 - */ - default boolean bool(SQLOperator operator, SQLCommandType sqlCommand) { - return bool(operator, sqlCommand, new BoolResultHandler()); - } - - /** - * bool操作,包含创建、更新、删除、插入表、删除表... - * - * @param operator SQLOperator操作 - * @param sqlCommand sql命令 - * @return true 成功 false 失败 - */ - boolean bool(SQLOperator operator, SQLCommandType sqlCommand, ResultSetHandler resultSetHandler); - - /** - * save or update。根据pojo的id查询是否存在 存在则更新,否则查询 - * - * @param pojo the pojo - * @return true 成功 false 失败 - */ - default

    boolean saveOrUpdate(P pojo) { - PojoWrapper

    pojoWrapper = new PojoWrapper<>(pojo); - SQLColumnDef id = pojoWrapper.findByIdColumn(); - return saveOrUpdate(pojo, f -> f.select(id.getSqlName()).from(pojoWrapper.getTable()).eq(id.getSqlName(), pojoWrapper.findByIdValue())); - } - - /** - * save or update - * - * @param pojo the pojo - * @param func the func - * @return true 成功 false 失败 - */ - default

    boolean saveOrUpdate(P pojo, UnaryOperator func) { - return saveOrUpdate(pojo, func.apply(getOperatorMetadata().query()), new IdMethodReferenceColumn

    (pojo)); - } - - /** - * save or update - * - * @param pojo the pojo - * @param func the func - * @param eqUpdate 用于比较更新字段 - * @return true 成功 false 失败 - */ - default

    boolean saveOrUpdate(P pojo, UnaryOperator func, MethodReferenceColumn

    eqUpdate) { - return saveOrUpdate(pojo, func.apply(getOperatorMetadata().query()), eqUpdate); - } - - /** - * save or update - * - * @param pojo the pojo - * @param dataExist the dataExist - * @param eqUpdate 用于比较更新字段 - * @return true 成功 false 失败 - */ - default

    boolean saveOrUpdate(P pojo, SQLQueryOperator dataExist, MethodReferenceColumn

    eqUpdate) { - PojoWrapper

    pojoWrapper = new PojoWrapper<>(pojo); - return saveOrUpdate( - dataExist, - () -> { - SQLUpdateOperator updateOperator = getOperatorMetadata().update(); - updateOperator.from(pojoWrapper.getTable()); - String column = eqUpdate.getColumn(); - // update for eq - Object eqValue = pojoWrapper.findByColumnValue(column); - if (eqValue != null) { - updateOperator.eq(column, eqValue); - } - // 不调用pojoWrapper.getPojoValue(),原因可能id会被赋值上,违反唯一约束,应该采用拦截器实现 - updateOperator.updatePojo(pojo); - return updateOperator; - }, - () -> { - SQLInsertOperator insertOperator = getOperatorMetadata().insert(); - insertOperator.from(pojoWrapper.getTable()); - insertOperator.insertPojo(pojoWrapper.getPojoValue()); - return insertOperator; - }); - } - - /** - * save or update - * - * @param f1 判断数据是否存在的query操作 - * @param f2 如果数据存在则update - * @param f3 如果数据不存在则insert - * @return true 成功 false 失败 - */ - default boolean saveOrUpdate(UnaryOperator f1, UnaryOperator f2, UnaryOperator f3) { - return saveOrUpdate(f1.apply(getOperatorMetadata().query()), () -> f2.apply(getOperatorMetadata().update()), () -> f3.apply(getOperatorMetadata().insert())); - } - - /** - * save or update - * - * @param dataExist 判断数据是否存在的query操作 - * @param updateOperator 如果数据存在则update - * @param insertOperator 如果数据不存在则insert - * @return true 成功 false 失败 - */ - default boolean saveOrUpdate(SQLQueryOperator dataExist, SQLUpdateOperator updateOperator, SQLInsertOperator insertOperator) { - return saveOrUpdate(dataExist, () -> updateOperator, () -> insertOperator); - } - - /** - * save or update - * 延迟模式 - * - * @param dataExist 判断数据是否存在的query操作 - * @param updateOperator 如果数据存在则update - * @param insertOperator 如果数据不存在则insert - * @return true 成功 false 失败 - */ - default boolean saveOrUpdate(SQLQueryOperator dataExist, Supplier updateOperator, Supplier insertOperator) { - boolean isExist = bool(dataExist, SQLCommandType.SELECT); - if (!isExist) { - return insert(insertOperator.get()); - } - return update(updateOperator.get()); - } - - /** - * 查询一个数据 - * - * @param entityClass entityClass - * @param 实体类型 - * @return 实体 or null - */ - default T queryOneById(Class entityClass, Object id) { - PojoWrapper pojoWrapper = new PojoWrapper<>(entityClass); - return queryOne(o -> o.from(pojoWrapper.getTable()).eq(pojoWrapper.findByIdColumn().getSqlName(), id), entityClass); - } - - /** - * 查询一个数据 - * - * @param func the func - * @param entityClass entityClass - * @param 实体类型 - * @return 实体 or null - */ - default T queryOne(UnaryOperator func, Class entityClass) { - return queryOne(func.apply(getOperatorMetadata().query()), new BeanResultSetHandler<>(entityClass)); - } - - /** - * 查询一个数据 - * - * @param queryOperator queryOperator - * @param entityClass entityClass - * @param 实体类型 - * @return 实体 or null - */ - default T queryOne(SQLQueryOperator queryOperator, Class entityClass) { - return queryOne(queryOperator, new BeanResultSetHandler<>(entityClass)); - } - - /** - * 查询结果Map - * - * @param func the func - * @return map - */ - default Map queryMap(UnaryOperator func) { - return queryMap(func.apply(getOperatorMetadata().query())); - } - - /** - * 查询结果Map - * - * @param queryOperator queryOperator - * @return map - */ - default Map queryMap(SQLQueryOperator queryOperator) { - return queryOne(queryOperator, new MapResultSetHandler()); - } - - /** - * 查询一个结果 - * - * @param func the func - * @return ResultGroup - */ - default ResultGroup queryOne(UnaryOperator func) { - return queryOne(func.apply(getOperatorMetadata().query())); - } - - /** - * 查询一个结果 - * - * @param queryOperator SQLQueryOperator - * @return ResultGroup - */ - default ResultGroup queryOne(SQLQueryOperator queryOperator) { - return queryOne(queryOperator, new DefaultResultSetHandler()); - } - - /** - * 查询一个结果 - * - * @param func the func - * @param 结果集对象 - * @return ResultGroup - */ - default R queryOne(UnaryOperator func, ResultSetHandler resultSetHandler) { - return queryOne(func.apply(getOperatorMetadata().query()), resultSetHandler); - } - - /** - * 查询一个结果 - * - * @param queryOperator SQLQueryOperator - * @param 结果集对象 - * @return ResultGroup - */ - default R queryOne(SQLQueryOperator queryOperator, ResultSetHandler resultSetHandler) { - List resultGroups = queryList(queryOperator); - if (CollectionUtils.isNotEmpty(resultGroups)) { - int size = resultGroups.size(); - if (size == 1) { - return resultSetHandler.apply(resultGroups.get(0)); - } else if (size > 1) { - throw new SQLException("Expected one result (or null) to be returned by queryOne(), but found: " + size); - } else { - return null; - } - } - return null; - } - - /** - * 查询list实体 - * - * @param func the func - * @param entityClass entityClass - * @param 类型 - * @return list - */ - default List queryList(UnaryOperator func, Class entityClass) { - return queryList(func.apply(getOperatorMetadata().query()), entityClass); - } - - /** - * 查询list实体 - * - * @param queryOperator SQLQueryOperator - * @param entityClass entityClass - * @param 类型 - * @return list - */ - default List queryList(SQLQueryOperator queryOperator, Class entityClass) { - return queryList(queryOperator, new ListBeanResultSetHandler<>(entityClass)); - } - - /** - * 查询list-Map - * - * @param func the func - * @return list map - */ - default List> queryListMap(UnaryOperator func) { - return queryListMap(func.apply(getOperatorMetadata().query())); - } - - /** - * 查询list-Map - * - * @param queryOperator SQLQueryOperator - * @return list map - */ - default List> queryListMap(SQLQueryOperator queryOperator) { - return queryList(queryOperator, new ListMapResultHandler()); - } - - /** - * 查询list - * - * @param func the func - * @return List - * @throws SQLException query failed throw - */ - default List queryList(UnaryOperator func) { - return queryList(func.apply(getOperatorMetadata().query())); - } - - /** - * 查询list - * - * @param queryOperator SQLQueryOperator - * @return List - * @throws SQLException query failed throw - */ - default List queryList(SQLQueryOperator queryOperator) { - return queryList(queryOperator, new DefaultListResultSetHandler()); - } - - /** - * 查询list - * - * @param func the func - * @param resultSetHandler 结果集处理器 - * @param 返回结果类型 - * @return List - * @throws SQLException query failed throw - */ - default List queryList(UnaryOperator func, ListResultSetHandler resultSetHandler) { - return queryList(func.apply(getOperatorMetadata().query()), resultSetHandler); - } - - /** - * 查询list - * - * @param queryOperator SQLQueryOperator - * @param resultSetHandler 结果集处理器 - * @param 返回结果类型 - * @return List - * @throws SQLException query failed throw - */ - List queryList(SQLQueryOperator queryOperator, ListResultSetHandler resultSetHandler); - - /** - * 查询分页 - * - * @param page page - * @param func the func - * @param 返回结果类型 - * @return List - * @throws SQLException query failed throw - */ - default IPage queryPage(IPage page, UnaryOperator func, Class entityClass) { - return queryPage(page, func.apply(getOperatorMetadata().query()), entityClass); - } - - /** - * 查询分页 - * - * @param page page - * @param queryOperator SQLQueryOperator - * @param 返回结果类型 - * @return List - * @throws SQLException query failed throw - */ - default IPage queryPage(IPage page, SQLQueryOperator queryOperator, Class entityClass) { - return queryPage(page, queryOperator, new ListBeanResultSetHandler<>(entityClass)); - } - - /** - * 查询分页 - * - * @param page page - * @param func the func - * @return List - * @throws SQLException query failed throw - */ - default IPage> queryPageMap(IPage page, UnaryOperator func) { - return queryPageMap(page, func.apply(getOperatorMetadata().query())); - } - - /** - * 查询分页 - * - * @param page page - * @param queryOperator SQLQueryOperator - * @return List - * @throws SQLException query failed throw - */ - default IPage> queryPageMap(IPage page, SQLQueryOperator queryOperator) { - return queryPage(page, queryOperator, new ListMapResultHandler()); - } - - /** - * 查询分页 - * - * @param page page - * @param func the func - * @return List - * @throws SQLException query failed throw - */ - default IPage queryPage(IPage page, UnaryOperator func) { - return queryPage(page, func.apply(getOperatorMetadata().query())); - } - - /** - * 查询分页 - * - * @param page page - * @param queryOperator SQLQueryOperator - * @return List - * @throws SQLException query failed throw - */ - default IPage queryPage(IPage page, SQLQueryOperator queryOperator) { - return queryPage(page, queryOperator, new DefaultListResultSetHandler()); - } - - /** - * 查询分页 - * - * @param page page - * @param func the func - * @param resultSetHandler 结果集处理器 - * @param 返回结果类型 - * @return List - * @throws SQLException query failed throw - * @see #queryList(SQLQueryOperator, ListResultSetHandler) - */ - default IPage queryPage(IPage page, UnaryOperator func, ListResultSetHandler resultSetHandler) { - return queryPage(page, func.apply(getOperatorMetadata().query()), resultSetHandler); - } - - /** - * 查询分页 - * - * @param page page - * @param queryOperator SQLQueryOperator - * @param resultSetHandler 结果集处理器 - * @param 返回结果类型 - * @return List - * @throws SQLException query failed throw - * @see #queryList(SQLQueryOperator, ListResultSetHandler) - */ - default IPage queryPage(IPage page, SQLQueryOperator queryOperator, ListResultSetHandler resultSetHandler) { - queryOperator.page(page.getCurrent(), page.getSize()); - List r = queryList(queryOperator, resultSetHandler); - Page rPage = new Page<>(page); - rPage.setTotal(r.size()); - rPage.setRecords(r); - return rPage; - } - - /** - * 获取某个表的字段 - * - * @param pojoClass pojoClass - * @return SQLColumnDef - */ - default List showColumns(Class pojoClass) { - PojoWrapper pojoWrapper = new PojoWrapper<>(pojoClass); - return showColumns(pojoWrapper.getTable()); - } - - /** - * 获取某个表的字段 - * - * @param tableName tableName - * @return SQLColumnDef - */ - default List showColumns(String tableName) { - return showColumns(o -> o.from(tableName)); - } - - /** - * 获取某个表的字段 - * - * @param table table - * @return SQLColumnDef - */ - default List showColumns(Table table) { - return showColumns(o -> o.from(table)); - } - - /** - * 获取某个表的字段 - * - * @param func the func - * @return SQLColumnDef - */ - default List showColumns(UnaryOperator func) { - return showColumns(func.apply(getOperatorMetadata().showColumns())); - } - - /** - * 获取某个表的字段 - * - * @param sqlShowColumnsOperator sqlShowColumnsOperator - * @return SQLColumnDef - */ - default List showColumns(SQLShowColumnsOperator sqlShowColumnsOperator) { - return queryList(sqlShowColumnsOperator.toQueryOperator(), new SQLColumnDefListResultSetHandler()); - } - - /** - * 获取执行器key - * - * @return ExecutorKey - */ - ExecutorKey getKey(); - - /** - * 获取SQL操作元数据。获取的将会是默认的值(也可以指定,建议使用默认)比如; - *

  • - *
      {@link MybatisSQLCommandExecutor} -> {@link DruidOperatorMetadata}
    - *
      {@link EsSQLCommandExecutor} -> {@link ElasticSearchOperatorMetadata}
    - *
      ...(待实现)
    - *
  • - * - * @return OperatorMetadata实例 - */ - OperatorMetadata getOperatorMetadata(); -} \ No newline at end of file diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandExecutorFactory.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandExecutorFactory.java deleted file mode 100644 index 33d31b90..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandExecutorFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -package cc.allio.uno.data.orm.executor; - -import cc.allio.uno.core.env.Envs; -import cc.allio.uno.data.orm.executor.elasticsearch.EsSQLCommandExecutor; -import cc.allio.uno.data.orm.executor.influxdb.InfluxDBSQLCommandExecutor; -import cc.allio.uno.data.orm.executor.mangodb.MangoDBSQLCommandExecutor; -import cc.allio.uno.data.orm.executor.mybatis.MybatisSQLCommandExecutor; -import cc.allio.uno.data.orm.executor.neo4j.Neo4jSQLCommandExecutor; -import cc.allio.uno.data.orm.executor.redis.RedisSQLCommandExecutor; -import com.google.common.collect.Maps; - -import java.util.Map; - -/** - * SQL Executor simple Factory - * - * @author jiangwei - * @date 2023/4/16 23:38 - * @since 1.1.4 - */ -public class SQLCommandExecutorFactory { - - private static final Map CACHES = Maps.newHashMap(); - - private SQLCommandExecutorFactory() { - } - - public static T create(SQLCommandExecutor.ExecutorKey executorKey, Object... values) { - if (SQLCommandExecutor.MYBATIS_SQL_COMMAND_EXECUTOR_KEY == executorKey) { - return (T) CACHES.computeIfAbsent(executorKey, k -> new MybatisSQLCommandExecutor(values)); - } else if (SQLCommandExecutor.ELASTICSEARCH_SQL_COMMAND_EXECUTOR_KEY == executorKey) { - return (T) CACHES.computeIfAbsent(executorKey, k -> new EsSQLCommandExecutor(values)); - } else if (SQLCommandExecutor.INFLUXDB_SQL_COMMAND_KEY == executorKey) { - return (T) CACHES.computeIfAbsent(executorKey, k -> new InfluxDBSQLCommandExecutor()); - } else if (SQLCommandExecutor.MONGODB_SQL_COMMAND_KEY == executorKey) { - return (T) CACHES.computeIfAbsent(executorKey, k -> new MangoDBSQLCommandExecutor()); - } else if (SQLCommandExecutor.NEO4J_SQL_COMMAND_KEY == executorKey) { - return (T) CACHES.computeIfAbsent(executorKey, k -> new Neo4jSQLCommandExecutor()); - } else if (SQLCommandExecutor.REDIS_SQL_COMMAND_KEY == executorKey) { - return (T) CACHES.computeIfAbsent(executorKey, k -> new RedisSQLCommandExecutor()); - } - // 默认为mybatis - Envs.setProperty(SQLCommandExecutor.SQL_EXECUTOR_TYPE_KEY, SQLCommandExecutor.MYBATIS_SQL_COMMAND_EXECUTOR_KEY.getKey()); - return (T) new MybatisSQLCommandExecutor(); - } - - /** - * 获取{@link SQLCommandExecutor}实例,默认为{@link MybatisSQLCommandExecutor} - * - * @return SQLExecutor - */ - public static T getSQLExecutor() { - return getSQLExecutor(SQLCommandExecutor.getSystemExecutorKey()); - } - - /** - * 获取{@link SQLCommandExecutor}实例,默认为{@link MybatisSQLCommandExecutor} - * - * @param executorKey 判断使用何种执行器key - * @return SQLExecutor - */ - public static T getSQLExecutor(SQLCommandExecutor.ExecutorKey executorKey) { - return (T) CACHES.get(executorKey); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandType.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandType.java deleted file mode 100644 index c8581c1b..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandType.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.allio.uno.data.orm.executor; - -/** - * SQL执行命令 - * - * @author jiangwei - * @date 2023/4/14 13:49 - * @since 1.1.4 - */ -public enum SQLCommandType { - UNKNOWN, CREATE_TABLE, DELETE_TABLE, EXIST_TABLE, INSERT, UPDATE, DELETE, SELECT, FLUSH -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandTypeExecutor.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandTypeExecutor.java deleted file mode 100644 index 6bd84aec..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/SQLCommandTypeExecutor.java +++ /dev/null @@ -1,23 +0,0 @@ -package cc.allio.uno.data.orm.executor; - -import cc.allio.uno.data.orm.sql.SQLOperator; - -/** - * 定义SQL命令类型执行器 - * - * @author jiangwei - * @date 2023/5/29 20:41 - * @since 1.1.4 - */ -public interface SQLCommandTypeExecutor { - - /** - * 执行类型 - * - * @param operator SQL操作器 - * @param resultSetHandler 结果集处理器 - * @return R - * @throws Throwable 执行发生异常时抛出 - */ - R exec(SQLOperator operator, ResultSetHandler resultSetHandler) throws Throwable; -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/executor.png b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/executor.png deleted file mode 100644 index 3581fe16..00000000 Binary files a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/executor.png and /dev/null differ diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/influxdb/InfluxDBSQLCommandExecutor.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/influxdb/InfluxDBSQLCommandExecutor.java deleted file mode 100644 index b9437636..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/influxdb/InfluxDBSQLCommandExecutor.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.allio.uno.data.orm.executor.influxdb; - -import cc.allio.uno.data.orm.sql.OperatorMetadata; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.executor.ListResultSetHandler; -import cc.allio.uno.data.orm.executor.ResultSetHandler; -import cc.allio.uno.data.orm.executor.SQLCommandType; -import cc.allio.uno.data.orm.executor.SQLCommandExecutor; - -import java.util.List; - -/** - * influx db sql执行器 - * - * @author jiangwei - * @date 2023/4/19 12:09 - * @since 1.1.4 - */ -public class InfluxDBSQLCommandExecutor implements SQLCommandExecutor { - @Override - public boolean bool(SQLOperator operator, SQLCommandType sqlCommand, ResultSetHandler resultSetHandler) { - return false; - } - - @Override - public List queryList(SQLQueryOperator queryOperator, ListResultSetHandler resultSetHandler) { - return null; - } - - @Override - public ExecutorKey getKey() { - return SQLCommandExecutor.INFLUXDB_SQL_COMMAND_KEY; - } - - @Override - public OperatorMetadata getOperatorMetadata() { - return null; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/mangodb/MangoDBSQLCommandExecutor.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/mangodb/MangoDBSQLCommandExecutor.java deleted file mode 100644 index f3ad6ef6..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/mangodb/MangoDBSQLCommandExecutor.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.allio.uno.data.orm.executor.mangodb; - -import cc.allio.uno.data.orm.sql.OperatorMetadata; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.executor.ListResultSetHandler; -import cc.allio.uno.data.orm.executor.ResultSetHandler; -import cc.allio.uno.data.orm.executor.SQLCommandType; -import cc.allio.uno.data.orm.executor.SQLCommandExecutor; - -import java.util.List; - -/** - * mango db sql执行器 - * - * @author jiangwei - * @date 2023/4/19 12:10 - * @since 1.1.4 - */ -public class MangoDBSQLCommandExecutor implements SQLCommandExecutor { - @Override - public boolean bool(SQLOperator operator, SQLCommandType sqlCommand, ResultSetHandler resultSetHandler) { - return false; - } - - @Override - public List queryList(SQLQueryOperator queryOperator, ListResultSetHandler resultSetHandler) { - return null; - } - - @Override - public ExecutorKey getKey() { - return SQLCommandExecutor.MONGODB_SQL_COMMAND_KEY; - } - - @Override - public OperatorMetadata getOperatorMetadata() { - return null; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/neo4j/Neo4jSQLCommandExecutor.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/neo4j/Neo4jSQLCommandExecutor.java deleted file mode 100644 index 20d754e7..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/neo4j/Neo4jSQLCommandExecutor.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.allio.uno.data.orm.executor.neo4j; - -import cc.allio.uno.data.orm.sql.OperatorMetadata; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.executor.ListResultSetHandler; -import cc.allio.uno.data.orm.executor.ResultSetHandler; -import cc.allio.uno.data.orm.executor.SQLCommandType; -import cc.allio.uno.data.orm.executor.SQLCommandExecutor; - -import java.util.List; - -/** - * neo4j sql执行器 - * - * @author jiangwei - * @date 2023/4/19 12:10 - * @since 1.1.4 - */ -public class Neo4jSQLCommandExecutor implements SQLCommandExecutor { - @Override - public boolean bool(SQLOperator operator, SQLCommandType sqlCommand, ResultSetHandler resultSetHandler) { - return false; - } - - @Override - public List queryList(SQLQueryOperator queryOperator, ListResultSetHandler resultSetHandler) { - return null; - } - - @Override - public ExecutorKey getKey() { - return SQLCommandExecutor.NEO4J_SQL_COMMAND_KEY; - } - - @Override - public OperatorMetadata getOperatorMetadata() { - return null; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/redis/RedisSQLCommandExecutor.java b/uno-data/src/main/java/cc/allio/uno/data/orm/executor/redis/RedisSQLCommandExecutor.java deleted file mode 100644 index 2fa368d9..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/redis/RedisSQLCommandExecutor.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.allio.uno.data.orm.executor.redis; - -import cc.allio.uno.data.orm.sql.OperatorMetadata; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.executor.ListResultSetHandler; -import cc.allio.uno.data.orm.executor.ResultSetHandler; -import cc.allio.uno.data.orm.executor.SQLCommandType; -import cc.allio.uno.data.orm.executor.SQLCommandExecutor; - -import java.util.List; - -/** - * redis sql执行器 - * - * @author jiangwei - * @date 2023/4/19 12:11 - * @since 1.1.4 - */ -public class RedisSQLCommandExecutor implements SQLCommandExecutor { - @Override - public boolean bool(SQLOperator operator, SQLCommandType sqlCommand, ResultSetHandler resultSetHandler) { - return false; - } - - @Override - public List queryList(SQLQueryOperator queryOperator, ListResultSetHandler resultSetHandler) { - return null; - } - - @Override - public ExecutorKey getKey() { - return SQLCommandExecutor.REDIS_SQL_COMMAND_KEY; - } - - @Override - public OperatorMetadata getOperatorMetadata() { - return null; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/UnoJpaAutoConfiguration.java b/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/UnoJpaAutoConfiguration.java deleted file mode 100644 index 846facd3..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/UnoJpaAutoConfiguration.java +++ /dev/null @@ -1,9 +0,0 @@ -package cc.allio.uno.data.orm.jpa; - -import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; - -@Configuration -@EnableJpaAuditing -public class UnoJpaAutoConfiguration { -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/id/JpaIdGenerator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/id/JpaIdGenerator.java deleted file mode 100644 index 7b693d71..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/id/JpaIdGenerator.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.allio.uno.data.orm.jpa.id; - -import cc.allio.uno.core.util.id.IdGenerator; -import cc.allio.uno.data.orm.jpa.model.BaseEntity; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.id.IdentifierGenerator; - -import java.io.Serializable; - -/** - * JPA ID生成器 - * - * @author jiangwei - * @date 2022/12/27 10:52 - * @see BaseEntity - * @since 1.1.4 - */ -public class JpaIdGenerator implements IdentifierGenerator { - - @Override - public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException { - return IdGenerator.defaultGenerator().getNextId(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/model/BaseEntity.java b/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/model/BaseEntity.java deleted file mode 100644 index f04a9b09..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/model/BaseEntity.java +++ /dev/null @@ -1,49 +0,0 @@ -package cc.allio.uno.data.orm.jpa.model; - -import cc.allio.uno.core.util.DateUtil; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; -import jakarta.persistence.*; -import lombok.*; -import org.hibernate.annotations.GenericGenerator; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.domain.Persistable; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import org.springframework.format.annotation.DateTimeFormat; - -import java.io.Serializable; -import java.util.Date; - -@Getter -@Setter -@ToString -@RequiredArgsConstructor -@MappedSuperclass -@EntityListeners(AuditingEntityListener.class) -public abstract class BaseEntity implements Serializable, Persistable { - - /** - * 主键id - */ - @Id - @GenericGenerator(name = "snowflake", strategy = "cc.allio.uno.data.jpa.id.JpaIdGenerator") - @GeneratedValue(generator = "snowflake") - @JsonSerialize(using = ToStringSerializer.class) - @Column(length = 64) - @org.springframework.data.annotation.Id - private Long id; - - /** - * 更新时间 - */ - @DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME) - @JsonFormat(pattern = DateUtil.PATTERN_DATETIME) - @LastModifiedDate - private Date updateTime; - - @Override - public boolean isNew() { - return getId() != null && getId() > 0; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/repository/JpaRepositoryImpl.java b/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/repository/JpaRepositoryImpl.java deleted file mode 100644 index bce4dc37..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/repository/JpaRepositoryImpl.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.allio.uno.data.orm.jpa.repository; - -import jakarta.persistence.EntityManager; -import org.springframework.data.jpa.repository.support.JpaEntityInformation; -import org.springframework.data.jpa.repository.support.SimpleJpaRepository; - -/** - * JPA Repository - * - * @author jiangwei - * @date 2022/12/27 14:14 - * @since 1.1.4 - */ -public abstract class JpaRepositoryImpl extends SimpleJpaRepository { - - protected JpaRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) { - super(entityInformation, entityManager); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/repository/ReactiveJpaRepositoryImpl.java b/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/repository/ReactiveJpaRepositoryImpl.java deleted file mode 100644 index 46f15dcf..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/jpa/repository/ReactiveJpaRepositoryImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -package cc.allio.uno.data.orm.jpa.repository; - -import org.springframework.data.r2dbc.convert.R2dbcConverter; -import org.springframework.data.r2dbc.core.R2dbcEntityOperations; -import org.springframework.data.r2dbc.repository.support.SimpleR2dbcRepository; -import org.springframework.data.relational.repository.query.RelationalEntityInformation; - -import java.io.Serializable; - -/** - * Reactive JPA Repository - * - * @author jiangwei - * @date 2022/12/27 14:11 - * @since 1.1.4 - */ -public abstract class ReactiveJpaRepositoryImpl extends SimpleR2dbcRepository { - - protected ReactiveJpaRepositoryImpl(RelationalEntityInformation entity, R2dbcEntityOperations entityOperations, R2dbcConverter converter) { - super(entity, entityOperations, converter); - } - - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Alias.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Alias.java deleted file mode 100644 index 8a6e47fc..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Alias.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.core.StringPool; -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * SQL alias - *
      - *
    • select filed_name as 'alias'
    • - *
    • count(field_name) 'alias'
    • - *
    • from table_name 'alias'
    • - *
    • etc..
    • - *
    - * - * @author jiangwei - * @date 2023/1/12 17:45 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -@AllArgsConstructor -public class Alias { - - @Getter - private final String alias; - - /** - * 返回带'的别名 - * - * @return 'alias' - */ - public String toQuoteAlias() { - return StringPool.SINGLE_QUOTE + alias + StringPool.SINGLE_QUOTE; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ColumnGroup.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ColumnGroup.java deleted file mode 100644 index b04ba4f6..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ColumnGroup.java +++ /dev/null @@ -1,24 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import java.util.LinkedHashSet; - -/** - * 字段{@link RuntimeColumn}组存储 - * - * @author jiangwei - * @date 2023/1/6 09:12 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public class ColumnGroup extends LinkedHashSet { - - /** - * 返回下一个{@link RuntimeColumn}实例 - * - * @return RuntimeColumn - */ - public RuntimeColumn next() { - return iterator().next(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ColumnStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ColumnStatement.java deleted file mode 100644 index ff2f36be..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ColumnStatement.java +++ /dev/null @@ -1,23 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import java.util.Collection; - -/** - * 包含Column的语句 - * - * @author jiangwei - * @date 2023/1/9 15:45 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface ColumnStatement> extends Statement { - - /** - * 获取当前语句字段实例列表。 - * - * @return Column列表 - * @see RuntimeColumn - */ - Collection getColumns(); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/DruidOperatorMetadata.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/DruidOperatorMetadata.java deleted file mode 100644 index e0f4b6a4..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/DruidOperatorMetadata.java +++ /dev/null @@ -1,74 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLDropTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLExistTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.ddl.druid.DruidSQLCreateOperator; -import cc.allio.uno.data.orm.sql.ddl.druid.DruidSQLDropTableOperator; -import cc.allio.uno.data.orm.sql.ddl.druid.DruidSQLExistTableOperator; -import cc.allio.uno.data.orm.sql.ddl.druid.DruidSQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.dml.SQLDeleteOperator; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.SQLUpdateOperator; -import cc.allio.uno.data.orm.sql.dml.druid.DruidSQLDeleteQueryOperator; -import cc.allio.uno.data.orm.sql.dml.druid.DruidSQLInsertOperator; -import cc.allio.uno.data.orm.sql.dml.druid.DruidSQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.druid.DruidSQLUpdateOperator; -import cc.allio.uno.data.orm.type.DBType; - -/** - * Druid Operator Metadata - * - * @author jiangwei - * @date 2023/4/13 18:55 - * @since 1.1.4 - */ -public class DruidOperatorMetadata implements OperatorMetadata { - - @Override - public SQLQueryOperator query(DBType dbType) { - return new DruidSQLQueryOperator(dbType); - } - - @Override - public SQLInsertOperator insert(DBType dbType) { - return new DruidSQLInsertOperator(dbType); - } - - @Override - public SQLUpdateOperator update(DBType dbType) { - return new DruidSQLUpdateOperator(dbType); - } - - @Override - public SQLDeleteOperator delete(DBType dbType) { - return new DruidSQLDeleteQueryOperator(dbType); - } - - @Override - public SQLCreateTableOperator createTable(DBType dbType) { - return new DruidSQLCreateOperator(dbType); - } - - @Override - public SQLDropTableOperator dropTable(DBType dbType) { - return new DruidSQLDropTableOperator(dbType); - } - - @Override - public SQLExistTableOperator existTable(DBType dbType) { - return new DruidSQLExistTableOperator(dbType); - } - - @Override - public SQLShowColumnsOperator showColumns(DBType dbType) { - return new DruidSQLShowColumnsOperator(dbType); - } - - @Override - public OperatorMetadataKey getKey() { - return DRUID_OPERATOR_KEY; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ElasticSearchOperatorMetadata.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ElasticSearchOperatorMetadata.java deleted file mode 100644 index f7a8c1ce..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ElasticSearchOperatorMetadata.java +++ /dev/null @@ -1,73 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLDropTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLExistTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.ddl.elasticsearch.ElasticSearchCreateIndexOperator; -import cc.allio.uno.data.orm.sql.ddl.elasticsearch.ElasticSearchDropIndexOperator; -import cc.allio.uno.data.orm.sql.ddl.elasticsearch.ElasticSearchExistIndexOperator; -import cc.allio.uno.data.orm.sql.ddl.elasticsearch.ElasticSearchShowColumnsOperator; -import cc.allio.uno.data.orm.sql.dml.SQLDeleteOperator; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.SQLUpdateOperator; -import cc.allio.uno.data.orm.sql.dml.elasticsearch.ElasticSearchDeleteOperator; -import cc.allio.uno.data.orm.sql.dml.elasticsearch.ElasticSearchInsertOperator; -import cc.allio.uno.data.orm.sql.dml.elasticsearch.ElasticSearchQueryOperator; -import cc.allio.uno.data.orm.sql.dml.elasticsearch.ElasticSearchUpdateOperator; -import cc.allio.uno.data.orm.type.DBType; - -/** - * elasticsearch实现 - * - * @author jiangwei - * @date 2023/5/28 15:32 - * @since 1.1.4 - */ -public class ElasticSearchOperatorMetadata implements OperatorMetadata { - @Override - public SQLQueryOperator query(DBType dbType) { - return new ElasticSearchQueryOperator(); - } - - @Override - public SQLInsertOperator insert(DBType dbType) { - return new ElasticSearchInsertOperator(); - } - - @Override - public SQLUpdateOperator update(DBType dbType) { - return new ElasticSearchUpdateOperator(); - } - - @Override - public SQLDeleteOperator delete(DBType dbType) { - return new ElasticSearchDeleteOperator(); - } - - @Override - public SQLCreateTableOperator createTable(DBType dbType) { - return new ElasticSearchCreateIndexOperator(); - } - - @Override - public SQLDropTableOperator dropTable(DBType dbType) { - return new ElasticSearchDropIndexOperator(); - } - - @Override - public SQLExistTableOperator existTable(DBType dbType) { - return new ElasticSearchExistIndexOperator(); - } - - @Override - public SQLShowColumnsOperator showColumns(DBType dbType) { - return new ElasticSearchShowColumnsOperator(); - } - - @Override - public OperatorMetadataKey getKey() { - return ELASTIC_SEARCH_KEY; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/From.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/From.java deleted file mode 100644 index ac7323f7..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/From.java +++ /dev/null @@ -1,39 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -/** - * SQL FROM语句 - * - * @author jiangwei - * @date 2023/1/6 18:02 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface From> extends Statement { - - /** - * 给定被注解{@link javax.persistence.Table}标识的实体,从其中获取表名称 - * - * @param tableEntity 实体 - * @return FROM - */ - T from(Class tableEntity) throws SQLException; - - /** - * FROM table - * - * @param table table名称 - * @return FROM - */ - T from(String table) throws SQLException; - - /** - * FROM table - * - * @param table table名称 - * @param alias alias别名 - * @return FROM - */ - T from(String table, String alias); - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/FromStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/FromStatement.java deleted file mode 100644 index c8fe274a..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/FromStatement.java +++ /dev/null @@ -1,85 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.core.util.ClassUtils; -import cc.allio.uno.core.util.StringUtils; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionContext; -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionStatement; -import cc.allio.uno.data.orm.sql.dml.local.expression.FromExpression; - -import java.util.Collection; - -/** - * from statement contains - *

    - * from xxx - *

    - *

    - * left join xxx - *

    - * - * @author jiangwei - * @date 2023/1/9 18:44 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public class FromStatement extends ExpressionStatement implements From { - - public FromStatement(ExpressionContext expressionContext) { - super(expressionContext); - } - - @Override - public FromStatement from(Class tableEntity) throws SQLException { - - jakarta.persistence.Table table = ClassUtils.getAnnotation(tableEntity, jakarta.persistence.Table.class); - if (table == null) { - throw new SQLException("Specifies @Table annotation for entity"); - } - String tableName = table.name(); - if (StringUtils.isBlank(tableName)) { - tableName = tableEntity.getSimpleName(); - } - FromExpression fromExpression = new FromExpression(Table.of(StringUtils.camelToUnderline(tableName)), expressionContext); - lazyOfferOne(fromExpression, null); - return self(); - } - - @Override - public FromStatement from(String table) throws SQLException { - FromExpression fromExpression = new FromExpression(Table.of(StringUtils.camelToUnderline(table)), expressionContext); - lazyOfferOne(fromExpression, null); - return self(); - } - - @Override - public FromStatement from(String table, String alias) { - return null; - } - - @Override - public String getSQL() throws SQLException { - return expressionGroup.getSQL(); - } - - @Override - protected String getStatementSyntax() { - return FROM; - } - - @Override - public Collection getExpressions() { - return expressionGroup.getExpression(); - } - - @Override - public void syntaxCheck() throws SQLException { - // TODO document why this method is empty - } - - @Override - public int order() { - return FROM_ORDER; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/JoinTypeAdapter.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/JoinTypeAdapter.java deleted file mode 100644 index 30f18097..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/JoinTypeAdapter.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.data.orm.SQLAdapter; - -/** - * join type adapter - * - * @author jiangwei - * @date 2023/4/13 13:23 - * @since 1.1.4 - */ -public interface JoinTypeAdapter extends SQLAdapter { -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/LocalOperatorMetadata.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/LocalOperatorMetadata.java deleted file mode 100644 index 427f4e77..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/LocalOperatorMetadata.java +++ /dev/null @@ -1,65 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLDropTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLExistTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.dml.SQLDeleteOperator; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.SQLUpdateOperator; -import cc.allio.uno.data.orm.type.DBType; - -/** - * local - * - * @author jiangwei - * @date 2023/4/16 13:07 - * @since 1.1.4 - */ -public class LocalOperatorMetadata implements OperatorMetadata { - @Override - public SQLQueryOperator query(DBType dbType) { - return null; - } - - @Override - public SQLInsertOperator insert(DBType dbType) { - return null; - } - - @Override - public SQLUpdateOperator update(DBType dbType) { - return null; - } - - @Override - public SQLDeleteOperator delete(DBType dbType) { - return null; - } - - @Override - public SQLCreateTableOperator createTable(DBType dbType) { - return null; - } - - @Override - public SQLDropTableOperator dropTable(DBType dbType) { - return null; - } - - @Override - public SQLExistTableOperator existTable(DBType dbType) { - return null; - } - - @Override - public SQLShowColumnsOperator showColumns(DBType dbType) { - return null; - } - - @Override - public OperatorMetadataKey getKey() { - return DRUID_OPERATOR_KEY; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/MethodReferenceColumn.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/MethodReferenceColumn.java deleted file mode 100644 index b0d28192..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/MethodReferenceColumn.java +++ /dev/null @@ -1,27 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.core.function.SerializedLambda; -import cc.allio.uno.core.function.StaticMethodReference; - -/** - * 可以通过静态方法引用来获取实体(需要实例实现{@link java.io.Serializable})的字段名称: - *
    - *     select(User::getName).eq(User::getAge, 2)...
    - * 
    - * - * @author jiangwei - * @date 2023/1/5 15:36 - * @since 1.1.4 - */ -public interface MethodReferenceColumn extends StaticMethodReference { - - /** - * 获取Column名称 - * - * @return Column名称 - * @throws java.io.NotSerializableException 当实体没有实现{@link java.io.Serializable}时抛出 - */ - default String getColumn() { - return SerializedLambda.of(this).getFieldName(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/OperatorMetadata.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/OperatorMetadata.java deleted file mode 100644 index 52e77b80..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/OperatorMetadata.java +++ /dev/null @@ -1,219 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.core.api.Key; -import cc.allio.uno.core.env.Envs; -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLDropTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLExistTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.dml.SQLDeleteOperator; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.SQLUpdateOperator; -import cc.allio.uno.data.orm.type.DBType; -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 操作管理接口 - * - * @author jiangwei - * @date 2023/4/13 18:52 - * @see SQLOperator - * @see SQLOperatorFactory - * @see DruidOperatorMetadata - * @see LocalOperatorMetadata - * @see ShardingSphereOperatorMetadata - * @since 1.1.4 - */ -public interface OperatorMetadata { - - String OPERATOR_METADATA_KEY = "allio.uno.data.orm.sql.operator"; - // 操作实现类型 - OperatorMetadataKey DRUID_OPERATOR_KEY = new OperatorMetadataKey("druid"); - OperatorMetadataKey LOCAL_OPERATOR_KEY = new OperatorMetadataKey("local"); - OperatorMetadataKey SHARDING_SPHERE_KEY = new OperatorMetadataKey("sharding-sphere"); - OperatorMetadataKey ELASTIC_SEARCH_KEY = new OperatorMetadataKey("elasticsearch"); - - @Getter - @AllArgsConstructor - class OperatorMetadataKey implements Key { - - private final String key; - - @Override - public String getProperties() { - return OPERATOR_METADATA_KEY; - } - } - - /** - * 获取系统配置下的operator key - * - * @return operator key or default DRUID_OPERATOR_KEY - * @see #DRUID_OPERATOR_KEY - * @see #LOCAL_OPERATOR_KEY - * @see #SHARDING_SPHERE_KEY - * @see #ELASTIC_SEARCH_KEY - */ - static OperatorMetadataKey getSystemOperatorKey() { - String operatorKey = Envs.getProperty(OPERATOR_METADATA_KEY); - if (DRUID_OPERATOR_KEY.getKey().equals(operatorKey)) { - return DRUID_OPERATOR_KEY; - } else if (LOCAL_OPERATOR_KEY.getKey().equals(operatorKey)) { - return LOCAL_OPERATOR_KEY; - } else if (SHARDING_SPHERE_KEY.getKey().equals(operatorKey)) { - return SHARDING_SPHERE_KEY; - } else if (ELASTIC_SEARCH_KEY.getKey().equals(operatorKey)) { - return ELASTIC_SEARCH_KEY; - } - return DRUID_OPERATOR_KEY; - } - - // ======================== DML ======================== - - /** - * 获取查询操作 - * - * @return QueryOperator - */ - default SQLQueryOperator query() { - return query(DBType.getSystemDbType()); - } - - /** - * 获取查询操作 - * - * @param dbType dbType - * @return QueryOperator - */ - SQLQueryOperator query(DBType dbType); - - /** - * 获取insert操作 - * - * @return InsertOperator - */ - default SQLInsertOperator insert() { - return insert(DBType.getSystemDbType()); - } - - /** - * 获取insert操作 - * - * @param dbType dbType - * @return InsertOperator - */ - SQLInsertOperator insert(DBType dbType); - - /** - * 获取update操作 - * - * @return SQLUpdateOperator - */ - default SQLUpdateOperator update() { - return update(DBType.getSystemDbType()); - } - - /** - * 获取update操作 - * - * @param dbType dbType - * @return SQLUpdateOperator - */ - SQLUpdateOperator update(DBType dbType); - - - /** - * 获取delete操作 - * - * @return SQLDeleteOperator - */ - default SQLDeleteOperator delete() { - return delete(DBType.getSystemDbType()); - } - - /** - * 获取delete操作 - * - * @return SQLDeleteOperator - */ - SQLDeleteOperator delete(DBType dbType); - - // ======================== DDL ======================== - - /** - * create table操作 - * - * @return SQLCreateTableOperator - */ - default SQLCreateTableOperator createTable() { - return createTable(DBType.getSystemDbType()); - } - - /** - * create table操作 - * - * @param dbType dbType - * @return SQLCreateTableOperator - */ - SQLCreateTableOperator createTable(DBType dbType); - - /** - * drop table - * - * @return SQLDropTableOperator - */ - default SQLDropTableOperator dropTable() { - return dropTable(DBType.getSystemDbType()); - } - - /** - * drop table - * - * @param dbType dbType - * @return SQLDropTableOperator - */ - SQLDropTableOperator dropTable(DBType dbType); - - /** - * exist table - * - * @return SQLExistTableOperator - */ - default SQLExistTableOperator existTable() { - return existTable(DBType.getSystemDbType()); - } - - /** - * exist table - * - * @param dbType dbType - * @return SQLExistTableOperator - */ - SQLExistTableOperator existTable(DBType dbType); - - /** - * show columns for table - * - * @return SQLShowColumnsOperator - */ - default SQLShowColumnsOperator showColumns() { - return showColumns(DBType.getSystemDbType()); - } - - /** - * show columns for table - * - * @param dbType dbType - * @return SQLShowColumnsOperator - */ - SQLShowColumnsOperator showColumns(DBType dbType); - - /** - * 获取 OperatorMetadata key - * - * @return OperatorMetadataKey - */ - OperatorMetadataKey getKey(); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/PlainColumn.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/PlainColumn.java deleted file mode 100644 index ed857357..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/PlainColumn.java +++ /dev/null @@ -1,17 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -/** - * PLAIN_FEATURE column - * - * @author jiangwei - * @date 2023/1/6 11:31 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public class PlainColumn extends RuntimeColumn { - - public PlainColumn(String name, Object[] value, Condition condition) { - super(name, value, condition); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/PojoWrapper.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/PojoWrapper.java deleted file mode 100644 index 25b39f61..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/PojoWrapper.java +++ /dev/null @@ -1,204 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.bean.ObjectWrapper; -import cc.allio.uno.core.type.Types; -import cc.allio.uno.core.util.ReflectUtils; -import cc.allio.uno.core.util.StringUtils; -import cc.allio.uno.core.util.id.IdGenerator; -import cc.allio.uno.core.util.template.ExpressionTemplate; -import cc.allio.uno.core.util.template.Tokenizer; -import cc.allio.uno.data.orm.type.JavaType; -import cc.allio.uno.data.orm.type.StringJavaType; -import cc.allio.uno.data.orm.type.TypeRegistry; -import jakarta.persistence.Id; -import org.springframework.core.annotation.AnnotationUtils; - -import java.lang.reflect.Field; -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; - -/** - * 定义Pojo与SQL相关的操作 - * 注:pojo的字段驼峰 - * - * @author jiangwei - * @date 2023/7/4 17:14 - * @since 1.1.4 - */ -public class PojoWrapper extends ObjectWrapper { - - private final T pojo; - private final Class pojoClass; - private final List pojoFields; - private final List columnDefs; - private static final ExpressionTemplate DOLLAR_TEMPLATE = ExpressionTemplate.createTemplate(Tokenizer.DOLLAR_BRACE); - - /** - * 常量字段 - */ - private static final String CREATE_TIME = "createTime"; - private static final FieldSetValueStrategy CREATE_TIME_STRATEGY = (p, f, t) -> p.setForce(f, new Date()); - private static final String UPDATE_TIME = "updateTime"; - private static final FieldSetValueStrategy UPDATE_TIME_STRATEGY = (p, f, t) -> p.setForce(f, new Date()); - private static final String IS_DELETED = "isDeleted"; - private static final FieldSetValueStrategy IS_DELETED_STRATEGY = (p, f, t) -> p.setForce(f, 0); - - public PojoWrapper(T pojo) { - super(pojo); - checkPojo(pojo); - this.pojo = pojo; - this.pojoClass = pojo.getClass(); - this.pojoFields = ReflectUtils.getAllField(pojoClass); - this.columnDefs = getSQLColumnDef(); - } - - public PojoWrapper(Class pojoClass) { - super(pojoClass); - this.pojo = null; - this.pojoClass = pojoClass; - this.pojoFields = ReflectUtils.getAllField(pojoClass); - this.columnDefs = getSQLColumnDef(); - } - - private void checkPojo(Object maybePojo) { - if (maybePojo == null) { - throw new IllegalArgumentException("pojo is null"); - } - if (!Types.isBean(maybePojo.getClass())) { - throw new IllegalArgumentException(String.format("given pojo is fake, it is %s", maybePojo.getClass())); - } - } - - /** - * 获取被{@link Id}注释的字段 - * - * @return SQLColumnDef - */ - public SQLColumnDef findByIdColumn() { - return columnDefs.stream() - .filter(SQLColumnDef::isPk) - .findFirst() - .orElseThrow(() -> new SQLException(String.format("the class %s not found id", pojoClass))); - } - - /** - * 获取被{@link Id}注释的字段的值 - */ - public Object findByIdValue() { - SQLColumnDef id = findByIdColumn(); - return getForce(id.getSqlName().format()); - } - - /** - * 根据column名称获取对应的数据 - * - * @param column the column(需要驼峰) - * @return the value - */ - public Object findByColumnValue(String column) { - return getForce(column); - } - - /** - * 获取该Pojo对象的表名 - * - * @return Table instance - */ - public Table getTable() { - // 取jpa注解 - jakarta.persistence.Table table = AnnotationUtils.findAnnotation(pojoClass, jakarta.persistence.Table.class); - String indexName = StringPool.EMPTY; - if (table != null) { - indexName = table.name(); - } - if (StringUtils.isEmpty(indexName)) { - // 取类名并转换为下划线命名 - indexName = SQLName.of(pojoClass.getSimpleName(), SQLName.UNDERLINE_FEATURE).format(); - } - if (pojo != null) { - indexName = DOLLAR_TEMPLATE.parseTemplate(indexName, findAllValuesForce()); - } - return Table.of(indexName); - } - - /** - * 获取该pojo字段的解析的sql字段 - */ - public List getSQLColumnDef() { - return pojoFields.stream() - .map(SQLColumnDef::of) - .toList(); - } - - /** - * 此方法返回经过策略调整后的值。包含以下: - *
      - *
    • {@link Id}的赋值
    • - *
    • {@link #CREATE_TIME}、{@link #UPDATE_TIME}、{@link #IS_DELETED}赋值
    • - *
    - */ - public T getPojoValue() { - for (SQLColumnDef columnDef : columnDefs) { - JavaType javaType; - try { - int jdbcType = columnDef.getDataType().getSqlType().getJdbcType(); - javaType = TypeRegistry.getInstance().findJavaType(jdbcType); - } catch (Throwable ex) { - // ignore - javaType = new StringJavaType(); - } - // 主键 - if (columnDef.isPk()) { - new IdStrategy().setValue(this, columnDef.getSqlName().format(SQLName.PLAIN_FEATURE), javaType.getJavaType()); - } - // 设置默认值 - if (CREATE_TIME.equals(columnDef.getSqlName().format(SQLName.PLAIN_FEATURE))) { - CREATE_TIME_STRATEGY.setValue(this, CREATE_TIME, javaType.getJavaType()); - } - if (UPDATE_TIME.equals(columnDef.getSqlName().format(SQLName.PLAIN_FEATURE))) { - UPDATE_TIME_STRATEGY.setValue(this, UPDATE_TIME, javaType.getJavaType()); - } - if (IS_DELETED.equals(columnDef.getSqlName().format(SQLName.PLAIN_FEATURE))) { - IS_DELETED_STRATEGY.setValue(this, IS_DELETED, javaType.getJavaType()); - } - } - return pojo; - } - - /** - * 字段设置值策略 - */ - interface FieldSetValueStrategy { - - /** - * 设置值 - * - * @param pojoWrapper the pojoWrapper - * @param fieldName - * @param fieldType the field - */ - void setValue(PojoWrapper pojoWrapper, String fieldName, Class fieldType); - } - - /** - * id值插入策略,当字段存在{@link Id}。如果值不为空则设置{@link IdGenerator} - */ - static class IdStrategy implements FieldSetValueStrategy { - - @Override - public void setValue(PojoWrapper pojoWrapper, String fieldName, Class fieldType) { - Object r = pojoWrapper.getForce(fieldType.getName()); - if (r == null) { - if (Types.isLong(fieldType)) { - Long nextId = IdGenerator.defaultGenerator().getNextId(); - pojoWrapper.setForce(fieldName, nextId); - } else if (Types.isString(fieldType)) { - String nextIdAsString = IdGenerator.defaultGenerator().getNextIdAsString(); - pojoWrapper.setForce(fieldType.getName(), nextIdAsString); - } - } - } - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/RuntimeColumn.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/RuntimeColumn.java deleted file mode 100644 index daaf9da3..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/RuntimeColumn.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * SQL构建过程中column - * - * @author jiangwei - * @date 2023/1/5 10:46 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Data -@EqualsAndHashCode(of = {"name", "value"}) -@AllArgsConstructor -@Deprecated -public abstract class RuntimeColumn { - - /** - * 字段名称 - */ - private final String name; - - /** - * 当前字段包含的值 - */ - private final Object[] value; - - /** - * 字段所属于的条件 - */ - private final Condition condition; - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLAssociation.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLAssociation.java deleted file mode 100644 index 6b25d719..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLAssociation.java +++ /dev/null @@ -1,24 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -/** - * 定义SQL相关联的集联操作 - * - * @author jiangwei - * @date 2022/9/30 13:35 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface SQLAssociation { - - /** - * 提供SQL集联操作 - * - * @param statement泛型对象 - * @param statement statement对象 - * @return statement对象 - */ - default > T then(T statement) { - return statement; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLColumnDef.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLColumnDef.java deleted file mode 100644 index fb67de0f..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLColumnDef.java +++ /dev/null @@ -1,111 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.core.util.CollectionUtils; -import cc.allio.uno.core.util.StringUtils; -import cc.allio.uno.data.orm.type.DataType; -import cc.allio.uno.data.orm.type.GenericSQLType; -import cc.allio.uno.data.orm.type.JdbcType; -import cc.allio.uno.data.orm.type.TypeRegistry; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.google.common.collect.Lists; -import jakarta.persistence.Column; -import jakarta.persistence.Id; -import lombok.Builder; -import lombok.Data; - -import java.lang.reflect.Field; -import java.util.Collection; - -/** - * SQL字段定义 - * - * @author jiangwei - * @date 2023/4/12 19:35 - * @since 1.1.4 - */ -@Data -@Builder -public class SQLColumnDef { - // 字段名称 - private SQLName sqlName; - // 字段注释 - private String comment; - // 数据类型 - private DataType dataType; - // 是否为主键 - private boolean isPk; - // 是否为外键 - private boolean isFk; - // 是否不为null - private boolean isNonNull; - // 是否为null - private boolean isNull; - // 是否唯一 - private boolean isUnique; - - private static final String ID = "id"; - - /** - * 根据java{@link Field}实例创建{@link SQLColumnDef}实例 - *

    检测指定字段的值是否包含以下jpa注解

    - *
      - *
    • {@link Id}
    • - *
    • {@link Column}
    • - *
    - *

    再检测字段是否包含mybatis注解

    - *
      - *
    • {@link TableId}
    • - *
    • {@link TableField}
    • - *
    - * - * @param field the field - */ - public static SQLColumnDef of(Field field) { - SQLColumnDefBuilder builder = SQLColumnDef.builder(); - // 解析id - Id id = field.getAnnotation(Id.class); - if (id != null) { - builder.isPk(true); - } - // 如果当前没有被@Id注解表示,尝试判断当前字段的名称是否为id - if (id == null && (field.getName().equals(ID))) { - builder.isPk(true); - } - TableId tableId = field.getAnnotation(TableId.class); - if (tableId != null) { - builder.isPk(true); - } - - // 默认按照下划线进行处理 - String maybeColumnName = field.getName(); - builder.sqlName(SQLName.of(maybeColumnName, SQLName.UNDERLINE_FEATURE)); - - // 解析是否包含@Column or @TableField - Column column = field.getAnnotation(Column.class); - if (column != null) { - builder.isNonNull(!column.nullable()); - builder.isNull(column.nullable()); - builder.isUnique(column.unique()); - String columnName = column.name(); - if (StringUtils.isNotBlank(columnName)) { - builder.sqlName(SQLName.of(columnName, SQLName.UNDERLINE_FEATURE)); - } - } - TableField tableField = field.getAnnotation(TableField.class); - if (tableField != null) { - String columnName = tableField.value(); - if (StringUtils.isNotBlank(columnName)) { - builder.sqlName(SQLName.of(columnName, SQLName.UNDERLINE_FEATURE)); - } - } - // 解析该字段的类型 - Collection jdbcTypes = TypeRegistry.getInstance().guessJdbcType(field.getType()); - if (CollectionUtils.isNotEmpty(jdbcTypes)) { - JdbcType jdbcType = Lists.newArrayList(jdbcTypes).get(0); - DataType type = DataType.create(GenericSQLType.getByJdbcCode(jdbcType.getJdbcCode())); - builder.dataType(type); - } - return builder.build(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLName.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLName.java deleted file mode 100644 index ceb3f9ee..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLName.java +++ /dev/null @@ -1,178 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.core.env.Envs; -import cc.allio.uno.core.util.StringUtils; -import lombok.Getter; - -/** - * sql name 如 table name、column name...根据指定格式化转换对应的name - * - * @author jiangwei - * @date 2023/4/17 16:16 - * @since 1.1.4 - */ -@Getter -public class SQLName { - - // 当前存入的sql name - private String name; - - private NameFeature feature; - - /** - * 名称格式化key - */ - private static final String NAME_FORMAT_KEY = "allio.uno.data.orm.sql.name.format"; - // 名称以下划线 - private static final String NAME_FORMAT_UNDERLINE = "underline"; - // 名称以驼峰 - private static final String NAME_FORM_HUMP = "hump"; - // 名称以原样 - private static final String NAME_FORM_PLAIN = "plain"; - // 名称以小写 - private static final String NAME_FORM_LOWER_CASE = "lower-case"; - // 名称以大写 - private static final String NAME_FORM_UPPER_CASE = "upper-case"; - - public static final NameFeature UNDERLINE_FEATURE = new UnderlineNameFeature(); - public static final NameFeature HUMP_FEATURE = new HumpNameFeature(); - public static final NameFeature PLAIN_FEATURE = new PlainNameFeature(); - public static final NameFeature LOWER_CASE_FEATURE = new LowerCaseFeature(); - public static final NameFeature UPPER_CASE_FEATURE = new UpperCaseFeature(); - - /** - * 获取name feature - * - * @return NameFeature or default {@link #PLAIN_FEATURE} - */ - public static NameFeature getNameFeature() { - String nameFormatKey = Envs.getProperty(NAME_FORMAT_KEY); - if (NAME_FORMAT_UNDERLINE.equals(nameFormatKey)) { - return UNDERLINE_FEATURE; - } else if (NAME_FORM_HUMP.equals(nameFormatKey)) { - return HUMP_FEATURE; - } else if (NAME_FORM_PLAIN.equals(nameFormatKey)) { - return PLAIN_FEATURE; - } else if (NAME_FORM_LOWER_CASE.equals(nameFormatKey)) { - return LOWER_CASE_FEATURE; - } else if (NAME_FORM_UPPER_CASE.equals(nameFormatKey)) { - return UPPER_CASE_FEATURE; - } - return UNDERLINE_FEATURE; - } - - /** - * 创建SQLName实例 - * - * @param name name - * @return SQLName - */ - public static SQLName of(String name) { - return of(name, getNameFeature()); - } - - /** - * 创建SQLName 实例 - * - * @param name name - * @param feature feature - * @return SQLName - */ - public static SQLName of(String name, NameFeature feature) { - SQLName sqlName = new SQLName(); - sqlName.name = name; - sqlName.feature = feature; - return sqlName; - } - - /** - * 把当前存入的sql name进行格式化 - * - * @return 格式化后的name - */ - public String format() { - return getFeature().format(getName()); - } - - /** - * 根据指定的名称特性 - * - * @param feature the feature - * @return format the name - */ - public String format(NameFeature feature) { - if (feature == null) { - throw new IllegalArgumentException("NameFeature is null"); - } - return feature.format(getName()); - } - - /** - * 名称特性 - */ - public interface NameFeature { - - /** - * 格式化 - * - * @param o 原始数据 - * @return 格式化后的名称 - */ - String format(String o); - } - - /** - * 不进行转换 - */ - public static class PlainNameFeature implements NameFeature { - - @Override - public String format(String o) { - return o; - } - } - - /** - * 小写 - */ - public static class LowerCaseFeature implements NameFeature { - - @Override - public String format(String o) { - return o.toLowerCase(); - } - } - - /** - * 大写 - */ - public static class UpperCaseFeature implements NameFeature { - - @Override - public String format(String o) { - return o.toUpperCase(); - } - } - - /** - * 下划线 - */ - public static class UnderlineNameFeature implements NameFeature { - - @Override - public String format(String o) { - return StringUtils.camelToUnderline(o); - } - } - - /** - * 驼峰 - */ - public static class HumpNameFeature implements NameFeature { - - @Override - public String format(String o) { - return StringUtils.underlineToCamel(o); - } - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLOperator.java deleted file mode 100644 index 347aab3f..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLOperator.java +++ /dev/null @@ -1,31 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -/** - * SQL操作 - * - * @author jiangwei - * @date 2023/4/12 19:44 - * @since 1.1.4 - */ -public interface SQLOperator> { - - /** - * 获取SQL字符串 - * - * @return SQL字符串 - */ - String getSQL(); - - /** - * 解析SQL - * - * @param sql sql - * @return SQLOperator - */ - T parse(String sql); - - /** - * 重制当前SQL已经存在的数据 - */ - void reset(); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLOperatorFactory.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLOperatorFactory.java deleted file mode 100644 index 38f1f256..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLOperatorFactory.java +++ /dev/null @@ -1,156 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.core.env.Envs; -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLDropTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLExistTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.dml.SQLDeleteOperator; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.SQLUpdateOperator; -import cc.allio.uno.data.orm.type.DBType; -import com.google.common.collect.Maps; - -import java.util.Map; - -/** - * {@link SQLOperator}的生成工厂(静态工厂) - * - * @author jiangwei - * @date 2023/4/16 13:10 - * @see SQLCreateTableOperator - * @see SQLDropTableOperator - * @see SQLInsertOperator - * @see SQLQueryOperator - * @since 1.1.4 - */ -public class SQLOperatorFactory { - - private SQLOperatorFactory() { - } - - private static final Map CACHES = Maps.newHashMapWithExpectedSize(3); - - /** - * 获取当前系统的SQL Operator - * - * @return OperatorMetadata or DruidOperatorMetadata(默认为druid) - */ - public static T getSystemOperatorMetadata() { - return getOperatorMetadata(OperatorMetadata.getSystemOperatorKey()); - } - - /** - * 获取当前系统的SQL Operator - * - * @return OperatorMetadata or DruidOperatorMetadata(默认为druid) - */ - public static T getOperatorMetadata(OperatorMetadata.OperatorMetadataKey operatorKey) { - if (OperatorMetadata.DRUID_OPERATOR_KEY.equals(operatorKey)) { - return (T) CACHES.computeIfAbsent(operatorKey, k -> new DruidOperatorMetadata()); - } else if (OperatorMetadata.SHARDING_SPHERE_KEY.equals(operatorKey)) { - return (T) CACHES.computeIfAbsent(operatorKey, k -> new ShardingSphereOperatorMetadata()); - } else if (OperatorMetadata.LOCAL_OPERATOR_KEY.equals(operatorKey)) { - return (T) CACHES.computeIfAbsent(operatorKey, k -> new LocalOperatorMetadata()); - } else if (OperatorMetadata.ELASTIC_SEARCH_KEY.equals(operatorKey)) { - return (T) CACHES.computeIfAbsent(operatorKey, k -> new ElasticSearchOperatorMetadata()); - } - // 系统配置中不存在uno.data.orm.sql.operator属性,设置默认 - Envs.setProperty(OperatorMetadata.OPERATOR_METADATA_KEY, OperatorMetadata.DRUID_OPERATOR_KEY.getKey()); - // 放入缓存中 - DruidOperatorMetadata druidOperatorMetadata = new DruidOperatorMetadata(); - CACHES.put(OperatorMetadata.DRUID_OPERATOR_KEY, druidOperatorMetadata); - return (T) druidOperatorMetadata; - } - - /** - * 根据operator的class获取指定operator实例. - *
      - *
    • operator key = {@link OperatorMetadata#getSystemOperatorKey()}
    • - *
    • dbtype = {@link DBType#getSystemDbType()}
    • - *
    - * - * @param operatorClass operatorClass - * @param SQLOperator - * @return SQLOperator - * @throws IllegalArgumentException operatorClass is null - * @throws NullPointerException An operation that does not exist - */ - public static > T getSQLOperator(Class operatorClass) { - return getSQLOperator(operatorClass, OperatorMetadata.getSystemOperatorKey(), DBType.getSystemDbType()); - } - - /** - * 根据operator的class获取指定operator实例 - *
      - *
    • dbtype = {@link DBType#getSystemDbType()}
    • - *
    - * - * @param operatorClass operatorClass - * @param SQLOperator - * @param operatorKey operatorKey - * @return SQLOperator - * @throws IllegalArgumentException operatorClass is null - * @throws NullPointerException An operation that does not exist - * @see OperatorMetadata#getSystemOperatorKey() - */ - public static > T getSQLOperator(Class operatorClass, OperatorMetadata.OperatorMetadataKey operatorKey) { - return getSQLOperator(operatorClass, operatorKey, DBType.getSystemDbType()); - } - - /** - * 根据operator的class获取指定operator实例 - *
      - *
    • dbtype = {@link DBType#getSystemDbType()}
    • - *
    - * - * @param operatorClass operatorClass - * @param SQLOperator - * @param dbType dbType - * @return SQLOperator - * @throws IllegalArgumentException operatorClass is null - * @throws NullPointerException An operation that does not exist - * @see OperatorMetadata#getSystemOperatorKey() - */ - public static > T getSQLOperator(Class operatorClass, DBType dbType) { - return getSQLOperator(operatorClass, OperatorMetadata.getSystemOperatorKey(), dbType); - } - - /** - * 根据operator的class获取指定operator实例 - * - * @param operatorClass operatorClass - * @param operatorKey operatorKey - * @param dbType dbtype - * @param SQLOperator - * @return SQLOperator - * @throws IllegalArgumentException operatorClass is null - * @throws NullPointerException An operation that does not exist - * @see OperatorMetadata.OperatorMetadataKey - */ - public static > T getSQLOperator(Class operatorClass, OperatorMetadata.OperatorMetadataKey operatorKey, DBType dbType) { - if (operatorClass == null) { - throw new IllegalArgumentException("operator class isnull"); - } - OperatorMetadata operatorMetadata = getOperatorMetadata(operatorKey); - if (SQLCreateTableOperator.class.isAssignableFrom(operatorClass)) { - return (T) operatorMetadata.createTable(dbType); - } else if (SQLDropTableOperator.class.isAssignableFrom(operatorClass)) { - return (T) operatorMetadata.dropTable(dbType); - } else if (SQLQueryOperator.class.isAssignableFrom(operatorClass)) { - return (T) operatorMetadata.query(dbType); - } else if (SQLInsertOperator.class.isAssignableFrom(operatorClass)) { - return (T) operatorMetadata.insert(dbType); - } else if (SQLUpdateOperator.class.isAssignableFrom(operatorClass)) { - return (T) operatorMetadata.update(dbType); - } else if (SQLDeleteOperator.class.isAssignableFrom(operatorClass)) { - return (T) operatorMetadata.delete(dbType); - } else if (SQLExistTableOperator.class.isAssignableFrom(operatorClass)) { - return (T) operatorMetadata.existTable(dbType); - } else if (SQLShowColumnsOperator.class.isAssignableFrom(operatorClass)) { - return (T) operatorMetadata.showColumns(dbType); - } - throw new NullPointerException(String.format("operator class %s system not exist", operatorClass.getName())); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLPrepareOperatorImpl.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLPrepareOperatorImpl.java deleted file mode 100644 index b323305d..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLPrepareOperatorImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import com.google.common.collect.Lists; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * SQLPrepareOperatorImpl - * - * @author jiangwei - * @date 2023/4/16 18:19 - * @since 1.1.4 - */ -public abstract class SQLPrepareOperatorImpl> implements SQLPrepareOperator { - private static final int DEFAULT_CAPACITY = 0; - protected PrepareValue[] prepareValues; - protected int prepareIndex; - - protected SQLPrepareOperatorImpl() { - this.prepareValues = new PrepareValue[DEFAULT_CAPACITY]; - this.prepareIndex = 0; - } - - /** - * 添加预处理SQL - * - * @param value value - */ - protected void addPrepareValue(String column, Object value) { - // ensure数组容量 - ensureCapacityInternal(prepareValues.length + 1); - prepareValues[prepareIndex++] = PrepareValue.of(prepareIndex, column, value); - } - - @Override - public List getPrepareValues() { - return Collections.unmodifiableList(Lists.newArrayList(prepareValues)); - } - - @Override - public void reset() { - prepareValues = new PrepareValue[DEFAULT_CAPACITY]; - prepareIndex = 0; - } - - protected void ensureCapacityInternal(int minCapacity) { - ensureExplicitCapacity(minCapacity); - } - - private void ensureExplicitCapacity(int minCapacity) { - - // overflow-conscious code - if (minCapacity - prepareValues.length > 0) - grow(minCapacity); - } - - /** - * Increases the capacity to ensure that it can hold at least the - * number of elements specified by the minimum capacity argument. - * - * @param minCapacity the desired minimum capacity - */ - private void grow(int minCapacity) { - // overflow-conscious code - // minCapacity is usually close to size, so this is a win: - prepareValues = Arrays.copyOf(prepareValues, minCapacity); - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLTableOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLTableOperator.java deleted file mode 100644 index de6ea683..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLTableOperator.java +++ /dev/null @@ -1,50 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -/** - * Table Operator (from xxx) - * - * @author jiangwei - * @date 2023/4/16 18:07 - * @since 1.1.4 - */ -public interface SQLTableOperator> extends Operator { - - /** - * FROM XX - * - * @param name table name - * @return Operator - */ - default T from(String name) { - return from(Table.of(name)); - } - - /** - * FROM XX - * - * @param name table name - * @param alias table alias - * @return Operator - */ - default T from(String name, String alias) { - return from(Table.of(name, alias)); - } - - /** - * FROM XX - * - * @param entityClass entityClass - * @return Operator - */ - default

    T from(Class

    entityClass) { - return from(new PojoWrapper

    (entityClass).getTable()); - } - - /** - * FROM XX - * - * @param table table - * @return Operator - */ - T from(Table table); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ShardingSphereOperatorMetadata.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ShardingSphereOperatorMetadata.java deleted file mode 100644 index 1e98ef38..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ShardingSphereOperatorMetadata.java +++ /dev/null @@ -1,65 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLDropTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLExistTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.dml.SQLDeleteOperator; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.SQLUpdateOperator; -import cc.allio.uno.data.orm.type.DBType; - -/** - * sharding-sphere - * - * @author jiangwei - * @date 2023/4/16 13:08 - * @since 1.1.4 - */ -public class ShardingSphereOperatorMetadata implements OperatorMetadata { - @Override - public SQLQueryOperator query(DBType dbType) { - return null; - } - - @Override - public SQLInsertOperator insert(DBType dbType) { - return null; - } - - @Override - public SQLUpdateOperator update(DBType dbType) { - return null; - } - - @Override - public SQLDeleteOperator delete(DBType dbType) { - return null; - } - - @Override - public SQLCreateTableOperator createTable(DBType dbType) { - return null; - } - - @Override - public SQLDropTableOperator dropTable(DBType dbType) { - return null; - } - - @Override - public SQLExistTableOperator existTable(DBType dbType) { - return null; - } - - @Override - public SQLShowColumnsOperator showColumns(DBType dbType) { - return null; - } - - @Override - public OperatorMetadataKey getKey() { - return DRUID_OPERATOR_KEY; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Statement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Statement.java deleted file mode 100644 index 30efc244..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Statement.java +++ /dev/null @@ -1,125 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; - -import java.util.Collection; -import java.util.Comparator; - -/** - * SQL标识接口,用于SQl相关语句的构建声明 - * - * @author jiangwei - * @date 2022/9/30 10:22 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface Statement> { - - // --------------- SQL常量 --------------- - - String IN = "IN"; - String IS_NULL = "IS NUll"; - String NOT_NULL = "NOT NULL"; - String LT = "lt"; - String LT_SYMBOL = "<"; - String LTE = "lte"; - String LTE_SYMBOL = "<="; - String GT = "gt"; - String GT_SYMBOL = ">"; - String GTE = "gte"; - String GTE_SYMBOL = ">="; - String EQ = "eq"; - String EQ_SYMBOL = "="; - String ASC = "ASC"; - String DESC = "DESC"; - String AND = "AND"; - String OR = "OR"; - String BETWEEN = "BETWEEN"; - String NOT_BETWEEN = "NOT BETWEEN"; - String AS = "AS"; - String LIKE = "LIKE"; - String $LIKE = "%"; - String SELECT = "SELECT"; - String FROM = "FROM"; - String WHERE = "WHERE"; - String ORDER = "ORDER"; - String GROUP_BY = "GROUP BY"; - String LIMIT = "LIMIT"; - String OFFSET = "OFFSET"; - - /** - * 返回自身实例 - * - * @return self - */ - default T self() { - return (T) this; - } - - /** - * 声明实现类需要返回sql字符串 - * - * @return SQL字符串 - * @throws SQLException 获取并解析SQL发生异常时抛出 - */ - String getSQL() throws SQLException; - - /** - * 获取条件语句如: - *

      - *
    • Select a , b -> a, b
    • - *
    • where a=1 -> a=1
    • - *
    - * - * @return condition - */ - String getCondition(); - - /** - * 获取当前语句表达式实例列表。 - * - * @return Expression列表 - * @see Expression - */ - Collection getExpressions(); - - /** - * 做语句语法校验 - * - * @throws SQLException 当语句没有通过时抛出该异常 - */ - void syntaxCheck() throws SQLException; - - // 语句排序 - int SELECT_ORDER = 0; - int FROM_ORDER = 1; - int WHERE_ORDER = 2; - int GROUP_ORDER = 3; - int ORDER_ORDER = 4; - int LIMIT_ORDER = 5; - - /** - * 获取语句执行顺序 - * - * @return 顺序 - * @see OrderComparator - */ - int order(); - - /** - * 默认排序比较器 - */ - OrderComparator ORDER_COMPARATOR = new OrderComparator(); - - /** - * 语句排序比较器 - */ - class OrderComparator implements Comparator> { - - @Override - public int compare(Statement o1, Statement o2) { - return Integer.compare(o1.order(), o2.order()); - } - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/TokenOperatorAdapter.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/TokenOperatorAdapter.java deleted file mode 100644 index d98c1bec..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/TokenOperatorAdapter.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.data.orm.SQLAdapter; - -/** - * SQL operator - * - * @author jiangwei - * @date 2023/4/13 13:13 - * @since 1.1.4 - */ -public interface TokenOperatorAdapter extends SQLAdapter { -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLAlterTableOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLAlterTableOperator.java deleted file mode 100644 index d0f0e359..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLAlterTableOperator.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl; - -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.SQLTableOperator; - -/** - * SQL修改表字段操作 - * - * @author jiangwei - * @date 2023/6/8 19:21 - * @since 1.1.4 - */ -public interface SQLAlterTableOperator extends SQLOperator, SQLTableOperator { -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLCreateTableOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLCreateTableOperator.java deleted file mode 100644 index 5a201a89..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLCreateTableOperator.java +++ /dev/null @@ -1,98 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl; - -import cc.allio.uno.core.util.CollectionUtils; -import cc.allio.uno.data.orm.sql.PojoWrapper; -import cc.allio.uno.data.orm.sql.SQLColumnDef; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.SQLTableOperator; - -import java.util.List; -import java.util.function.Function; - -/** - * SQL创建操作 - * - * @author jiangwei - * @date 2023/4/12 19:42 - * @since 1.1.4 - */ -public interface SQLCreateTableOperator extends SQLOperator, SQLTableOperator { - - /** - * 根据pojo的class文件创建SQL创表实例 - * - * @param pojoClass the pojoClass - * @return SQLCreateTableOperator - */ - default SQLCreateTableOperator fromPojo(Class pojoClass) { - PojoWrapper pojoWrapper = new PojoWrapper<>(pojoClass); - from(pojoWrapper.getTable()); - List sqlColumnDefs = pojoWrapper.getSQLColumnDef(); - columns(sqlColumnDefs); - return self(); - } - - /** - * 字段 - * - * @param sqlColumnDefs 集合 - * @return SQLCreateOperator - */ - default SQLCreateTableOperator columns(SQLColumnDef... sqlColumnDefs) { - if (sqlColumnDefs != null) { - for (SQLColumnDef sqlColumnDef : sqlColumnDefs) { - column(sqlColumnDef); - } - } - return self(); - } - - /** - * 字段 - * - * @param sqlColumnDefs 集合 - * @return SQLCreateOperator - */ - default SQLCreateTableOperator columns(List sqlColumnDefs) { - if (CollectionUtils.isNotEmpty(sqlColumnDefs)) { - for (SQLColumnDef sqlColumnDef : sqlColumnDefs) { - column(sqlColumnDef); - } - } - return self(); - } - - /** - * 字段 - * - * @param builder the builder - * @return SQLCreateOperator - */ - default SQLCreateTableOperator column(Function builder) { - return column(builder.apply(SQLColumnDef.builder()).build()); - } - - /** - * 字段 - * - * @param columnDef SQLColumnDef - * @return SQLCreateOperator - */ - SQLCreateTableOperator column(SQLColumnDef columnDef); - - /** - * 约束 - * - * @param schemaName schemaName - * @return SQLCreateOperator - */ - SQLCreateTableOperator schemaName(String schemaName); - - /** - * 注释 - * - * @param comment 注释 - * @return SQLCreateOperator - */ - SQLCreateTableOperator comment(String comment); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLDropTableOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLDropTableOperator.java deleted file mode 100644 index 6810e791..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLDropTableOperator.java +++ /dev/null @@ -1,22 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl; - -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.SQLTableOperator; - -/** - * Drop table - * - * @author jiangwei - * @date 2023/4/16 12:52 - * @since 1.1.4 - */ -public interface SQLDropTableOperator extends SQLOperator, SQLTableOperator { - - /** - * Drop table if exist - * - * @param ifExist ifExist - * @return SQLDropTableOperator - */ - SQLDropTableOperator ifExist(Boolean ifExist); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLExistTableOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLExistTableOperator.java deleted file mode 100644 index 5cab9722..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLExistTableOperator.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl; - -import cc.allio.uno.data.orm.sql.SQLPrepareOperator; -import cc.allio.uno.data.orm.sql.SQLTableOperator; - -/** - * SQL 查询是否存在指定表 - * - * @author jiangwei - * @date 2023/4/17 09:46 - * @since 1.1.4 - */ -public interface SQLExistTableOperator extends SQLPrepareOperator, SQLTableOperator { - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLShowColumnsOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLShowColumnsOperator.java deleted file mode 100644 index dbf5ae95..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/SQLShowColumnsOperator.java +++ /dev/null @@ -1,22 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl; - -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.SQLPrepareOperator; -import cc.allio.uno.data.orm.sql.SQLTableOperator; - -/** - * SQL表结构查询 - * - * @author jiangwei - * @date 2023/6/8 19:19 - * @since SWP-2.0.1 - */ -public interface SQLShowColumnsOperator extends SQLPrepareOperator, SQLTableOperator { - - /** - * 转换为{@link SQLQueryOperator} - * - * @return SQLQueryOperator for instance - */ - SQLQueryOperator toQueryOperator(); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLAlterTableOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLAlterTableOperator.java deleted file mode 100644 index 60512fe4..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLAlterTableOperator.java +++ /dev/null @@ -1,47 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.druid; - -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.ddl.SQLAlterTableOperator; - -/** - * druid for modify table structure - * - * @author jiangwei - * @date 2023/6/8 19:55 - * @since 1.1.4 - */ -public class DruidSQLAlterTableOperator implements SQLAlterTableOperator { - - private final SQLAlterTableStatement alterTableStatement; - private final DbType druidDbType; - - public DruidSQLAlterTableOperator(DBType dbType) { - this.druidDbType = DruidDbTypeAdapter.getInstance().get(dbType); - this.alterTableStatement = new SQLAlterTableStatement(druidDbType); - - } - - @Override - public String getSQL() { - return null; - } - - @Override - public SQLAlterTableOperator parse(String sql) { - return null; - } - - @Override - public void reset() { - - } - - @Override - public SQLAlterTableOperator from(Table table) { - return null; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLCreateOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLCreateOperator.java deleted file mode 100644 index 5c93532e..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLCreateOperator.java +++ /dev/null @@ -1,127 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.druid; - -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.DataType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import cc.allio.uno.data.orm.type.druid.DruidTypeAdapter; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.SQLDataType; -import com.alibaba.druid.sql.ast.SQLStatement; -import com.alibaba.druid.sql.ast.statement.*; -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; -import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; -import cc.allio.uno.core.util.CollectionUtils; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.SQLColumnDef; -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; - -import java.util.List; - -/** - * 基于Druid create operator - * - * @author jiangwei - * @date 2023/4/12 19:45 - * @since 1.1.4 - */ -public class DruidSQLCreateOperator implements SQLCreateTableOperator { - - private SQLCreateTableStatement createTableStatement; - private final DbType druidType; - - public DruidSQLCreateOperator(DBType dbType) { - this.druidType = DruidDbTypeAdapter.getInstance().get(dbType); - SQLCreateTableStatement druidCreateTableStatement; - switch (druidType) { - case mysql: - druidCreateTableStatement = new MySqlCreateTableStatement(); - break; - case oracle: - druidCreateTableStatement = new OracleCreateTableStatement(); - break; - default: - druidCreateTableStatement = new SQLCreateTableStatement(); - } - this.createTableStatement = druidCreateTableStatement; - } - - @Override - public String getSQL() { - return SQLUtils.toSQLString(createTableStatement); - } - - @Override - public SQLCreateTableOperator parse(String sql) { - List sqlStatements = SQLUtils.parseStatements(sql, druidType); - if (CollectionUtils.isNotEmpty(sqlStatements)) { - this.createTableStatement = (SQLCreateTableStatement) sqlStatements.get(0); - } - return self(); - } - - @Override - public void reset() { - // reset - this.createTableStatement = new SQLCreateTableStatement(druidType); - } - - @Override - public SQLCreateTableOperator from(String table) { - createTableStatement.setTableName(table); - return self(); - } - - @Override - public SQLCreateTableOperator from(Table table) { - createTableStatement.setTableName(table.getName().format()); - return self(); - } - - @Override - public SQLCreateTableOperator column(SQLColumnDef columnDef) { - SQLColumnDefinition sqlColumnDefinition = new SQLColumnDefinition(); - sqlColumnDefinition.setComment(columnDef.getComment()); - sqlColumnDefinition.setName(columnDef.getSqlName().format()); - sqlColumnDefinition.setDbType(druidType); - DataType dataType = columnDef.getDataType(); - SQLDataType druidType = DruidTypeAdapter.getInstance().get(dataType); - if (druidType != null) { - druidType.setDbType(this.druidType); - sqlColumnDefinition.setDataType(druidType); - } - if (columnDef.isPk()) { - SQLColumnPrimaryKey sqlPrimaryKey = new SQLColumnPrimaryKey(); - sqlColumnDefinition.addConstraint(sqlPrimaryKey); - } - if (columnDef.isFk()) { - SQLColumnReference sqlColumnReference = new SQLColumnReference(); - sqlColumnDefinition.addConstraint(sqlColumnReference); - } - if (columnDef.isNull()) { - SQLNullConstraint sqlNullConstraint = new SQLNullConstraint(); - sqlColumnDefinition.addConstraint(sqlNullConstraint); - } - if (columnDef.isNonNull()) { - SQLNotNullConstraint sqlNotNullConstraint = new SQLNotNullConstraint(); - sqlColumnDefinition.addConstraint(sqlNotNullConstraint); - } - if (columnDef.isUnique()) { - SQLColumnUniqueKey sqlColumnUniqueKey = new SQLColumnUniqueKey(); - sqlColumnDefinition.addConstraint(sqlColumnUniqueKey); - } - createTableStatement.addColumn(sqlColumnDefinition); - return self(); - } - - @Override - public SQLCreateTableOperator schemaName(String schemaName) { - createTableStatement.setSchema(schemaName); - return self(); - } - - @Override - public SQLCreateTableOperator comment(String comment) { - return self(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLDropTableOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLDropTableOperator.java deleted file mode 100644 index dd58326d..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLDropTableOperator.java +++ /dev/null @@ -1,57 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.druid; - -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; -import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.ddl.SQLDropTableOperator; - -/** - * DruidSQLDropTableOperator - * - * @author jiangwei - * @date 2023/4/16 13:02 - * @since 1.1.4 - */ -public class DruidSQLDropTableOperator implements SQLDropTableOperator { - private SQLDropTableStatement dropTableStatement; - private final DbType druidDbType; - - public DruidSQLDropTableOperator(DBType dbType) { - this.druidDbType = DruidDbTypeAdapter.getInstance().get(dbType); - this.dropTableStatement = new SQLDropTableStatement(); - dropTableStatement.setDbType(druidDbType); - } - - @Override - public String getSQL() { - return SQLUtils.toSQLString(dropTableStatement); - } - - @Override - public SQLDropTableOperator parse(String sql) { - return null; - } - - @Override - public void reset() { - // reset - this.dropTableStatement = new SQLDropTableStatement(); - dropTableStatement.setDbType(druidDbType); - } - - @Override - public SQLDropTableOperator from(Table table) { - dropTableStatement.addTableSource(new SQLExprTableSource(table.getName().format())); - return self(); - } - - @Override - public SQLDropTableOperator ifExist(Boolean ifExist) { - dropTableStatement.setIfExists(ifExist); - return self(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLExistTableOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLExistTableOperator.java deleted file mode 100644 index 86a91593..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLExistTableOperator.java +++ /dev/null @@ -1,76 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.druid; - -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.alibaba.druid.DbType; -import cc.allio.uno.data.orm.sql.PrepareValue; -import cc.allio.uno.data.orm.sql.SQLOperatorFactory; -import cc.allio.uno.data.orm.sql.SQLPrepareOperatorImpl; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.ddl.SQLExistTableOperator; - -import java.util.List; - -/** - * druid - * - * @author jiangwei - * @date 2023/4/17 09:47 - * @since 1.1.4 - */ -public class DruidSQLExistTableOperator extends SQLPrepareOperatorImpl implements SQLExistTableOperator { - - private final DbType druidDbType; - private final SQLQueryOperator queryOperator; - - public DruidSQLExistTableOperator(DBType dbType) { - this.druidDbType = DruidDbTypeAdapter.getInstance().get(dbType); - this.queryOperator = SQLOperatorFactory.getSQLOperator(SQLQueryOperator.class); - } - - @Override - public String getSQL() { - return queryOperator.getSQL(); - } - - @Override - public SQLExistTableOperator parse(String sql) { - throw new UnsupportedOperationException("DruidSQLExistTableOperator Unsupported"); - } - - @Override - public String getPrepareSQL() { - return queryOperator.getPrepareSQL(); - } - - @Override - public SQLExistTableOperator from(Table table) { - if (DbType.mysql == druidDbType) { - queryOperator.count() - .from("information._schema.TABLES") - .$like$("TABLE_NAME", table.getName().format()); - } else if (DbType.postgresql == druidDbType) { - queryOperator.count() - .from("pg_statio_user_tables") - .eq("relname", table.getName().format()); - } - return self(); - } - - @Override - protected void addPrepareValue(String column, Object value) { - throw new UnsupportedOperationException("DruidSQLExistTableOperator Unsupported"); - } - - @Override - public List getPrepareValues() { - return queryOperator.getPrepareValues(); - } - - @Override - public void reset() { - super.reset(); - queryOperator.reset(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLShowColumnsOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLShowColumnsOperator.java deleted file mode 100644 index bce1291f..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLShowColumnsOperator.java +++ /dev/null @@ -1,106 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.druid; - -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; -import com.alibaba.druid.sql.ast.statement.SQLShowColumnsStatement; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; - -import java.util.List; - -/** - * 表结构 - * - * @author jiangwei - * @date 2023/6/8 19:20 - * @since 1.1.4 - */ -public class DruidSQLShowColumnsOperator extends SQLPrepareOperatorImpl implements SQLShowColumnsOperator { - - private final DbType druidDbType; - private final SQLQueryOperator queryOperator; - private final SQLShowColumnsStatement showColumnsStatement; - - public DruidSQLShowColumnsOperator(DBType dbType) { - this.druidDbType = DruidDbTypeAdapter.getInstance().get(dbType); - this.queryOperator = SQLOperatorFactory.getSQLOperator(SQLQueryOperator.class); - this.showColumnsStatement = new SQLShowColumnsStatement(); - } - - @Override - public String getSQL() { - if (druidDbType == DbType.mysql) { - return SQLUtils.toSQLString(showColumnsStatement); - } else if (druidDbType == DbType.postgresql || druidDbType == DbType.db2 || druidDbType == DbType.h2) { - return queryOperator.getSQL(); - } - throw new UnsupportedOperationException(String.format("DruidSQLTableStructureOperator Unsupported db type for %s", druidDbType)); - } - - @Override - public SQLShowColumnsOperator parse(String sql) { - throw new UnsupportedOperationException("DruidSQLTableStructureOperator Unsupported"); - } - - @Override - public String getPrepareSQL() { - throw new UnsupportedOperationException("DruidSQLTableStructureOperator Unsupported"); - } - - @Override - public List getPrepareValues() { - throw new UnsupportedOperationException("DruidSQLTableStructureOperator Unsupported"); - } - - @Override - public void reset() { - super.reset(); - queryOperator.reset(); - } - - @Override - public SQLShowColumnsOperator from(Table table) { - if (druidDbType == DbType.mysql) { - SQLPropertyExpr sqlPropertyExpr = new SQLPropertyExpr(); - sqlPropertyExpr.setName(table.getName().format()); - showColumnsStatement.setTable(sqlPropertyExpr); - } else if (druidDbType == DbType.postgresql) { - queryOperator.select(SQLName.of("column_name", SQLName.PLAIN_FEATURE), "field") - .select(SQLName.of("data_type", SQLName.PLAIN_FEATURE), "type") - .select(SQLName.of("is_nullable", SQLName.PLAIN_FEATURE), "nulls") - .select(SQLName.of("column_default", SQLName.PLAIN_FEATURE), "CDEFAULT") - .from(Table.of(SQLName.of("information_schema.columns", SQLName.PLAIN_FEATURE))) - .eq(SQLName.of("table_name", SQLName.PLAIN_FEATURE), table.getName().format()); - } else if (druidDbType == DbType.db2) { - queryOperator.select(SQLName.of("COLNAME", SQLName.PLAIN_FEATURE), "field") - .select(SQLName.of("TYPENAME", SQLName.PLAIN_FEATURE), "type") - .select(SQLName.of("NULLS", SQLName.PLAIN_FEATURE), "nulls") - .select(SQLName.of("DEFAULT", SQLName.PLAIN_FEATURE), "CDEFAULT") - .from(Table.of(SQLName.of("SYSCAT.COLUMNS", SQLName.PLAIN_FEATURE))) - .eq(SQLName.of("TABNAME", SQLName.PLAIN_FEATURE), table.getName().format()); - } else if (druidDbType == DbType.h2) { - queryOperator.select(SQLName.of("COLUMN_NAME", SQLName.PLAIN_FEATURE), "field") - .select(SQLName.of("DATA_TYPE", SQLName.PLAIN_FEATURE), "type") - .select(SQLName.of("IS_NULLABLE", SQLName.PLAIN_FEATURE), "nulls") - .select(SQLName.of("COLUMN_DEFAULT", SQLName.PLAIN_FEATURE), "CDEFAULT") - .from(Table.of(SQLName.of("INFORMATION_SCHEMA.COLUMNS", SQLName.PLAIN_FEATURE))) - .eq(SQLName.of("TABLE_NAME", SQLName.PLAIN_FEATURE), table.getName().format()); - } - return self(); - } - - @Override - public SQLQueryOperator toQueryOperator() { - if (druidDbType == DbType.mysql) { - queryOperator.reset(); - return queryOperator.parse(SQLUtils.toSQLString(showColumnsStatement)); - } else if (druidDbType == DbType.postgresql || druidDbType == DbType.db2 || druidDbType == DbType.h2) { - return queryOperator; - } - throw new UnsupportedOperationException(String.format("DruidSQLTableStructureOperator Unsupported db type for %s", druidDbType)); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchDropIndexOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchDropIndexOperator.java deleted file mode 100644 index fffd15b0..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchDropIndexOperator.java +++ /dev/null @@ -1,63 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.elasticsearch; - -import co.elastic.clients.elasticsearch.indices.DeleteIndexRequest; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.ddl.SQLDropTableOperator; - -/** - * 删除索引{@link DeleteIndexRequest} - * - * @author jiangwei - * @date 2023/5/29 18:43 - * @since 1.1.4 - */ -public class ElasticSearchDropIndexOperator implements SQLDropTableOperator { - - private DeleteIndexRequest deleteIndexRequest; - private DeleteIndexRequest.Builder builder; - private static final String ERROR_MSG = "elasticsearch drop operator not support that operator"; - - public ElasticSearchDropIndexOperator() { - builder = new DeleteIndexRequest.Builder(); - } - - @Override - public String getSQL() { - throw new SQLException(ERROR_MSG); - } - - @Override - public SQLDropTableOperator parse(String sql) { - return null; - } - - @Override - public void reset() { - deleteIndexRequest = null; - builder = new DeleteIndexRequest.Builder(); - } - - @Override - public SQLDropTableOperator from(Table table) { - builder.index(table.getName().format()); - return self(); - } - - @Override - public SQLDropTableOperator ifExist(Boolean ifExist) { - throw new SQLException(ERROR_MSG); - } - - /** - * 获取删除index请求 - * - * @return DeleteIndexRequest - */ - public DeleteIndexRequest getDeleteIndexRequest() { - if (deleteIndexRequest == null) { - deleteIndexRequest = builder.build(); - } - return deleteIndexRequest; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchExistIndexOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchExistIndexOperator.java deleted file mode 100644 index cc6bef57..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchExistIndexOperator.java +++ /dev/null @@ -1,72 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.elasticsearch; - -import co.elastic.clients.elasticsearch.core.SearchRequest; -import cc.allio.uno.data.orm.sql.PrepareValue; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.ddl.SQLExistTableOperator; - -import java.util.List; - -/** - * 判断索引是否存在{@link co.elastic.clients.elasticsearch.indices.ExistsRequest} - * - * @author jiangwei - * @date 2023/5/29 18:59 - * @since 1.1.4 - */ -public class ElasticSearchExistIndexOperator implements SQLExistTableOperator { - - private SearchRequest searchRequest; - SearchRequest.Builder builder; - private static final String ERROR_MSG = "elasticsearch drop operator not support that operator"; - - public ElasticSearchExistIndexOperator() { - builder = new SearchRequest.Builder(); - } - - @Override - public String getSQL() { - throw new SQLException(ERROR_MSG); - } - - @Override - public SQLExistTableOperator parse(String sql) { - return null; - } - - @Override - public void reset() { - searchRequest = null; - builder = new SearchRequest.Builder(); - } - - @Override - public String getPrepareSQL() { - throw new SQLException(ERROR_MSG); - } - - @Override - public List getPrepareValues() { - throw new SQLException(ERROR_MSG); - } - - @Override - public SQLExistTableOperator from(Table table) { - builder.index(table.getName().format()); - return self(); - } - - /** - * 获取存在request - * - * @return ExistsRequest - */ - public SearchRequest getSearchRequest() { - if (searchRequest == null) { - searchRequest = builder.build(); - } - return searchRequest; - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchPropertyAdapter.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchPropertyAdapter.java deleted file mode 100644 index 36bd91ca..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchPropertyAdapter.java +++ /dev/null @@ -1,103 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.elasticsearch; - -import cc.allio.uno.data.orm.type.DataType; -import cc.allio.uno.data.orm.type.DataTypeAdapter; -import cc.allio.uno.data.orm.type.GenericSQLType; -import cc.allio.uno.data.orm.type.SQLType; -import co.elastic.clients.elasticsearch._types.analysis.Analyzer; -import co.elastic.clients.elasticsearch._types.mapping.Property; -import cc.allio.uno.core.util.StringUtils; - -/** - * JDBC数据类型转换为es类型 - * - * @author jiangwei - * @date 2023/7/4 15:25 - * @since 1.1.4 - */ -public class ElasticSearchPropertyAdapter implements DataTypeAdapter { - - private final String analyzer; - - public ElasticSearchPropertyAdapter() { - this(null); - } - - public ElasticSearchPropertyAdapter(String analyzer) { - this.analyzer = analyzer; - } - - @Override - public Property get(DataType o) { - DataType dataType = o; - // dataType为null,赋值于VARCHAR - if (dataType == null) { - dataType = DataType.createCharType(GenericSQLType.VARCHAR, 64); - } - // 通用的做分组比较 - SQLType sqlType = dataType.getSqlType(); - // 每个数据库类型的做创建 - GenericSQLType sqlTypeConstant = GenericSQLType.getByJdbcCode(sqlType.getJdbcType()); - switch (sqlTypeConstant) { - case BIGINT: - return Property.of(p -> p.long_(l -> l)); - case SMALLINT: - case TINYINT: - case INTEGER: - return Property.of(p -> p.integer(i -> i)); - case BIT: - return Property.of(p -> p.boolean_(b -> b)); - case DOUBLE: - case NUMBER: - case DECIMAL: - return Property.of(p -> p.double_(d -> d)); - case FLOAT: - return Property.of(p -> p.float_(f -> f)); - case DATE: - case TIME: - case TIMESTAMP: - return Property.of(p -> p.date(d -> d.locale("zh_CN"))); - case OBJECT: - return Property.of(p -> p.object(obj -> obj)); - case ARRAY: - case CHAR: - case VARCHAR: - case NVARCHAR: - case VARBINARY: - case LONGVARCHAR: - case LONGNVARCHAR: - case LONGVARBINARY: - default: - return Property.of(p -> p.text(t -> t.analyzer(StringUtils.isBlank(analyzer) ? Analyzer.Kind.Standard.jsonValue() : analyzer))); - } - } - - @Override - public DataType reversal(Property property) { - switch (property._kind()) { - case Binary: - case Byte: - return DataType.create(GenericSQLType.BIT); - case DateNanos: - case DateRange: - case Date: - return DataType.create(GenericSQLType.DATE); - case Long: - return DataType.create(GenericSQLType.BIGINT); - case Float: - return DataType.create(GenericSQLType.FLOAT); - case Double: - return DataType.create(GenericSQLType.DOUBLE); - case Integer: - return DataType.create(GenericSQLType.INTEGER); - case Short: - return DataType.create(GenericSQLType.SMALLINT); - case Object: - return DataType.create(GenericSQLType.OBJECT); - case Text: - default: - return DataType.createCharType(GenericSQLType.VARCHAR, 0); - - } - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchShowColumnsOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchShowColumnsOperator.java deleted file mode 100644 index 2c7220d3..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchShowColumnsOperator.java +++ /dev/null @@ -1,77 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.elasticsearch; - -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import co.elastic.clients.elasticsearch.indices.GetMappingRequest; -import cc.allio.uno.data.orm.sql.PrepareValue; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import com.google.common.collect.Lists; - -import java.util.List; - -/** - * es 查询所有映射.{@link co.elastic.clients.elasticsearch.indices.GetMappingRequest} - * - * @author jiangwei - * @date 2023/6/11 20:07 - * @since 1.1.4 - */ -public class ElasticSearchShowColumnsOperator implements SQLShowColumnsOperator { - - private GetMappingRequest.Builder builder; - private GetMappingRequest getMappingRequest; - - public ElasticSearchShowColumnsOperator() { - this.builder = new GetMappingRequest.Builder(); - } - - @Override - public String getSQL() { - throw new SQLException(String.format("%s This operation is not supported", this.getClass().getName())); - } - - @Override - public SQLShowColumnsOperator parse(String sql) { - throw new SQLException(String.format("%s This operation is not supported", this.getClass().getName())); - } - - @Override - public void reset() { - builder = new GetMappingRequest.Builder(); - getMappingRequest = null; - } - - @Override - public String getPrepareSQL() { - throw new SQLException(String.format("%s This operation is not supported", this.getClass().getName())); - } - - @Override - public List getPrepareValues() { - throw new SQLException(String.format("%s This operation is not supported", this.getClass().getName())); - } - - @Override - public SQLShowColumnsOperator from(Table table) { - builder = builder.index(Lists.newArrayList(table.getName().format())); - return self(); - } - - @Override - public SQLQueryOperator toQueryOperator() { - throw new SQLException(String.format("%s This operation is not supported", this.getClass().getName())); - } - - /** - * 获取索引映射request - * - * @return GetMappingRequest for instance - */ - public GetMappingRequest getMappingRequest() { - if (getMappingRequest == null) { - getMappingRequest = builder.build(); - } - return getMappingRequest; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/AbstractStatementDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/AbstractStatementDelegate.java deleted file mode 100644 index fa6c670f..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/AbstractStatementDelegate.java +++ /dev/null @@ -1,72 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.data.orm.sql.dml.local.*; -import cc.allio.uno.data.orm.sql.From; -import cc.allio.uno.data.orm.sql.FromStatement; -import cc.allio.uno.data.orm.sql.Statement; -import lombok.Getter; - -/** - * 抽象的SQL语句代理,实现相关的SQL集联操作 - * - * @author jiangwei - * @date 2022/9/30 14:02 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -@Getter -public abstract class AbstractStatementDelegate implements QuerySQLAssociation { - - private final Select select; - private final From from; - private final Where where; - private final Group group; - private final Order order; - private final Limit limit; - private final Statement parent; - - protected AbstractStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit) { - this(select, from, where, group, order, limit, null); - } - - protected AbstractStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit, Statement parent) { - this.select = select; - this.from = from; - this.where = where; - this.group = group; - this.order = order; - this.parent = parent; - this.limit = limit; - } - - @Override - public SelectDelegate thenSelect() { - return then(new SelectStatementDelegate(select, from, where, group, order, limit, parent)); - } - - @Override - public SelectFrom thenFrom() { - return then(new QueryFromStatement(select, from, where, group, order, limit, parent)); - } - - @Override - public WhereDelegate thenWhere() { - return then(new WhereStatementDelegate(select, from, where, group, order, limit, parent)); - } - - @Override - public OrderDelegate thenOrder() { - return then(new OrderStatementDelegate(select, from, where, group, order, limit, parent)); - } - - @Override - public GroupDelegate thenGroup() { - return then(new GroupStatementDelegate(select, from, where, group, order, limit, parent)); - } - - @Override - public LimitDelegate thenLimit() { - return then(new LimitStatementDelegate(select, from, where, group, order, limit, parent)); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Group.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Group.java deleted file mode 100644 index 9b23749b..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Group.java +++ /dev/null @@ -1,54 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - - -import cc.allio.uno.data.orm.sql.ColumnStatement; -import cc.allio.uno.data.orm.sql.MethodReferenceColumn; - -import java.util.Collection; - -/** - * SQL Group相关语法定义 - * - * @author jiangwei - * @date 2022/9/30 13:37 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface Group> extends ColumnStatement { - - /** - * 由某一个字段进行分组 - * - * @param reference 方法引用 - * @return Group对象 - */ - default T byOne(MethodReferenceColumn reference) { - return byOnes(reference.getColumn()); - } - - /** - * 由某一个字段进行分组 - * - * @param fieldName java variable name - * @return Group对象 - */ - T byOne(String fieldName); - - /** - * 由某一类字段进行分组 - * - * @param fieldNames java variable name数组 - * @return Group对象 - */ - T byOnes(String... fieldNames); - - /** - * 由某一类字段进行分组 - * - * @param fieldNames java variable name集合 - * @return Group对象 - */ - T byOnes(Collection fieldNames); - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/GroupDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/GroupDelegate.java deleted file mode 100644 index 470c75e6..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/GroupDelegate.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -/** - * Group代理 - * - * @author jiangwei - * @date 2022/9/30 15:12 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface GroupDelegate extends QuerySQLAssociation, Group { -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/JoinFrom.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/JoinFrom.java deleted file mode 100644 index 7273609c..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/JoinFrom.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.data.orm.sql.From; - -/** - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface JoinFrom> extends From { - - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Limit.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Limit.java deleted file mode 100644 index 3be3c1b2..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Limit.java +++ /dev/null @@ -1,42 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.data.orm.sql.Statement; - -/** - * limit - * - * @author jiangwei - * @date 2023/1/11 14:52 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface Limit> extends Statement { - - /** - * LIMIT { number | ALL } - * - * @param number 起始行数 - * @return Limit - */ - T limit(Integer number); - - /** - * [ OFFSET number ] - * - * @param number 偏移位置 - * @return Limit - */ - T offset(Integer number); - - /** - * 分页 - * - * @param current 当前页 - * @param pageSize 页大小 - * @return Limit - */ - default T page(int current, int pageSize) { - return limit((current - 1) * pageSize).offset(pageSize); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/LimitDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/LimitDelegate.java deleted file mode 100644 index 20f9a143..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/LimitDelegate.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -/** - * limit delegate - * - * @author jiangwei - * @date 2023/1/11 19:18 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface LimitDelegate extends QuerySQLAssociation, Limit { -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Order.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Order.java deleted file mode 100644 index 9b5b6e35..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Order.java +++ /dev/null @@ -1,110 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.data.orm.sql.dml.local.OrderCondition; -import cc.allio.uno.data.orm.sql.ColumnStatement; -import cc.allio.uno.data.orm.sql.MethodReferenceColumn; - -/** - * SQL ORDER相关语法定义 - * - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface Order> extends ColumnStatement { - - /** - * 默认Order排序规则 - * - * @param fieldName java variable name - * @return Order对象 - */ - default T by(String fieldName) { - return byDesc(fieldName); - } - - /** - * 默认Order排序规则 - * - * @param reference 方法引用 - * @return Order对象 - */ - default T by(MethodReferenceColumn reference) { - return by(reference.getColumn()); - } - - /** - * 添加ORDER ASC - * - * @param reference 方法引用 - * @return Order对象 - */ - default T byAsc(MethodReferenceColumn reference) { - return byAsc(reference.getColumn()); - } - - /** - * 添加ORDER ASC - * - * @param fieldName java variable name - * @return Order对象 - */ - T byAsc(String fieldName); - - /** - * 添加ORDER DESC - * - * @param reference 方法引用 - * @return Order对象 - */ - default T byDesc(MethodReferenceColumn reference) { - return byDesc(reference.getColumn()); - } - - /** - * 添加ORDER DESC - * - * @param fieldName java variable name - * @return Order对象 - */ - T byDesc(String fieldName); - - /** - * 添加Order语句 - * - * @param reference 方法引用 - * @param order 排序 - * @return Order对象 - */ - default T orderBy(MethodReferenceColumn reference, String order) { - return orderBy(reference.getColumn(), order); - } - - /** - * 添加Order语句 - * - * @param fieldName java variable name - * @param order 排序 - * @return Order对象 - */ - T orderBy(String fieldName, String order); - - /** - * 添加Order语句 - * - * @param reference 方法引用 - * @param orderCondition 排序条件 - * @return Order对象 - */ - default T orderBy(MethodReferenceColumn reference, OrderCondition orderCondition) { - return orderBy(reference.getColumn(), orderCondition); - } - - /** - * 添加Order语句 - * - * @param fieldName java variable name - * @param orderCondition 排序条件 - * @return Order对象 - */ - T orderBy(String fieldName, OrderCondition orderCondition); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/OrderDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/OrderDelegate.java deleted file mode 100644 index 30778547..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/OrderDelegate.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -/** - * Order代理 - * - * @author jiangwei - * @date 2022/9/30 15:10 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface OrderDelegate extends QuerySQLAssociation, Order { - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/QuerySQLAssociation.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/QuerySQLAssociation.java deleted file mode 100644 index c60f059b..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/QuerySQLAssociation.java +++ /dev/null @@ -1,57 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.data.orm.sql.SQLAssociation; - -/** - * Query 集联的动作定义 - * - * @author jiangwei - * @date 2022/9/30 13:51 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface QuerySQLAssociation extends SQLAssociation { - - /** - * select 集联操作 - * - * @return select实例 - */ - SelectDelegate thenSelect(); - - /** - * from 级联操作 - * - * @return from实例 - */ - SelectFrom thenFrom(); - - /** - * where 集联操作 - * - * @return where实例 - */ - WhereDelegate thenWhere(); - - /** - * order 集联操作 - * - * @return order实例 - */ - OrderDelegate thenOrder(); - - /** - * group 集联操作 - * - * @return group实例 - */ - GroupDelegate thenGroup(); - - /** - * limit 集联操作 - * - * @return limit实例 - */ - LimitDelegate thenLimit(); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLDeleteOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLDeleteOperator.java deleted file mode 100644 index fcde83c1..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLDeleteOperator.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.data.orm.sql.SQLPrepareOperator; -import cc.allio.uno.data.orm.sql.SQLTableOperator; -import cc.allio.uno.data.orm.sql.SQLWhereOperator; - -/** - * SQLDeleteOperator - * - * @author jiangwei - * @date 2023/4/16 18:42 - * @since 1.1.4 - */ -public interface SQLDeleteOperator extends - SQLPrepareOperator, SQLTableOperator, SQLWhereOperator { -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLInsertOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLInsertOperator.java deleted file mode 100644 index 6fefd640..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLInsertOperator.java +++ /dev/null @@ -1,174 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.core.bean.ObjectWrapper; -import cc.allio.uno.core.util.CollectionUtils; -import cc.allio.uno.data.orm.sql.MethodReferenceColumn; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLPrepareOperator; -import cc.allio.uno.data.orm.sql.SQLTableOperator; -import com.google.common.collect.Maps; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * SQL INSERT。值得注意的是没调用一次{@link #insert(String, Object)} }api,都会生成一个VALUES。建议调用{@link #batchInserts(Collection, Collection)}api批量生成 - * - * @author jiangwei - * @date 2023/4/13 15:25 - * @since 1.1.4 - */ -public interface SQLInsertOperator extends SQLPrepareOperator, SQLTableOperator { - - - /** - * INSERT VALUES - * - * @param reference key - * @param value value - * @return InsertOperator - */ - default SQLInsertOperator insert(MethodReferenceColumn reference, Object value) { - return insert(reference.getColumn(), value); - } - - /** - * INSERT VALUES - * - * @param fieldName fieldName - * @param value value - * @return InsertOperator - */ - default SQLInsertOperator insert(String fieldName, Object value) { - return insert(Tuples.of(fieldName, value)); - } - - /** - * INSERT VALUES - * - * @param f1 f1 - * @param v1 v1 - * @return InsertOperator - */ - default SQLInsertOperator insert(String f1, Object v1, String f2, Object v2) { - return insert(Tuples.of(f1, v1), Tuples.of(f2, v2)); - } - - /** - * INSERT VALUES - * - * @param f1 f1 - * @param v1 v1 - * @param f2 f2 - * @param v2 v2 - * @return InsertOperator - */ - default SQLInsertOperator insert(String f1, Object v1, String f2, Object v2, String f3, Object v3) { - return insert(Tuples.of(f1, v1), Tuples.of(f2, v2), Tuples.of(f3, v3)); - } - - /** - * INSERT VALUES - * - * @param f1 f1 - * @param v1 v1 - * @param f2 f2 - * @param v2 v2 - * @param f3 f3 - * @param v3 v3 - * @param f4 f4 - * @param v4 v4 - * @return InsertOperator - */ - default SQLInsertOperator insert(String f1, Object v1, String f2, Object v2, String f3, Object v3, String f4, Object v4) { - return insert(Tuples.of(f1, v1), Tuples.of(f2, v2), Tuples.of(f3, v3), Tuples.of(f4, v4)); - } - - /** - * INSERT VALUES - * - * @param tuple2s Key value - * @return InsertOperator - */ - default SQLInsertOperator insert(Tuple2... tuple2s) { - Map values = Maps.newHashMap(); - for (Tuple2 tuple2 : tuple2s) { - values.put(tuple2.getT1(), tuple2.getT2()); - } - return insert(values); - } - - /** - * INSERT VALUES - * - * @param pojo - * @return - */ - default SQLInsertOperator insertPojo(T pojo) { - ObjectWrapper wrapper = new ObjectWrapper(pojo); - return insert(wrapper.findAllValuesForce()); - } - - /** - * INSERT VALUES - * - * @param values Key value - * @return InsertOperator - */ - default SQLInsertOperator insert(Map values) { - Map inserts = Maps.newHashMap(); - for (Map.Entry entry : values.entrySet()) { - inserts.put(SQLName.of(entry.getKey()), entry.getValue()); - } - return inserts(inserts); - } - - /** - * INSERT VALUES - * - * @param values Key value - * @return InsertOperator - */ - SQLInsertOperator inserts(Map values); - - /** - * INSERT VALUES,VALUES,VALUES - * - * @param pojos pojos list - * @return SQLInsertOperator - */ - default SQLInsertOperator batchInsertPojos(List pojos) { - if (CollectionUtils.isEmpty(pojos)) { - return self(); - } - List> pojoDescribes = pojos.stream() - .map(pojo -> new ObjectWrapper(pojo).findAllValuesForce()) - .collect(Collectors.toList()); - Map first = pojoDescribes.get(0); - Collection> values = pojoDescribes.stream().map(Map::values).collect(Collectors.toList()); - return batchInsert(first.keySet(), values); - - } - - /** - * INSERT VALUES,VALUES,VALUES - * - * @param values values - * @return SQLInsertOperator - */ - default SQLInsertOperator batchInsert(Collection columns, Collection> values) { - return batchInserts(columns.stream().map(SQLName::of).collect(Collectors.toList()), values); - } - - /** - * INSERT VALUES,VALUES,VALUES - * - * @param values values - * @return SQLInsertOperator - */ - SQLInsertOperator batchInserts(Collection columns, Collection> values); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLUpdateOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLUpdateOperator.java deleted file mode 100644 index 51404ef2..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLUpdateOperator.java +++ /dev/null @@ -1,132 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.core.bean.ObjectWrapper; -import cc.allio.uno.data.orm.sql.*; -import com.google.common.collect.Maps; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.Map; - -/** - * SQL Update Operator - * - * @author jiangwei - * @date 2023/4/16 15:19 - * @since 1.1.4 - */ -public interface SQLUpdateOperator extends SQLPrepareOperator, SQLTableOperator, SQLWhereOperator { - - /** - * UPDATE VALUES - * - * @param reference key - * @param value value - * @return SQLUpdateOperator - */ - default SQLUpdateOperator update(MethodReferenceColumn reference, Object value) { - return update(reference.getColumn(), value); - } - - /** - * UPDATE VALUES - * - * @param fieldName fieldName - * @param value value - * @return SQLUpdateOperator - */ - default SQLUpdateOperator update(String fieldName, Object value) { - return update(Tuples.of(fieldName, value)); - } - - /** - * UPDATE VALUES - * - * @param f1 f1 - * @param v1 v1 - * @return SQLUpdateOperator - */ - default SQLUpdateOperator update(String f1, Object v1, String f2, Object v2) { - return update(Tuples.of(f1, v1), Tuples.of(f2, v2)); - } - - /** - * UPDATE VALUES - * - * @param f1 f1 - * @param v1 v1 - * @param f2 f2 - * @param v2 v2 - * @return SQLUpdateOperator - */ - default SQLUpdateOperator update(String f1, Object v1, String f2, Object v2, String f3, Object v3) { - return update(Tuples.of(f1, v1), Tuples.of(f2, v2), Tuples.of(f3, v3)); - } - - /** - * UPDATE VALUES - * - * @param f1 f1 - * @param v1 v1 - * @param f2 f2 - * @param v2 v2 - * @param f3 f3 - * @param v3 v3 - * @param f4 f4 - * @param v4 v4 - * @return SQLUpdateOperator - */ - default SQLUpdateOperator update(String f1, Object v1, String f2, Object v2, String f3, Object v3, String f4, Object v4) { - return update(Tuples.of(f1, v1), Tuples.of(f2, v2), Tuples.of(f3, v3), Tuples.of(f4, v4)); - } - - /** - * UPDATE VALUES - * - * @param tuple2s Key value - * @return SQLUpdateOperator - */ - default SQLUpdateOperator update(Tuple2... tuple2s) { - Map values = Maps.newHashMap(); - for (Tuple2 tuple2 : tuple2s) { - values.put(tuple2.getT1(), tuple2.getT2()); - } - return update(values); - } - - /** - * UPDATE VALUES - * - * @param pojo pojo - * @return SQLUpdateOperator - */ - default SQLUpdateOperator updatePojo(Object pojo) { - ObjectWrapper wrapper = new ObjectWrapper(pojo); - return update(wrapper.findAllValuesForce()); - } - - /** - * UPDATE VALUES,将会过滤为空的值 - * - * @param values Key value - * @return SQLUpdateOperator - */ - default SQLUpdateOperator update(Map values) { - Map updates = Maps.newHashMap(); - for (Map.Entry entry : values.entrySet()) { - Object value = entry.getValue(); - if (value != null) { - updates.put(SQLName.of(entry.getKey()), entry.getValue()); - } - } - return updates(updates); - } - - /** - * UPDATE VALUES - * - * @param values Key value - * @return SQLUpdateOperator - */ - SQLUpdateOperator updates(Map values); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Select.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Select.java deleted file mode 100644 index 39d55f51..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Select.java +++ /dev/null @@ -1,335 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.dialect.func.Func; -import cc.allio.uno.data.orm.sql.word.Distinct; -import cc.allio.uno.data.orm.sql.ColumnStatement; -import cc.allio.uno.data.orm.sql.MethodReferenceColumn; - -import java.util.Collection; - -/** - * SQL Select相关语法 - * - * @author jiangwei - * @date 2022/9/30 13:44 - * @see SQLQueryOperator - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -public interface Select> extends ColumnStatement { - - /** - * 添加'SELECT'条件 - * - * @param reference 方法引用 - * @return Select - */ - default T select(MethodReferenceColumn reference) { - return select(reference.getColumn()); - } - - /** - * 添加'SELECT'条件 - * - * @param reference 方法引用 - * @param alias alias - * @return Select - */ - default T select(MethodReferenceColumn reference, String alias) { - return select(reference.getColumn(), alias); - } - - /** - * select * - * - * @return Select - */ - default T selectAll() { - return select(StringPool.ASTERISK); - } - - /** - * 添加'SELECT'条件 - * - * @param fieldName java variable name - * @return Select - */ - T select(String fieldName); - - /** - * 添加'SELECT'条件 - * - * @param fieldName java variable name - * @param alias alias - * @return Select - */ - T select(String fieldName, String alias); - - /** - * 批量添加'SELECT'条件 - * - * @param fieldNames java variable name - * @return Select - */ - T select(String[] fieldNames); - - /** - * 批量条件'SELECT'条件 - * - * @param fieldNames java variable name - * @return Select - */ - T select(Collection fieldNames); - - /** - * 添加 distinct - * - * @return Select - */ - T distinct(); - - /** - * 添加 distinct on - * - * @param reference 方法引用 - * @param 实体类型 - * @return Select - */ - default T distinctOn(MethodReferenceColumn reference) { - return distinctOn(reference.getColumn()); - } - - /** - * 添加 distinct on - * - * @param reference 方法引用 - * @param alias 别名 - * @param 实体类型 - * @return Select - */ - default T distinctOn(MethodReferenceColumn reference, String alias) { - return distinctOn(reference.getColumn(), alias); - } - - /** - * 添加 distinct on - * - * @param fieldName java variable name - * @return Select - */ - default T distinctOn(String fieldName) { - return distinctOn(fieldName, fieldName); - } - - /** - * 添加 distinct on - * - * @param fieldName java variable name - * @param alias 别名 - * @return Select - */ - T distinctOn(String fieldName, String alias); - - /** - * 添加 min(field) alias - * - * @param reference 方法引用 - * @param 实体类型 - * @return Select - */ - default T min(MethodReferenceColumn reference) { - return min(reference.getColumn()); - } - - /** - * 添加 min(field) alias - * - * @param reference 方法引用 - * @param alias 别名 - * @param 实体类型 - * @return Select - */ - default T min(MethodReferenceColumn reference, String alias) { - return min(reference.getColumn(), alias); - } - - /** - * 添加 min(field) alias - * - * @param fieldName java variable name - * @return Select - */ - default T min(String fieldName) { - return min(fieldName, null); - } - - /** - * 添加 min(field) alias - * - * @param fieldName java variable name - * @param alias 别名 - * @return Select - */ - default T min(String fieldName, String alias) { - return aggregate(Func.MIN_FUNCTION.getName(), fieldName, alias, null); - } - - /** - * 添加 max(field) alias - * - * @param reference 方法引用 - * @param 实体类型 - * @return Select - */ - default T max(MethodReferenceColumn reference) { - return max(reference.getColumn()); - } - - /** - * 添加 max(field) alias - * - * @param reference 方法应用 - * @param alias 别名 - * @param 实体类型 - * @return Select - */ - default T max(MethodReferenceColumn reference, String alias) { - return max(reference.getColumn(), alias); - } - - /** - * 添加 max(field) alias - * - * @param fieldName java variable name - * @return Select - */ - default T max(String fieldName) { - return max(fieldName, fieldName); - } - - /** - * 添加 max(field) alias - * - * @param fieldName java variable name - * @param alias 别名 - * @return Select - */ - default T max(String fieldName, String alias) { - return aggregate(Func.MAX_FUNCTION.getName(), fieldName, alias, null); - } - - /** - * 添加 avg(field) alias - * - * @param reference 方法引用 - * @param 实体类型 - * @return Select - */ - default T avg(MethodReferenceColumn reference) { - return avg(reference.getColumn()); - } - - /** - * 添加 avg(field) alias - * - * @param reference 方法应用 - * @param alias 别名 - * @param 实体类型 - * @return Select - */ - default T avg(MethodReferenceColumn reference, String alias) { - return avg(reference.getColumn(), alias); - } - - /** - * 添加 avg(field) alias - * - * @param fieldName java variable name - * @return Select - */ - default T avg(String fieldName) { - return avg(fieldName, fieldName); - } - - /** - * 添加 avg(field) alias - * - * @param fieldName java variable name - * @param alias 别名 - * @return Select - */ - default T avg(String fieldName, String alias) { - return aggregate(Func.AVG_FUNCTION.getName(), fieldName, alias, null); - } - - /** - * 添加 count(field) alias - * - * @return Select - */ - default T count() { - return count(StringPool.ASTERISK, "count"); - } - - /** - * 添加 count(field) alias - * - * @param reference 方法应用 - * @param 实体类型 - * @return Select - */ - default T count(MethodReferenceColumn reference) { - return count(reference.getColumn(), null); - } - - /** - * 添加 count(field) alias - * - * @param reference 方法引用 - * @param alias 别名 - * @param 实体类型 - * @return Select - */ - default T count(MethodReferenceColumn reference, String alias) { - return count(reference.getColumn(), alias); - } - - /** - * 添加 count(field) alias - * - * @param fieldName java variable name - * @return Select - */ - default T count(String fieldName) { - return count(fieldName, null); - } - - /** - * 添加 count(field) alias - * - * @param fieldName java variable name - * @param alias 别名 - * @return Select - */ - default T count(String fieldName, String alias) { - return aggregate(Func.COUNT_FUNCTION.getName(), fieldName, alias, null); - } - - /** - * Select 函数 - * - * @param syntax 函数语法 - * @param fieldName java variable name - * @param alias 别名 - * @param distinct distinct - * @return Select - * @see Func - */ - T aggregate(String syntax, String fieldName, String alias, Distinct distinct); - - @Override - default int order() { - return SELECT_ORDER; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SelectDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SelectDelegate.java deleted file mode 100644 index 576ab6ca..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SelectDelegate.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -/** - * Select代理 - * - * @author jiangwei - * @date 2022/9/30 15:05 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface SelectDelegate extends QuerySQLAssociation, Select { - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SelectFrom.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SelectFrom.java deleted file mode 100644 index 7094a0ed..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SelectFrom.java +++ /dev/null @@ -1,38 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.data.orm.sql.From; -import cc.allio.uno.data.orm.sql.JoinType; - -/** - * from delegate - * - * @author jiangwei - * @date 2023/1/11 09:50 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface SelectFrom> extends From { - - /** - * FROM SUB_QUERY - * - * @return SubQueryFrom - */ - SubQueryFrom subQuery(); - - /** - * JOIN - * - * @return JoinFrom - */ - JoinFrom join(JoinType joinType); - - default JoinFrom leftJoin() { - return join(JoinType.LEFT_OUTER_JOIN); - } - - default JoinFrom rightJoin() { - return join(JoinType.RIGHT_OUTER_JOIN); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SubQueryFrom.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SubQueryFrom.java deleted file mode 100644 index cce04045..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SubQueryFrom.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -/** - * FROM (SUB_QUERY) - * - * @author jiangwei - * @date 2023/2/27 18:00 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface SubQueryFrom extends QuerySQLAssociation { - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Where.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Where.java deleted file mode 100644 index d8087eae..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/Where.java +++ /dev/null @@ -1,290 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -import cc.allio.uno.data.orm.sql.ColumnStatement; -import cc.allio.uno.data.orm.sql.MethodReferenceColumn; - -/** - * SQL Where相关语法 - * - * @author jiangwei - * @date 2022/9/30 13:46 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface Where> extends ColumnStatement { - - /** - * > condition - * - * @param reference 方法引用 - * @param value 比较数据值 - * @return where instance - */ - default T gt(MethodReferenceColumn reference, Object value) { - return gt(reference.getColumn(), value); - } - - /** - * > condition - * - * @param fieldName java variable name - * @param value 比较数据值 - * @return where instance - */ - T gt(String fieldName, Object value); - - /** - * >= condition - * - * @param reference 方法引用 - * @param value 比较数据值 - * @return where instance - */ - default T gte(MethodReferenceColumn reference, Object value) { - return gte(reference.getColumn(), value); - } - - /** - * >= condition - * - * @param fieldName java variable name - * @param value 比较数据值 - * @return where instance - */ - T gte(String fieldName, Object value); - - /** - * < condition - * - * @param reference 方法引用 - * @param value 比较数据值 - * @return where instance - */ - default T lt(MethodReferenceColumn reference, Object value) { - return lt(reference.getColumn(), value); - } - - /** - * < condition - * - * @param fieldName java variable name - * @param value 比较数据值 - * @return where instance - */ - T lt(String fieldName, Object value); - - /** - * <= condition - * - * @param reference 方法引用 - * @param value 比较数据值 - * @return where instance - */ - default T lte(MethodReferenceColumn reference, Object value) { - return lte(reference.getColumn(), value); - } - - /** - * <= condition - * - * @param fieldName java variable name - * @param value 比较数据值 - * @return where instance - */ - T lte(String fieldName, Object value); - - /** - * = condition - * - * @param reference 方法引用 - * @param value 比较数据值 - * @return where instance - */ - default T eq(MethodReferenceColumn reference, Object value) { - return eq(reference.getColumn(), value); - } - - /** - * = condition - * - * @param fieldName java variable name - * @param value 比较数据值 - * @return where instance - */ - T eq(String fieldName, Object value); - - /** - * is not null condition - * - * @param reference 方法引用 - * @return where instance - */ - default T notNull(MethodReferenceColumn reference) { - return notNull(reference.getColumn()); - } - - /** - * is not null condition - * - * @param fieldName java variable name - * @return where instance - */ - T notNull(String fieldName); - - /** - * is null condition - * - * @param reference 方法引用 - * @return where - */ - default T isNull(MethodReferenceColumn reference) { - return isNull(reference.getColumn()); - } - - /** - * is null condition - * - * @param fieldName java variable name - * @return where - */ - T isNull(String fieldName); - - /** - * 'in'条件 - * - * @param reference 方法引用 - * @param values 数值数据 - * @return where instance - */ - default T in(MethodReferenceColumn reference, Object... values) { - return in(reference.getColumn(), values); - } - - /** - * 'in'条件 - * - * @param fieldName java variable name - * @param values 数值数据 - * @return where instance - */ - T in(String fieldName, Object... values); - - /** - * between condition - * - * @param reference 方法引用 - * @param withValue between起始值 - * @param endValue between结束值 - * @return where instance - */ - default T between(MethodReferenceColumn reference, Object withValue, Object endValue) { - return between(reference.getColumn(), withValue, endValue); - } - - /** - * between condition - * - * @param fieldName java variable name - * @param withValue between起始值 - * @param endValue between结束值 - * @return where instance - */ - T between(String fieldName, Object withValue, Object endValue); - - /** - * not between condition - * - * @param reference 方法引用 - * @param withValue between起始值 - * @param endValue between结束值 - * @return where instance - */ - default T notBetween(MethodReferenceColumn reference, Object withValue, Object endValue) { - return notBetween(reference.getColumn(), withValue, endValue); - } - - /** - * not between condition - * - * @param fieldName java variable name - * @param withValue between起始值 - * @param endValue between结束值 - * @return where instance - */ - T notBetween(String fieldName, Object withValue, Object endValue); - - /** - * '%field' - * - * @param reference 方法引用 - * @param value like值 - * @return where instance - */ - default T $like(MethodReferenceColumn reference, Object value) { - return $like(reference.getColumn(), value); - } - - /** - * '%field' - * - * @param fieldName java variable name - * @param value like值 - * @return where instance - */ - T $like(String fieldName, Object value); - - /** - * 'field%' - * - * @param reference 方法引用 - * @param value like值 - * @return where instance - */ - default T like$(MethodReferenceColumn reference, Object value) { - return like$(reference.getColumn(), value); - } - - /** - * 'field%' - * - * @param fieldName java variable name - * @param value like值 - * @return where instance - */ - T like$(String fieldName, Object value); - - /** - * '%like%' - * - * @param reference 方法引用 - * @param value like值 - * @return where instance - */ - default T $like$(MethodReferenceColumn reference, Object value) { - return $like$(reference.getColumn(), value); - } - - /** - * '%like%' - * - * @param fieldName java variable name - * @param value like值 - * @return where instance - */ - T $like$(String fieldName, Object value); - - /** - * 逻辑'and'控制 - * - * @return where instance - */ - T or(); - - /** - * 逻辑'or'控制 - * - * @return where instance - */ - T and(); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/WhereDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/WhereDelegate.java deleted file mode 100644 index bea0cba2..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/WhereDelegate.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml; - -/** - * Where代理 - * - * @author jiangwei - * @date 2022/9/30 14:59 - * @since 1.1.0 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public interface WhereDelegate extends QuerySQLAssociation, Where { - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidJoinFrom.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidJoinFrom.java deleted file mode 100644 index 7ca63b4a..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidJoinFrom.java +++ /dev/null @@ -1,59 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; -import cc.allio.uno.data.orm.sql.JoinType; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.dml.JoinFrom; - -import java.util.Collection; - -public class DruidJoinFrom implements JoinFrom { - - private final DruidSelectFrom parent; - private final JoinType joinType; - - public DruidJoinFrom(DruidSelectFrom parent, JoinType joinType) { - this.parent = parent; - this.joinType = joinType; - } - - @Override - public DruidJoinFrom from(Class tableEntity) throws SQLException { - return null; - } - - @Override - public DruidJoinFrom from(String table) throws SQLException { - return null; - } - - @Override - public DruidJoinFrom from(String table, String alias) { - return null; - } - - @Override - public String getSQL() throws SQLException { - return null; - } - - @Override - public String getCondition() { - return null; - } - - @Override - public Collection getExpressions() { - return null; - } - - @Override - public void syntaxCheck() throws SQLException { - - } - - @Override - public int order() { - return 0; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLDeleteQueryOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLDeleteQueryOperator.java deleted file mode 100644 index 35305d7c..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLDeleteQueryOperator.java +++ /dev/null @@ -1,214 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.sql.PrepareValue; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLPrepareOperatorImpl; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.expr.*; -import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; -import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; -import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; -import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.type.Types; -import cc.allio.uno.data.orm.sql.dml.SQLDeleteOperator; - -import java.util.Arrays; -import java.util.stream.Collectors; - -/** - * DruidSQLDeleteQueryOperator - * - * @author jiangwei - * @date 2023/4/16 18:43 - * @since 1.1.4 - */ -public class DruidSQLDeleteQueryOperator extends SQLPrepareOperatorImpl implements SQLDeleteOperator { - - private SQLDeleteStatement deleteStatement; - private final DbType druidDbType; - - public DruidSQLDeleteQueryOperator(DBType dbType) { - super(); - this.druidDbType = DruidDbTypeAdapter.getInstance().get(dbType); - this.deleteStatement = new SQLDeleteStatement(); - deleteStatement.setDbType(druidDbType); - } - - @Override - public String getSQL() { - return ParameterizedOutputVisitorUtils.restore( - getPrepareSQL(), - druidDbType, - getPrepareValues().stream().map(PrepareValue::getValue).collect(Collectors.toList())); - - } - - @Override - public SQLDeleteOperator parse(String sql) { - return null; - } - - @Override - public void reset() { - super.reset(); - this.deleteStatement = new SQLDeleteStatement(); - deleteStatement.setDbType(druidDbType); - } - - @Override - public String getPrepareSQL() { - return SQLUtils.toSQLString(deleteStatement); - } - - @Override - public SQLDeleteOperator from(Table table) { - SQLExprTableSource tableSource = new SQLExprTableSource(); - tableSource.setExpr(new SQLIdentifierExpr(table.getName().format())); - tableSource.setCatalog(table.getCatalog()); - deleteStatement.setFrom(tableSource); - return self(); - } - - @Override - public SQLDeleteOperator gt(SQLName sqlName, Object value) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.GreaterThan, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLDeleteOperator gte(SQLName sqlName, Object value) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.GreaterThanOrEqual, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLDeleteOperator lt(SQLName sqlName, Object value) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.LessThan, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLDeleteOperator lte(SQLName sqlName, Object value) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.LessThanOrEqual, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLDeleteOperator eq(SQLName sqlName, Object value) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Equality, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLDeleteOperator notNull(SQLName sqlName) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.IsNot, new SQLNullExpr(), druidDbType)); - return self(); - } - - @Override - public SQLDeleteOperator isNull(SQLName sqlName) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Is, new SQLNullExpr(), druidDbType)); - return self(); - } - - @Override - public SQLDeleteOperator in(SQLName sqlName, Object... values) { - SQLInListExpr sqlInListExpr = new SQLInListExpr(new SQLIdentifierExpr(sqlName.format())); - Arrays.stream(values).forEach(value -> { - sqlInListExpr.addTarget(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - addPrepareValue(sqlName.getName(), value); - }); - deleteStatement.addWhere(sqlInListExpr); - return self(); - } - - @Override - public SQLDeleteOperator between(SQLName sqlName, Object withValue, Object endValue) { - SQLBetweenExpr sqlBetweenExpr = - new SQLBetweenExpr(new SQLIdentifierExpr(sqlName.format()), new SQLVariantRefExpr(StringPool.QUESTION_MARK), new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - addPrepareValue(sqlName.getName(), withValue); - addPrepareValue(sqlName.getName(), endValue); - deleteStatement.addWhere(sqlBetweenExpr); - return self(); - } - - @Override - public SQLDeleteOperator notBetween(SQLName sqlName, Object withValue, Object endValue) { - SQLBetweenExpr sqlBetweenExpr = - new SQLBetweenExpr(new SQLIdentifierExpr(sqlName.format()), new SQLVariantRefExpr(StringPool.QUESTION_MARK), new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - sqlBetweenExpr.setNot(true); - addPrepareValue(sqlName.getName(), withValue); - addPrepareValue(sqlName.getName(), endValue); - deleteStatement.addWhere(sqlBetweenExpr); - return self(); - } - - @Override - public SQLDeleteOperator like(SQLName sqlName, Object value) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLDeleteOperator $like(SQLName sqlName, Object value) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus + Types.toString(value)); - return self(); - } - - @Override - public SQLDeleteOperator like$(SQLName sqlName, Object value) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), Types.toString(value) + SQLBinaryOperator.Modulus); - return self(); - } - - @Override - public SQLDeleteOperator $like$(SQLName sqlName, Object value) { - deleteStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus + Types.toString(value) + SQLBinaryOperator.Modulus); - return self(); - } - - @Override - public SQLDeleteOperator or() { - throw new UnsupportedOperationException("DruidQueryOperator not support"); - } - - @Override - public SQLDeleteOperator and() { - throw new UnsupportedOperationException("DruidQueryOperator not support"); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLInsertOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLInsertOperator.java deleted file mode 100644 index 73abab33..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLInsertOperator.java +++ /dev/null @@ -1,154 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.sql.PrepareValue; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLPrepareOperatorImpl; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.SQLStatement; -import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; -import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; -import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; -import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; -import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * Druid INSERT - * - * @author jiangwei - * @date 2023/4/13 16:25 - * @since 1.1.4 - */ -public class DruidSQLInsertOperator extends SQLPrepareOperatorImpl implements SQLInsertOperator { - - private SQLInsertStatement insertStatement; - private final DbType druidDbType; - // 暂存于已经添加过的column - private final Set columns; - - public DruidSQLInsertOperator(DBType dbType) { - super(); - this.druidDbType = DruidDbTypeAdapter.getInstance().get(dbType); - this.insertStatement = new SQLInsertStatement(); - insertStatement.setDbType(druidDbType); - this.columns = Sets.newHashSet(); - } - - @Override - public String getSQL() { - return ParameterizedOutputVisitorUtils.restore( - getPrepareSQL(), - druidDbType, - getPrepareValues().stream().map(PrepareValue::getValue).collect(Collectors.toList())); - } - - @Override - public SQLInsertOperator parse(String sql) { - List sqlStatements = SQLUtils.parseStatements(sql, druidDbType); - insertStatement = (SQLInsertStatement) sqlStatements.get(0); - insertStatement.setDbType(druidDbType); - return self(); - } - - @Override - public void reset() { - super.reset(); - this.insertStatement = new SQLInsertStatement(); - insertStatement.setDbType(druidDbType); - columns.clear(); - } - - @Override - public SQLInsertOperator from(Table table) { - SQLExprTableSource tableSource = new SQLExprTableSource(); - tableSource.setExpr(new SQLIdentifierExpr(table.getName().format())); - tableSource.setCatalog(table.getCatalog()); - insertStatement.setTableSource(tableSource); - return self(); - } - - @Override - public SQLInsertOperator inserts(Map values) { - SQLInsertStatement.ValuesClause valuesClause = new SQLInsertStatement.ValuesClause(); - for (Map.Entry columnValue : values.entrySet()) { - String column = columnValue.getKey().format(); - Object value = columnValue.getValue(); - addColumn(column); - valuesClause.addValue(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - addPrepareValue(columnValue.getKey().getName(), value); - } - // 验证value是否与columns一致 - if (valuesClause.getValues().size() != columns.size()) { - throw new IllegalArgumentException( - String.format("Append values not equals columns. now columns is %s, values is %s", columns, valuesClause.getValues())); - } - insertStatement.addValueCause(valuesClause); - return self(); - } - - @Override - public SQLInsertOperator batchInserts(Collection columns, Collection> values) { - // 添加column - for (SQLName sqlName : columns) { - addColumn(sqlName.getName()); - } - List newColumns = Lists.newArrayList(columns); - // 添加value - AtomicInteger index = new AtomicInteger(0); - values.stream().flatMap(value -> { - // match and verifying - SQLInsertStatement.ValuesClause valuesClause = new SQLInsertStatement.ValuesClause(); - value.forEach(nowValue -> { - SQLName matchColumn; - try { - matchColumn = newColumns.get(index.getAndIncrement()); - } catch (ArrayIndexOutOfBoundsException ex) { - throw new IllegalArgumentException("Append values more than columns.", ex); - } - valuesClause.addValue(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - addPrepareValue(matchColumn.getName(), nowValue); - }); - index.set(0); - return Stream.of(valuesClause); - }) - .forEach(valuesClause -> { - // 验证 - if (valuesClause.getValues().size() != columns.size()) { - throw new IllegalArgumentException( - String.format("Append values not equals columns. now columns is %s, values is %s", columns, valuesClause.getValues())); - } - insertStatement.addValueCause(valuesClause); - }); - return self(); - } - - /** - * 添加column到缓存与{@link SQLInsertStatement},如果已经存在则不进行添加。 - * - * @param column column - */ - private void addColumn(String column) { - if (!columns.contains(column)) { - columns.add(column); - insertStatement.addColumn(new SQLIdentifierExpr(column)); - } - } - - @Override - public String getPrepareSQL() { - return SQLUtils.toSQLString(insertStatement); - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLQueryOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLQueryOperator.java deleted file mode 100644 index df6c32fd..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLQueryOperator.java +++ /dev/null @@ -1,405 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.dialect.func.Func; -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.dml.local.OrderCondition; -import cc.allio.uno.data.orm.sql.word.Distinct; -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.*; -import com.alibaba.druid.sql.ast.expr.*; -import com.alibaba.druid.sql.ast.statement.*; -import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; -import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.util.CollectionUtils; -import cc.allio.uno.core.type.Types; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Druid Query Operator - * - * @author jiangwei - * @date 2023/4/12 23:08 - * @since 1.1.4 - */ -public class DruidSQLQueryOperator extends SQLPrepareOperatorImpl implements SQLQueryOperator { - - private final DbType druidDbType; - private final DruidTokenOperatorAdapter tokenOperatorAdapter; - - private SQLSelectQueryBlock selectQuery; - private SQLTableSource tableSource; - - // order by - private SQLOrderBy orderBy; - // group by - private SQLSelectGroupByClause groupBy; - // limit by - private SQLLimit sqlLimit; - - public DruidSQLQueryOperator(DBType dbType) { - super(); - this.tokenOperatorAdapter = new DruidTokenOperatorAdapter(); - this.druidDbType = DruidDbTypeAdapter.getInstance().get(dbType); - this.selectQuery = new SQLSelectQueryBlock(); - selectQuery.setDbType(druidDbType); - } - - @Override - public String getSQL() { - List values = getPrepareValues().stream().map(PrepareValue::getValue).collect(Collectors.toList()); - if (CollectionUtils.isEmpty(values)) { - return getPrepareSQL(); - } - return ParameterizedOutputVisitorUtils.restore( - getPrepareSQL(), - druidDbType, - getPrepareValues().stream().map(PrepareValue::getValue).collect(Collectors.toList())); - } - - @Override - public SQLQueryOperator parse(String sql) { - return null; - } - - @Override - public void reset() { - super.reset(); - this.selectQuery = new SQLSelectQueryBlock(); - selectQuery.setDbType(druidDbType); - this.tableSource = null; - this.orderBy = null; - this.groupBy = null; - this.sqlLimit = null; - } - - @Override - public SQLQueryOperator select(SQLName sqlName) { - SQLSelectItem sqlSelectItem; - if (StringPool.ASTERISK.equals(sqlName.format())) { - sqlSelectItem = new SQLSelectItem(new SQLAllColumnExpr()); - } else { - sqlSelectItem = new SQLSelectItem(new SQLIdentifierExpr(sqlName.format())); - } - selectQuery.addSelectItem(sqlSelectItem); - return self(); - } - - @Override - public SQLQueryOperator select(SQLName sqlName, String alias) { - SQLSelectItem sqlSelectItem = new SQLSelectItem(new SQLIdentifierExpr(sqlName.format()), alias); - selectQuery.addSelectItem(sqlSelectItem); - return self(); - } - - @Override - public SQLQueryOperator selects(Collection sqlNames) { - for (SQLName sqlName : sqlNames) { - SQLSelectItem sqlSelectItem = new SQLSelectItem(new SQLIdentifierExpr(sqlName.format())); - selectQuery.addSelectItem(sqlSelectItem); - } - return self(); - } - - @Override - public SQLQueryOperator distinct() { - SQLSelectItem sqlSelectItem = new SQLSelectItem(new SQLAggregateExpr("", SQLAggregateOption.DISTINCT)); - selectQuery.addSelectItem(sqlSelectItem); - return self(); - } - - @Override - public SQLQueryOperator distinctOn(SQLName sqlName, String alias) { - SQLSelectItem sqlSelectItem = new SQLSelectItem(new SQLAggregateExpr(sqlName.format(), SQLAggregateOption.DISTINCT)); - selectQuery.addSelectItem(sqlSelectItem); - return self(); - } - - @Override - public SQLQueryOperator aggregate(Func syntax, SQLName sqlName, String alias, Distinct distinct) { - SQLSelectItem sqlSelectItem = new SQLSelectItem(); - SQLAggregateExpr sqlAggregateExpr = new SQLAggregateExpr(syntax.getName()); - if (distinct != null) { - sqlAggregateExpr.setOption(SQLAggregateOption.DISTINCT); - } - sqlAggregateExpr.addArgument(new SQLIdentifierExpr(sqlName.format())); - sqlSelectItem.setExpr(sqlAggregateExpr); - selectQuery.addSelectItem(sqlSelectItem); - return self(); - } - - @Override - public SQLQueryOperator from(Table table) { - this.tableSource = new SQLExprTableSource(new SQLIdentifierExpr(table.getName().getName()), table.getAlias()); - return self(); - } - - @Override - public SQLQueryOperator from(SQLQueryOperator fromTable, String alias) { - String fromSQL = fromTable.getSQL(); - SQLStatement sqlStatement = SQLUtils.parseSingleStatement(fromSQL, druidDbType, true); - SQLSubqueryTableSource from = new SQLSubqueryTableSource((SQLSelect) sqlStatement); - from.setAlias(alias); - this.tableSource = from; - return self(); - } - - @Override - public SQLQueryOperator join(Table left, JoinType joinType, Table right, SQLBinaryCondition condition) { - // 构建连接关系 - SQLExprTableSource rightSource = new SQLExprTableSource(new SQLIdentifierExpr(right.getName().format()), right.getAlias()); - SQLBinaryOperator operator = tokenOperatorAdapter.get(condition.getSyntax()); - SQLBinaryOpExpr opExpr = new SQLBinaryOpExpr(new SQLIdentifierExpr(condition.getLeft()), operator, new SQLIdentifierExpr(condition.getRight())); - // 判断是否已经包含连接关系,如果则组建复合关系 - if (tableSource != null && tableSource instanceof SQLJoinTableSource) { - SQLJoinTableSource combineTableSource = new SQLJoinTableSource(); - tableSource.setAlias(left.getAlias()); - combineTableSource.setLeft(tableSource); - combineTableSource.setRight(rightSource); - combineTableSource.setJoinType(DruidJoinTypeAdapter.getInstance().get(joinType)); - combineTableSource.setCondition(opExpr); - this.tableSource = combineTableSource; - } else { - SQLJoinTableSource joinTableSource = new SQLJoinTableSource(); - SQLExprTableSource leftSource = new SQLExprTableSource(new SQLIdentifierExpr(left.getName().format()), left.getAlias()); - joinTableSource.setRight(rightSource); - joinTableSource.setJoinType(DruidJoinTypeAdapter.getInstance().get(joinType)); - joinTableSource.setCondition(opExpr); - joinTableSource.setLeft(leftSource); - this.tableSource = joinTableSource; - } - return self(); - } - - @Override - public SQLQueryOperator orderBy(SQLName sqlName, OrderCondition orderCondition) { - OrderCondition selfOrderCondition = orderCondition; - if (selfOrderCondition == null) { - selfOrderCondition = OrderCondition.DESC; - } - SQLOrderingSpecification druidOrder; - switch (selfOrderCondition) { - case ASC: - druidOrder = SQLOrderingSpecification.ASC; - break; - case DESC: - default: - druidOrder = SQLOrderingSpecification.DESC; - } - getOrderBy().addItem(new SQLIdentifierExpr(sqlName.format()), druidOrder); - return self(); - } - - @Override - public SQLQueryOperator limit(Long limit, Long offset) { - getLimit().setOffset(Math.toIntExact(offset)); - getLimit().setRowCount(Math.toIntExact(limit)); - return self(); - } - - @Override - public SQLQueryOperator groupByOnes(Collection fieldNames) { - fieldNames.stream() - .map(sqlName -> new SQLIdentifierExpr(sqlName.format())) - .forEach(getGroupBy()::addItem); - return self(); - } - - @Override - public SQLQueryOperator gt(SQLName sqlName, Object value) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.GreaterThan, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLQueryOperator gte(SQLName sqlName, Object value) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.GreaterThanOrEqual, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLQueryOperator lt(SQLName sqlName, Object value) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.LessThan, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLQueryOperator lte(SQLName sqlName, Object value) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.LessThanOrEqual, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLQueryOperator eq(SQLName sqlName, Object value) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Equality, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLQueryOperator notNull(SQLName sqlName) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.IsNot, new SQLNullExpr(), druidDbType)); - return self(); - } - - @Override - public SQLQueryOperator isNull(SQLName sqlName) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Is, new SQLNullExpr(), druidDbType)); - return self(); - } - - @Override - public SQLQueryOperator in(SQLName sqlName, Object... values) { - SQLInListExpr sqlInListExpr = new SQLInListExpr(new SQLIdentifierExpr(sqlName.format())); - Arrays.stream(values).forEach(value -> { - sqlInListExpr.addTarget(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - addPrepareValue(sqlName.getName(), value); - }); - selectQuery.addWhere(sqlInListExpr); - return self(); - } - - @Override - public SQLQueryOperator between(SQLName sqlName, Object withValue, Object endValue) { - SQLBetweenExpr sqlBetweenExpr = - new SQLBetweenExpr(new SQLIdentifierExpr(sqlName.format()), new SQLVariantRefExpr(StringPool.QUESTION_MARK), new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - addPrepareValue(sqlName.getName(), withValue); - addPrepareValue(sqlName.getName(), endValue); - selectQuery.addWhere(sqlBetweenExpr); - return self(); - } - - @Override - public SQLQueryOperator notBetween(SQLName sqlName, Object withValue, Object endValue) { - SQLBetweenExpr sqlBetweenExpr = - new SQLBetweenExpr(new SQLIdentifierExpr(sqlName.format()), new SQLVariantRefExpr(StringPool.QUESTION_MARK), new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - sqlBetweenExpr.setNot(true); - addPrepareValue(sqlName.getName(), withValue); - addPrepareValue(sqlName.getName(), endValue); - selectQuery.addWhere(sqlBetweenExpr); - return self(); - } - - @Override - public SQLQueryOperator like(SQLName sqlName, Object value) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLQueryOperator $like(SQLName sqlName, Object value) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus + Types.toString(value)); - return self(); - } - - @Override - public SQLQueryOperator like$(SQLName sqlName, Object value) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), Types.toString(value) + SQLBinaryOperator.Modulus); - return self(); - } - - @Override - public SQLQueryOperator $like$(SQLName sqlName, Object value) { - selectQuery.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus + Types.toString(value) + SQLBinaryOperator.Modulus); - return self(); - } - - @Override - public SQLQueryOperator or() { - throw new UnsupportedOperationException("DruidQueryOperator not support"); - } - - @Override - public SQLQueryOperator and() { - throw new UnsupportedOperationException("DruidQueryOperator not support"); - } - - /** - * 获取 order by子句 - * - * @return orderBy - */ - private SQLOrderBy getOrderBy() { - if (orderBy == null) { - orderBy = new SQLOrderBy(); - } - return orderBy; - } - - /** - * 获取 group by 实例 - * - * @return groupBy - */ - private SQLSelectGroupByClause getGroupBy() { - if (groupBy == null) { - groupBy = new SQLSelectGroupByClause(); - } - return groupBy; - } - - /** - * 获取limit子句 - * - * @return limit - */ - private SQLLimit getLimit() { - if (sqlLimit == null) { - sqlLimit = new SQLLimit(); - } - return sqlLimit; - } - - @Override - public String getPrepareSQL() { - if (orderBy != null) { - selectQuery.setOrderBy(orderBy); - } - if (groupBy != null) { - selectQuery.setGroupBy(groupBy); - } - if (sqlLimit != null) { - selectQuery.setLimit(sqlLimit); - } - selectQuery.setFrom(tableSource); - return SQLUtils.toSQLString(selectQuery); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLUpdateOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLUpdateOperator.java deleted file mode 100644 index 67e1b754..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLUpdateOperator.java +++ /dev/null @@ -1,269 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.expr.*; -import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; -import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; -import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; -import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; -import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.type.Types; -import cc.allio.uno.data.orm.sql.PrepareValue; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLPrepareOperatorImpl; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.dml.SQLUpdateOperator; -import org.apache.commons.lang3.ArrayUtils; - -import java.util.Arrays; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * DruidSQLUpdateOperator - * - * @author jiangwei - * @date 2023/4/16 18:18 - * @since 1.1.4 - */ -public class DruidSQLUpdateOperator extends SQLPrepareOperatorImpl implements SQLUpdateOperator { - - private final DbType druidDbType; - - private SQLUpdateStatement updateStatement; - - /** - * 记录update where开始的索引 - */ - private int wherePrepareIndex; - - /** - * where条件值的大小 - */ - private int whereSize; - - public DruidSQLUpdateOperator(DBType dbType) { - super(); - this.druidDbType = DruidDbTypeAdapter.getInstance().get(dbType); - this.updateStatement = new SQLUpdateStatement(); - updateStatement.setDbType(druidDbType); - } - - @Override - public String getSQL() { - return ParameterizedOutputVisitorUtils.restore( - getPrepareSQL(), - druidDbType, - getPrepareValues().stream().map(PrepareValue::getValue).collect(Collectors.toList())); - } - - @Override - public SQLUpdateOperator parse(String sql) { - throw new UnsupportedOperationException("DruidSQLUpdateOperator not support"); - } - - @Override - public void reset() { - super.reset(); - this.updateStatement = new SQLUpdateStatement(); - updateStatement.setDbType(druidDbType); - } - - @Override - public SQLUpdateOperator from(Table table) { - SQLExprTableSource tableSource = new SQLExprTableSource(); - tableSource.setExpr(new SQLIdentifierExpr(table.getName().format())); - tableSource.setCatalog(table.getCatalog()); - updateStatement.setFrom(tableSource); - updateStatement.setTableSource(tableSource); - return self(); - } - - @Override - public SQLUpdateOperator gt(SQLName sqlName, Object value) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.GreaterThan, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLUpdateOperator gte(SQLName sqlName, Object value) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.GreaterThanOrEqual, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLUpdateOperator lt(SQLName sqlName, Object value) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.LessThan, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLUpdateOperator lte(SQLName sqlName, Object value) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.LessThanOrEqual, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLUpdateOperator eq(SQLName sqlName, Object value) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Equality, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLUpdateOperator notNull(SQLName sqlName) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.IsNot, new SQLNullExpr(), druidDbType)); - return self(); - } - - @Override - public SQLUpdateOperator isNull(SQLName sqlName) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Is, new SQLNullExpr(), druidDbType)); - return self(); - } - - @Override - public SQLUpdateOperator in(SQLName sqlName, Object... values) { - SQLInListExpr sqlInListExpr = new SQLInListExpr(new SQLIdentifierExpr(sqlName.format())); - Arrays.stream(values).forEach(value -> { - sqlInListExpr.addTarget(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - addPrepareValue(sqlName.getName(), value); - }); - updateStatement.addWhere(sqlInListExpr); - return self(); - } - - @Override - public SQLUpdateOperator between(SQLName sqlName, Object withValue, Object endValue) { - SQLBetweenExpr sqlBetweenExpr = - new SQLBetweenExpr(new SQLIdentifierExpr(sqlName.format()), new SQLVariantRefExpr(StringPool.QUESTION_MARK), new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - addPrepareValue(sqlName.getName(), withValue); - addPrepareValue(sqlName.getName(), endValue); - updateStatement.addWhere(sqlBetweenExpr); - return self(); - } - - @Override - public SQLUpdateOperator notBetween(SQLName sqlName, Object withValue, Object endValue) { - SQLBetweenExpr sqlBetweenExpr = - new SQLBetweenExpr(new SQLIdentifierExpr(sqlName.format()), new SQLVariantRefExpr(StringPool.QUESTION_MARK), new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - sqlBetweenExpr.setNot(true); - addPrepareValue(sqlName.getName(), withValue); - addPrepareValue(sqlName.getName(), endValue); - updateStatement.addWhere(sqlBetweenExpr); - return self(); - } - - @Override - public SQLUpdateOperator like(SQLName sqlName, Object value) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), value); - return self(); - } - - @Override - public SQLUpdateOperator $like(SQLName sqlName, Object value) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus + Types.toString(value)); - return self(); - } - - @Override - public SQLUpdateOperator like$(SQLName sqlName, Object value) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), Types.toString(value) + SQLBinaryOperator.Modulus); - return self(); - } - - @Override - public SQLUpdateOperator $like$(SQLName sqlName, Object value) { - updateStatement.addWhere( - new SQLBinaryOpExpr( - new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.Like, new SQLVariantRefExpr(StringPool.QUESTION_MARK), druidDbType)); - addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus + Types.toString(value) + SQLBinaryOperator.Modulus); - return self(); - } - - @Override - public SQLUpdateOperator or() { - throw new UnsupportedOperationException("DruidSQLUpdateOperator not support"); - } - - @Override - public SQLUpdateOperator and() { - throw new UnsupportedOperationException("DruidSQLUpdateOperator not support"); - } - - @Override - public SQLUpdateOperator updates(Map values) { - for (Map.Entry columnValue : values.entrySet()) { - String column = columnValue.getKey().format(); - Object value = columnValue.getValue(); - SQLUpdateSetItem updateSetItem = new SQLUpdateSetItem(); - updateSetItem.setColumn(new SQLIdentifierExpr(column)); - updateSetItem.setValue(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); - updateStatement.addItem(updateSetItem); - addPrepareValue(columnValue.getKey().getName(), value, false); - } - return self(); - } - - @Override - public String getPrepareSQL() { - return SQLUtils.toSQLString(updateStatement); - } - - /** - * 在where查询中,这部分是没有问题。如果在update,导致update xx where column = ?的占位符的值排序到前面,导致数据插入问题 - */ - @Override - protected void addPrepareValue(String column, Object value) { - addPrepareValue(column, value, true); - } - - /** - * 如果遇到非where条件,则把where数据进行挪动,让非where数据记录到where最后一个 - */ - private void addPrepareValue(String column, Object value, boolean isWhere) { - if (isWhere) { - super.addPrepareValue(column, value); - whereSize++; - } else { - ensureCapacityInternal(prepareValues.length + 1); - PrepareValue[] updateReplace = ArrayUtils.subarray(prepareValues, wherePrepareIndex, wherePrepareIndex + whereSize); - prepareValues[wherePrepareIndex] = PrepareValue.of(prepareIndex++, column, value); - // update数据进行替换 - for (int i = 0; i < updateReplace.length; i++) { - prepareValues[wherePrepareIndex + i + 1] = updateReplace[i]; - } - wherePrepareIndex++; - } - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSelect.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSelect.java deleted file mode 100644 index d288f2c2..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSelect.java +++ /dev/null @@ -1,123 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; -import cc.allio.uno.data.orm.sql.word.Distinct; -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.druid.DruidDbTypeAdapter; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.statement.SQLSelectItem; -import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.util.StringUtils; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.dml.Select; -import com.google.common.collect.Lists; - -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Druid 适配器 - * - * @author jiangwei - * @date 2023/2/23 16:28 - * @since 1.1.4 - * @deprecated 1.1.4版本删除 - */ -@Deprecated -public class DruidSelect implements Select { - - private final List selectItems; - private final DbType dbType; - - public DruidSelect(DBType dbType) { - this.selectItems = Lists.newLinkedList(); - this.dbType = DruidDbTypeAdapter.getInstance().get(dbType); - } - - @Override - public Collection getColumns() { - throw new UnsupportedOperationException("druid select un support operation"); - } - - @Override - public String getSQL() throws SQLException { - return selectItems.stream().map(SQLUtils::toSQLString).collect(Collectors.joining()); - } - - @Override - public String getCondition() { - return null; - } - - @Override - public Collection getExpressions() { - throw new UnsupportedOperationException("druid select un support operation"); - } - - @Override - public void syntaxCheck() throws SQLException { - - } - - @Override - public DruidSelect select(String fieldName) { - SQLExpr sqlExpr = SQLUtils.toSQLExpr(fieldName, dbType); - SQLSelectItem selectItem = new SQLSelectItem(sqlExpr); - selectItems.add(selectItem); - return self(); - } - - @Override - public DruidSelect select(String fieldName, String alias) { - SQLExpr sqlExpr = SQLUtils.toSQLExpr(fieldName, dbType); - SQLSelectItem selectItem = new SQLSelectItem(sqlExpr, alias); - selectItems.add(selectItem); - return self(); - } - - @Override - public DruidSelect select(String[] fieldNames) { - return select(Lists.newArrayList(fieldNames)); - } - - @Override - public DruidSelect select(Collection fieldNames) { - for (String fieldName : fieldNames) { - SQLSelectItem selectItem = SQLUtils.toSelectItem(fieldName, dbType); - selectItems.add(selectItem); - } - return self(); - } - - @Override - public DruidSelect distinct() { - throw new UnsupportedOperationException("druid select un support operation"); - } - - @Override - public DruidSelect distinctOn(String fieldName, String alias) { - throw new UnsupportedOperationException("druid select un support operation"); - } - - @Override - public DruidSelect aggregate(String syntax, String fieldName, String alias, Distinct distinct) { - String aggFunc = syntax + StringPool.LEFT_BRACKET + fieldName + StringPool.RIGHT_BRACKET; - SQLExpr sqlExpr = SQLUtils.toSQLExpr(aggFunc); - SQLSelectItem selectItem; - if (StringUtils.isBlank(alias)) { - selectItem = new SQLSelectItem(sqlExpr); - } else { - selectItem = new SQLSelectItem(sqlExpr, alias); - } - selectItems.add(selectItem); - return self(); - } - - public List getSelectItems() { - return selectItems; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSelectFrom.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSelectFrom.java deleted file mode 100644 index 13e49cb4..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSelectFrom.java +++ /dev/null @@ -1,81 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; -import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; -import cc.allio.uno.data.orm.sql.JoinType; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.dml.JoinFrom; -import cc.allio.uno.data.orm.sql.dml.SelectFrom; -import cc.allio.uno.data.orm.sql.dml.SubQueryFrom; -import jakarta.persistence.Table; -import org.springframework.core.annotation.AnnotationUtils; - -import java.util.Collection; - -/** - * DruidSelectFrom - * - * @author jiangwei - * @date 2023/4/13 15:01 - * @see DruidSQLQueryOperator - * @since 1.1.4 - * @deprecated 1.1.4 之后删除 - */ -@Deprecated -public class DruidSelectFrom implements SelectFrom { - - private final SQLExprTableSource tableSource = new SQLExprTableSource(); - - @Override - public DruidSelectFrom from(Class tableEntity) throws SQLException { - Table table = AnnotationUtils.findAnnotation(tableEntity, Table.class); - String tableName = table.name(); - return from(tableName); - } - - @Override - public DruidSelectFrom from(String table) throws SQLException { - return null; - } - - @Override - public DruidSelectFrom from(String table, String alias) { - - return null; - } - - @Override - public String getSQL() throws SQLException { - return null; - } - - @Override - public String getCondition() { - return null; - } - - @Override - public Collection getExpressions() { - return null; - } - - @Override - public void syntaxCheck() throws SQLException { - - } - - @Override - public int order() { - return 0; - } - - @Override - public SubQueryFrom subQuery() { - return null; - } - - @Override - public JoinFrom join(JoinType joinType) { - return new DruidJoinFrom(this, joinType); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/GroupColumn.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/GroupColumn.java deleted file mode 100644 index 62e8bf94..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/GroupColumn.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.Condition; -import cc.allio.uno.data.orm.sql.RuntimeColumn; - -/** - * Group Column - * - * @author jiangwei - * @date 2023/1/5 10:53 - * @since 1.1.4 - */ -public class GroupColumn extends RuntimeColumn { - - public GroupColumn(String name, Object[] value, Condition condition) { - super(name, value, condition); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/GroupStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/GroupStatement.java deleted file mode 100644 index b4fbb407..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/GroupStatement.java +++ /dev/null @@ -1,66 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionColumnStatement; -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionContext; -import cc.allio.uno.data.orm.sql.dml.local.expression.PlainExpression; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.dml.Group; -import com.baomidou.mybatisplus.core.toolkit.StringPool; -import com.baomidou.mybatisplus.core.toolkit.StringUtils; -import com.google.common.collect.Lists; - -import java.util.Collection; - -/** - * 分组语句 - * - * @author jiangwei - * @date 2022/9/30 13:40 - * @since 1.1.0 - */ -public class GroupStatement extends ExpressionColumnStatement implements Group { - - public GroupStatement(ExpressionContext expressionContext) { - super(expressionContext); - } - - @Override - public GroupStatement byOne(String fieldName) { - GroupColumn groupColumn = new GroupColumn(StringUtils.camelToUnderline(fieldName), null, null); - PlainExpression plainExpression = new PlainExpression(groupColumn, expressionContext); - lazyOffer(plainExpression, StringPool.COMMA); - addPrivatizationColumn(groupColumn); - return this; - } - - @Override - public GroupStatement byOnes(String... fieldNames) { - return byOnes(Lists.newArrayList(fieldNames)); - } - - @Override - public GroupStatement byOnes(Collection fieldNames) { - for (String name : fieldNames) { - GroupColumn groupColumn = new GroupColumn(StringUtils.camelToUnderline(name), null, null); - PlainExpression plainExpression = new PlainExpression(groupColumn, expressionContext); - lazyOffer(plainExpression, StringPool.COMMA); - addPrivatizationColumn(groupColumn); - } - return self(); - } - - @Override - public void syntaxCheck() throws SQLException { - - } - - @Override - public int order() { - return GROUP_ORDER; - } - - @Override - protected String getStatementSyntax() { - return GROUP_BY; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/GroupStatementDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/GroupStatementDelegate.java deleted file mode 100644 index 8375b29d..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/GroupStatementDelegate.java +++ /dev/null @@ -1,79 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.dml.*; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; - -import java.util.Collection; - -/** - * groupSQL语句代码 - * - * @author jiangwei - * @date 2022/9/30 14:13 - * @since 1.1.0 - */ -public class GroupStatementDelegate extends AbstractStatementDelegate implements GroupDelegate { - - public GroupStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit) { - super(select, from, where, group, order, limit); - } - - public GroupStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit, Statement parent) { - super(select, from, where, group, order, limit, parent); - } - - @Override - public GroupDelegate byOne(String fieldName) { - getGroup().byOne(fieldName); - return self(); - } - - @Override - public GroupDelegate byOnes(String... fieldNames) { - getGroup().byOnes(fieldNames); - return self(); - } - - @Override - public GroupDelegate byOnes(Collection fieldNames) { - getGroup().byOnes(fieldNames); - return self(); - } - - @Override - public String getSQL() throws SQLException { - if (getParent() != null) { - return getParent().getSQL(); - } - return getGroup().getSQL(); - } - - @Override - public String getCondition() { - return getGroup().getCondition(); - } - - @Override - public Collection getExpressions() { - if (getParent() != null) { - return getParent().getExpressions(); - } - return getGroup().getExpressions(); - } - - @Override - public void syntaxCheck() throws SQLException { - getGroup().syntaxCheck(); - } - - @Override - public int order() { - return getGroup().order(); - } - - @Override - public Collection getColumns() { - return getGroup().getColumns(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/LimitStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/LimitStatement.java deleted file mode 100644 index 93152c5e..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/LimitStatement.java +++ /dev/null @@ -1,68 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.dml.Limit; - -import java.util.Collection; -import java.util.Collections; - -/** - * limit statement - * - * @author jiangwei - * @date 2023/1/11 17:51 - * @since 1.1.4 - */ -public class LimitStatement implements Limit { - - // 赋予默认值 - private Integer limit = 0; - private Integer offset = 0; - - @Override - public Collection getExpressions() { - return Collections.emptyList(); - } - - @Override - public void syntaxCheck() throws SQLException { - if (limit == null) { - throw new SQLException("Limit Statement must exist [limit data]"); - } - } - - @Override - public int order() { - return LIMIT_ORDER; - } - - @Override - public LimitStatement limit(Integer number) { - this.limit = number; - return self(); - } - - @Override - public LimitStatement offset(Integer number) { - this.offset = number; - return self(); - } - - @Override - public String getSQL() throws SQLException { - StringBuilder limitSQL = new StringBuilder(); - limitSQL.append(LIMIT).append(StringPool.SPACE).append(limit); - if (offset != null) { - limitSQL.append(StringPool.SPACE).append(OFFSET).append(StringPool.SPACE).append(offset); - } - return limitSQL.toString(); - } - - @Override - public String getCondition() { - return null; - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/LimitStatementDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/LimitStatementDelegate.java deleted file mode 100644 index dae162c0..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/LimitStatementDelegate.java +++ /dev/null @@ -1,66 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.From; -import cc.allio.uno.data.orm.sql.FromStatement; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.Statement; -import cc.allio.uno.data.orm.sql.dml.*; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; - -import java.util.Collection; - -/** - * limit statement delegate - * - * @author jiangwei - * @date 2023/1/11 19:19 - * @since 1.1.4 - */ -public class LimitStatementDelegate extends AbstractStatementDelegate implements LimitDelegate { - - public LimitStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit) { - super(select, from, where, group, order, limit); - } - - public LimitStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit, Statement parent) { - super(select, from, where, group, order, limit, parent); - } - - @Override - public String getSQL() throws SQLException { - return getLimit().getSQL(); - } - - @Override - public String getCondition() { - return getLimit().getCondition(); - } - - @Override - public Collection getExpressions() { - return getLimit().getExpressions(); - } - - @Override - public void syntaxCheck() throws SQLException { - getLimit().syntaxCheck(); - } - - @Override - public int order() { - return getLimit().order(); - } - - @Override - public LimitDelegate limit(Integer number) { - getLimit().limit(number); - return self(); - } - - @Override - public LimitDelegate offset(Integer number) { - getLimit().offset(number); - return self(); - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderColumn.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderColumn.java deleted file mode 100644 index 43a0ec94..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderColumn.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.Condition; -import cc.allio.uno.data.orm.sql.RuntimeColumn; - -/** - * order column - * - * @author jiangwei - * @date 2023/1/5 10:54 - * @since 1.1.4 - */ -public class OrderColumn extends RuntimeColumn { - - public OrderColumn(String name, Object[] value, Condition condition) { - super(name, value, condition); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderStatement.java deleted file mode 100644 index a089098d..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderStatement.java +++ /dev/null @@ -1,62 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionColumnStatement; -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionContext; -import cc.allio.uno.data.orm.sql.dml.local.expression.PlainExpression; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.dml.Order; -import com.baomidou.mybatisplus.core.toolkit.StringPool; -import com.baomidou.mybatisplus.core.toolkit.StringUtils; - -/** - * 排序语句 - * - * @author jiangwei - * @date 2022/9/30 13:42 - * @since 1.1.0 - */ -public class OrderStatement extends ExpressionColumnStatement implements Order { - - public OrderStatement(ExpressionContext expressionContext) { - super(expressionContext); - } - - @Override - public OrderStatement byAsc(String fieldName) { - return orderBy(fieldName, ASC); - } - - @Override - public OrderStatement byDesc(String fieldName) { - return orderBy(fieldName, DESC); - } - - @Override - public OrderStatement orderBy(String fieldName, String order) { - return orderBy(fieldName, OrderCondition.valueOf(order)); - } - - @Override - public OrderStatement orderBy(String fieldName, OrderCondition orderCondition) { - OrderColumn orderColumn = new OrderColumn(StringUtils.camelToUnderline(fieldName), null, orderCondition); - PlainExpression plainExpression = new PlainExpression(orderColumn, expressionContext); - lazyOffer(plainExpression, StringPool.COMMA); - addPrivatizationColumn(orderColumn); - return self(); - } - - @Override - public void syntaxCheck() throws SQLException { - - } - - @Override - public int order() { - return ORDER_ORDER; - } - - @Override - protected String getStatementSyntax() { - return ORDER; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderStatementDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderStatementDelegate.java deleted file mode 100644 index 6ea636bb..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderStatementDelegate.java +++ /dev/null @@ -1,85 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.dml.*; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; - -import java.util.Collection; - -/** - * orderSQL语句代理 - * - * @author jiangwei - * @date 2022/9/30 14:11 - * @since 1.1.0 - */ -public class OrderStatementDelegate extends AbstractStatementDelegate implements OrderDelegate { - - public OrderStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit) { - super(select, from, where, group, order, limit); - } - - public OrderStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit, Statement parent) { - super(select, from, where, group, order, limit, parent); - } - - @Override - public OrderDelegate byAsc(String fieldName) { - getOrder().byAsc(fieldName); - return self(); - } - - @Override - public OrderDelegate byDesc(String fieldName) { - getOrder().byDesc(fieldName); - return self(); - } - - @Override - public OrderDelegate orderBy(String fieldName, String order) { - getOrder().orderBy(fieldName, order); - return self(); - } - - @Override - public OrderDelegate orderBy(String fieldName, OrderCondition orderCondition) { - getOrder().orderBy(fieldName, orderCondition); - return self(); - } - - @Override - public String getSQL() throws SQLException { - if (getParent() != null) { - return getParent().getSQL(); - } - return getOrder().getSQL(); - } - - @Override - public String getCondition() { - return getOrder().getCondition(); - } - - @Override - public Collection getExpressions() { - if (getParent() != null) { - return getParent().getExpressions(); - } - return getOrder().getExpressions(); - } - - @Override - public void syntaxCheck() throws SQLException { - getOrder().syntaxCheck(); - } - - @Override - public int order() { - return getOrder().order(); - } - - @Override - public Collection getColumns() { - return getOrder().getColumns(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/QueryFromStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/QueryFromStatement.java deleted file mode 100644 index 447f9e52..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/QueryFromStatement.java +++ /dev/null @@ -1,83 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.dml.*; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; - -import java.util.Collection; - -/** - * from statement delegate - * - * @author jiangwei - * @date 2023/1/11 13:27 - * @since 1.1.4 - */ -public class QueryFromStatement extends AbstractStatementDelegate implements SelectFrom { - - public QueryFromStatement(Select select, From from, Where where, Group group, Order order, Limit limit) { - super(select, from, where, group, order, limit); - } - - public QueryFromStatement(Select select, From from, Where where, Group group, Order order, Limit limit, Statement parent) { - super(select, from, where, group, order, limit, parent); - } - - @Override - public QueryFromStatement from(Class tableEntity) throws SQLException { - getFrom().from(tableEntity); - return self(); - } - - @Override - public QueryFromStatement from(String table) throws SQLException { - getFrom().from(table); - return self(); - } - - @Override - public QueryFromStatement from(String table, String alias) { - return null; - } - - @Override - public SubQueryFrom subQuery() { - return null; - } - - @Override - public JoinFrom join(JoinType joinType) { - return null; - } - - @Override - public String getSQL() throws SQLException { - if (getParent() != null) { - return getParent().getSQL(); - } - return getFrom().getSQL(); - } - - @Override - public String getCondition() { - return null; - } - - @Override - public Collection getExpressions() { - if (getParent() != null) { - return getParent().getExpressions(); - } - return getFrom().getExpressions(); - } - - @Override - public void syntaxCheck() throws SQLException { - getFrom().syntaxCheck(); - } - - @Override - public int order() { - return getFrom().order(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/QueryOperator.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/QueryOperator.java deleted file mode 100644 index 4cbe09c8..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/QueryOperator.java +++ /dev/null @@ -1,145 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.util.StringUtils; -import cc.allio.uno.core.util.template.Tokenizer; -import cc.allio.uno.data.orm.sql.FromStatement; -import cc.allio.uno.data.orm.sql.Operator; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.Statement; -import cc.allio.uno.data.orm.sql.dml.*; -import cc.allio.uno.data.orm.sql.dml.local.expression.DefaultExpressionContext; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionContext; - -import java.util.Collection; -import java.util.Map; -import java.util.PriorityQueue; -import java.util.stream.Collectors; - -/** - * 查询实现层 - * - * @author jiangwei - * @date 2023/1/5 10:25 - * @since 1.1.4 - */ -public class QueryOperator implements - Operator, QuerySQLAssociation, Statement { - - private final SelectDelegate selectDelegate; - private final SelectFrom fromDelegate; - private final WhereDelegate whereDelegate; - private final OrderDelegate orderDelegate; - private final GroupDelegate groupDelegate; - private final LimitDelegate limitDelegate; - private final ExpressionContext expressionContext; - private final PriorityQueue> sortStatements; - - public QueryOperator() { - this.expressionContext = new DefaultExpressionContext(); - this.sortStatements = new PriorityQueue<>(ORDER_COMPARATOR); - SelectStatement select = new SelectStatement(expressionContext); - sortStatements.add(select); - FromStatement from = new FromStatement(expressionContext); - sortStatements.add(from); - WhereStatement where = new WhereStatement(expressionContext); - sortStatements.add(where); - OrderStatement order = new OrderStatement(expressionContext); - sortStatements.add(order); - GroupStatement group = new GroupStatement(expressionContext); - sortStatements.add(group); - LimitStatement limit = new LimitStatement(); - sortStatements.add(limit); - this.selectDelegate = new SelectStatementDelegate(select, from, where, group, order, limit, this); - this.fromDelegate = new QueryFromStatement(select, from, where, group, order, limit, this); - this.whereDelegate = new WhereStatementDelegate(select, from, where, group, order, limit, this); - this.orderDelegate = new OrderStatementDelegate(select, from, where, group, order, limit, this); - this.groupDelegate = new GroupStatementDelegate(select, from, where, group, order, limit, this); - this.limitDelegate = new LimitStatementDelegate(select, from, where, group, order, limit, this); - } - - @Override - public SelectDelegate thenSelect() { - return then(selectDelegate); - } - - @Override - public SelectFrom thenFrom() { - return then(fromDelegate); - } - - @Override - public WhereDelegate thenWhere() { - return then(whereDelegate); - } - - @Override - public OrderDelegate thenOrder() { - return then(orderDelegate); - } - - @Override - public GroupDelegate thenGroup() { - return then(groupDelegate); - } - - @Override - public LimitDelegate thenLimit() { - return then(limitDelegate); - } - - @Override - public String getSQL() throws SQLException { - String templateSQL = sortStatements.stream() - .map(Statement::getSQL) - // 过滤为空字符串SQL - .filter(StringUtils::isNotBlank) - // ' '进行拼接 - .collect(Collectors.joining(StringPool.SPACE)); - // 构建模板解析变量 - Map runVariables = expressionContext.getExpressionVariables() - .entrySet() - .stream() - // key 去除token value 调用thenRun - .collect(Collectors.toMap( - k -> { - String tokenKey = k.getKey(); - Tokenizer.TokenSymbol symbol = expressionContext.getTokenizer().getSymbol(); - return tokenKey.replace(symbol.getOpen(), StringPool.EMPTY).replace(symbol.getClose(), StringPool.EMPTY); - }, - v -> v.getValue().thenRun())); - // 未解析SQL - return expressionContext.getExpressionTemplate().parseTemplate(templateSQL, runVariables); - } - - @Override - public String getCondition() { - return null; - } - - @Override - public Collection getExpressions() { - return sortStatements - .stream() - .flatMap(statement -> statement.getExpressions().stream()) - .collect(Collectors.toList()); - } - - @Override - public void syntaxCheck() throws SQLException { - for (Statement statement : sortStatements) { - statement.syntaxCheck(); - } - } - - @Override - public int order() { - return Integer.MIN_VALUE; - } - - @Override - public QueryOperator self() { - return this; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/SelectColumn.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/SelectColumn.java deleted file mode 100644 index ec7c0766..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/SelectColumn.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.Condition; -import cc.allio.uno.data.orm.sql.RuntimeColumn; - -/** - * select column - * - * @author jiangwei - * @date 2023/1/5 10:54 - * @since 1.1.4 - */ -public class SelectColumn extends RuntimeColumn { - - public SelectColumn(String name, Object[] value, Condition condition) { - super(name, value, condition); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/SelectStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/SelectStatement.java deleted file mode 100644 index f77d81d5..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/SelectStatement.java +++ /dev/null @@ -1,107 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.word.Distinct; -import cc.allio.uno.data.orm.sql.Alias; -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionColumnStatement; -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionContext; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.dml.Select; -import cc.allio.uno.data.orm.sql.dml.local.expression.DistinctExpression; -import cc.allio.uno.data.orm.sql.dml.local.expression.FunctionExpression; -import cc.allio.uno.data.orm.sql.dml.local.expression.PlainExpression; -import com.baomidou.mybatisplus.core.toolkit.StringPool; -import com.baomidou.mybatisplus.core.toolkit.StringUtils; -import com.google.common.collect.Lists; - -import java.util.Collection; -import java.util.List; - -/** - * SQL Select语句 - * - * @author jiangwei - * @date 2022/9/30 13:45 - * @since 1.1.0 - */ -public class SelectStatement extends ExpressionColumnStatement implements Select { - - public SelectStatement(ExpressionContext expressionContext) { - super(expressionContext); - } - - public SelectStatement select(String fieldName) { - SelectColumn selectColumn = new SelectColumn(StringUtils.camelToUnderline(fieldName), null, null); - PlainExpression plainExpression = new PlainExpression(selectColumn, expressionContext); - lazyOffer(plainExpression, StringPool.COMMA); - addPrivatizationColumn(selectColumn); - return this; - } - - @Override - public SelectStatement select(String fieldName, String alias) { - SelectColumn selectColumn = new SelectColumn(StringUtils.camelToUnderline(fieldName), null, null); - PlainExpression plainExpression = new PlainExpression(selectColumn, expressionContext); - plainExpression.alias(alias); - lazyOffer(plainExpression, StringPool.COMMA); - addPrivatizationColumn(selectColumn); - return this; - } - - @Override - public SelectStatement select(String[] fieldNames) { - return select(Lists.newArrayList(fieldNames)); - } - - @Override - public SelectStatement select(Collection fieldNames) { - for (String name : fieldNames) { - SelectColumn selectColumn = new SelectColumn(StringUtils.camelToUnderline(name), null, null); - PlainExpression plainExpression = new PlainExpression(selectColumn, expressionContext); - lazyOffer(plainExpression, StringPool.COMMA); - addPrivatizationColumn(selectColumn); - } - return self(); - } - - @Override - public SelectStatement distinct() { - lazyOfferOne(new DistinctExpression(null, null), null); - return self(); - } - - @Override - public SelectStatement distinctOn(String fieldName, String alias) { - SelectColumn selectColumn = new SelectColumn(StringUtils.camelToUnderline(fieldName), null, null); - PlainExpression plainExpression = new PlainExpression(selectColumn, expressionContext); - lazyOffer(new DistinctExpression(plainExpression, alias), null); - return self(); - } - - @Override - public SelectStatement aggregate(String syntax, String fieldName, String alias, Distinct distinct) { - List arguments = Lists.newArrayList(); - if (StringUtils.isNotBlank(fieldName)) { - SelectColumn column = new SelectColumn(StringUtils.camelToUnderline(fieldName), null, null); - arguments.add(column); - } - if (StringUtils.isNotBlank(alias)) { - Alias aliasTo = new Alias(alias); - arguments.add(aliasTo); - } - if (distinct != null) { - arguments.add(distinct); - } - lazyOffer(new FunctionExpression(expressionContext, syntax, arguments.toArray()), null); - return self(); - } - - @Override - public void syntaxCheck() throws SQLException { - - } - - @Override - protected String getStatementSyntax() { - return SELECT; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/SelectStatementDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/SelectStatementDelegate.java deleted file mode 100644 index 4bd3c59e..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/SelectStatementDelegate.java +++ /dev/null @@ -1,105 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.dml.*; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; -import cc.allio.uno.data.orm.sql.word.Distinct; - -import java.util.Collection; - -/** - * select语句代理 - * - * @author jiangwei - * @date 2022/9/30 14:07 - * @see Select - * @since 1.1.0 - */ -public class SelectStatementDelegate extends AbstractStatementDelegate implements SelectDelegate { - - public SelectStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit) { - super(select, from, where, group, order, limit); - } - - public SelectStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit, Statement parent) { - super(select, from, where, group, order, limit, parent); - } - - @Override - public SelectDelegate select(String fieldName) { - getSelect().select(fieldName); - return self(); - } - - @Override - public SelectDelegate select(String fieldName, String alias) { - getSelect().select(fieldName, alias); - return self(); - } - - @Override - public SelectDelegate select(String[] fieldNames) { - getSelect().select(fieldNames); - return self(); - } - - @Override - public SelectDelegate select(Collection fieldNames) { - getSelect().select(fieldNames); - return self(); - } - - @Override - public SelectDelegate distinct() { - getSelect().distinct(); - return self(); - } - - @Override - public SelectDelegate distinctOn(String fieldName, String alias) { - getSelect().distinctOn(fieldName, alias); - return self(); - } - - @Override - public SelectDelegate aggregate(String syntax, String fieldName, String alias, Distinct distinct) { - getSelect().aggregate(syntax, fieldName, alias, distinct); - return self(); - } - - @Override - public String getSQL() throws SQLException { - if (getParent() != null) { - return getParent().getSQL(); - } - return getSelect().getSQL(); - } - - @Override - public String getCondition() { - return getSelect().getCondition(); - } - - @Override - public Collection getExpressions() { - if (getParent() != null) { - return getParent().getExpressions(); - } - return getSelect().getExpressions(); - } - - @Override - public void syntaxCheck() throws SQLException { - getSelect().syntaxCheck(); - } - - @Override - public int order() { - return getSelect().order(); - } - - @Override - public Collection getColumns() { - return getSelect().getColumns(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/WhereColumn.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/WhereColumn.java deleted file mode 100644 index 80cdf250..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/WhereColumn.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.Condition; -import cc.allio.uno.data.orm.sql.RuntimeColumn; - -/** - * Where Column - * - * @author jiangwei - * @date 2023/1/5 18:52 - * @since 1.1.4 - */ -public class WhereColumn extends RuntimeColumn { - - public WhereColumn(String name, Object[] value, Condition condition) { - super(name, value, condition); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/WhereStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/WhereStatement.java deleted file mode 100644 index 2e85870d..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/WhereStatement.java +++ /dev/null @@ -1,249 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.core.util.StringUtils; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.dml.local.expression.*; -import cc.allio.uno.data.orm.sql.dml.Where; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * SQL-Where条件,包含常用的ge、lte...如果没有指明使用{@link #and()}与{@link #or()}方法,所有的条件以'and'进行连接。 - * 当指明时,会把之前已经填写的条件以'AND'进行连接 - * - * @author jiangwei - * @date 2022/9/30 10:41 - * @since 1.1.0 - */ -public class WhereStatement extends ExpressionColumnStatement implements Where { - - // 标识下一个sql是否进行逻辑语法控制 - private final AtomicBoolean nextLogicPredicate = new AtomicBoolean(false); - // 逻辑连接词 - private String logicPredicate; - // 默认连接的谓词 - private static final String DEFAULT_LOGIC_PREDICATE = AND; - - public WhereStatement(ExpressionContext expressionContext) { - super(expressionContext); - } - - /** - * '>' 条件 - * - * @param fieldName Java字段名称 - * @param value 比较数据值 - * @return WhereCondition对象 - */ - @Override - public WhereStatement gt(String fieldName, Object value) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{value}, null); - GTExpression expression = new GTExpression(whereColumn, expressionContext); - logicConnect(expression, whereColumn); - return self(); - } - - /** - * '>=' 条件 - * - * @param fieldName Java字段名称 - * @param value 比较数据值 - * @return WhereCondition对象 - */ - @Override - public WhereStatement gte(String fieldName, Object value) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{value}, null); - GTEExpression expression = new GTEExpression(whereColumn, expressionContext); - logicConnect(expression, whereColumn); - return self(); - } - - /** - * '<' 条件 - * - * @param fieldName Java字段名称 - * @param value 比较数据值 - * @return WhereCondition对象 - */ - @Override - public WhereStatement lt(String fieldName, Object value) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{value}, null); - LTExpression expression = new LTExpression(whereColumn, expressionContext); - logicConnect(expression, whereColumn); - return self(); - } - - /** - * '<=' 条件 - * - * @param fieldName Java字段名称 - * @param value 比较数据值 - * @return WhereCondition对象 - */ - @Override - public WhereStatement lte(String fieldName, Object value) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{value}, null); - LTEExpression expression = new LTEExpression(whereColumn, expressionContext); - logicConnect(expression, whereColumn); - return self(); - } - - /** - * '=' 条件 - * - * @param fieldName Java字段名称 - * @param value 比较数据值 - * @return WhereCondition对象 - */ - @Override - public WhereStatement eq(String fieldName, Object value) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{value}, null); - EQExpression expression = new EQExpression(whereColumn, expressionContext); - logicConnect(expression, whereColumn); - return self(); - } - - /** - * is not null 条件 - * - * @param fieldName Java字段名称 - * @return WhereCondition对象 - */ - @Override - public WhereStatement notNull(String fieldName) { - WhereColumn whereColumn = new WhereColumn(fieldName, null, null); - NotNullExpression expression = new NotNullExpression(whereColumn, expressionContext); - logicConnect(expression, whereColumn); - return self(); - } - - @Override - public WhereStatement isNull(String fieldName) { - WhereColumn whereColumn = new WhereColumn(fieldName, null, null); - IsNullExpression expression = new IsNullExpression(whereColumn, expressionContext); - logicConnect(expression, whereColumn); - return self(); - } - - /** - * 'in'条件 - * - * @param fieldName Java字段名称 - * @param values 数值数据 - * @return WhereCondition对象 - */ - @Override - public WhereStatement in(String fieldName, Object[] values) { - WhereColumn whereColumn = new WhereColumn(fieldName, values, null); - INExpression expression = new INExpression(whereColumn, expressionContext); - logicConnect(expression, whereColumn); - return self(); - } - - /** - * 'between' 条件 - * - * @param fieldName Java字段名称 - * @param withValue between起始值 - * @param endValue between结束值 - * @return WhereCondition对象 - */ - @Override - public WhereStatement between(String fieldName, Object withValue, Object endValue) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{withValue, endValue}, null); - BetweenExpression expression = new BetweenExpression(whereColumn, expressionContext, BetweenExpression.Strategy.IN); - logicConnect(expression, whereColumn); - return self(); - } - - @Override - public WhereStatement notBetween(String fieldName, Object withValue, Object endValue) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{withValue, endValue}, null); - BetweenExpression expression = new BetweenExpression(whereColumn, expressionContext, BetweenExpression.Strategy.NOT); - logicConnect(expression, whereColumn); - return self(); - } - - @Override - public WhereStatement $like(String fieldName, Object value) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{value}, null); - LikeExpression expression = new LikeExpression(whereColumn, expressionContext, LikeExpression.Strategy.LEFT); - logicConnect(expression, whereColumn); - return self(); - } - - @Override - public WhereStatement like$(String fieldName, Object value) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{value}, null); - LikeExpression expression = new LikeExpression(whereColumn, expressionContext, LikeExpression.Strategy.RIGHT); - logicConnect(expression, whereColumn); - return self(); - } - - @Override - public WhereStatement $like$(String fieldName, Object value) { - WhereColumn whereColumn = new WhereColumn(fieldName, new Object[]{value}, null); - LikeExpression expression = new LikeExpression(whereColumn, expressionContext, LikeExpression.Strategy.ALL); - logicConnect(expression, whereColumn); - return self(); - } - - /** - * 逻辑'与'控制 - * - * @return WhereCondition对象 - */ - @Override - public WhereStatement or() { - nextLogicPredicate.set(true); - logicPredicate = OR; - return this; - } - - /** - * 逻辑'或'控制 - * - * @return WhereCondition对象 - */ - @Override - public WhereStatement and() { - nextLogicPredicate.set(true); - logicPredicate = AND; - return this; - } - - /** - * 通过比较是否需要下一个语法进行逻辑连接。 - * - * @param expression expression实例 - * @param runtimeColumn column实例 - */ - public void logicConnect(Expression expression, RuntimeColumn runtimeColumn) { - // 判断连接的谓词 - String predicate = DEFAULT_LOGIC_PREDICATE; - if (StringUtils.isNotBlank(logicPredicate) && nextLogicPredicate.get()) { - predicate = logicPredicate; - // 重制 - logicPredicate = null; - nextLogicPredicate.set(false); - } - lazyOffer(expression, predicate); - addPrivatizationColumn(runtimeColumn); - } - - @Override - public void syntaxCheck() throws SQLException { - - } - - @Override - public int order() { - return WHERE_ORDER; - } - - @Override - protected String getStatementSyntax() { - return WHERE; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/WhereStatementDelegate.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/WhereStatementDelegate.java deleted file mode 100644 index 02aa58d5..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/WhereStatementDelegate.java +++ /dev/null @@ -1,152 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.dml.*; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; - -import java.util.Collection; - -/** - * whereSQL语句代理 - * - * @author jiangwei - * @date 2022/9/30 14:03 - * @see Where - * @since 1.1.0 - */ -public class WhereStatementDelegate extends AbstractStatementDelegate implements WhereDelegate { - - public WhereStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit) { - super(select, from, where, group, order, limit); - } - - public WhereStatementDelegate(Select select, From from, Where where, Group group, Order order, Limit limit, Statement parent) { - super(select, from, where, group, order, limit, parent); - } - - @Override - public WhereDelegate gt(String fieldName, Object value) { - getWhere().gt(fieldName, value); - return self(); - } - - @Override - public WhereDelegate gte(String fieldName, Object value) { - getWhere().gte(fieldName, value); - return self(); - } - - @Override - public WhereDelegate lt(String fieldName, Object value) { - getWhere().lt(fieldName, value); - return self(); - } - - @Override - public WhereDelegate lte(String fieldName, Object value) { - getWhere().lte(fieldName, value); - return self(); - } - - @Override - public WhereDelegate eq(String fieldName, Object value) { - getWhere().eq(fieldName, value); - return self(); - } - - @Override - public WhereDelegate notNull(String fieldName) { - getWhere().notNull(fieldName); - return self(); - } - - @Override - public WhereDelegate isNull(String fieldName) { - getWhere().isNull(fieldName); - return self(); - } - - @Override - public WhereDelegate in(String fieldName, Object[] values) { - getWhere().in(fieldName, values); - return self(); - } - - @Override - public WhereDelegate between(String fieldName, Object withValue, Object endValue) { - getWhere().between(fieldName, withValue, endValue); - return self(); - } - - @Override - public WhereDelegate notBetween(String fieldName, Object withValue, Object endValue) { - getWhere().notBetween(fieldName, withValue, endValue); - return self(); - } - - @Override - public WhereDelegate $like(String fieldName, Object value) { - getWhere().$like(fieldName, value); - return self(); - } - - @Override - public WhereDelegate like$(String fieldName, Object value) { - getWhere().like$(fieldName, value); - return self(); - } - - @Override - public WhereDelegate $like$(String fieldName, Object value) { - getWhere().$like$(fieldName, value); - return self(); - } - - @Override - public WhereDelegate or() { - getWhere().or(); - return self(); - } - - @Override - public WhereDelegate and() { - getWhere().and(); - return self(); - } - - @Override - public String getSQL() throws SQLException { - if (getParent() != null) { - return getParent().getSQL(); - } - return getWhere().getSQL(); - } - - @Override - public String getCondition() { - return getWhere().getCondition(); - } - - @Override - public Collection getExpressions() { - if (getParent() != null) { - return getParent().getExpressions(); - } - return getWhere().getExpressions(); - } - - @Override - public void syntaxCheck() throws SQLException { - getWhere().syntaxCheck(); - } - - @Override - public int order() { - return getWhere().order(); - } - - @Override - public Collection getColumns() { - return getWhere().getColumns(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/BetweenExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/BetweenExpression.java deleted file mode 100644 index c377795e..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/BetweenExpression.java +++ /dev/null @@ -1,78 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import com.google.common.collect.Lists; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.List; -import java.util.Optional; -import java.util.function.Function; - -/** - * between expression - * - * @author jiangwei - * @date 2023/1/6 13:26 - * @since 1.1.4 - */ -public class BetweenExpression extends ColumnExpression implements ConditionExpression { - - public static final String STRATEGY_KEY = "strategy"; - - public BetweenExpression(RuntimeColumn column, ExpressionContext context, Strategy strategy) { - super(column, context, column.getValue()); - valuePlaceholder.putAttribute(STRATEGY_KEY, strategy); - } - - @Override - public String getSQL() { - String syntax = getSyntax(); - Object[] paris = valuePlaceholder.getList().stream().map(Tuple2::getT1).toArray(Object[]::new); - if (paris.length == 2) { - syntax = String.format(syntax, paris); - } - return column + StringPool.SPACE + syntax; - } - - @Override - protected Function>> getValuePlaceholder() { - return valuePlaceholder -> { - List> valuePlaceholders = Lists.newLinkedList(); - Optional> doubleValue = getDoubleValue(); - doubleValue.ifPresent(pairs -> { - for (int index = 0; index < 2; index++) { - Object value = pairs.get(index); - valuePlaceholders.add( - Tuples.of( - context.getTokenizer().createTokenString(column + StringPool.UNDERSCORE + "bt" + index), - ExpressionValue.of(value) - )); - } - }); - return valuePlaceholders; - }; - } - - @Override - public String getSyntax() { - Strategy strategy = valuePlaceholder.get(STRATEGY_KEY, Strategy.class).orElse(Strategy.IN); - switch (strategy) { - case IN: - // BETWEEN %s AND %s - return Statement.BETWEEN + StringPool.SPACE + StringPool.FormatterConversion.STRING + StringPool.SPACE + Statement.AND + StringPool.SPACE + StringPool.FormatterConversion.STRING; - case NOT: - // NOT BETWEEN %s AND %s - return Statement.NOT_BETWEEN + StringPool.SPACE + StringPool.FormatterConversion.STRING + StringPool.SPACE + Statement.AND + StringPool.SPACE + StringPool.FormatterConversion.STRING; - default: - return StringPool.EMPTY; - } - } - - public enum Strategy { - NOT, - IN - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ColumnExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ColumnExpression.java deleted file mode 100644 index 9630faee..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ColumnExpression.java +++ /dev/null @@ -1,38 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.util.StringUtils; -import cc.allio.uno.data.orm.sql.RuntimeColumn; - -import java.util.Collections; - -/** - * Column - * - * @author jiangwei - * @date 2023/1/5 17:00 - * @since 1.1.4 - */ -public abstract class ColumnExpression extends ValueExpression { - - protected final String column; - protected final ExpressionContext context; - protected final RuntimeColumn runtimeColumn; - - /** - * @see ValuePlaceholder - */ - public static final String COLUMN = "column"; - - protected ColumnExpression(RuntimeColumn column, ExpressionContext context) { - this(column, context, column.getValue()); - } - - protected ColumnExpression(RuntimeColumn column, ExpressionContext context, Object[] values) { - super(context, values, Collections.emptyMap()); - this.column = StringUtils.camelToUnderline(column.getName()); - this.context = context; - this.runtimeColumn = column; - context.getColumnGroup().add(runtimeColumn); - valuePlaceholder.putAttribute(COLUMN, column); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ConditionExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ConditionExpression.java deleted file mode 100644 index 5b87c57a..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ConditionExpression.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -/** - * Condition Expression - * - * @author jiangwei - * @date 2023/1/5 17:03 - * @since 1.1.4 - */ -public interface ConditionExpression extends Expression { - - /** - * 获取当前表达式语法 - * - * @return 语法 - */ - String getSyntax(); -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/DefaultExpressionContext.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/DefaultExpressionContext.java deleted file mode 100644 index c3e5ee2b..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/DefaultExpressionContext.java +++ /dev/null @@ -1,58 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.util.template.ExpressionTemplate; -import cc.allio.uno.core.util.template.Tokenizer; -import cc.allio.uno.data.orm.dialect.Dialect; -import cc.allio.uno.data.orm.sql.ColumnGroup; -import cc.allio.uno.data.orm.sql.Table; -import com.google.common.collect.Maps; -import lombok.Getter; - -import java.util.Map; - -/** - * 表达式上下文对象,作用多个表达式,复用模板表达式 - * - * @author jiangwei - * @date 2023/1/5 18:26 - * @since 1.0 - */ -@Getter -public class DefaultExpressionContext implements ExpressionContext { - // 数据库方言对象 - private final Dialect dialect; - // 表达式模板 - private final ExpressionTemplate expressionTemplate; - // 表达式变量L - private final Map expressionVariables; - private final Tokenizer tokenizer; - private final ColumnGroup columnGroup; - - private Table table; - - public DefaultExpressionContext() { - this(null); - } - - public DefaultExpressionContext(Dialect dialect) { - this(dialect, Tokenizer.HASH_BRACE); - } - - public DefaultExpressionContext(Dialect dialect, Tokenizer tokenizer) { - this.dialect = dialect; - this.tokenizer = tokenizer; - this.expressionTemplate = ExpressionTemplate.createTemplate(tokenizer); - this.expressionVariables = Maps.newHashMap(); - this.columnGroup = new ColumnGroup(); - } - - @Override - public Table getTable() { - return table; - } - - @Override - public void setTable(Table table) { - this.table = table; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/DistinctExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/DistinctExpression.java deleted file mode 100644 index ef705bc4..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/DistinctExpression.java +++ /dev/null @@ -1,34 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; - -/** - * distinct expression - * - * @author jiangwei - * @date 2023/1/10 13:20 - * @since 1.1.4 - */ -public class DistinctExpression implements SingleExpression { - - // constant - public static final String DISTINCT = "DISTINCT"; - public static final String DISTINCT_ON = "DISTINCT ON"; - - // ON Field - private final PlainExpression onExpression; - private final String alias; - - public DistinctExpression(PlainExpression onExpression, String alias) { - this.onExpression = onExpression; - this.alias = alias; - } - - @Override - public String getSQL() { - // DISTINCT or DISTINCT ON (alias) alias - return onExpression == null ? - DISTINCT : - DISTINCT_ON + StringPool.SPACE + StringPool.LEFT_BRACKET + onExpression.column + StringPool.RIGHT_BRACKET + StringPool.SPACE + alias; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/EQExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/EQExpression.java deleted file mode 100644 index dc62a1c6..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/EQExpression.java +++ /dev/null @@ -1,55 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import com.google.common.collect.Lists; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.List; -import java.util.function.Function; - -/** - * eq expression - * - * @author jiangwei - * @date 2023/1/5 16:56 - * @since 1.1.4 - */ -public class EQExpression extends ColumnExpression implements ConditionExpression { - - public EQExpression(RuntimeColumn column, ExpressionContext context) { - super(column, context); - } - - @Override - protected Function>> getValuePlaceholder() { - return valuePlaceholder -> { - int index = 0; - List> valuePlaceholders = Lists.newLinkedList(); - valuePlaceholders.add( - Tuples.of( - // context.xx_xx - context.getTokenizer().createTokenString(prefix + StringPool.ORIGIN_DOT + column + StringPool.UNDERSCORE + Statement.EQ + StringPool.UNDERSCORE + index), - ExpressionValue.of(getSingleValue(StringPool.EMPTY)) - ) - ); - return valuePlaceholders; - }; - } - - @Override - public String getSyntax() { - return Statement.EQ_SYMBOL; - } - - @Override - public String getSQL() { - // column = placeholder - return column + - StringPool.SPACE + getSyntax() + StringPool.SPACE + - valuePlaceholder.get(0).getT1(); - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/Expression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/Expression.java deleted file mode 100644 index 1b36efcd..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/Expression.java +++ /dev/null @@ -1,52 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.util.template.ExpressionTemplate; - -import java.util.Collections; -import java.util.Map; - -/** - * SQL表达式。 - * 每个实现类衍生自SQL关键字,如FROM、IN、NOT IN... 表达式具备模版站位的能力 - * - * @author jiangwei - * @date 2023/1/5 10:02 - * @see ExpressionTemplate - * @since 1.1.4 - */ -public interface Expression { - - /** - * 返回当前表达式SQL - * - * @return SQL字符串 - */ - String getSQL(); - - /** - * 获取占位符SQL - * - * @return 占位符SQL - */ - default String getPrepareSQL() { - return getSQL(); - } - - /** - * 获取字面量SQL - * - * @return 字面量 - */ - default String getLiteralSQL() { - return getSQL(); - } - - /** - * 获取表达式value与key的映射 - * - * @return key 表达式占位符, value值 - */ - default Map getExpMapping() { - return Collections.emptyMap(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionColumnStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionColumnStatement.java deleted file mode 100644 index a08bfc46..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionColumnStatement.java +++ /dev/null @@ -1,42 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.sql.ColumnStatement; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import com.google.common.collect.Sets; - -import java.util.Collection; -import java.util.Set; - -/** - * expression column statement - * - * @author jiangwei - * @date 2023/1/9 18:30 - * @since 1.1.4 - */ -public abstract class ExpressionColumnStatement> extends ExpressionStatement implements ColumnStatement { - - /** - * 当前语句的Column - */ - private final Set columns; - - protected ExpressionColumnStatement(ExpressionContext expressionContext) { - super(expressionContext); - this.columns = Sets.newHashSet(); - } - - @Override - public Collection getColumns() { - return expressionContext.getColumnGroup(); - } - - /** - * 添加当前语句私有化的{@link RuntimeColumn} - * - * @param column RuntimeColumn实例 - */ - protected void addPrivatizationColumn(RuntimeColumn column) { - columns.add(column); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionContext.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionContext.java deleted file mode 100644 index ab1eee73..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionContext.java +++ /dev/null @@ -1,108 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.util.template.ExpressionTemplate; -import cc.allio.uno.core.util.template.Tokenizer; -import cc.allio.uno.data.orm.dialect.Dialect; -import cc.allio.uno.data.orm.sql.ColumnGroup; -import cc.allio.uno.data.orm.sql.Table; - -import java.util.Map; - -/** - * 表达式上下文 - * - * @author jiangwei - * @date 2023/1/6 09:16 - * @since 1.1.4 - */ -public interface ExpressionContext { - - /** - * 获取当前执行表达式数据库方言对象 - * - * @return Dialect实例 - */ - Dialect getDialect(); - - /** - * 获取{@link ExpressionTemplate}实例对象 - * - * @return ExpressionTemplate实例 - */ - ExpressionTemplate getExpressionTemplate(); - - /** - * 获取{@link ExpressionTemplate}构建变量对象 - * - * @return ExpressionVariables对象 - */ - Map getExpressionVariables(); - - /** - * 获取Tokenizer - * - * @return Tokenizer实例 - */ - Tokenizer getTokenizer(); - - /** - * 获取ColumnGroup实例 - * - * @return ColumnGroup - */ - ColumnGroup getColumnGroup(); - - /** - * 获取Table实例对象 - * - * @return - */ - Table getTable(); - - /** - * 设置Table实例对象 - * - * @param table table实例对象 - */ - void setTable(Table table); - - /** - * empty 的上下文对象。所有的操作抛出{@link UnsupportedOperationException} - */ - ExpressionContext EMPTY = new ExpressionContext() { - @Override - public Dialect getDialect() { - throw new UnsupportedOperationException("unsupported operations"); - } - - @Override - public ExpressionTemplate getExpressionTemplate() { - throw new UnsupportedOperationException("unsupported operations"); - } - - @Override - public Map getExpressionVariables() { - throw new UnsupportedOperationException("unsupported operations"); - } - - @Override - public Tokenizer getTokenizer() { - throw new UnsupportedOperationException("unsupported operations"); - } - - @Override - public ColumnGroup getColumnGroup() { - throw new UnsupportedOperationException("unsupported operations"); - } - - @Override - public Table getTable() { - throw new UnsupportedOperationException("unsupported operations"); - } - - @Override - public void setTable(Table table) { - - } - }; -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionGroup.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionGroup.java deleted file mode 100644 index 2d903217..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionGroup.java +++ /dev/null @@ -1,138 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import com.google.common.collect.Lists; - -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.NoSuchElementException; -import java.util.stream.Collectors; - -/** - * ExpressionGroup queue - *

    expression1

    - *

    ,

    - *

    expression2

    - *

    ,

    - *

    expression3

    - * - * @author jiangwei - * @date 2023/1/6 11:53 - * @since 1.1.4 - */ -public class ExpressionGroup implements Expression { - - private final LinkedList expressionSymbols = Lists.newLinkedList(); - - /** - * 向ExpressionGroup中提供数据支持 - *

    在Select语句中添加,..

    - *

    在Where语句中添加AND、OR...

    - * - * @param expression 表达式实例 - * @param symbol 符号,如, AND OR... - */ - public void offer(Expression expression, String symbol) { - // 不是 single expression - Object last; - try { - last = expressionSymbols.getLast(); - } catch (NoSuchElementException ex) { - last = null; - } - // 上一个以及当前expression不是SingleExpression时才进行插入symbol数据 - if ((last != null && !SingleExpression.class.isAssignableFrom(last.getClass())) - && !SingleExpression.class.isAssignableFrom(expression.getClass())) { - expressionSymbols.add(symbol); - } - expressionSymbols.add(expression); - } - - /** - * 向ExpressionGroup中提供数据支持,只支持当前Expression类型存在于一种。通过比较Class对象 - * - * @param expression 表达式实例 - * @param symbol 符号,如, AND OR... - */ - public void offerOne(Expression expression, String symbol) { - Iterator iterator = expressionSymbols.iterator(); - while (iterator.hasNext()) { - Object inner = iterator.next(); - if (inner.getClass().isAssignableFrom(expression.getClass())) { - iterator.remove(); - break; - } - } - offer(expression, symbol); - } - - /** - * 向ExpressionGroup中提供数据支持,只支持一个symbol - * - * @param expression 表达式实例 - * @param symbol 符号,如, AND OR... - */ - public void offerOneSymbol(Expression expression, String symbol) { - Iterator iterator = expressionSymbols.iterator(); - while (iterator.hasNext()) { - Object inner = iterator.next(); - if (inner.equals(symbol)) { - iterator.remove(); - break; - } - } - offer(expression, symbol); - } - - /** - * 向ExpressionGroup中提供数据支持 - * - * @param symbol 符号 - */ - public void offerSymbol(String symbol) { - expressionSymbols.add(symbol); - } - - /** - * 获取当前存储的{@link Expression}实例 - */ - public Collection getExpression() { - return expressionSymbols.stream() - .filter(e -> Expression.class.isAssignableFrom(e.getClass())) - .map(Expression.class::cast) - .collect(Collectors.toList()); - } - - /** - * 判断指定的元素是否包含在group中 - * - * @param element 元素 - * @return true 存在 false 不存在 - */ - public boolean contains(Object element) { - return expressionSymbols.contains(element); - } - - /** - * 判断指定元素是否不包含在group中 - * - * @param element 元素 - * @return true 不存在 false 存在 - */ - public boolean notContains(Object element) { - return !contains(element); - } - - @Override - public String getSQL() { - return expressionSymbols.stream() - .map(e -> { - if (e instanceof Expression) { - return ((Expression) e).getSQL(); - } - return (String) e; - }) - .collect(Collectors.joining(StringPool.SPACE)); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionStatement.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionStatement.java deleted file mode 100644 index f41a72f0..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionStatement.java +++ /dev/null @@ -1,101 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.Statement; - -import java.util.Collection; -import java.util.stream.Collectors; - -/** - * 使用{@link Expression}的语句 - * - * @author jiangwei - * @date 2023/1/6 13:11 - * @since 1.1.4 - */ -public abstract class ExpressionStatement> implements Statement { - - protected final ExpressionGroup expressionGroup; - protected final ExpressionContext expressionContext; - - protected ExpressionStatement(ExpressionContext expressionContext) { - this.expressionGroup = new ExpressionGroup(); - this.expressionContext = expressionContext; - } - - @Override - public Collection getExpressions() { - return expressionGroup.getExpression(); - } - - @Override - public String getSQL() throws SQLException { - return expressionGroup.getSQL(); - } - - /** - * 获取条件语句如: - *
      - *
    • Select a , b -> a, b
    • - *
    • where a=1 -> a=1
    • - *
    - * - * @return condition - */ - @Override - public String getCondition() { - return expressionGroup.getExpression().stream() - .filter(e -> !StatementExpression.class.isAssignableFrom(e.getClass())) - .map(Expression::getSQL) - .collect(Collectors.joining(StringPool.SPACE)); - } - - /** - * 延迟把语句放入{@link ExpressionGroup}中 - * - * @param expression expression实例 - * @param symbol 符号,如, AND OR... - * @see ExpressionGroup#offer(Expression, String) - */ - protected void lazyOffer(Expression expression, String symbol) { - lazyOfferStatementSyntax(); - expressionGroup.offer(expression, symbol); - } - - /** - * 延迟把语句放入{@link ExpressionGroup}中 - * - * @param expression expression实例 - * @param symbol 符号,如, AND OR... - * @see ExpressionGroup#offerOne(Expression, String) - */ - protected void lazyOfferOne(Expression expression, String symbol) { - lazyOfferStatementSyntax(); - expressionGroup.offerOne(expression, symbol); - } - - /** - * 延迟提供语句语法 - */ - private void lazyOfferStatementSyntax() { - String statementSyntax = getStatementSyntax(); - StatementExpression statementExpression = new StatementExpression(statementSyntax); - if (expressionGroup.notContains(statementExpression)) { - expressionGroup.offerOne(statementExpression, null); - } - } - - @Override - public String toString() { - return getSQL(); - } - - /** - * 获取Statement语法 - * - * @return Statement语法 - */ - protected abstract String getStatementSyntax(); - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionValue.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionValue.java deleted file mode 100644 index dd1ebd4f..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionValue.java +++ /dev/null @@ -1,105 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.type.Types; -import lombok.Getter; -import lombok.NonNull; - -/** - * column value - * - * @author jiangwei - * @date 2023/1/6 11:12 - * @see Appender - * @since 1.1.4 - */ -@Getter -public class ExpressionValue { - - private ExpressionValue() { - } - - /** - * 值 - */ - private Object value; - - /** - * 值的类型 - */ - private Class type; - - /** - * 追加策略 - */ - private Appender appender; - - /** - * 基于当前值策略,返回修改后的值 - * - * @return 修改后的值 - */ - public Object thenRun() { - if (appender != null && Types.isString(type)) { - String valueString = (String) value; - switch (appender) { - case LEFT_QUOTE: - valueString = StringPool.SINGLE_QUOTE + valueString; - break; - case RIGHT_QUOTE: - valueString = value + StringPool.SINGLE_QUOTE; - break; - case QUOTE: - valueString = StringPool.SINGLE_QUOTE + valueString + StringPool.SINGLE_QUOTE; - break; - default: - break; - } - return valueString; - } - return value; - } - - /** - * 创建ExpressionValue - * - * @param value 值 非空 - * @return ExpressionValue - */ - public static ExpressionValue of(@NonNull Object value) { - Appender appender = Appender.NONE; - if (Types.isString(value.getClass())) { - appender = Appender.QUOTE; - } - return of(value, appender); - } - - /** - * 创建ExpressionValue - * - * @param value 值 非空 - * @param appender 追加策略 - * @return ExpressionValue实例 - */ - public static ExpressionValue of(@NonNull Object value, Appender appender) { - ExpressionValue expressionValue = new ExpressionValue(); - expressionValue.value = value; - expressionValue.type = value.getClass(); - expressionValue.appender = appender; - return expressionValue; - } - - /** - * value注解策略。 - *

    如:为值添加''

    - */ - public enum Appender { - NONE, - // 添加'value - LEFT_QUOTE, - // 添加value' - RIGHT_QUOTE, - // 添加'value' - QUOTE - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/FromExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/FromExpression.java deleted file mode 100644 index 64a48684..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/FromExpression.java +++ /dev/null @@ -1,53 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.Statement; -import cc.allio.uno.data.orm.sql.Table; -import com.google.common.collect.Lists; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.List; -import java.util.function.Function; - -/** - * from expression - * - * @author jiangwei - * @date 2023/1/5 19:45 - * @since 1.1.4 - */ -public class FromExpression extends ValueExpression implements SingleExpression { - - /** - * @see ValuePlaceholder#putAttribute(String, Object) - */ - static final String TABLE_KEY = "table"; - - public FromExpression(Table table, ExpressionContext context) { - super(context, new Object[]{table.getName()}); - valuePlaceholder.putAttribute(TABLE_KEY, table); - } - - @Override - public String getSQL() { - return valuePlaceholder.get(0).getT1(); - } - - @Override - protected Function>> getValuePlaceholder() { - return valuePlaceholder -> { - Table table = valuePlaceholder.get(TABLE_KEY, Table.class).orElseThrow(() -> new SQLException("Table instance not exist")); - int index = 0; - List> valuePlaceholders = Lists.newArrayList(); - valuePlaceholders.add( - Tuples.of( - context.getTokenizer().createTokenString(table.getName() + StringPool.UNDERSCORE + Statement.FROM + StringPool.UNDERSCORE + index), - ExpressionValue.of(getSingleValue()) - ) - ); - return valuePlaceholders; - }; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/FunctionExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/FunctionExpression.java deleted file mode 100644 index d13d471a..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/FunctionExpression.java +++ /dev/null @@ -1,37 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.dialect.Dialect; -import cc.allio.uno.data.orm.dialect.func.FuncDescriptor; -import cc.allio.uno.data.orm.sql.SQLException; - -/** - * aggregate expression. - *

    包含有MIN、MAX_FUNCTION、AVG等等函数

    - * - * @author jiangwei - * @date 2023/1/10 13:46 - * @see FuncDescriptor - * @since 1.1.4 - */ -public class FunctionExpression implements Expression { - - private final FuncDescriptor func; - // 函数执行的参数 - private final Object[] arguments; - - public FunctionExpression(ExpressionContext expressionContext, String functionSyntax, Object[] arguments) { - Dialect dialect = expressionContext.getDialect(); - FuncDescriptor func = dialect.getFuncRegistry().findFunc(functionSyntax); - if (func == null) { - throw new SQLException(String.format("expect func %s nonentity ", functionSyntax)); - } - this.func = func; - this.arguments = arguments; - } - - @Override - public String getSQL() { - return func.render(arguments); - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/GTEExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/GTEExpression.java deleted file mode 100644 index fffd35b9..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/GTEExpression.java +++ /dev/null @@ -1,53 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import com.google.common.collect.Lists; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.List; -import java.util.function.Function; - -/** - * gte expression - * - * @author jiangwei - * @date 2023/1/5 19:11 - * @since 1.1.4 - */ -public class GTEExpression extends ColumnExpression implements ConditionExpression { - - public GTEExpression(RuntimeColumn column, ExpressionContext context) { - super(column, context); - } - - @Override - protected Function>> getValuePlaceholder() { - return parameter -> { - int index = 0; - List> valuePlaceholders = Lists.newLinkedList(); - valuePlaceholders.add( - Tuples.of( - context.getTokenizer().createTokenString(column + StringPool.UNDERSCORE + Statement.GTE + StringPool.UNDERSCORE + index), - ExpressionValue.of(getSingleValue(StringPool.EMPTY)) - ) - ); - return valuePlaceholders; - }; - } - - @Override - public String getSyntax() { - return Statement.GTE_SYMBOL; - } - - @Override - public String getSQL() { - // column <= placeholder - return column + - StringPool.SPACE + getSyntax() + StringPool.SPACE + - valuePlaceholder.get(0).getT1(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/GTExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/GTExpression.java deleted file mode 100644 index 517fa1aa..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/GTExpression.java +++ /dev/null @@ -1,54 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import com.google.common.collect.Lists; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.List; -import java.util.function.Function; - -/** - * te expression - * - * @author jiangwei - * @date 2023/1/5 19:11 - * @since 1.1.4 - */ -public class GTExpression extends ColumnExpression implements ConditionExpression { - - public GTExpression(RuntimeColumn column, ExpressionContext context) { - super(column, context); - } - - @Override - protected Function>> getValuePlaceholder() { - return parameter -> { - int index = 0; - List> valuePlaceholders = Lists.newLinkedList(); - valuePlaceholders.add( - Tuples.of( - context.getTokenizer().createTokenString(column + StringPool.UNDERSCORE + Statement.GT + StringPool.UNDERSCORE + index), - ExpressionValue.of(getSingleValue(StringPool.EMPTY)) - ) - ); - return valuePlaceholders; - }; - } - - @Override - public String getSyntax() { - return Statement.GT_SYMBOL; - } - - @Override - public String getSQL() { - // column <= placeholder - return column + - StringPool.SPACE + getSyntax() + StringPool.SPACE + - valuePlaceholder.get(0).getT1(); - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/INExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/INExpression.java deleted file mode 100644 index 723717a5..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/INExpression.java +++ /dev/null @@ -1,60 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * in expression - * - * @author jiangwei - * @date 2023/1/5 19:48 - * @since 1.1.4 - */ -public class INExpression extends ColumnExpression implements ConditionExpression { - - public INExpression(RuntimeColumn column, ExpressionContext context) { - super(column, context, column.getValue()); - } - - @Override - public String getSyntax() { - return Statement.IN; - } - - @Override - public String getSQL() { - // column in (...) - return column + - StringPool.SPACE + getSyntax() + StringPool.SPACE - + StringPool.LEFT_BRACKET - + valuePlaceholder.getList().stream().map(Tuple2::getT1).collect(Collectors.joining(StringPool.COMMA)) - + StringPool.RIGHT_BRACKET; - } - - @Override - protected Function>> getValuePlaceholder() { - return parameter -> { - AtomicInteger index = new AtomicInteger(); - return getValues().map(Arrays::stream).orElse(Stream.empty()) - .map(value -> { - Tuple2 pairs = Tuples.of( - context.getTokenizer().createTokenString(column + StringPool.UNDERSCORE + getSyntax() + StringPool.UNDERSCORE + index), - ExpressionValue.of(value) - ); - index.getAndIncrement(); - return pairs; - }) - .collect(Collectors.toList()); - }; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/IsNullExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/IsNullExpression.java deleted file mode 100644 index 786175b4..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/IsNullExpression.java +++ /dev/null @@ -1,39 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import reactor.util.function.Tuple2; - -import java.util.Collections; -import java.util.List; -import java.util.function.Function; - -/** - * is null expression - * - * @author jiangwei - * @date 2023/1/6 13:46 - * @since 1.1.4 - */ -public class IsNullExpression extends ColumnExpression implements ConditionExpression { - - public IsNullExpression(RuntimeColumn column, ExpressionContext context) { - super(column, context); - } - - @Override - public String getSQL() { - return column + StringPool.SPACE + getSyntax(); - } - - @Override - public String getSyntax() { - return Statement.IS_NULL; - } - - @Override - protected Function>> getValuePlaceholder() { - return t -> Collections.emptyList(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/LTEExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/LTEExpression.java deleted file mode 100644 index 4d6559fe..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/LTEExpression.java +++ /dev/null @@ -1,53 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import com.google.common.collect.Lists; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.List; -import java.util.function.Function; - -/** - * lte expression - * - * @author jiangwei - * @date 2023/1/5 19:11 - * @since 1.1.4 - */ -public class LTEExpression extends ColumnExpression implements ConditionExpression { - - public LTEExpression(RuntimeColumn column, ExpressionContext context) { - super(column, context); - } - - @Override - protected Function>> getValuePlaceholder() { - return parameter -> { - int index = 0; - List> valuePlaceholders = Lists.newLinkedList(); - valuePlaceholders.add( - Tuples.of( - context.getTokenizer().createTokenString(column + StringPool.UNDERSCORE + Statement.LTE + StringPool.UNDERSCORE + index), - ExpressionValue.of(getSingleValue(StringPool.EMPTY)) - ) - ); - return valuePlaceholders; - }; - } - - @Override - public String getSyntax() { - return Statement.LTE_SYMBOL; - } - - @Override - public String getSQL() { - // column <= placeholder - return column + - StringPool.SPACE + getSyntax() + StringPool.SPACE + - valuePlaceholder.get(0).getT1(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/LTExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/LTExpression.java deleted file mode 100644 index c3be2a32..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/LTExpression.java +++ /dev/null @@ -1,53 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import com.google.common.collect.Lists; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.List; -import java.util.function.Function; - -/** - * lt expression - * - * @author jiangwei - * @date 2023/1/5 19:11 - * @since 1.1.4 - */ -public class LTExpression extends ColumnExpression implements ConditionExpression { - - public LTExpression(RuntimeColumn column, ExpressionContext context) { - super(column, context); - } - - @Override - protected Function>> getValuePlaceholder() { - return parameter -> { - int index = 0; - List> valuePlaceholders = Lists.newLinkedList(); - valuePlaceholders.add( - Tuples.of( - context.getTokenizer().createTokenString(column + StringPool.UNDERSCORE + Statement.LT + StringPool.UNDERSCORE + index), - ExpressionValue.of(getSingleValue(StringPool.EMPTY)) - ) - ); - return valuePlaceholders; - }; - } - - @Override - public String getSyntax() { - return Statement.LT_SYMBOL; - } - - @Override - public String getSQL() { - // column < placeholder - return column + - StringPool.SPACE + getSyntax() + StringPool.SPACE + - valuePlaceholder.get(0).getT1(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/LikeExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/LikeExpression.java deleted file mode 100644 index 720e52d9..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/LikeExpression.java +++ /dev/null @@ -1,73 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import com.google.common.collect.Lists; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.List; -import java.util.function.Function; - -/** - * like expression - * - * @author jiangwei - * @date 2023/1/6 10:17 - * @since 1.1.4 - */ -public class LikeExpression extends ColumnExpression implements ConditionExpression { - - static final String STRATEGY_KEY = "strategy"; - - public LikeExpression(RuntimeColumn column, ExpressionContext context, Strategy likeStrategy) { - super(column, context); - valuePlaceholder.putAttribute(STRATEGY_KEY, likeStrategy); - } - - @Override - public String getSQL() { - // column LIKE %{{..}} - return column + - StringPool.SPACE + Statement.LIKE + StringPool.SPACE + - // 添加 '' - StringPool.SINGLE_QUOTE + valuePlaceholder.get(0).getT1() + StringPool.SINGLE_QUOTE; - } - - @Override - protected Function>> getValuePlaceholder() { - return valuePlaceholder -> { - Strategy strategy = valuePlaceholder.get(STRATEGY_KEY, Strategy.class).orElse(Strategy.ALL); - int index = 0; - List> valuePlaceholders = Lists.newLinkedList(); - String token = context.getTokenizer().createTokenString(column + StringPool.UNDERSCORE + Statement.LIKE + StringPool.UNDERSCORE + index); - switch (strategy) { - case ALL: - token = getSyntax() + token + getSyntax(); - break; - case LEFT: - token = getSyntax() + token; - break; - case RIGHT: - token = token + getSyntax(); - break; - } - valuePlaceholders.add( - Tuples.of(token, ExpressionValue.of(getSingleValue(StringPool.EMPTY))) - ); - return valuePlaceholders; - }; - } - - @Override - public String getSyntax() { - return Statement.$LIKE; - } - - public enum Strategy { - LEFT, - RIGHT, - ALL - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/NotNullExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/NotNullExpression.java deleted file mode 100644 index 040937f2..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/NotNullExpression.java +++ /dev/null @@ -1,39 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import reactor.util.function.Tuple2; - -import java.util.Collections; -import java.util.List; -import java.util.function.Function; - -/** - * not null expression - * - * @author jiangwei - * @date 2023/1/6 13:45 - * @since 1.1.4 - */ -public class NotNullExpression extends ColumnExpression implements ConditionExpression { - - public NotNullExpression(RuntimeColumn column, ExpressionContext context) { - super(column, context); - } - - @Override - public String getSQL() { - return column + StringPool.SPACE + getSyntax(); - } - - @Override - public String getSyntax() { - return Statement.NOT_NULL; - } - - @Override - protected Function>> getValuePlaceholder() { - return obj -> Collections.emptyList(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/PlainExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/PlainExpression.java deleted file mode 100644 index 58f40d5e..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/PlainExpression.java +++ /dev/null @@ -1,52 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.util.StringUtils; -import cc.allio.uno.data.orm.sql.Condition; -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.Statement; -import reactor.util.function.Tuple2; - -import java.util.List; -import java.util.function.Function; - -/** - * column expression - * - * @author jiangwei - * @date 2023/1/6 10:10 - * @since 1.1.4 - */ -public class PlainExpression extends ColumnExpression { - - private String alias; - - public PlainExpression(RuntimeColumn column, ExpressionContext context) { - super(column, context); - } - - public void alias(String alias) { - this.alias = alias; - } - - @Override - public String getSQL() { - StringBuilder sql = new StringBuilder(); - sql.append(column); - // 添加alias - if (StringUtils.isNotBlank(alias)) { - sql.append(StringPool.SPACE).append(Statement.AS).append(StringPool.SPACE).append(alias); - } - // 添加 ASC DESC等等条件 - Condition condition = runtimeColumn.getCondition(); - if (condition != null) { - sql.append(StringPool.SPACE).append(condition.getName()); - } - return sql.toString(); - } - - @Override - protected Function>> getValuePlaceholder() { - return null; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/SingleExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/SingleExpression.java deleted file mode 100644 index 3c31e48b..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/SingleExpression.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -/** - * 标识接口,标识当前表达式值允许存在于单个。 - * - * @author jiangwei - * @date 2023/1/10 19:18 - * @see ExpressionGroup - * @since 1.1.4 - */ -public interface SingleExpression extends Expression { -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/StatementExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/StatementExpression.java deleted file mode 100644 index 459f78d0..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/StatementExpression.java +++ /dev/null @@ -1,38 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import java.util.Objects; - -/** - * statement expression - * - * @author jiangwei - * @date 2023/1/10 19:30 - * @since 1.1.4 - */ -public class StatementExpression implements SingleExpression { - - private final String statementSyntax; - - public StatementExpression(String statementSyntax) { - this.statementSyntax = statementSyntax; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - StatementExpression that = (StatementExpression) o; - return Objects.equals(statementSyntax, that.statementSyntax); - } - - @Override - public int hashCode() { - return Objects.hash(statementSyntax); - } - - @Override - public String getSQL() { - return statementSyntax; - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ValueExpression.java b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ValueExpression.java deleted file mode 100644 index 73dc8fc0..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/expression/ValueExpression.java +++ /dev/null @@ -1,179 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.api.OptionalContext; -import cc.allio.uno.core.util.CollectionUtils; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.springframework.context.ApplicationContext; -import reactor.util.function.Tuple2; -import reactor.util.function.Tuples; - -import java.util.*; -import java.util.function.Function; - -/** - * 对于eq lt lte gt...等等的语句都包需要包含值的作用。故单独创建该类,使实现类能够更好的使用值 - * - * @author jiangwei - * @date 2023/1/5 19:00 - * @since 1.1.4 - */ -public abstract class ValueExpression implements Expression { - - protected final String prefix = "context"; - protected final Object[] values; - protected final ExpressionContext context; - // 值暂位符 - protected final ValuePlaceholder valuePlaceholder; - - /** - * 放入ValueExpression上下文对象 - * - * @see ValuePlaceholder - */ - public static final String CONTEXT_KEY = "context"; - - protected ValueExpression(ExpressionContext context) { - this(context, null); - } - - protected ValueExpression(ExpressionContext context, Object[] values) { - this(context, values, Collections.emptyMap()); - } - - protected ValueExpression(ExpressionContext context, Object[] values, Map runContext) { - this.context = context; - this.values = values; - this.valuePlaceholder = new ValuePlaceholder(this); - valuePlaceholder.putAll(runContext); - valuePlaceholder.putAttribute(CONTEXT_KEY, context); - } - - @Override - public Map getExpMapping() { - Map exp = Maps.newHashMap(); - for (Tuple2 ex : valuePlaceholder.getList()) { - exp.put(ex.getT1(), ex.getT2().getValue()); - } - return exp; - } - - /** - * 获取当前存放值数组的第一个值 - * - * @return 第一个值 - */ - protected Optional getSingleValue() { - if (values != null && values.length > 0) { - return Optional.ofNullable(values[0]); - } - return Optional.empty(); - } - - /** - * 获取当前存放值数组的第一个值 - * - * @param defaultValue 如果没有的话的默认值 - * @return 第一个值 or 默认值 - */ - protected Object getSingleValue(Object defaultValue) { - return getSingleValue().orElse(defaultValue); - } - - /** - * 获取当前存放值数组的第一个和第二个值 - * - * @return double value - * @throws NullPointerException 如果值是null的话则抛出 - */ - protected Optional> getDoubleValue() { - if (values != null && values.length > 1) { - return Optional.of(Tuples.of(values[0], values[1])); - } - return Optional.empty(); - } - - /** - * 获取当前存放值的数组 - * - * @return values - */ - protected Optional getValues() { - return Optional.ofNullable(values); - } - - /** - * 子类实现,获取子类包含的集合对的结构,其中成对出现的Key为valuePlaceholder value为对应占位符的值. - *

    t1: Key t2: expression value

    - *

    单值: eq lt lte gt gte...

    - *

    双值:

    - *

    多值: in

    - * - * @return 集合结构 - */ - protected abstract Function>> getValuePlaceholder(); - - /** - * ValuePlaceholder实例 - */ - static class ValuePlaceholder implements OptionalContext { - private final ValueExpression expression; - private final List> placeholderAndValues; - private final Map context; - - public ValuePlaceholder(ValueExpression expression) { - this.expression = expression; - this.placeholderAndValues = Lists.newLinkedList(); - this.context = Maps.newHashMap(); - } - - /** - * 根据指定的索引获取某个Value and ExpressionValue - * - * @param index 索引位置 - * @return t1 placeholder t2 value - */ - public Tuple2 get(int index) { - List> lazy = getList(); - return lazy.get(index); - } - - /** - * 获取Value-ExpressionValue List - * - * @return List - */ - public List> getList() { - // 延迟加载 - if (CollectionUtils.isEmpty(placeholderAndValues)) { - placeholderAndValues.addAll( - Optional.ofNullable(expression.getValuePlaceholder()).map(func -> func.apply(this)).orElse(Collections.emptyList()) - ); - for (Tuple2 pairs : placeholderAndValues) { - expression.context.getExpressionVariables().put(pairs.getT1(), pairs.getT2()); - } - } - return placeholderAndValues; - } - - @Override - public Optional get(String key) { - return Optional.ofNullable(context.get(key)); - } - - @Override - public void putAttribute(String key, Object obj) { - context.put(key, obj); - } - - @Override - public Optional getApplicationContext() { - return Optional.empty(); - } - - @Override - public Map getAll() { - return context; - } - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/druid-sql.png b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/druid-sql.png deleted file mode 100644 index 632163e1..00000000 Binary files a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/druid-sql.png and /dev/null differ diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/es-sql.png b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/es-sql.png deleted file mode 100644 index b0209400..00000000 Binary files a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/es-sql.png and /dev/null differ diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/operator.png b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/operator.png deleted file mode 100644 index 4ca924db..00000000 Binary files a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/operator.png and /dev/null differ diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/sql.png b/uno-data/src/main/java/cc/allio/uno/data/orm/sql/sql.png deleted file mode 100644 index 02b5fda0..00000000 Binary files a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/sql.png and /dev/null differ diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DBType.java b/uno-data/src/main/java/cc/allio/uno/data/orm/type/DBType.java deleted file mode 100644 index 76211033..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DBType.java +++ /dev/null @@ -1,125 +0,0 @@ -package cc.allio.uno.data.orm.type; - -import cc.allio.uno.core.env.Envs; -import com.google.common.collect.Lists; - -import java.util.List; -import java.util.Objects; - -/** - * 定义数据库类型 - * - * @author jiangwei - * @date 2023/2/23 16:36 - * @since 1.1.4 - */ -public interface DBType { - - /** - * 数据库类型配置标识 - * - * @see #MYSQL - * @see #POSTGRESQL - */ - String DB_TYPE_CONFIG_KEY = "allio.uno.data.orm.dbtype"; - - DBType MYSQL = new DefaultDBType("MySQL", DBCategory.RELATIONAL); - DBType POSTGRESQL = new DefaultDBType("PostgreSQL", DBCategory.RELATIONAL); - DBType SQLSERVER = new DefaultDBType("SQLServer", DBCategory.RELATIONAL); - DBType ORACLE = new DefaultDBType("Oracle", DBCategory.RELATIONAL); - DBType OPEN_GAUSS = new DefaultDBType(" OpenGauss", DBCategory.RELATIONAL); - DBType SQL_92 = new DefaultDBType("SQL-92", DBCategory.RELATIONAL); - DBType H2 = new DefaultDBType("H2", DBCategory.RELATIONAL); - DBType ELASTIC_SEARCH = new DefaultDBType("ElasticSearch", DBCategory.SEARCH_ENGINES); - DBType TD_ENGINE = new DefaultDBType("TDEngine", DBCategory.TIME_SERIES); - DBType INFLUXDB = new DefaultDBType("Influxdb", DBCategory.TIME_SERIES); - - /** - * 类型集合 - */ - List TYPE_SETS = Lists.newArrayList(MYSQL, POSTGRESQL, SQLSERVER, ORACLE, OPEN_GAUSS, SQL_92, H2, ELASTIC_SEARCH, TD_ENGINE, INFLUXDB); - - /** - * 获取数据库类型名称 - * - * @return 数据库全名称 - */ - String getName(); - - /** - * 数据库类别 - * - * @return DBCategory - */ - DBCategory getCategory(); - - /** - * 获取当前项目中的数据库类型。多数据源采用主数据源作为数据库类型 - * - * @return DBType or H2数据库 - */ - static DBType getSystemDbType() { - String dbtype = Envs.getProperty(DB_TYPE_CONFIG_KEY); - try { - return getDbType(dbtype); - } catch (IllegalArgumentException ex) { - // ignore - return H2; - } - } - - /** - * 根据dbtype的字符串获取DBType。 - * - * @param dbtype dbtype - * @return DBType default {@link #H2} - */ - static DBType getDbType(String dbtype) { - return TYPE_SETS.stream() - .filter(dbType -> dbType.getName().equals(dbtype)) - .findFirst() - .orElse(H2); - } - - /** - * 数据库类型分类 - * - * @see see - */ - enum DBCategory { - RELATIONAL, KEY_VALUE, DOCUMENT, TIME_SERIES, GRAPH, SEARCH_ENGINES, OBJECT_ORIENTED - } - - class DefaultDBType implements DBType { - private final String name; - private final DBCategory category; - - public DefaultDBType(String name, DBCategory category) { - this.name = name; - this.category = category; - } - - @Override - public String getName() { - return name; - } - - @Override - public DBCategory getCategory() { - return category; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - DefaultDBType that = (DefaultDBType) o; - return Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DBTypeAdapter.java b/uno-data/src/main/java/cc/allio/uno/data/orm/type/DBTypeAdapter.java deleted file mode 100644 index 67a24b03..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DBTypeAdapter.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.allio.uno.data.orm.type; - -import cc.allio.uno.data.orm.SQLAdapter; - -/** - * SQL 数据库类型适配器 - * - * @author jiangwei - * @date 2023/4/13 13:17 - * @since 1.1.4 - */ -public interface DBTypeAdapter extends SQLAdapter { -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DataTypeAdapter.java b/uno-data/src/main/java/cc/allio/uno/data/orm/type/DataTypeAdapter.java deleted file mode 100644 index 5fa40225..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DataTypeAdapter.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.allio.uno.data.orm.type; - -import cc.allio.uno.data.orm.SQLAdapter; - -/** - * 适用于不同框架的类型定义 - * - * @author jiangwei - * @date 2023/4/12 20:01 - * @since 1.1.4 - */ -public interface DataTypeAdapter extends SQLAdapter { - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/GenericSQLType.java b/uno-data/src/main/java/cc/allio/uno/data/orm/type/GenericSQLType.java deleted file mode 100644 index 95d96867..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/GenericSQLType.java +++ /dev/null @@ -1,68 +0,0 @@ -package cc.allio.uno.data.orm.type; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.sql.Types; - -/** - * 系统存在的sql type 常量定义 - * - * @author jiangwei - * @date 2023/4/18 11:11 - * @since 1.1.4 - */ -@Getter -@AllArgsConstructor -public enum GenericSQLType implements SQLType { - - // ====================== 数字型 ====================== - BIGINT("bigint", Types.BIGINT, 64, null), - SMALLINT("smallint", Types.SMALLINT, 32, null), - INTEGER("int", Types.INTEGER, 64, null), - BIT("bit", Types.BIT, 4, null), - TINYINT("tinyint", Types.TINYINT, 16, null), - NUMBER("number", Types.NUMERIC, 12, 2), - DOUBLE("double", Types.DOUBLE, 12, 2), - FLOAT("float", Types.FLOAT, 12, 2), - - // ====================== 时间型 ====================== - TIME("time", Types.TIME, 6, null), - TIMESTAMP("timestamp", Types.TIMESTAMP, null, null), - DATE("date", Types.DATE, 6, null), - DECIMAL("DECIMAL", Types.DECIMAL, 6, null), - - // ====================== 字符型 ====================== - CHAR("char", Types.CHAR, 64, null), - VARCHAR("varchar", Types.VARCHAR, 64, null), - NVARCHAR("nvarchar", Types.NVARCHAR, 64, null), - LONGVARCHAR("longvarchar", Types.LONGVARCHAR, 1024, null), - LONGNVARCHAR("longnvarchar", Types.LONGNVARCHAR, 1024, null), - VARBINARY("varbinary", Types.VARBINARY, 1024, null), - LONGVARBINARY("longvarchar", Types.LONGVARBINARY, 2048, null), - - // ====================== 高级类型 ====================== - OBJECT("object", Types.JAVA_OBJECT, null, null), - ARRAY("array", Types.ARRAY, null, null); - - - private final String name; - private final int jdbcType; - private final Integer defaultPrecision; - private final Integer defaultScala; - - /** - * 根据jdbc code获取SQLType实例 - * - * @param jdbcCode jdbcCode - * @return SQLType - */ - public static GenericSQLType getByJdbcCode(int jdbcCode) { - for (GenericSQLType value : values()) { - if (value.getJdbcType() == jdbcCode) { - return value; - } - } - return null; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/SQLType.java b/uno-data/src/main/java/cc/allio/uno/data/orm/type/SQLType.java deleted file mode 100644 index ecf13386..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/SQLType.java +++ /dev/null @@ -1,87 +0,0 @@ -package cc.allio.uno.data.orm.type; - -import cc.allio.uno.data.orm.type.db.MySQLType; -import cc.allio.uno.data.orm.type.db.PostgresSQLType; - -import java.util.List; - -/** - * SQL 类型定义 - * - * @author jiangwei - * @date 2023/4/12 20:03 - * @see DataType - * @see GenericSQLType - * @see PostgresSQLType - * @see MySQLType - * @since 1.1.4 - */ -public interface SQLType { - - /** - * 获取sql type name - * - * @return String - */ - String getName(); - - /** - * 获取 sql type对应的jdbc type code - * - * @return jdbc code - */ - int getJdbcType(); - - /** - * 获取默认的Precision - * - * @return Precision - */ - Integer getDefaultPrecision(); - - /** - * 获取默认的Scala - * - * @return Scala - */ - Integer getDefaultScala(); - - /** - * 根据db类型创建sqlType - * - * @param sqlType sqlType - * @return SQLType - */ - static SQLType create(GenericSQLType sqlType) { - return create(sqlType, DBType.getSystemDbType()); - } - - /** - * 根据db类型创建sqlType - * - * @param sqlType sqlType - * @param dbType dbType - * @return SQLType - */ - static SQLType create(GenericSQLType sqlType, DBType dbType) { - if (DBType.POSTGRESQL.equals(dbType)) { - return new PostgresSQLType(sqlType); - } else if (DBType.MYSQL.equals(dbType)) { - return new MySQLType(sqlType); - } - return sqlType; - } - - /** - * 关联于某一个SQLType - */ - interface SQLLinkType extends SQLType { - - /** - * 关联的SQL Type - * - * @return SQLType - */ - List getParent(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/db/MySQLType.java b/uno-data/src/main/java/cc/allio/uno/data/orm/type/db/MySQLType.java deleted file mode 100644 index 06c0ad71..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/db/MySQLType.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.allio.uno.data.orm.type.db; - -import cc.allio.uno.data.orm.type.GenericSQLType; -import cc.allio.uno.data.orm.type.SQLType; - -/** - * 对mysql库字段进行处理 - * - * @author jiangwei - * @date 2023/4/18 11:15 - * @since 1.1.4 - */ -public class MySQLType implements SQLType { - - private final GenericSQLType sqlType; - - public MySQLType(GenericSQLType sqlType) { - this.sqlType = sqlType; - } - - @Override - public String getName() { - return null; - } - - @Override - public int getJdbcType() { - return 0; - } - - @Override - public Integer getDefaultPrecision() { - return null; - } - - @Override - public Integer getDefaultScala() { - return null; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/db/PostgresSQLType.java b/uno-data/src/main/java/cc/allio/uno/data/orm/type/db/PostgresSQLType.java deleted file mode 100644 index fa8b4669..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/db/PostgresSQLType.java +++ /dev/null @@ -1,70 +0,0 @@ -package cc.allio.uno.data.orm.type.db; - -import cc.allio.uno.data.orm.type.GenericSQLType; -import cc.allio.uno.data.orm.type.SQLType; -import com.google.common.collect.Lists; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.sql.Types; -import java.util.List; - -/** - * 对pg库的字段类型进行处理 - * - * @author jiangwei - * @date 2023/4/18 11:14 - * @since 1.1.4 - */ -public class PostgresSQLType implements SQLType { - - private SQLType sqlType; - - public PostgresSQLType(GenericSQLType sqlType) { - for (PostgreSQLLinkType linkType : PostgreSQLLinkType.values()) { - List parent = linkType.getParent(); - if (parent.stream().anyMatch(p -> p.getName().equals(sqlType.getName()))) { - this.sqlType = linkType; - break; - } - } - if (this.sqlType == null) { - this.sqlType = sqlType; - } - } - - @Override - public String getName() { - return sqlType.getName(); - } - - @Override - public int getJdbcType() { - return sqlType.getJdbcType(); - } - - @Override - public Integer getDefaultPrecision() { - return sqlType.getDefaultPrecision(); - } - - @Override - public Integer getDefaultScala() { - return sqlType.getDefaultScala(); - } - - @Getter - @AllArgsConstructor - public enum PostgreSQLLinkType implements SQLLinkType { - INT8("int8", Types.BIGINT, null, null, Lists.newArrayList(GenericSQLType.BIGINT)), - FLOAT("float8", Types.FLOAT, 12, 2, Lists.newArrayList(GenericSQLType.FLOAT)), - NUMERIC("numeric", Types.DOUBLE, 12, 2, Lists.newArrayList(GenericSQLType.DOUBLE, GenericSQLType.NUMBER)), - INT4("int4", Types.INTEGER, null, null, Lists.newArrayList(GenericSQLType.INTEGER)); - - private final String name; - private final int jdbcType; - private final Integer defaultPrecision; - private final Integer defaultScala; - private final List parent; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/druid/DruidTypeAdapter.java b/uno-data/src/main/java/cc/allio/uno/data/orm/type/druid/DruidTypeAdapter.java deleted file mode 100644 index 9904aa39..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/druid/DruidTypeAdapter.java +++ /dev/null @@ -1,90 +0,0 @@ -package cc.allio.uno.data.orm.type.druid; - -import cc.allio.uno.data.orm.type.DataType; -import cc.allio.uno.data.orm.type.DataTypeAdapter; -import cc.allio.uno.data.orm.type.GenericSQLType; -import cc.allio.uno.data.orm.type.SQLType; -import com.alibaba.druid.sql.ast.SQLDataType; -import com.alibaba.druid.sql.ast.SQLDataTypeImpl; -import com.alibaba.druid.sql.ast.expr.*; - -/** - * druid的类型转换器 - * - * @author jiangwei - * @date 2023/4/12 20:06 - * @since 1.1.4 - */ -public class DruidTypeAdapter implements DataTypeAdapter { - private static final DruidTypeAdapter INSTANCE = new DruidTypeAdapter(); - - @Override - public SQLDataType get(DataType o) { - DataType dataType = o; - // dataType为null,赋值于VARCHAR - if (dataType == null) { - dataType = DataType.createCharType(GenericSQLType.VARCHAR, 64); - } - // 通用的做分组比较 - SQLType sqlType = dataType.getSqlType(); - // 每个数据库类型的做创建 - GenericSQLType sqlTypeConstant = GenericSQLType.getByJdbcCode(sqlType.getJdbcType()); - // scale 随着 precision值进行赋予,precision没值时,scale没值 - Integer precision = dataType.getPrecision(); - Integer scale = dataType.getScale(); - switch (sqlTypeConstant) { - case BIGINT: - case SMALLINT: - case TINYINT: - case BIT: - case INTEGER: - case DOUBLE: - case NUMBER: - case FLOAT: - if (precision == null) { - return new SQLDataTypeImpl(sqlType.getName()); - } else if (scale == null) { - return new SQLDataTypeImpl(sqlType.getName(), precision); - } else { - return new SQLDataTypeImpl(sqlType.getName(), precision, scale); - } - case DECIMAL: - SQLDataTypeImpl decimalDataType = new SQLDataTypeImpl(sqlType.getName()); - if (precision != null) { - decimalDataType.addArgument(new SQLIntegerExpr(dataType.getPrecision())); - } - if (scale != null) { - decimalDataType.addArgument(new SQLIntegerExpr(dataType.getPrecision())); - } - return decimalDataType; - case DATE: - case TIME: - case TIMESTAMP: - SQLDataTypeImpl dateDataType = new SQLDataTypeImpl(sqlType.getName()); - if (precision != null) { - dateDataType.addArgument(new SQLIntegerExpr(precision)); - } - return dateDataType; - case CHAR: - case VARCHAR: - case NVARCHAR: - case VARBINARY: - case LONGVARCHAR: - case LONGNVARCHAR: - case LONGVARBINARY: - default: - SQLDataTypeImpl charDataType = new SQLDataTypeImpl(sqlType.getName()); - charDataType.addArgument(new SQLIntegerExpr(dataType.getPrecision())); - return charDataType; - } - } - - @Override - public DataType reversal(SQLDataType sqlDataType) { - return null; - } - - public static DruidTypeAdapter getInstance() { - return INSTANCE; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/type.png b/uno-data/src/main/java/cc/allio/uno/data/orm/type/type.png deleted file mode 100644 index f69d90b2..00000000 Binary files a/uno-data/src/main/java/cc/allio/uno/data/orm/type/type.png and /dev/null differ diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/BaseQueryFilter.java b/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/BaseQueryFilter.java deleted file mode 100644 index f24e91f4..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/BaseQueryFilter.java +++ /dev/null @@ -1,208 +0,0 @@ -package cc.allio.uno.data.query.mybatis; - -import cc.allio.uno.data.orm.dialect.func.Func; -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.local.OrderCondition; -import cc.allio.uno.data.orm.sql.word.Distinct; -import cc.allio.uno.data.orm.type.DBType; - -import java.util.Collection; -import java.util.List; - -/** - * 基于{@link SQLQueryOperator}实现的{@link QueryFilter} - * - * @author jiangwei - * @date 2023/4/17 18:21 - * @since 1.1.4 - */ -public class BaseQueryFilter implements QueryFilter, SQLQueryOperator { - - private QueryWrapper queryWrapper; - private final SQLQueryOperator queryOperator; - - public BaseQueryFilter(DBType dbType, OperatorMetadata.OperatorMetadataKey operatorMetadataKey) { - queryOperator = SQLOperatorFactory.getSQLOperator(SQLQueryOperator.class, operatorMetadataKey, dbType); - } - - @Override - public String getSQL() { - return queryOperator.getSQL(); - } - - @Override - public SQLQueryOperator parse(String sql) { - return queryOperator.parse(sql); - } - - @Override - public void reset() { - queryOperator.reset(); - } - - @Override - public void setQueryWrapper(QueryWrapper queryWrapper) { - this.queryWrapper = queryWrapper; - } - - @Override - public QueryWrapper getQueryWrapper() { - return queryWrapper; - } - - @Override - public String getPrepareSQL() { - return queryOperator.getPrepareSQL(); - } - - @Override - public List getPrepareValues() { - return queryOperator.getPrepareValues(); - } - - @Override - public SQLQueryOperator from(Table table) { - return queryOperator.from(table); - } - - @Override - public SQLQueryOperator gt(SQLName sqlName, Object value) { - return queryOperator.gt(sqlName, value); - } - - @Override - public SQLQueryOperator gte(SQLName sqlName, Object value) { - return queryOperator.gte(sqlName, value); - } - - @Override - public SQLQueryOperator lt(SQLName sqlName, Object value) { - return queryOperator.lt(sqlName, value); - } - - @Override - public SQLQueryOperator lte(SQLName sqlName, Object value) { - return queryOperator.lte(sqlName, value); - } - - @Override - public SQLQueryOperator eq(SQLName sqlName, Object value) { - return queryOperator.eq(sqlName, value); - } - - @Override - public SQLQueryOperator notNull(SQLName sqlName) { - return queryOperator.notNull(sqlName); - } - - @Override - public SQLQueryOperator isNull(SQLName sqlName) { - return queryOperator.isNull(sqlName); - } - - @Override - public SQLQueryOperator in(SQLName sqlName, Object... values) { - return queryOperator.in(sqlName, values); - } - - @Override - public SQLQueryOperator between(SQLName sqlName, Object withValue, Object endValue) { - return queryOperator.between(sqlName, withValue, endValue); - } - - @Override - public SQLQueryOperator notBetween(SQLName sqlName, Object withValue, Object endValue) { - return queryOperator.notBetween(sqlName, withValue, endValue); - } - - @Override - public SQLQueryOperator like(SQLName sqlName, Object value) { - return queryOperator.like(sqlName, value); - } - - @Override - public SQLQueryOperator $like(SQLName sqlName, Object value) { - return queryOperator.$like(sqlName, value); - } - - @Override - public SQLQueryOperator like$(SQLName sqlName, Object value) { - return queryOperator.like$(sqlName, value); - } - - @Override - public SQLQueryOperator $like$(SQLName sqlName, Object value) { - return queryOperator.$like$(sqlName, value); - } - - @Override - public SQLQueryOperator or() { - return queryOperator.or(); - } - - @Override - public SQLQueryOperator and() { - return queryOperator.and(); - } - - @Override - public SQLQueryOperator select(SQLName sqlName) { - return queryOperator.select(sqlName); - } - - @Override - public SQLQueryOperator select(SQLName sqlName, String alias) { - return queryOperator.select(sqlName, alias); - } - - @Override - public SQLQueryOperator selects(Collection sqlNames) { - return queryOperator.selects(sqlNames); - } - - @Override - public SQLQueryOperator distinct() { - return queryOperator.distinct(); - } - - @Override - public SQLQueryOperator distinctOn(SQLName sqlName, String alias) { - return queryOperator.distinctOn(sqlName, alias); - } - - @Override - public SQLQueryOperator aggregate(Func syntax, SQLName sqlName, String alias, Distinct distinct) { - return queryOperator.aggregate(syntax, sqlName, alias, distinct); - } - - @Override - public SQLQueryOperator from(SQLQueryOperator fromTable, String alias) { - return queryOperator.from(fromTable, alias); - } - - @Override - public SQLQueryOperator join(Table left, JoinType joinType, Table right, SQLBinaryCondition condition) { - return queryOperator.join(left, joinType, right, condition); - } - - @Override - public SQLQueryOperator orderBy(SQLName sqlName, OrderCondition orderCondition) { - return queryOperator.orderBy(sqlName, orderCondition); - } - - @Override - public SQLQueryOperator limit(Long limit, Long offset) { - return queryOperator.limit(limit, offset); - } - - @Override - public SQLQueryOperator groupByOnes(Collection fieldNames) { - return queryOperator.groupByOnes(fieldNames); - } - - @Override - public SQLQueryOperator self() { - return queryOperator; - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/MybatisQueryFilter.java b/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/MybatisQueryFilter.java deleted file mode 100644 index d049f720..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/MybatisQueryFilter.java +++ /dev/null @@ -1,157 +0,0 @@ -package cc.allio.uno.data.query.mybatis; - -import cc.allio.uno.core.util.ObjectUtils; -import cc.allio.uno.data.orm.sql.From; -import cc.allio.uno.data.orm.sql.FromStatement; -import cc.allio.uno.data.orm.sql.dml.*; -import cc.allio.uno.data.orm.sql.dml.local.*; -import cc.allio.uno.data.orm.sql.dml.local.expression.DefaultExpressionContext; -import cc.allio.uno.data.orm.sql.dml.local.expression.Expression; -import cc.allio.uno.data.orm.sql.dml.local.expression.ExpressionContext; -import cc.allio.uno.data.orm.sql.dml.local.expression.StatementExpression; -import com.google.common.collect.Maps; -import com.google.common.collect.Streams; - -import java.util.Map; -import java.util.stream.Stream; - -/** - * MybatisQueryFilter - * - * @author jiangwei - * @date 2023/4/17 18:11 - * @since 1.1.4 - */ -public class MybatisQueryFilter implements QueryFilter { - - // 查询 - private final SelectDelegate select; - private final SelectFrom from; - private final WhereDelegate where; - private final OrderDelegate order; - private final GroupDelegate group; - private final LimitDelegate limit; - private Map context; - - /** - * 关联查询包装器 - */ - private QueryWrapper queryWrapper; - - public MybatisQueryFilter() { - ExpressionContext expressionContext = new DefaultExpressionContext(); - SelectStatement select = new SelectStatement(expressionContext); - FromStatement from = new FromStatement(expressionContext); - WhereStatement where = new WhereStatement(expressionContext); - GroupStatement group = new GroupStatement(expressionContext); - OrderStatement order = new OrderStatement(expressionContext); - LimitStatement limit = new LimitStatement(); - this.select = new SelectStatementDelegate(select, from, where, group, order, limit); - this.from = new QueryFromStatement(select, from, where, group, order, limit); - this.where = new WhereStatementDelegate(select, from, where, group, order, limit); - this.order = new OrderStatementDelegate(select, from, where, group, order, limit); - this.group = new GroupStatementDelegate(select, from, where, group, order, limit); - this.limit = new LimitStatementDelegate(select, from, where, group, order, limit); - } - - @Override - public String getSQL() { - throw new UnsupportedOperationException("mybatis query filter un support"); - } - - @Override - public void setQueryWrapper(QueryWrapper queryWrapper) { - this.queryWrapper = queryWrapper; - } - - @Override - public QueryWrapper getQueryWrapper() { - return queryWrapper; - } - - /** - * select SQL语句 - * - * @return SELECT实例对象 - * @see Select - */ - public SelectDelegate selectSql() { - return select; - } - - /** - * from SQL语句 - * - * @return FROM实例 - * @see From - */ - public SelectFrom fromSql() { - return from; - } - - /** - * WHERE SQL语句 - * - * @return Where实例对象 - * @see Where - */ - public WhereDelegate whereSql() { - return where; - } - - /** - * order SQL语句 - * - * @return Order实例对象 - * @see Order - */ - public OrderDelegate orderSql() { - return order; - } - - /** - * group SQL语句 - * - * @return Group实例对象 - * @see Group - */ - public GroupDelegate groupSql() { - return group; - } - - /** - * limit SQl语句 - * - * @return Limit实例对象 - * @see Limit - */ - public LimitDelegate limitSql() { - return limit; - } - - /** - * 获取mybatis数据上下文 - * - * @return the map - * @see {@link Expression#getExpMapping()} - */ - public Map getContext() { - if (ObjectUtils.isEmpty(context)) { - Stream se = select.getExpressions().stream(); - Stream fr = from.getExpressions().stream(); - Stream wh = where.getExpressions().stream(); - Stream or = order.getExpressions().stream(); - Stream gr = group.getExpressions().stream(); - Stream li = limit.getExpressions().stream(); - this.context = Streams.concat(se, fr, wh, or, gr, li) - .filter(p -> !StatementExpression.class.isAssignableFrom(p.getClass())) - .map(Expression::getExpMapping) - .reduce(Maps.newHashMap(), (o, i) -> { - o.putAll(i); - return o; - }); - } - return context; - } - -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/UnoDataMybatisAutoConfiguration.java b/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/UnoDataMybatisAutoConfiguration.java deleted file mode 100644 index 106eca78..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/UnoDataMybatisAutoConfiguration.java +++ /dev/null @@ -1,50 +0,0 @@ -package cc.allio.uno.data.query.mybatis; - -import cc.allio.uno.data.query.mybatis.query.interceptor.QueryInterceptor; -import cc.allio.uno.data.query.mybatis.type.DateDimensionTypeHandler; -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties; -import org.apache.ibatis.type.TypeHandlerRegistry; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.SmartInitializingSingleton; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.EnableAspectJAutoProxy; - -/** - * UNO-DATA配置 - * - * @author jiangwei - * @date 2022/11/22 15:11 - * @since 1.1.2 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({MybatisPlusAutoConfiguration.class}) -@EnableAspectJAutoProxy -@AutoConfigureAfter(MybatisPlusAutoConfiguration.class) -public class UnoDataMybatisAutoConfiguration implements ApplicationContextAware, SmartInitializingSingleton { - - private ApplicationContext applicationContext; - - @Bean - public QueryInterceptor unoQueryInterceptor() { - return new QueryInterceptor(); - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @Override - public void afterSingletonsInstantiated() { - MybatisPlusProperties properties = applicationContext.getBean(MybatisPlusProperties.class); - com.baomidou.mybatisplus.core.MybatisConfiguration configuration = properties.getConfiguration(); - TypeHandlerRegistry registry = configuration.getTypeHandlerRegistry(); - registry.register(DateDimensionTypeHandler.class); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/higher-query.png b/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/higher-query.png deleted file mode 100644 index c96dcadd..00000000 Binary files a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/higher-query.png and /dev/null differ diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/SQLCommandExecutorStream.java b/uno-data/src/main/java/cc/allio/uno/data/query/stream/SQLCommandExecutorStream.java deleted file mode 100644 index fa825dfc..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/SQLCommandExecutorStream.java +++ /dev/null @@ -1,32 +0,0 @@ -package cc.allio.uno.data.query.stream; - -import cc.allio.uno.data.orm.executor.SQLCommandExecutor; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import reactor.core.publisher.Flux; - -import java.util.Map; - -/** - * 基于{@link SQLCommandExecutor}的流 - * - * @author jiangwei - * @date 2023/4/21 13:21 - * @since 1.1.4 - */ -public class SQLCommandExecutorStream implements CollectionTimeStream> { - - private final SQLCommandExecutor sqlCommandExecutor; - - public SQLCommandExecutorStream(SQLCommandExecutor sqlCommandExecutor) { - this.sqlCommandExecutor = sqlCommandExecutor; - } - - @Override - public Flux> read(QueryFilter queryFilter) throws Throwable { - if (queryFilter instanceof SQLQueryOperator) { - return new CollectionTimeStreamImpl<>(sqlCommandExecutor.queryListMap((SQLQueryOperator) queryFilter)).read(queryFilter); - } - return Flux.empty(); - } -} diff --git a/uno-data/src/main/java/cc/allio/uno/data/tx/TransactionContext.java b/uno-data/src/main/java/cc/allio/uno/data/tx/TransactionContext.java deleted file mode 100644 index 7af97d8e..00000000 --- a/uno-data/src/main/java/cc/allio/uno/data/tx/TransactionContext.java +++ /dev/null @@ -1,71 +0,0 @@ -package cc.allio.uno.data.tx; - -import lombok.NonNull; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.DefaultTransactionDefinition; - -/** - * 基于Spring编程式事物工具 - * - * @author jiangwei - * @date 2022/1/10 21:57 - * @since 1.0 - */ -@Slf4j -public class TransactionContext { - - /** - * 默认事物定义,事物传播行为与隔离级别 - */ - private static final DefaultTransactionDefinition DEFINITION = new DefaultTransactionDefinition(); - - static { - DEFINITION.setReadOnly(false); - DEFINITION.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - } - - private static PlatformTransactionManager transactionManager; - - public TransactionContext(PlatformTransactionManager transactionManager) { - TransactionContext.transactionManager = transactionManager; - } - - /** - * 基于Spring事物管理,执行事物代码,当执行过程中抛出异常将会捕获,并且回滚事物。 - * - * @param transaction 可执行事物代码块,非空 - * @throws NoSuchBeanDefinitionException 在IOC容器中没有找到{@link PlatformTransactionManager}实例抛出 - */ - public static void execute(@NonNull Transaction transaction) { - if (transactionManager != null) { - TransactionStatus status = transactionManager.getTransaction(DEFINITION); - synchronized (TransactionContext.class) { - try { - transaction.around(); - transactionManager.commit(status); - } catch (Exception e) { - log.error("transaction execute failed, data will be rollback", e); - transactionManager.rollback(status); - } - } - } - } - - /** - * 定义包含事物的代码块 - */ - @FunctionalInterface - public interface Transaction { - - /** - * 将带着事物执行的代码块 - * - * @throws Exception 代码块存在异常时抛出 - */ - void around() throws Exception; - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/ResourceSqlExecutor.java b/uno-data/src/test/java/cc/allio/uno/data/ResourceSqlExecutor.java deleted file mode 100644 index 5919b21a..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/ResourceSqlExecutor.java +++ /dev/null @@ -1,71 +0,0 @@ -package cc.allio.uno.data; - -import cc.allio.uno.core.util.IoUtil; -import cc.allio.uno.core.util.template.ExpressionTemplate; -import cc.allio.uno.core.util.template.Tokenizer; -import lombok.extern.slf4j.Slf4j; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; -import org.springframework.core.io.UrlResource; -import org.springframework.util.ResourceUtils; - -import java.net.URL; -import java.sql.Connection; -import java.sql.Statement; - -/** - * resource - * - * @author jiangwei - * @date 2022/12/14 19:45 - * @since 1.1.3 - */ -@Slf4j -public class ResourceSqlExecutor { - - public static final String H2 = "h2"; - public static final String MYSQL = "mysql"; - public static final String POSTGRES = "postgres"; - public static final String ORACLE = "oracle"; - public static final String MSSQL = "mssql"; - - private static final String SQL_FILE = "classpath:database/" + "{{dbType}}" + "/" + "{{sqlName}}"; - - private static final ExpressionTemplate TEMPLATE = ExpressionTemplate.createTemplate(Tokenizer.DOUBLE_BRACE); - - - /** - * 执行指定resource下的SQL文件 - * - * @param dbType 数据类型 - * @param sqlName sql文件名称 - * @param factory SqlSessionFactory实例对象,创建Statement执行创建表语句 - * @throws Throwable 发生异常时抛出 - */ - public static void executeSql(String dbType, String sqlName, SqlSessionFactory factory) throws Throwable { - String sql = TEMPLATE.parseTemplate(SQL_FILE, "dbType", dbType, "sqlName", sqlName); - URL url = ResourceUtils.getURL(sql); - UrlResource resource = new UrlResource(url); - String sqlStatement = IoUtil.readToString(resource.getInputStream()); - executeSql(sqlStatement, factory); - } - - /** - * 执行给定的SQL语句 - * - * @param sql - * @param factory - */ - public static void executeSql(String sqlStatement, SqlSessionFactory factory) { - SqlSession sqlSession = factory.openSession(); - Connection connection = sqlSession.getConnection(); - try { - Statement statement = connection.createStatement(); - statement.execute(sqlStatement); - sqlSession.commit(); - } catch (Throwable ex) { - log.error("execute sql: {} error", sqlStatement, ex); - sqlSession.rollback(true); - } - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/jpa/JpaConfiguration.java b/uno-data/src/test/java/cc/allio/uno/data/jpa/JpaConfiguration.java deleted file mode 100644 index 9ddc4108..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/jpa/JpaConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -package cc.allio.uno.data.jpa; - -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.domain.AuditorAware; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; - -import java.util.Optional; - -@Configuration -@EnableJpaRepositories("cc.allio.uno.data.jpa") -@EntityScan("cc.allio.uno") -@EnableJpaAuditing -public class JpaConfiguration { - - @Bean - public AuditorAwareImpl auditorAwareImpl() { - return new AuditorAwareImpl(); - } - - - public static class AuditorAwareImpl implements AuditorAware { - - @Override - public Optional getCurrentAuditor() { - return Optional.of(123L); - } - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/CarRepository.java b/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/CarRepository.java deleted file mode 100644 index 7a875846..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/CarRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.allio.uno.data.jpa.repository; - -import cc.allio.uno.data.model.Car; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface CarRepository extends JpaRepository { - - List findByBrand(String brand); - - List findByUserId(Long userId); -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/CarRepositoryTest.java b/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/CarRepositoryTest.java deleted file mode 100644 index 3d6cdb2b..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/CarRepositoryTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package cc.allio.uno.data.jpa.repository; - -import cc.allio.uno.data.jpa.JpaConfiguration; -import cc.allio.uno.data.model.Car; -import cc.allio.uno.data.model.User; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.DefaultTransactionDefinition; - -import java.util.List; - -@DataJpaTest -@ContextConfiguration(classes = JpaConfiguration.class) -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -class CarRepositoryTest extends Assertions { - - /** - * 默认事物定义,事物传播行为与隔离级别 - */ - private static final DefaultTransactionDefinition DEFINITION = new DefaultTransactionDefinition(); - - static { - DEFINITION.setReadOnly(false); - DEFINITION.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - } - - @Autowired - private CarRepository carRepository; - @Autowired - private UserRepository userRepository; - @Autowired - private PlatformTransactionManager transactionManager; - - @Test - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - void testSaveOne() { - TransactionStatus status = transactionManager.getTransaction(DEFINITION); - User user = new User(); - user.setName("name"); - user = userRepository.save(user); - Car car = new Car(); - car.setBrand("brand"); - car.setUserId(user.getId()); - carRepository.save(car); - transactionManager.commit(status); - List cars = carRepository.findByUserId(user.getId()); - assertEquals(1, cars.size()); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/DeptRepository.java b/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/DeptRepository.java deleted file mode 100644 index c2ef1005..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/DeptRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package cc.allio.uno.data.jpa.repository; - -import cc.allio.uno.data.model.Dept; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface DeptRepository extends JpaRepository { -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/DeptRepositoryTest.java b/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/DeptRepositoryTest.java deleted file mode 100644 index bead2fb2..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/DeptRepositoryTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package cc.allio.uno.data.jpa.repository; - -import cc.allio.uno.data.jpa.JpaConfiguration; -import cc.allio.uno.data.orm.jpa.UnoJpaAutoConfiguration; -import cc.allio.uno.data.model.Dept; -import com.google.common.collect.Lists; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.DefaultTransactionDefinition; - -import java.util.List; - -@DataJpaTest -@ContextConfiguration(classes = {JpaConfiguration.class, UnoJpaAutoConfiguration.class}) -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -public class DeptRepositoryTest { - - @Autowired - private DeptRepository repository; - @Autowired - private PlatformTransactionManager transactionManager; - /** - * 默认事物定义,事物传播行为与隔离级别 - */ - private static final DefaultTransactionDefinition DEFINITION = new DefaultTransactionDefinition(); - - static { - DEFINITION.setReadOnly(false); - DEFINITION.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - } - - - @Test - void testInsert() { - TransactionStatus status = transactionManager.getTransaction(DEFINITION); - Dept dept = new Dept(); - dept.setUserIds(Lists.newArrayList("1", "2")); - repository.save(dept); - transactionManager.commit(status); - } - - @Test - void testSelect() { - List depts = repository.findAll(); - System.out.println(depts); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/RoleRepository.java b/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/RoleRepository.java deleted file mode 100644 index 04d4283a..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/RoleRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.allio.uno.data.jpa.repository; - -import cc.allio.uno.data.model.Role; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface RoleRepository extends JpaRepository { - - List findByName(String name); -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/RoleRepositoryTest.java b/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/RoleRepositoryTest.java deleted file mode 100644 index 63dc343a..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/RoleRepositoryTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.allio.uno.data.jpa.repository; - -import cc.allio.uno.data.jpa.JpaConfiguration; -import cc.allio.uno.data.model.Role; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.test.context.ContextConfiguration; - -@DataJpaTest -@ContextConfiguration(classes = JpaConfiguration.class) -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -class RoleRepositoryTest { - - @Autowired - private RoleRepository roleRepository; - - @Test - void testSave() { - Role role = new Role(); - role.setName("name"); - roleRepository.save(role); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/UserRepository.java b/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/UserRepository.java deleted file mode 100644 index ba6ece43..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/UserRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.allio.uno.data.jpa.repository; - -import cc.allio.uno.data.model.User; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface UserRepository extends JpaRepository { - - List findByName(String name); - - int deleteByName(String name); -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/UserRepositoryTest.java b/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/UserRepositoryTest.java deleted file mode 100644 index 6c95014c..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/jpa/repository/UserRepositoryTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package cc.allio.uno.data.jpa.repository; - -import cc.allio.uno.data.jpa.JpaConfiguration; -import cc.allio.uno.data.model.Role; -import cc.allio.uno.data.model.User; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.test.context.ContextConfiguration; - -import java.util.List; - -@DataJpaTest -@ContextConfiguration(classes = JpaConfiguration.class) -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -class UserRepositoryTest extends Assertions { - - @Autowired - private UserRepository userRepository; - @Autowired - private RoleRepository roleRepository; - - @Test - void testSaveOne() { - User user = new User(); - user.setName("name"); - userRepository.save(user); - - List users = userRepository.findByName("name"); - assertEquals(1, users.size()); - User user0 = users.get(0); - assertEquals(user.getName(), user0.getName()); - } - - /** - * Test Case: 测试级联保存 - */ - @Test - void testRoleManyToManyCascadeSave() { - save(); - List users = userRepository.findByName("name"); - assertEquals(1, users.size()); - User user0 = users.get(0); - assertEquals("name", user0.getName()); -// assertEquals(1, user0.getRoles().size()); - } - - - /** - * Test Case: 测试多对多级联删除 - */ - @Test - void testRoleManyToManyCascadeDelete() { - save(); - - int deleteUserCount = userRepository.deleteByName("name"); - assertEquals(1, deleteUserCount); - - List roles = roleRepository.findByName("name"); - assertEquals(0, roles.size()); - } - - void save() { - User user = new User(); - user.setName("name"); - Role role = new Role(); - role.setName("name"); - // 需要在数据库中存在该实例 - role = roleRepository.save(role); -// user.setRoles(Sets.newHashSet(role)); - userRepository.save(user); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/RiReal.java b/uno-data/src/test/java/cc/allio/uno/data/model/RiReal.java deleted file mode 100644 index 241d75fc..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/model/RiReal.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2018-2028, www.beree.com.cn All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the beree.net developer nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - */ -package cc.allio.uno.data.model; - -import cc.allio.uno.data.model.constant.WaterPotentialEnum; -import com.baomidou.mybatisplus.annotation.TableName; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.NullSerializer; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.math.BigDecimal; - -/** - * 水位实时数据 - * - * @author htz - * @since 2021-12-20 - */ -@EqualsAndHashCode(callSuper = true) -@Data -@TableName("wr_ri_real") -public class RiReal extends StationReal implements Serializable { - - /** - * 水位 - */ - @JsonSerialize(nullsUsing = NullSerializer.class) - private BigDecimal z; - - /** - * 埋深 - */ - @JsonSerialize(nullsUsing = NullSerializer.class) - private BigDecimal d; - - /** - * 水势 - */ - private WaterPotentialEnum wptn = WaterPotentialEnum.KEEP; - -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/StationReal.java b/uno-data/src/test/java/cc/allio/uno/data/model/StationReal.java deleted file mode 100644 index 246341c1..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/model/StationReal.java +++ /dev/null @@ -1,58 +0,0 @@ -package cc.allio.uno.data.model; - -import cc.allio.uno.data.model.constant.AlarmStatusEnum; -import cc.allio.uno.data.model.constant.StinfoStatusEnum; -import cc.allio.uno.data.model.constant.SttpTypeEnum; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.NullSerializer; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; -import lombok.Data; - -import java.util.Date; - -/** - * 测站基本实时数据 - * - * @author jiangwei - * @date 2021/12/22 00:48 - * @since 1.0 - */ -@Data -public class StationReal extends BaseEntity { - - private static final long serialVersionUID = 1L; - /** - * 测站编码 - */ - @JsonSerialize(using = ToStringSerializer.class, nullsUsing = NullSerializer.class) - private String stcd; - /** - * 测站ID - */ - @JsonSerialize(nullsUsing = NullSerializer.class) - private Long stId; - - /** - * 测站类型 - */ - @JsonSerialize(nullsUsing = NullSerializer.class) - private SttpTypeEnum sttp; - - /** - * 监测时间 - */ - @JsonSerialize(nullsUsing = NullSerializer.class) - private Date mot; - - /** - * 报警状态 - */ - @JsonSerialize(nullsUsing = NullSerializer.class) - private AlarmStatusEnum alarmStatus; - - /** - * 通讯状态 - */ - @JsonSerialize(nullsUsing = NullSerializer.class) - private StinfoStatusEnum commStatus; -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/constant/AlarmStatusEnum.java b/uno-data/src/test/java/cc/allio/uno/data/model/constant/AlarmStatusEnum.java deleted file mode 100644 index 77bb8a3e..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/model/constant/AlarmStatusEnum.java +++ /dev/null @@ -1,75 +0,0 @@ -package cc.allio.uno.data.model.constant; - -import com.baomidou.mybatisplus.annotation.EnumValue; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Objects; - - -/** - * 报警状态 - */ -@Getter -@AllArgsConstructor -public enum AlarmStatusEnum { - /** - * 正常:0,报警:1 - */ - NORMAL("NORMAL", "正常"), - /** - * 1 报警 - */ - ALARM("ALARM", "报警"); - - @JsonValue - @EnumValue - private String value; - - private String label; - - public static String getLabel(Integer value) { - for (AlarmStatusEnum workStatus : values()) { - if (workStatus.value.equals(value)) { - return workStatus.label; - } - } - return null; - } - - public static String getValue(String code) { - for (AlarmStatusEnum workStatus : values()) { - if (Objects.equals(workStatus.value, code)) { - return workStatus.value; - } - } - return null; - } - - public static AlarmStatusEnum getEnumByCode(String code) { - for (AlarmStatusEnum workStatus : values()) { - if (workStatus.label.equals(code)) - return workStatus; - } - return null; - } - - /** - * 解决前端传入为空 导致程序异常的问题 - * - * @param value - */ - @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - public static AlarmStatusEnum jsonCreator(String value) { - if (null != value) { - for (AlarmStatusEnum item : values()) { - if (item.value.equals(value)) { - return item; - } - } - } - return null; - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/constant/IoTOperate.java b/uno-data/src/test/java/cc/allio/uno/data/model/constant/IoTOperate.java deleted file mode 100644 index 58687838..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/model/constant/IoTOperate.java +++ /dev/null @@ -1,87 +0,0 @@ -package cc.allio.uno.data.model.constant; - -import com.baomidou.mybatisplus.annotation.EnumValue; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.util.ObjectUtils; - -import java.util.Arrays; - -/** - * 物联网推送数据操作 - * - * @author heitianzhen - * @date 2022/3/25 9:41 - */ -@Getter -@AllArgsConstructor -public enum IoTOperate { - /** - * 雨量水位一体化站 - */ - ONLINE("ONLINE", "设备上线"), - - /** - * 离线 - */ - OFFLINE("OFFLINE", "设备下线"), - - /** - * 上报 - */ - REPORT_PROPERTY("REPORT_PROPERTY", "属性上报"); - - - @EnumValue - @JsonValue - private String value; - - private String label; - - public String getValue() { - return value; - } - - public static String getLabel(String value) { - for (IoTOperate operationStatus : values()) { - if (operationStatus.getValue().equals(value)) { - return operationStatus.getLabel(); - } - } - return null; - } - - /** - * 解决前端传入为空 导致程序异常的问题 - * 反序列化时,调用 @JsonCreator 标注的构造器或者工厂方法来创建对象 - */ - @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - public static IoTOperate jsonCreator(@JsonProperty("value") String value) { - if (!ObjectUtils.isEmpty(value)) { - for (IoTOperate item : values()) { - if (item.value.equals(value)) { - return item; - } - } - } - return null; - } - - public static IoTOperate getIoTOperate(String operate) { - return Arrays.stream(values()) - .filter(ioTOperate -> ioTOperate.getValue().equals(operate)) - .findFirst() - .orElse(null); - } - - @Override - public String toString() { - return "OperationStatusEnum{" + - "value='" + value + '\'' + - ", label='" + label + '\'' + - '}'; - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/constant/StinfoStatusEnum.java b/uno-data/src/test/java/cc/allio/uno/data/model/constant/StinfoStatusEnum.java deleted file mode 100644 index d51ca1a0..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/model/constant/StinfoStatusEnum.java +++ /dev/null @@ -1,64 +0,0 @@ -package cc.allio.uno.data.model.constant; - -import com.baomidou.mybatisplus.annotation.EnumValue; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; -import lombok.AllArgsConstructor; -import lombok.Getter; - - -/** - * @author ljl - * @since 2021-08-13 - */ -@Getter -@AllArgsConstructor -public enum StinfoStatusEnum { - - ONLINE("ONLINE", "在线"), - OFFLINE("OFFLINE", "离线"); - - //离线:0,在线:1 - @EnumValue - @JsonValue - private String value; - - private String label; - - /** - * 解决前端传入为空 导致程序异常的问题 - * - * @param value - */ - @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - public static StinfoStatusEnum jsonCreator(@JsonProperty("value") String value) { - if (null != value) { - for (StinfoStatusEnum item : values()) { - if (item.value.equals(value)) { - return item; - } - } - } - return null; - } - - public static StinfoStatusEnum getEnumByCode(String label) { - for (StinfoStatusEnum item : values()) { - if (item.getLabel().equals(label)) { - return item; - } - } - return null; - } - - public static String getLabel(String value) - { - for (StinfoStatusEnum stinfoStatus : values()) - { - if (stinfoStatus.getValue().equals(value)) - return stinfoStatus.getLabel(); - } - return null; - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/constant/SttpTypeEnum.java b/uno-data/src/test/java/cc/allio/uno/data/model/constant/SttpTypeEnum.java deleted file mode 100644 index 687d3024..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/model/constant/SttpTypeEnum.java +++ /dev/null @@ -1,113 +0,0 @@ -package cc.allio.uno.data.model.constant; - -import com.baomidou.mybatisplus.annotation.EnumValue; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.util.ObjectUtils; - - -/** - * @author ljl - * @since 2021-08-13 - */ -@Getter -@AllArgsConstructor -public enum SttpTypeEnum { - /** - * 雨量水位一体化站 - */ - PZ("PZ", "雨量水位一体化站"), - - /** - * 流量站 - */ - SG("SG", "流量站"), - - /** - * 雨量站 - */ - PP("PP", "雨量站"), - - /** - * 水位站 - */ - ZZ("ZZ", "水位站"), - - /** - * 水质站 - */ - WQ("WQ", "水质站"), - - /** - * 墒情站 - */ - SS("SS", "墒情站"), - - /** - * 地下水位站 - */ - ZG("ZG", "地下水位站"), - - /** - * 村庄远传水表 - */ - VWM("VWM", "村庄远传水表"), - - /** - * 管网流量站 - */ - PSG("PSG", "管网流量站"), - - /** - * 流量计 - */ - ESG("ESG", "流量计"), - - /** - * 视频站 - */ - VIDEO("VIDEO", "视频站"); - - - @EnumValue - @JsonValue - private String value; - - private String label; - - public static String getLabel(String value) { - for (SttpTypeEnum sttpType : values()) { - if (sttpType.getValue().equals(value)) { - return sttpType.getLabel(); - } - } - return null; - } - - /** - * 解决前端传入为空 导致程序异常的问题 - * 反序列化时,调用 @JsonCreator 标注的构造器或者工厂方法来创建对象 - */ - @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - public static SttpTypeEnum jsonCreator(@JsonProperty("value") String value) { - if (!ObjectUtils.isEmpty(value)) { - for (SttpTypeEnum item : values()) { - if (item.value.equals(value)) { - return item; - } - } - } - return null; - } - - @Override - public String toString() { - return "SttpTypeEnum{" + - "value='" + value + '\'' + - ", label='" + label + '\'' + - '}'; - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/constant/WaterPotentialEnum.java b/uno-data/src/test/java/cc/allio/uno/data/model/constant/WaterPotentialEnum.java deleted file mode 100644 index 7eb3093e..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/model/constant/WaterPotentialEnum.java +++ /dev/null @@ -1,77 +0,0 @@ -package cc.allio.uno.data.model.constant; - -import com.baomidou.mybatisplus.annotation.EnumValue; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.util.ObjectUtils; - -/** - * 水位站-水势 - * - * @author jiangwei - * @date 2022/1/19 15:55 - * @since 1.0 - */ -@Getter -@AllArgsConstructor -public enum WaterPotentialEnum { - - /** - * 水势-涨 - */ - UP("UP", "涨"), - - /** - * 水势-落 - */ - DOWN("DOWN", "落"), - - /** - * 水势-平 - */ - KEEP("KEEP", "平"), - - /** - * 水势-未知 - */ - UNKNOWN("UNKNOWN", "未知"); - - @EnumValue - @JsonValue - private String value; - - private String label; - - public static String getLabel(String value) { - for (WaterPotentialEnum sourceEnum : values()) { - if (sourceEnum.getValue().equals(value)) { - return sourceEnum.getLabel(); - } - } - return null; - } - - public static String getValue(String code) { - for (WaterPotentialEnum sourceEnum : values()) { - if (sourceEnum.getLabel().equals(code)) { - return sourceEnum.getValue(); - } - } - return null; - } - - @JsonCreator(mode = JsonCreator.Mode.DELEGATING) - public static WaterPotentialEnum jsonCreator(@JsonProperty("value") String value) { - if (!ObjectUtils.isEmpty(value)) { - for (WaterPotentialEnum item : values()) { - if (item.value.equals(value)) { - return item; - } - } - } - return null; - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/ElasticSearchEnvTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/ElasticSearchEnvTest.java deleted file mode 100644 index 167499a6..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/ElasticSearchEnvTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package cc.allio.uno.data.orm; - -import cc.allio.uno.data.orm.config.ElasticSearchAutoConfiguration; -import cc.allio.uno.data.orm.executor.elasticsearch.EsSQLCommandExecutor; -import cc.allio.uno.test.BaseTestCase; -import cc.allio.uno.test.Inject; -import cc.allio.uno.test.RunTest; -import cc.allio.uno.test.env.annotation.EsEnv; -import cc.allio.uno.test.env.annotation.properties.EsProperties; -import org.junit.jupiter.api.Test; - -@RunTest(components = ElasticSearchAutoConfiguration.class) -@EsEnv -@EsProperties(uris = "http://43.143.195.208:9200") -public class ElasticSearchEnvTest extends BaseTestCase { - - @Inject - private EsSQLCommandExecutor sqlCommandExecutor; - - @Test - void testNotNull() { - assertNotNull(sqlCommandExecutor); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/ElasticSearchSQLCommandExecutorTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/ElasticSearchSQLCommandExecutorTest.java deleted file mode 100644 index 9be19fb7..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/ElasticSearchSQLCommandExecutorTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package cc.allio.uno.data.orm; - -import cc.allio.uno.data.orm.sql.dml.elasticsearch.ElasticSearchQueryOperator; -import cc.allio.uno.data.orm.executor.elasticsearch.EsSQLCommandExecutor; -import cc.allio.uno.data.orm.sql.SQLColumnDef; -import cc.allio.uno.test.BaseTestCase; -import org.apache.http.HttpHost; -import org.elasticsearch.client.RestClient; -import org.elasticsearch.client.RestClientBuilder; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.List; - -public class ElasticSearchSQLCommandExecutorTest extends BaseTestCase { - - ElasticSearchQueryOperator queryOperator = new ElasticSearchQueryOperator(); - EsSQLCommandExecutor sqlCommandExecutor; - - // =========================== DML =========================== - - @BeforeEach - @Override - public void setup() { - HttpHost httpHost = HttpHost.create("http://43.143.195.208:9200"); - RestClientBuilder builder = RestClient.builder(httpHost); - sqlCommandExecutor = new EsSQLCommandExecutor(new Object[]{builder}); - } - - @Test - void testInsertData() { - User user = new User(); - user.setId(1L); - user.setUserName("1"); - user.setPassword("2"); - boolean insert = sqlCommandExecutor.insertPojo(user); - assertTrue(insert); - } - - @Test - void testQueryOne() { - User user = sqlCommandExecutor.queryOneById(User.class, 1L); - assertNotNull(user); - } - - @Test - void testUpdateData() { - User user = new User(); - user.setUserName("aaa"); - user.setPassword("333"); - boolean update = sqlCommandExecutor.updatePojoById(user, 1L); - assertTrue(update); - - User user1 = sqlCommandExecutor.queryOneById(User.class, 1L); - System.out.println(user1); - - } - - @Test - void testEQQuery() { - List users = sqlCommandExecutor.queryList(o -> o.from(User.class).eq(User::getUserName, "aaa"), User.class); - System.out.println(users); - } - - // =========================== DDL =========================== - - @Test - void testCreateIndex() { - boolean isCreate = sqlCommandExecutor.createTable(User.class); - assertTrue(isCreate); - } - - @Test - void testDropIndex() { - boolean isDrop = sqlCommandExecutor.dropTable(User.class); - assertTrue(isDrop); - } - - @Test - void testExistIndex() { - boolean isExist = sqlCommandExecutor.existTable(User.class); - assertFalse(isExist); - } - - @Test - void testShowColumns() { - List sqlColumnDefs = sqlCommandExecutor.showColumns(User.class); - assertEquals(3, sqlColumnDefs.size()); - } - -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/H2DialectTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/H2DialectTest.java deleted file mode 100644 index 6afa825d..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/H2DialectTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package cc.allio.uno.data.orm; - -import cc.allio.uno.data.orm.dialect.Dialect; -import cc.allio.uno.data.orm.dialect.H2Dialect; -import cc.allio.uno.data.orm.dialect.func.FuncDescriptor; -import cc.allio.uno.data.orm.dialect.func.ReuseFuncFactory; -import cc.allio.uno.data.orm.sql.word.Distinct; -import cc.allio.uno.data.orm.type.JdbcType; -import cc.allio.uno.data.orm.sql.Alias; -import cc.allio.uno.data.orm.sql.PlainColumn; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -import java.sql.Types; - -class H2DialectTest extends BaseTestCase { - - Dialect dialect = new H2Dialect(); - - @Test - void testFindFunc() { - FuncDescriptor func = dialect.getFuncRegistry().findFunc("count"); - assertEquals("count", func.getFuncName()); - } - - @Test - void testCountFunc() { - FuncDescriptor func = ReuseFuncFactory.count(dialect); - String sql = func.render(new Object[]{new PlainColumn("user_name", null, null)}); - assertEquals("count(user_name)", sql); - String sql2 = func.render(new Object[]{new PlainColumn("user_name", null, null), new Alias("b")}); - assertEquals("count(user_name) b", sql2); - String sql3 = func.render(new Object[]{new Distinct(), new PlainColumn("user_name", null, null), new Alias("b")}); - assertEquals("count(distinct user_name) b", sql3); - } - - /** - * Test Case: 查找 integer type - */ - @Test - void testIntegerType() { - JdbcType integer = dialect.getTypeRegistry().findJdbcType(Types.INTEGER); - assertNotNull(integer); - } - - @Test - void testVarcharType() { - JdbcType varchar = dialect.getTypeRegistry().findJdbcType(Types.VARCHAR); - assertNotNull(varchar); - } - -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/MybatisSqlExecutorTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/MybatisSqlExecutorTest.java deleted file mode 100644 index 3b79ea5e..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/MybatisSqlExecutorTest.java +++ /dev/null @@ -1,134 +0,0 @@ -package cc.allio.uno.data.orm; - -import cc.allio.uno.data.orm.config.DataBaseAutoConfiguration; -import cc.allio.uno.data.orm.executor.mybatis.MybatisSQLCommandExecutor; -import cc.allio.uno.data.orm.sql.DruidOperatorMetadata; -import cc.allio.uno.data.orm.sql.SQLColumnDef; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLOperatorFactory; -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; -import cc.allio.uno.test.BaseTestCase; -import cc.allio.uno.test.Inject; -import cc.allio.uno.test.RunTest; -import cc.allio.uno.test.env.annotation.DataSourceEnv; -import cc.allio.uno.test.env.annotation.MybatisPlusEnv; -import com.google.common.collect.Lists; -import jakarta.persistence.Column; -import jakarta.persistence.Table; -import lombok.Data; -import org.apache.ibatis.session.*; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.sql.SQLException; -import java.util.List; - -@RunTest(components = DataBaseAutoConfiguration.class) -@MybatisPlusEnv -@DataSourceEnv -public class MybatisSqlExecutorTest extends BaseTestCase { - - @Inject - private SqlSessionFactory sqlSessionFactory; - - @Inject - private MybatisSQLCommandExecutor sqlExecutor; - - @Inject - private DruidOperatorMetadata druidOperatorMetadata; - - @Test - void testCreate() throws SQLException { - testData(sqlSessionFactory.getConfiguration()); - } - - @Test - void testCreateByLambda() { - sqlExecutor.createTable(f -> f.from("dual").column(SQLColumnDef.builder().sqlName(SQLName.of("t1")).build())); - } - - @Test - void testCreatePojo() { - sqlExecutor.createTable(Demo.class); - } - - @Test - void testDropTable() { - // 调用 - sqlExecutor.dropTable("dual"); - // lambda - sqlExecutor.dropTable(f -> f.from("dula")); - // pojo - sqlExecutor.dropTable(Demo.class); - } - - @Test - void testExistTable() { - // 调用 - sqlExecutor.existTable("dual"); - // lambda - sqlExecutor.existTable(f -> f.from("dual")); - // pojo - sqlExecutor.existTable(Demo.class); - } - - @Test - void testInsert() { - // 调用 - sqlExecutor.insert(f -> f.from("dual").insert("t1", "t1")); - // pojo - Demo demo = new Demo(); - sqlExecutor.insertPojo(demo); - // batch - sqlExecutor.batchInsertPojos(Lists.newArrayList(demo)); - } - - @Test - void testUpdate() { - // 调用 - sqlExecutor.update(f -> f.from("dual").update("t1", "t1")); - // pojo where - Demo demo = new Demo(); - sqlExecutor.updatePojoByCondition(demo, c -> c.eq("t1", "t1")); - } - - @Test - void testQuery() throws SQLException { - testData(sqlSessionFactory.getConfiguration()); - User user = sqlExecutor.queryOne(f -> f.select("name").from("t_user").eq(User::getName, "1"), User.class); - Assertions.assertEquals("1", user.name); - } - - @Test - void testShowColumns() { - testData(sqlSessionFactory.getConfiguration()); - List users = sqlExecutor.showColumns(SQLOperatorFactory.getSQLOperator(SQLShowColumnsOperator.class).from("t_user")); - assertEquals(1, users.size()); - } - - void testData(Configuration configuration) { - sqlExecutor.createTable( - SQLOperatorFactory.getSQLOperator(SQLCreateTableOperator.class) - .from("t_user") - .column(SQLColumnDef.builder().sqlName(SQLName.of("name")).build())); - sqlExecutor.insert(SQLOperatorFactory.getSQLOperator(SQLInsertOperator.class).from("t_user").insert("name", "1")); - } - - @Data - public static class User { - private String name; - } - - @Data - @Table(name = "dual") - public static class Demo { - - @Column(name = "id") - private String id; - - @Column(name = "name") - private String name; - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/OperatorMetadataTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/OperatorMetadataTest.java deleted file mode 100644 index 75a2110d..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/OperatorMetadataTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.allio.uno.data.orm; - -import cc.allio.uno.data.orm.sql.DruidOperatorMetadata; -import cc.allio.uno.data.orm.sql.ElasticSearchOperatorMetadata; -import cc.allio.uno.data.orm.sql.OperatorMetadata; -import cc.allio.uno.data.orm.sql.SQLOperatorFactory; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -public class OperatorMetadataTest extends BaseTestCase { - - @Test - void testTypeOfDataCorrectness() { - OperatorMetadata drOperator = SQLOperatorFactory.getOperatorMetadata(OperatorMetadata.DRUID_OPERATOR_KEY); - assertTrue(DruidOperatorMetadata.class.isAssignableFrom(drOperator.getClass())); - OperatorMetadata esOperator = SQLOperatorFactory.getOperatorMetadata(OperatorMetadata.ELASTIC_SEARCH_KEY); - assertTrue(ElasticSearchOperatorMetadata.class.isAssignableFrom(esOperator.getClass())); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/User.java b/uno-data/src/test/java/cc/allio/uno/data/orm/User.java deleted file mode 100644 index 5197120b..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/User.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.allio.uno.data.orm; - -import jakarta.persistence.Id; -import lombok.Data; - -@Data -public class User { - - @Id - private Long id; - private String userName; - private String password; -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLCreateOperatorTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLCreateOperatorTest.java deleted file mode 100644 index 14aa6d68..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/ddl/druid/DruidSQLCreateOperatorTest.java +++ /dev/null @@ -1,139 +0,0 @@ -package cc.allio.uno.data.orm.sql.ddl.druid; - -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.DataType; -import cc.allio.uno.data.orm.type.GenericSQLType; -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.SQLStatement; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLColumnDef; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -import java.util.List; - -public class DruidSQLCreateOperatorTest extends BaseTestCase { - - @Test - void testCreateTable() { - DruidSQLCreateOperator createOperator = new DruidSQLCreateOperator(DBType.POSTGRESQL); - String sql = createOperator.from("sxxx") - .column( - SQLColumnDef.builder() - .sqlName(SQLName.of("name")) - .dataType(DataType.createCharType(GenericSQLType.CHAR, 9)) - .isPk(true) - .isNonNull(true) - .isUnique(true) - .build()) - .getSQL(); - System.out.println(sql); - } - - @Test - void pgTable() { - String cr_pg = "CREATE TABLE \"am_device_instance\"\n" + - "(\n" + - " \"id\" int8 NOT NULL,\n" + - " \"code\" varchar(64),\n" + - " \"name\" varchar(64),\n" + - " \"type\" varchar(64),\n" + - " \"region_code\" varchar(64),\n" + - " \"manufacture_date\" date,\n" + - " \"manufacturer\" varchar(64),\n" + - " \"address\" varchar(255),\n" + - " \"facility_code\" varchar(64),\n" + - " \"installation_date\" date,\n" + - " \"geometry\" varchar(512),\n" + - " \"data_access_configuration\" varchar(900),\n" + - " \"create_user\" int8,\n" + - " \"create_time\" date,\n" + - " \"create_dept\" int8,\n" + - " \"update_user\" int8,\n" + - " \"update_time\" date,\n" + - " \"update_dept\" int8,\n" + - " \"status\" int4,\n" + - " \"is_deleted\" int4,\n" + - " \"tenant_id\" int8,\n" + - " \"images\" text,\n" + - " \"parent_code\" varchar(64),\n" + - " CONSTRAINT \"am_device_instance_pkey\" PRIMARY KEY (\"id\")\n" + - ")\n" + - ";\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"id\" IS '主键';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"code\" IS '设备编码';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"name\" IS '设备名称';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"type\" IS '设备类型';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"region_code\" IS '行政区划code';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"manufacture_date\" IS '生产日期';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"manufacturer\" IS '生产商';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"address\" IS '站址';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"facility_code\" IS '设施;设施id';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"installation_date\" IS '安装日期';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"geometry\" IS '空间信息';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"data_access_configuration\" IS '数据接入配置;{ \"source\": [ \"KAFKA\", \"HTTP\", \"RABIITMQ\" ], \"converters\": [ { \"source\": \"xxx\", \"targer\": \"xxx\", \"converterType\": \"xxx转换器\", \"defaultValue\": \"\" } ], \"clean\": [ { \"key\": \"监测指标\", \"value\": \"清洗值\", \"action\": \">/=/is null/not null\", \"logic\": \"and/or\" } ], \"trasform\": [ { \"index\": \"监测指标\", \"value\": \"变换后的目标值\" } ], \"storage\": { \"type\": \"database/key-value/document/search-engine/time-series/graph\", \"policy\": \"database/redis/mangodb/elasticsearch/influxdb/neo4j\", \"index\": \"表名或者索引名称\" }, \"push\": [ \"WEBSOCKET\", \"MQTT\" ] }';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"create_user\" IS '创建人';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"create_time\" IS '创建时间';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"create_dept\" IS '创建部门';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"update_user\" IS '更新人';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"update_time\" IS '更新时间';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"update_dept\" IS '更新部门';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"status\" IS '状态';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"is_deleted\" IS '逻辑删除';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"tenant_id\" IS '租户';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"images\" IS '图片信息';\n" + - "\n" + - "COMMENT\n" + - "ON COLUMN \"am_device_instance\".\"parent_code\" IS '父设备code';\n" + - "\n" + - "COMMENT\n" + - "ON TABLE \"am_device_instance\" IS '设备实例';\n"; - List sqlStatements = SQLUtils.parseStatements(cr_pg, DbType.postgresql); - - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/DruidInsertOperatorTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/DruidInsertOperatorTest.java deleted file mode 100644 index 2b132d92..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/DruidInsertOperatorTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.test.BaseTestCase; -import com.google.common.collect.Lists; -import jakarta.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Data; -import org.junit.jupiter.api.Test; - -public class DruidInsertOperatorTest extends BaseTestCase { - - @Test - void testInsert() { - DruidSQLInsertOperator insertOperator = new DruidSQLInsertOperator(DBType.H2); - String sql = insertOperator.from("test") - .insert("x", "2") - .getSQL(); - assertEquals("INSERT INTO test (x)\n" + - "VALUES ('2')", sql); - insertOperator.reset(); - sql = insertOperator. - from(User.class) - .batchInsertPojos(Lists.newArrayList(new User("21", 2), new User("xc", 2))) - .getSQL(); - assertEquals("INSERT INTO t_user (name, age)\n" + - "VALUES ('21', 2), ('xc', 2)", sql); - } - - @Test - void testParse() { - DruidSQLInsertOperator insertOperator = new DruidSQLInsertOperator(DBType.H2); - - insertOperator.parse("INSERT INTO t_user (name, age)\n" + - "VALUES ('21', 2), ('xc', 2)"); - String sql = insertOperator.getSQL(); - } - - @Data - @Table(name = "t_user") - @AllArgsConstructor - public static class User { - private String name; - private int age; - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLUpdateOperatorTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLUpdateOperatorTest.java deleted file mode 100644 index 9d8352e7..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSQLUpdateOperatorTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -public class DruidSQLUpdateOperatorTest extends BaseTestCase { - - DruidSQLUpdateOperator updateOperator = new DruidSQLUpdateOperator(DBType.H2); - - @Test - void testUpdateWherePrepareValue() { - updateOperator.eq("eq1", "eq1"); - updateOperator.update("t11", "t11"); - - // 交替 - updateOperator.eq("eq2", "eq2"); - updateOperator.update("t12", "t12"); - - // 循环10次 update - for (int i = 0; i < 10; i++) { - updateOperator.update("t12", "t12"); - } - - // 循环5次 eq - for (int i = 0; i < 5; i++) { - updateOperator.eq("eq2", "eq2"); - } - - // 循环10次 update - for (int i = 0; i < 10; i++) { - updateOperator.update("t12", "t12"); - } - - System.out.println(updateOperator.getPrepareValues()); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSelectTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSelectTest.java deleted file mode 100644 index c8742ee4..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/DruidSelectTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import com.alibaba.druid.DbType; -import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; -import com.alibaba.druid.sql.parser.SQLParserUtils; -import com.alibaba.druid.sql.parser.SQLStatementParser; -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -public class DruidSelectTest extends BaseTestCase { - - @Test - void testSelect() { - DruidSelect druidSelect = new DruidSelect(DBType.H2); - String sql = druidSelect.select("z").getSQL(); - assertEquals("z", sql); - } - - @Test - void testAggregate() { - DruidSelect druidSelect = new DruidSelect(DBType.H2); - String count = druidSelect.count().getSQL(); - assertEquals("count(*) AS count", count); - - String zCount = druidSelect.count("z", "zcount").getSQL(); - System.out.println(zCount); - - } - - @Test - void testSQLParser() { - SQLStatementParser sqlStatementParser = SQLParserUtils.createSQLStatementParser("", DbType.db2); - - SQLCreateTableStatement sqlCreateTableStatement = new SQLCreateTableStatement(); - sqlCreateTableStatement.setTableName("test"); - - String sqlString = SQLUtils.toSQLString(sqlCreateTableStatement); - - } - -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/QueryOperatorTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/QueryOperatorTest.java deleted file mode 100644 index 4092a8cc..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/druid/QueryOperatorTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.druid; - -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.sql.SQLBinaryCondition; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.TokenOperator; -import cc.allio.uno.data.orm.sql.dml.local.OrderCondition; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -public class QueryOperatorTest extends BaseTestCase { - - @Test - void testSelect() { - DruidSQLQueryOperator operator = new DruidSQLQueryOperator(DBType.H2); - String sql = operator.selectAll().getSQL(); - assertEquals("SELECT *", sql); - } - - @Test - void testFunc() { - DruidSQLQueryOperator operator = new DruidSQLQueryOperator(DBType.H2); - String sql = operator.select("z") - .min("z") - .getSQL(); - assertEquals("SELECT z, MIN(z)", sql); - } - - @Test - void testSimpleWhere() { - DruidSQLQueryOperator operator = new DruidSQLQueryOperator(DBType.H2); - String sql = operator.select("z").from("test").like("x", "zxc").getSQL(); - assertEquals("SELECT z\n" + - "FROM test\n" + - "WHERE x LIKE 'zxc'", sql); - } - - @Test - void testSubTable() { - DruidSQLQueryOperator operator = new DruidSQLQueryOperator(DBType.H2); - String sql = operator.leftJoin(Table.of("dual1"), Table.of("dual2"), SQLBinaryCondition.of("dual1.cc", "dual2.aa", TokenOperator.EQUALITY)) - .leftJoinThen("dual", "dual3", SQLBinaryCondition.of("dual.xx", "dual3.xx", TokenOperator.EQUALITY)) - .getSQL(); - assertEquals("SELECT \n" + - "FROM (dual1\n" + - "\tLEFT JOIN dual2 ON dual1.cc = dual2.aa) AS dual\n" + - "\tLEFT JOIN dual3 dual3 ON dual.xx = dual3.xx", sql); - } - - @Test - void testOrder() { - DruidSQLQueryOperator operator = new DruidSQLQueryOperator(DBType.H2); - String sql = operator.select("a") - .from("dual") - .orderBy("a", OrderCondition.DESC) - .getSQL(); - assertEquals("SELECT a\n" + - "FROM dual\n" + - "ORDER BY a DESC", sql); - } - - @Test - void testGroup() { - DruidSQLQueryOperator operator = new DruidSQLQueryOperator(DBType.H2); - String sql = operator.select("z") - .from("dual") - .groupByOne("z") - .getSQL(); - assertEquals("SELECT z\n" + - "FROM dual\n" + - "GROUP BY z", sql); - } - - @Test - void testLimit() { - DruidSQLQueryOperator operator = new DruidSQLQueryOperator(DBType.H2); - String sql = operator.select("z") - .from("dual") - .page(1L, 10L) - .getSQL(); - assertEquals("SELECT z\n" + - "FROM dual\n" + - "LIMIT 10, 0", sql); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/FromTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/FromTest.java deleted file mode 100644 index 434de84e..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/FromTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.dml.local.expression.TestExpressionContext; -import cc.allio.uno.data.orm.sql.FromStatement; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class FromTest extends BaseTestCase { - - @Test - void testFrom() { - FromStatement fromStatement = new FromStatement(TestExpressionContext.INSTANCE); - String sql = fromStatement.from("tableA").getSQL(); - assertEquals("FROM table_a", sql); - - String sql2 = fromStatement.from("tableB").getSQL(); - assertEquals("FROM table_b", sql2); - - - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/GroupTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/GroupTest.java deleted file mode 100644 index 3926eb75..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/GroupTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.dml.local.expression.TestExpressionContext; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -/** - * Group语句构建测试 - * - * @author jiangwei - * @date 2022/10/1 14:31 - * @since 1.1.0 - */ -class GroupTest extends BaseTestCase { - - @Test - void testByOne() { - GroupStatement group = new GroupStatement(TestExpressionContext.INSTANCE); - String sql = group.byOne("userName") - .byOnes("z") - .getSQL(); - assertEquals("GROUP BY user_name , z", sql); - } - -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/LimitTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/LimitTest.java deleted file mode 100644 index 12106e73..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/LimitTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.dml.Limit; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class LimitTest extends BaseTestCase { - - Limit limit = new LimitStatement(); - - @Test - void testPage() { - String sql = limit.page(1, 10).getSQL(); - assertEquals("LIMIT 0 OFFSET 10", sql); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/OrderTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/OrderTest.java deleted file mode 100644 index b6a68cf2..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/OrderTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.dml.local.expression.TestExpressionContext; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -/** - * Order语句测试 - * - * @author jiangwei - * @date 2022/10/1 14:40 - * @since 1.1.0 - */ -class OrderTest extends BaseTestCase { - - @Test - void byAscAndByDesc() { - OrderStatement orderStatement = new OrderStatement(TestExpressionContext.INSTANCE); - String sql = orderStatement.byAsc("userName") - .byDesc("iPhone") - .getSQL(); - assertEquals("ORDER user_name ASC , i_phone DESC", sql); - } - - @Test - void testBy() { - OrderStatement orderStatement = new OrderStatement(TestExpressionContext.INSTANCE); - String sql = orderStatement.by("userName").getSQL(); - assertEquals("ORDER user_name DESC", sql); - } - -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/SelectTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/SelectTest.java deleted file mode 100644 index dbbe3cc2..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/SelectTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.dml.local.expression.TestExpressionContext; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -/** - * Select语句测试 - * - * @author jiangwei - * @date 2022/10/1 14:21 - * @since 1.1.0 - */ -class SelectTest extends BaseTestCase { - - SelectStatement selectStatement = new SelectStatement(TestExpressionContext.INSTANCE); - - @Test - void testSelectFieldName() { - String sql = selectStatement.select("z") - .select("userName") - .getSQL(); - assertEquals("SELECT z , user_name", sql); - } - - @Test - void testSelectMultiFields() { - String sql = selectStatement.select(new String[]{"userName", "userAge"}).getSQL(); - assertEquals("SELECT user_name , user_age", sql); - } - - @Test - void testSelectAlias() { - String sql = selectStatement.select("userName", "a").getSQL(); - assertEquals("SELECT user_name AS a", sql); - } - - @Test - void testSelectAll() { - String sql = selectStatement.selectAll().getSQL(); - assertEquals("SELECT *", sql); - } - - @Test - void testSelectMin() { - String sql = selectStatement.min("userName").getSQL(); - assertEquals("SELECT MIN(user_name)", sql); - } - - @Test - void testSelectCount() { - String sql = selectStatement.count().getSQL(); - assertEquals("SELECT COUNT(*) count", sql); - } - -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/WhereTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/WhereTest.java deleted file mode 100644 index 0f140c52..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/WhereTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local; - -import cc.allio.uno.data.orm.sql.dml.local.expression.TestExpressionContext; -import cc.allio.uno.data.model.User; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -/** - * Where-SQL语句测试 - * - * @author jiangwei - * @date 2022/10/1 14:48 - * @since 1.1.0 - */ -class WhereTest extends BaseTestCase { - - WhereStatement where = new WhereStatement(TestExpressionContext.INSTANCE); - - @Test - void testEmpty() { - String sql = where.getSQL(); - assertEquals("", sql); - } - - @Test - void testGt() { - where.gt("userName", 1); - String sql = where.getSQL(); - assertEquals("WHERE user_name > {{user_name_gt_0}}", sql); - } - - @Test - void testGte() { - where.gte("userName", 1); - String sql = where.getSQL(); - assertEquals("WHERE user_name >= {{user_name_gte_0}}", sql); - } - - @Test - void testLt() { - where.lt("userName", 1); - String sql = where.getSQL(); - assertEquals("WHERE user_name < {{user_name_lt_0}}", sql); - } - - @Test - void testLte() { - where.lte("userName", 1); - String sql = where.getSQL(); - assertEquals("WHERE user_name <= {{user_name_lte_0}}", sql); - } - - @Test - void testEq() { - where.eq("userName", 1); - String sql = where.getSQL(); - assertEquals("WHERE user_name = {{user_name_eq_0}}", sql); - } - - @Test - void testEQAndLT() { - where.eq("userName", 1); - where.lt("userName", 1); - String sql = where.getSQL(); - assertEquals("WHERE user_name = {{user_name_eq_0}} AND user_name < {{user_name_lt_0}}", sql); - } - - @Test - void testEQOrLT() { - where.eq("userName", 1) - .or() - .lt("userName", 1); - String sql = where.getSQL(); - assertEquals("WHERE user_name = {{user_name_eq_0}} OR user_name < {{user_name_lt_0}}", sql); - } - - @Test - void testUserEQAndLEOrLike() { - String sql = where.lt(User::getName, "1") - .lt(User::getRoleId, "2") - .or() - .like$(User::getId, "3") - .getSQL(); - assertEquals("WHERE name < {{name_lt_0}} AND role_id < {{role_id_lt_0}} OR id LIKE '{{id_LIKE_0}}%'", sql); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/BetweenExpressionTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/BetweenExpressionTest.java deleted file mode 100644 index 08e75f62..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/BetweenExpressionTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.sql.dml.local.WhereColumn; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class BetweenExpressionTest extends BaseTestCase { - - @Test - void testSingleValue() { - WhereColumn whereColumn = new WhereColumn("userName", new Object[]{"1"}, null); - BetweenExpression expression = new BetweenExpression(whereColumn, TestExpressionContext.INSTANCE, BetweenExpression.Strategy.IN); - String sql = expression.getSQL(); - assertEquals("user_name BETWEEN %s AND %s", sql); - } - - @Test - void testBetween() { - WhereColumn whereColumn = new WhereColumn("userName", new Object[]{"1", 2}, null); - BetweenExpression expression = new BetweenExpression(whereColumn, TestExpressionContext.INSTANCE, BetweenExpression.Strategy.IN); - String sql = expression.getSQL(); - assertEquals("user_name BETWEEN {{user_name_bt0}} AND {{user_name_bt1}}", sql); - } - - @Test - void testNotBetween() { - WhereColumn whereColumn = new WhereColumn("userName", new Object[]{"1", 2}, null); - BetweenExpression expression = new BetweenExpression(whereColumn, TestExpressionContext.INSTANCE, BetweenExpression.Strategy.NOT); - String sql = expression.getSQL(); - assertEquals("user_name NOT BETWEEN {{user_name_bt0}} AND {{user_name_bt1}}", sql); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/EQExpressionTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/EQExpressionTest.java deleted file mode 100644 index 629fc619..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/EQExpressionTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.dml.local.WhereColumn; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -import java.util.Map; - -class EQExpressionTest extends BaseTestCase { - - @Test - void testEQ() { - RuntimeColumn runtimeColumn = new WhereColumn("userName", new Object[]{"test"}, null); - EQExpression expression = new EQExpression(runtimeColumn, TestExpressionContext.INSTANCE); - assertEquals("user_name = {{user_name_eq_0}}", expression.getSQL()); - } - - @Test - void testLiteral() { - RuntimeColumn runtimeColumn = new WhereColumn("userName", new Object[]{"test"}, null); - EQExpression expression = new EQExpression(runtimeColumn, TestExpressionContext.INSTANCE); - String literalSQL = expression.getLiteralSQL(); - System.out.println(literalSQL); - } - - @Test - void testExpValues() { - RuntimeColumn runtimeColumn = new WhereColumn("userName", new Object[]{"test"}, null); - EQExpression expression = new EQExpression(runtimeColumn, TestExpressionContext.INSTANCE); - Map expMapping = expression.getExpMapping(); - System.out.println(expMapping); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionGroupTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionGroupTest.java deleted file mode 100644 index cdeb8b2c..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/ExpressionGroupTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.PlainColumn; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -public class ExpressionGroupTest extends BaseTestCase { - - @Test - void testOfferToSQL() { - PlainColumn column1 = new PlainColumn("userName", null, null); - ExpressionGroup expressionGroup = new ExpressionGroup(); - expressionGroup.offer(new PlainExpression(column1, TestExpressionContext.INSTANCE), StringPool.COMMA); - assertEquals("user_name", expressionGroup.getSQL()); - - PlainColumn column2 = new PlainColumn("userAge", null, null); - expressionGroup.offer(new PlainExpression(column2, TestExpressionContext.INSTANCE), StringPool.COMMA); - assertEquals("user_name , user_age", expressionGroup.getSQL()); - - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/FromExpressionTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/FromExpressionTest.java deleted file mode 100644 index 3a430141..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/FromExpressionTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class FromExpressionTest extends BaseTestCase { - - @Test - void testFrom() { - FromExpression expression = new FromExpression(Table.of("dual"), TestExpressionContext.INSTANCE); - assertEquals("{{dual_FROM_0}}", expression.getSQL()); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/FunctionExpressionTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/FunctionExpressionTest.java deleted file mode 100644 index bbe7d95b..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/FunctionExpressionTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.dialect.func.Func; -import cc.allio.uno.data.orm.sql.Alias; -import cc.allio.uno.data.orm.sql.dml.local.SelectColumn; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class FunctionExpressionTest extends BaseTestCase { - SelectColumn column = new SelectColumn("user_name", null, null); - - @Test - void testMin() { - FunctionExpression expression = new FunctionExpression(TestExpressionContext.INSTANCE, Func.MIN_FUNCTION.getName(), new Object[]{column}); - assertEquals("min(user_name)", expression.getSQL()); - } - - @Test - void testMax() { - FunctionExpression expression = new FunctionExpression(TestExpressionContext.INSTANCE, Func.MAX_FUNCTION.getName(), new Object[]{column}); - assertEquals("max(user_name)", expression.getSQL()); - } - - @Test - void testCount() { - FunctionExpression expression = new FunctionExpression(TestExpressionContext.INSTANCE, Func.COUNT_FUNCTION.getName(), new Object[]{column}); - assertEquals("count(user_name)", expression.getSQL()); - } - - @Test - void testCountAlias() { - FunctionExpression expression = new FunctionExpression(TestExpressionContext.INSTANCE, Func.COUNT_FUNCTION.getName(), new Object[]{column, new Alias("count")}); - assertEquals("count(user_name) count", expression.getSQL()); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/INExpressionTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/INExpressionTest.java deleted file mode 100644 index 87af43b2..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/INExpressionTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.dml.local.WhereColumn; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class INExpressionTest extends BaseTestCase { - - @Test - void testIN() { - RuntimeColumn runtimeColumn = new WhereColumn("userName", new Object[]{"121", 21, "32"}, null); - INExpression expression = new INExpression(runtimeColumn, TestExpressionContext.INSTANCE); - assertEquals("user_name IN ({{user_name_IN_0}},{{user_name_IN_1}},{{user_name_IN_2}})", expression.getSQL()); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/LTExpressionTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/LTExpressionTest.java deleted file mode 100644 index f97bc9c0..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/LTExpressionTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.dml.local.WhereColumn; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class LTExpressionTest extends BaseTestCase { - - @Test - void testLT() { - RuntimeColumn runtimeColumn = new WhereColumn("userName", new Object[]{"test"}, null); - LTExpression expression = new LTExpression(runtimeColumn, TestExpressionContext.INSTANCE); - assertEquals("user_name < {{user_name_lt_0}}", expression.getSQL()); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/LikeExpressionTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/LikeExpressionTest.java deleted file mode 100644 index d87454b4..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/LikeExpressionTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.sql.RuntimeColumn; -import cc.allio.uno.data.orm.sql.dml.local.WhereColumn; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class LikeExpressionTest extends BaseTestCase { - - @Test - void test$Like() { - RuntimeColumn runtimeColumn = new WhereColumn("userName", new Object[]{"test"}, null); - LikeExpression expression = new LikeExpression(runtimeColumn, TestExpressionContext.INSTANCE, LikeExpression.Strategy.LEFT); - assertEquals("user_name LIKE '%{{user_name_LIKE_0}}'", expression.getSQL()); - } - - @Test - void testLike$() { - RuntimeColumn runtimeColumn = new WhereColumn("userName", new Object[]{"test"}, null); - LikeExpression expression = new LikeExpression(runtimeColumn, TestExpressionContext.INSTANCE, LikeExpression.Strategy.RIGHT); - assertEquals("user_name LIKE '{{user_name_LIKE_0}}%'", expression.getSQL()); - } - - @Test - void test$Like$() { - RuntimeColumn runtimeColumn = new WhereColumn("userName", new Object[]{"test"}, null); - LikeExpression expression = new LikeExpression(runtimeColumn, TestExpressionContext.INSTANCE, LikeExpression.Strategy.ALL); - assertEquals("user_name LIKE '%{{user_name_LIKE_0}}%'", expression.getSQL()); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/PlainExpressionTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/PlainExpressionTest.java deleted file mode 100644 index 9639b074..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/PlainExpressionTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.sql.PlainColumn; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class PlainExpressionTest extends BaseTestCase { - - @Test - void testAlias() { - PlainColumn column = new PlainColumn("test", null, null); - PlainExpression expression = new PlainExpression(column, TestExpressionContext.INSTANCE); - expression.alias("name"); - assertEquals("test AS name", expression.getSQL()); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/TestExpressionContext.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/TestExpressionContext.java deleted file mode 100644 index 34bda0f7..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/expression/TestExpressionContext.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.expression; - -import cc.allio.uno.data.orm.dialect.Dialect; -import cc.allio.uno.data.orm.dialect.H2Dialect; - -public class TestExpressionContext extends DefaultExpressionContext { - public static final DefaultExpressionContext INSTANCE = new TestExpressionContext(new H2Dialect()); - - public TestExpressionContext(Dialect dialect) { - super(dialect); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/query/QueryOperatorTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/query/QueryOperatorTest.java deleted file mode 100644 index 3ab5eae7..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/local/query/QueryOperatorTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package cc.allio.uno.data.orm.sql.dml.local.query; - -import cc.allio.uno.data.orm.sql.dml.local.QueryOperator; -import cc.allio.uno.test.BaseTestCase; -import org.junit.jupiter.api.Test; - -class QueryOperatorTest extends BaseTestCase { - - QueryOperator queryOperator = new QueryOperator(); - - @Test - void testSelectFrom() { - String sql = queryOperator.thenSelect().select("z").thenFrom().from("dual").getSQL(); - assertEquals("SELECT z FROM dual", sql); - } - - @Test - void testSelectDistinct() { - String sql = queryOperator.thenSelect().distinct().select("name").thenFrom().from("dual").getSQL(); - assertEquals("SELECT DISTINCT name FROM dual", sql); - } - - @Test - void testSelectWhere() { - String sql = queryOperator - .thenFrom().from("tableA") - .getSQL(); - assertEquals("SELECT * FROM table_a WHERE a = '1' AND b = '2'", sql); - } - - @Test - void testSelectFromWhereOrder() { - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/type/TypeRegistryTest.java b/uno-data/src/test/java/cc/allio/uno/data/orm/type/TypeRegistryTest.java deleted file mode 100644 index 5584ecd4..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/type/TypeRegistryTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package cc.allio.uno.data.orm.type; - -import cc.allio.uno.test.BaseTestCase; -import com.google.common.collect.Lists; -import org.junit.jupiter.api.Test; - -import java.util.Collection; - -public class TypeRegistryTest extends BaseTestCase { - - @Test - void testGuessType() { - Collection jdbcTypes = TypeRegistry.getInstance().guessJdbcType(TestEnum.class); - assertNotNull(jdbcTypes); - JdbcType jdbcType = Lists.newArrayList(jdbcTypes).get(0); - - } - - public enum TestEnum { - - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/reactive/R2dbcConfiguration.java b/uno-data/src/test/java/cc/allio/uno/data/reactive/R2dbcConfiguration.java deleted file mode 100644 index f963f60d..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/reactive/R2dbcConfiguration.java +++ /dev/null @@ -1,11 +0,0 @@ -package cc.allio.uno.data.reactive; - -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; - -@Configuration -@EntityScan("cc.allio.uno") -@EnableR2dbcRepositories("cc.allio.uno.data.reactive") -public class R2dbcConfiguration { -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/reactive/RoleConverter.java b/uno-data/src/test/java/cc/allio/uno/data/reactive/RoleConverter.java deleted file mode 100644 index 0d059252..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/reactive/RoleConverter.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.allio.uno.data.reactive; - -import cc.allio.uno.data.model.Role; -import io.r2dbc.spi.Row; -import org.springframework.core.convert.converter.Converter; -import org.springframework.data.convert.ReadingConverter; - -@ReadingConverter -public class RoleConverter implements Converter { - @Override - public Role convert(Row row) { - return new Role(); - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/CarReactiveRepository.java b/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/CarReactiveRepository.java deleted file mode 100644 index 693cf812..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/CarReactiveRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package cc.allio.uno.data.reactive.repository; - -import cc.allio.uno.data.model.Car; -import org.springframework.data.r2dbc.repository.R2dbcRepository; - -public interface CarReactiveRepository extends R2dbcRepository { -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/CarReactiveRepositoryTest.java b/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/CarReactiveRepositoryTest.java deleted file mode 100644 index b04ce5a7..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/CarReactiveRepositoryTest.java +++ /dev/null @@ -1,11 +0,0 @@ -package cc.allio.uno.data.reactive.repository; - -import cc.allio.uno.data.reactive.R2dbcConfiguration; -import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest; -import org.springframework.test.context.ContextConfiguration; - -@DataR2dbcTest -@ContextConfiguration(classes = R2dbcConfiguration.class) -public class CarReactiveRepositoryTest { - -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/RoleReactiveRepository.java b/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/RoleReactiveRepository.java deleted file mode 100644 index d21b7d70..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/RoleReactiveRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package cc.allio.uno.data.reactive.repository; - -import cc.allio.uno.data.model.Role; -import org.springframework.data.r2dbc.repository.R2dbcRepository; -import reactor.core.publisher.Flux; - -public interface RoleReactiveRepository extends R2dbcRepository { - - Flux findByNameContains(String name); -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/RoleRepositoryTest.java b/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/RoleRepositoryTest.java deleted file mode 100644 index 03cc518c..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/RoleRepositoryTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.allio.uno.data.reactive.repository; - -import cc.allio.uno.data.model.Role; -import cc.allio.uno.data.reactive.R2dbcConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest; -import org.springframework.test.context.ContextConfiguration; -import reactor.test.StepVerifier; - -@DataR2dbcTest -@ContextConfiguration(classes = R2dbcConfiguration.class) -public class RoleRepositoryTest { - - @Autowired - private RoleReactiveRepository roleReactiveRepository; - - @Test - void testSaveOne() { - Role role = new Role(); - role.setId(1L); - role.setName("role"); - - roleReactiveRepository.save(role) - .thenMany(roleReactiveRepository.findByNameContains("role")) - .count() - .as(StepVerifier::create) - .expectNext(1L) - .verifyComplete(); - - roleReactiveRepository.delete(role) - .as(StepVerifier::create) - .verifyComplete(); - - } -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/UserReactiveRepository.java b/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/UserReactiveRepository.java deleted file mode 100644 index bc4fc6ff..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/UserReactiveRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.allio.uno.data.reactive.repository; - -import cc.allio.uno.data.model.User; -import org.springframework.data.r2dbc.repository.R2dbcRepository; -import org.springframework.stereotype.Repository; -import reactor.core.publisher.Flux; - -@Repository -public interface UserReactiveRepository extends R2dbcRepository { - - - Flux findByNameContains(String name); -} diff --git a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/UserReactiveRepositoryTest.java b/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/UserReactiveRepositoryTest.java deleted file mode 100644 index 72cfcf69..00000000 --- a/uno-data/src/test/java/cc/allio/uno/data/reactive/repository/UserReactiveRepositoryTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package cc.allio.uno.data.reactive.repository; - -import cc.allio.uno.data.model.Role; -import cc.allio.uno.data.model.User; -import cc.allio.uno.data.reactive.R2dbcConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest; -import org.springframework.test.context.ContextConfiguration; -import reactor.test.StepVerifier; - -@DataR2dbcTest -@ContextConfiguration(classes = R2dbcConfiguration.class) -class UserReactiveRepositoryTest { - - @Autowired - private UserReactiveRepository userRepository; - @Autowired - private RoleReactiveRepository roleRepository; - - - @Test - void testSaveOne() { - User user = new User(); - user.setId(1L); - user.setName("name"); - userRepository.save(user) - .thenMany(userRepository.findByNameContains("name")) - .count() - .as(StepVerifier::create) - .expectNext(1L) - .verifyComplete(); - - userRepository.delete(user) - .as(StepVerifier::create) - .verifyComplete(); - } - - @Test - void testCascadeRole() { - User user = new User(); - user.setId(1L); - user.setName("name"); - Role role = new Role(); - role.setId(1L); - role.setName("role"); - user.setRoleId(role.getId()); - roleRepository.save(role) - .then(userRepository.save(user)) - .thenMany(userRepository.findByNameContains("name")) - .flatMap(thenUser -> roleRepository.findById(user.getRoleId())) - .count() - .as(StepVerifier::create) - .verifyComplete(); - } -} diff --git a/uno-data/src/test/resources/application-r2db.yaml b/uno-data/src/test/resources/application-r2db.yaml deleted file mode 100644 index 145faaa0..00000000 --- a/uno-data/src/test/resources/application-r2db.yaml +++ /dev/null @@ -1,10 +0,0 @@ -spring: - r2dbc: - # mysql - url: r2dbc:mysql://192.168.2.29:3306/jpa - username: root - password: 123456 - # pg -# url: r2dbc:postgresql://localhost:5432/jpa -# username: postgres -# password: 123456 diff --git a/uno-data/src/test/resources/application.yaml b/uno-data/src/test/resources/application.yaml deleted file mode 100644 index 4416cc82..00000000 --- a/uno-data/src/test/resources/application.yaml +++ /dev/null @@ -1,14 +0,0 @@ -spring: - jpa: - hibernate: - ddl-auto: create # 自动执行创表语句 - database: mysql - properties: - hibernate: - show_sql: true - use_sql_comments: true - profiles: - include: db - -mybatis: - tab \ No newline at end of file diff --git a/uno-data/uno-data-api/pom.xml b/uno-data/uno-data-api/pom.xml new file mode 100644 index 00000000..4dd8162c --- /dev/null +++ b/uno-data/uno-data-api/pom.xml @@ -0,0 +1,29 @@ + + + + cc.allio + uno-data + 1.1.6-beta.1 + ../pom.xml + + jar + 4.0.0 + uno-data-api + + + + jakarta.persistence + jakarta.persistence-api + + + jakarta.validation + jakarta.validation-api + + + org.springframework.data + spring-data-commons + + + \ No newline at end of file diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/annotation/LogicDelete.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/annotation/LogicDelete.java new file mode 100644 index 00000000..dcb11e01 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/annotation/LogicDelete.java @@ -0,0 +1,43 @@ +package cc.allio.uno.data.orm.annotation; + +import java.lang.annotation.*; + +/** + * 逻辑删除 + *
    + *     Example:
    + *
    + *     @Entity
    + *     @Table(name="CUST")
    + *     public class Customer {
    + *
    + *         @LogicDelete
    + *         private Integer isDeleted
    + *      }
    + *
    + * 
    + * + * @author jiangwei + * @date 2024/2/19 16:16 + * @since 1.1.6 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface LogicDelete { + + /** + * 字段标识 + */ + String column() default "is_deleted"; + + /** + * 未删除值 + */ + int undeleted() default 0; + + /** + * 已删除的值 + */ + int deleted() default 1; +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLBinaryCondition.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/BinaryCondition.java similarity index 82% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLBinaryCondition.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/BinaryCondition.java index 2aaeac26..7183dc7e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLBinaryCondition.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/BinaryCondition.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; import lombok.AllArgsConstructor; import lombok.Data; @@ -12,7 +12,7 @@ */ @Data @AllArgsConstructor(staticName = "of") -public class SQLBinaryCondition { +public class BinaryCondition { // left private String left; // right diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ColumnDef.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ColumnDef.java new file mode 100644 index 00000000..867c307e --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ColumnDef.java @@ -0,0 +1,76 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.api.EqualsTo; +import cc.allio.uno.core.type.TypeOperatorFactory; +import cc.allio.uno.data.orm.dsl.type.DataType; +import cc.allio.uno.data.orm.dsl.type.JavaType; +import cc.allio.uno.data.orm.dsl.type.TypeRegistry; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Objects; +import java.util.Optional; + +/** + * SQL字段定义 + * + * @author jiangwei + * @date 2023/4/12 19:35 + * @since 1.1.4 + */ +@Data +@Builder +@EqualsAndHashCode(of = {"dslName", "dataType"}) +public class ColumnDef implements EqualsTo { + + // 字段名称 + private DSLName dslName; + // 字段注释 + private String comment; + // 数据类型 + private DataType dataType; + // 默认值 + private Object defaultValue; + // 是否为主键 + private boolean isPk; + // 是否为外键 + private boolean isFk; + // 是否不为null + private boolean isNonNull; + // 是否为null + private boolean isNull; + // 是否唯一 + private boolean isUnique; + // 是否是删除标识字段 + private boolean isDeleted; + // 未删除值 + private Object undeleted; + // 已删除值 + private Object deleted; + + @Override + public boolean equalsTo(ColumnDef other) { + return Objects.equals(this.getDslName(), other.getDslName()) + && dataType.equalsTo(other.getDataType()); + } + + /** + * 给定字段值按照当前{@link DataType}进行转换 + * + * @param ori ori + * @return 转换后的值 + */ + public Object castValue(Object ori) { + return Optional.ofNullable(dataType) + .map(DataType::getDslType) + .flatMap(dslType -> { + int jdbcType = dslType.getJdbcType(); + JavaType javaType = TypeRegistry.getInstance().findJavaType(jdbcType); + return Optional.ofNullable(javaType); + }) + .map(j -> TypeOperatorFactory.translator(j.getJavaType())) + .map(typeOperator -> typeOperator.convert(ori)) + .orElse(null); + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Condition.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Condition.java similarity index 59% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/Condition.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Condition.java index 00cdf793..d5b993e1 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Condition.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Condition.java @@ -1,17 +1,12 @@ -package cc.allio.uno.data.orm.sql; - -import cc.allio.uno.data.orm.sql.dml.local.OrderCondition; +package cc.allio.uno.data.orm.dsl; /** * SQL条件,如'OR'、'WHERE'... * * @author jiangwei * @date 2023/1/5 10:47 - * @see OrderCondition * @since 1.1.4 - * @deprecated 1.1.4版本删除 */ -@Deprecated public interface Condition { /** diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/DSLName.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/DSLName.java new file mode 100644 index 00000000..418d8ce9 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/DSLName.java @@ -0,0 +1,255 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.env.Envs; +import cc.allio.uno.core.util.StringUtils; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.util.regex.Pattern; + +/** + * dsl name 如 xxxx name、column name...根据指定格式化转换对应的name + * + * @author jiangwei + * @date 2023/4/17 16:16 + * @since 1.1.4 + */ +@Getter +@EqualsAndHashCode(of = "name") +public class DSLName implements Comparable { + + // 当前存入的dsl name + private String name; + + private NameFeature feature; + + private static final String HUMP_REGULAR = "^[a-z]+(?:[A-Z][a-z]*)*$"; + private static final Pattern HUMP_PATTERN = Pattern.compile(HUMP_REGULAR); + + private static final String UNDERLINE_REGULAR = "^[a-zA-Z]+(?:_[a-zA-Z]+)*$"; + private static final Pattern UNDERLINE_PATTERN = Pattern.compile(UNDERLINE_REGULAR); + + /** + * 名称格式化key + */ + private static final String NAME_FORMAT_KEY = "allio.uno.data.orm.sql.name.format"; + // 名称以下划线 + private static final String NAME_FORMAT_UNDERLINE = "underline"; + // 名称以驼峰 + private static final String NAME_FORM_HUMP = "hump"; + // 名称以原样 + private static final String NAME_FORM_PLAIN = "plain"; + // 名称以小写 + private static final String NAME_FORM_LOWER_CASE = "lower-case"; + // 名称以大写 + private static final String NAME_FORM_UPPER_CASE = "upper-case"; + + public static final NameFeature UNDERLINE_FEATURE = new UnderlineFeature(); + public static final NameFeature HUMP_FEATURE = new HumpFeature(); + public static final NameFeature PLAIN_FEATURE = new PlainFeature(); + public static final NameFeature LOWER_CASE_FEATURE = new LowerCaseFeature(); + public static final NameFeature UPPER_CASE_FEATURE = new UpperCaseFeature(); + + /** + * 获取name feature + * + * @return NameFeature or default {@link #PLAIN_FEATURE} + */ + public static NameFeature getNameFeature() { + String nameFormatKey = Envs.getProperty(NAME_FORMAT_KEY); + if (NAME_FORMAT_UNDERLINE.equals(nameFormatKey)) { + return UNDERLINE_FEATURE; + } else if (NAME_FORM_HUMP.equals(nameFormatKey)) { + return HUMP_FEATURE; + } else if (NAME_FORM_PLAIN.equals(nameFormatKey)) { + return PLAIN_FEATURE; + } else if (NAME_FORM_LOWER_CASE.equals(nameFormatKey)) { + return LOWER_CASE_FEATURE; + } else if (NAME_FORM_UPPER_CASE.equals(nameFormatKey)) { + return UPPER_CASE_FEATURE; + } + return UNDERLINE_FEATURE; + } + + /** + * 创建SQLName实例 + * + * @param name name + * @return SQLName + */ + public static DSLName of(String name) { + return of(name, getNameFeature()); + } + + /** + * 创建SQLName 实例 + * + * @param name name + * @param feature feature + * @return SQLName + */ + public static DSLName of(String name, NameFeature feature) { + DSLName sqlName = new DSLName(); + sqlName.name = name; + sqlName.feature = feature; + return sqlName; + } + + /** + * 创建SQLName 实例 + * + * @param sqlName sqlName + * @param feature feature + * @return SQLName + */ + public static DSLName of(DSLName sqlName, NameFeature... feature) { + DSLName newName = new DSLName(); + newName.name = sqlName.name; + newName.setFeature(feature); + return newName; + } + + /** + * 下划线转驼峰 + * + * @param underline underline + * @return hump string + */ + public static String toHump(String underline) { + return DSLName.of(underline, HUMP_FEATURE).format(); + } + + /** + * 驼峰转下划线 + * + * @param hump hump + * @return underline string + */ + public static String toUnderline(String hump) { + return DSLName.of(hump, UNDERLINE_FEATURE).format(); + } + + private void setFeature(NameFeature... features) { + this.feature = new AggregateNameFeature(features); + } + + /** + * 把当前存入的sql name进行格式化 + * + * @return 格式化后的name + */ + public String format() { + return getFeature().format(getName()); + } + + /** + * 根据指定的名称特性 + * + * @param feature the feature + * @return format the name + */ + public String format(NameFeature feature) { + if (feature == null) { + throw new IllegalArgumentException("NameFeature is null"); + } + return feature.format(getName()); + } + + @Override + public int compareTo(DSLName o) { + return this.name.compareTo(o.name); + } + + /** + * 名称特性 + */ + public interface NameFeature { + + /** + * 格式化 + * + * @param o 原始数据 + * @return 格式化后的名称 + */ + String format(String o); + + /** + * 集合于{@link NameFeature} + * + * @param nameFeatures nameFeatures + * @return NameFeature + */ + static NameFeature aggregate(NameFeature... nameFeatures) { + return new AggregateNameFeature(nameFeatures); + } + } + + static class AggregateNameFeature implements NameFeature { + + private final NameFeature[] features; + + AggregateNameFeature(NameFeature... features) { + this.features = features; + } + + @Override + public String format(String o) { + for (NameFeature feature : features) { + o = feature.format(o); + } + return o; + } + } + + static class UnderlineFeature implements NameFeature { + + @Override + public String format(String ori) { + if (UNDERLINE_PATTERN.matcher(ori).matches()) { + return ori; + } + if (HUMP_PATTERN.matcher(ori).matches()) { + return StringUtils.camelToUnderline(ori); + } + return ori; + } + } + + static class HumpFeature implements NameFeature { + + @Override + public String format(String ori) { + if (HUMP_PATTERN.matcher(ori).matches()) { + return ori; + } + if (UNDERLINE_PATTERN.matcher(ori).matches()) { + return StringUtils.underlineToCamel(ori); + } + return ori; + } + } + + static class LowerCaseFeature implements NameFeature { + + @Override + public String format(String o) { + return o.toLowerCase(); + } + } + + static class PlainFeature implements NameFeature { + + @Override + public String format(String o) { + return o; + } + } + + static class UpperCaseFeature implements NameFeature { + + @Override + public String format(String o) { + return o.toUpperCase(); + } + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/DataBaseOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/DataBaseOperator.java new file mode 100644 index 00000000..fca84892 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/DataBaseOperator.java @@ -0,0 +1,35 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.api.Self; + +/** + * database relevant operator + * + * @author jiangwei + * @date 2024/2/15 11:43 + * @since 1.1.6 + */ +public interface DataBaseOperator> extends Self { + + /** + * @see #database(DSLName) + */ + default T database(String database) { + return database(DSLName.of(database)); + } + + /** + * @see #database(Database) + */ + default T database(DSLName database) { + return database(Database.of(database)); + } + + /** + * set database + * + * @param database database + * @return Self + */ + T database(Database database); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Database.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Database.java new file mode 100644 index 00000000..da26575c --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Database.java @@ -0,0 +1,22 @@ +package cc.allio.uno.data.orm.dsl; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * 数据库信息 + * + * @author jiangwei + * @date 2024/1/4 18:32 + * @since 1.1.6 + */ +@Data +@AllArgsConstructor(staticName = "of") +public class Database { + + /** + * 数据库名 + */ + private DSLName name; + +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/Func.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Func.java similarity index 94% rename from uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/Func.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Func.java index 38653a51..e836fd3e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/dialect/func/Func.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Func.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.dialect.func; +package cc.allio.uno.data.orm.dsl; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/JDBCTypes.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JDBCTypes.java similarity index 93% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/JDBCTypes.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JDBCTypes.java index 8992562f..982feaab 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/JDBCTypes.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JDBCTypes.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; import cc.allio.uno.core.StringPool; import cc.allio.uno.core.type.Types; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/JoinTable.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JoinTable.java similarity index 90% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/JoinTable.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JoinTable.java index 2bfef1d3..192a982a 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/JoinTable.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JoinTable.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/JoinType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JoinType.java similarity index 80% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/JoinType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JoinType.java index ef5b1dd8..55e87354 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/JoinType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JoinType.java @@ -1,6 +1,4 @@ -package cc.allio.uno.data.orm.sql; - -import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; +package cc.allio.uno.data.orm.dsl; /** * SQL join @@ -36,8 +34,4 @@ public enum JoinType { this.name = name; this.nameLCase = name.toLowerCase(); } - - public static String toString(SQLJoinTableSource.JoinType joinType) { - return joinType.name; - } } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JoinTypeAdapter.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JoinTypeAdapter.java new file mode 100644 index 00000000..e16bb35c --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/JoinTypeAdapter.java @@ -0,0 +1,13 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.api.Adapter; + +/** + * join type adapter + * + * @author jiangwei + * @date 2023/4/13 13:23 + * @since 1.1.4 + */ +public interface JoinTypeAdapter extends Adapter { +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Operator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Operator.java new file mode 100644 index 00000000..8ec9294b --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Operator.java @@ -0,0 +1,69 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.bean.ValueWrapper; +import cc.allio.uno.data.orm.dsl.type.DBType; + +import java.lang.annotation.*; +import java.util.Objects; + +/** + * DSL操作 + * + * @author jiangwei + * @date 2023/4/12 19:44 + * @since 1.1.4 + */ +public interface Operator> { + + /** + * 获取DSL字符串 + * + * @return DSL字符串 + */ + String getDSL(); + + /** + * 解析DSL + * + * @param dsl dsl + * @return SQLOperator + */ + T parse(String dsl); + + /** + * reset operator + */ + void reset(); + + /** + * set db type + * + * @param dbType dbType + */ + void setDBType(DBType dbType); + + /** + * 获取DBType + */ + DBType getDBType(); + + /** + * 如果给定原始为null,则返回{@link ValueWrapper#EMPTY_VALUE} + * + * @param originalValue originalValue + * @return + */ + default Object getValueIfNullThenNullValue(Object originalValue) { + return Objects.requireNonNullElse(originalValue, ValueWrapper.EMPTY_VALUE); + } + + /** + * Operator 分组注解 + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE) + @interface Group { + String value(); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/OperatorGroup.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/OperatorGroup.java new file mode 100644 index 00000000..15365dd6 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/OperatorGroup.java @@ -0,0 +1,340 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.data.orm.dsl.ddl.*; +import cc.allio.uno.data.orm.dsl.dml.DeleteOperator; +import cc.allio.uno.data.orm.dsl.dml.InsertOperator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.dml.UpdateOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * 操作管理接口 + * + * @author jiangwei + * @date 2023/4/13 18:52 + * @see Operator + * @since 1.1.4 + */ +public interface OperatorGroup { + + // ======================== DML ======================== + + /** + * 获取查询操作 + * + * @return QueryOperator + */ + default QueryOperator query() { + return query(DBType.getSystemDbType()); + } + + /** + * 获取查询操作 + * + * @param dbType dbType + * @return QueryOperator + */ + QueryOperator query(DBType dbType); + + /** + * 获取insert操作 + * + * @return InsertOperator + */ + default InsertOperator insert() { + return insert(DBType.getSystemDbType()); + } + + /** + * 获取insert操作 + * + * @param dbType dbType + * @return InsertOperator + */ + InsertOperator insert(DBType dbType); + + /** + * 获取update操作 + * + * @return SQLUpdateOperator + */ + default UpdateOperator update() { + return update(DBType.getSystemDbType()); + } + + /** + * 获取update操作 + * + * @param dbType dbType + * @return SQLUpdateOperator + */ + UpdateOperator update(DBType dbType); + + + /** + * 获取delete操作 + * + * @return SQLDeleteOperator + */ + default DeleteOperator delete() { + return delete(DBType.getSystemDbType()); + } + + /** + * 获取delete操作 + * + * @return SQLDeleteOperator + */ + DeleteOperator delete(DBType dbType); + + // ======================== DDL ======================== + + /** + * registry table操作 + * + * @return CreateTableOperator + */ + default CreateTableOperator createTable() { + return createTable(DBType.getSystemDbType()); + } + + /** + * registry table操作 + * + * @param dbType dbType + * @return CreateTableOperator + */ + CreateTableOperator createTable(DBType dbType); + + /** + * drop xxxx + * + * @return DropTableOperator + */ + default DropTableOperator dropTable() { + return dropTable(DBType.getSystemDbType()); + } + + /** + * drop xxxx + * + * @param dbType dbType + * @return DropTableOperator + */ + DropTableOperator dropTable(DBType dbType); + + /** + * exist xxxx + * + * @return ExistTableOperator + */ + default ExistTableOperator existTable() { + return existTable(DBType.getSystemDbType()); + } + + /** + * exist xxxx + * + * @param dbType dbType + * @return ExistTableOperator + */ + ExistTableOperator existTable(DBType dbType); + + /** + * show columns for xxxx + * + * @return ShowColumnsOperator + */ + default ShowColumnsOperator showColumns() { + return showColumns(DBType.getSystemDbType()); + } + + /** + * show columns for xxxx + * + * @param dbType dbType + * @return ShowColumnsOperator + */ + ShowColumnsOperator showColumns(DBType dbType); + + /** + * show tables + * + * @return ShowTablesOperator + */ + default ShowTablesOperator showTables() { + return showTables(DBType.getSystemDbType()); + } + + /** + * show tables + * + * @param dbType dbType + * @return ShowTablesOperator + */ + ShowTablesOperator showTables(DBType dbType); + + /** + * @see #alterTables(DBType) + */ + default AlterTableOperator alterTables() { + return alterTables(DBType.getSystemDbType()); + } + + /** + * alert tables + * + * @param dbType dbType + * @return AlterTableOperator + */ + AlterTableOperator alterTables(DBType dbType); + + /** + * 获取当前系统的SQL Operator + * + * @return OperatorMetadata or DruidOperatorMetadata + */ + static OperatorGroup getSystemOperatorGroup() { + OperatorKey systemOperatorKey = OperatorKey.getSystemOperatorKey(); + if (systemOperatorKey == null) { + return null; + } + return getOperatorGroup(systemOperatorKey); + } + + static OperatorGroup getOperatorGroup(OperatorKey operatorKey) { + if (operatorKey != null) { + return new OperatorGroupImpl(operatorKey); + } + return null; + } + + + /** + * 根据operator的class获取指定operator实例. + *
      + *
    • operator key = {@link OperatorKey#getSystemOperatorKey()}
    • + *
    • dbtype = {@link DBType#getSystemDbType()}
    • + *
    + * + * @param operatorClass operatorClass + * @param SQLOperator + * @return SQLOperator + * @throws IllegalArgumentException operatorClass is null + * @throws NullPointerException An operation that does not exist + */ + static > T getOperator(Class operatorClass) { + return getOperator(operatorClass, OperatorKey.getSystemOperatorKey(), DBType.getSystemDbType()); + } + + /** + * 根据operator的class获取指定operator实例 + *
      + *
    • dbtype = {@link DBType#getSystemDbType()}
    • + *
    + * + * @param operatorClass operatorClass + * @param SQLOperator + * @param operatorKey operatorKey + * @return SQLOperator + * @throws IllegalArgumentException operatorClass is null + * @throws NullPointerException An operation that does not exist + * @see OperatorKey#getSystemOperatorKey() + */ + static > T getOperator(Class operatorClass, OperatorKey operatorKey) { + return getOperator(operatorClass, operatorKey, DBType.getSystemDbType()); + } + + /** + * 根据operator的class获取指定operator实例 + *
      + *
    • dbtype = {@link DBType#getSystemDbType()}
    • + *
    + * + * @param operatorClass operatorClass + * @param SQLOperator + * @param dbType dbType + * @return SQLOperator + * @throws IllegalArgumentException operatorClass is null + * @throws NullPointerException An operation that does not exist + * @see OperatorKey#getSystemOperatorKey() + */ + static > T getOperator(Class operatorClass, DBType dbType) { + return getOperator(operatorClass, OperatorKey.getSystemOperatorKey(), dbType); + } + + /** + * 根据operator的class获取指定operator实例 + * + * @param operatorClass operatorClass + * @param operatorKey operatorKey + * @param dbType dbtype + * @param SQLOperator + * @return SQLOperator + * @throws IllegalArgumentException operatorClass is null + * @throws NullPointerException An operation that does not exist + * @see OperatorKey + */ + static > T getOperator(Class operatorClass, OperatorKey operatorKey, DBType dbType) { + return SPIOperatorHelper.lazyGet(operatorClass, operatorKey, dbType); + } + + @Data + @AllArgsConstructor + class OperatorGroupImpl implements OperatorGroup { + + private final OperatorKey key; + + @Override + public QueryOperator query(DBType dbType) { + return SPIOperatorHelper.lazyGet(QueryOperator.class, key, dbType); + } + + @Override + public InsertOperator insert(DBType dbType) { + return SPIOperatorHelper.lazyGet(InsertOperator.class, key, dbType); + } + + @Override + public UpdateOperator update(DBType dbType) { + return SPIOperatorHelper.lazyGet(UpdateOperator.class, key, dbType); + } + + @Override + public DeleteOperator delete(DBType dbType) { + return SPIOperatorHelper.lazyGet(DeleteOperator.class, key, dbType); + } + + @Override + public CreateTableOperator createTable(DBType dbType) { + return SPIOperatorHelper.lazyGet(CreateTableOperator.class, key, dbType); + } + + @Override + public DropTableOperator dropTable(DBType dbType) { + return SPIOperatorHelper.lazyGet(DropTableOperator.class, key, dbType); + } + + @Override + public ExistTableOperator existTable(DBType dbType) { + return SPIOperatorHelper.lazyGet(ExistTableOperator.class, key, dbType); + } + + @Override + public ShowColumnsOperator showColumns(DBType dbType) { + return SPIOperatorHelper.lazyGet(ShowColumnsOperator.class, key, dbType); + } + + @Override + public ShowTablesOperator showTables(DBType dbType) { + return SPIOperatorHelper.lazyGet(ShowTablesOperator.class, key, dbType); + } + + @Override + public AlterTableOperator alterTables(DBType dbType) { + return SPIOperatorHelper.lazyGet(AlterTableOperator.class, key, dbType); + } + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/OperatorKey.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/OperatorKey.java new file mode 100644 index 00000000..8d50d72a --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/OperatorKey.java @@ -0,0 +1,70 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.api.Key; +import cc.allio.uno.core.env.Envs; +import cc.allio.uno.core.util.StringUtils; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * OperatorKey + * + * @author jiangwei + * @date 2024/1/3 22:48 + * @since 1.1.6 + */ +public interface OperatorKey extends Key { + + String OPERATOR_METADATA_KEY = "allio.uno.data.orm.dsl.operator.key"; + String SQL_LITERAL = "sql"; + OperatorKey SQL = returnKey(SQL_LITERAL); + String ELASTICSEARCH_LITERAL = "elasticsearch"; + OperatorKey ELASTICSEARCH = returnKey(ELASTICSEARCH_LITERAL); + String INFLUXDB_LITERAL = "influxdb"; + OperatorKey INFLUXDB = returnKey(INFLUXDB_LITERAL); + String MONGODB_LITERAL = "mongodb"; + OperatorKey MONGODB = returnKey(MONGODB_LITERAL); + String NEO4j_LITERAL = "neo4j"; + OperatorKey NEO4j = returnKey(NEO4j_LITERAL); + String REDIS_LITERAL = "redis"; + OperatorKey REDIS = returnKey(REDIS_LITERAL); + + /** + * 获取系统配置下的operator key + * + * @return operator key or default DRUID_OPERATOR_KEY + */ + static OperatorKey getSystemOperatorKey() { + String operatorKey = Envs.getProperty(OPERATOR_METADATA_KEY); + if (StringUtils.isBlank(operatorKey)) { + return null; + } + return OperatorKey.returnKey(operatorKey); + } + + @Override + default String getProperties() { + return OPERATOR_METADATA_KEY; + } + + default boolean equalsTo(String key) { + return this.key().equals(key); + } + + static OperatorKey returnKey(String key) { + return new DefaultOperatorKey(key); + } + + @Data + @EqualsAndHashCode(of = "key", callSuper = false) + @AllArgsConstructor + class DefaultOperatorKey implements OperatorKey { + private final String key; + + @Override + public String key() { + return key; + } + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderCondition.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/OrderCondition.java similarity index 78% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderCondition.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/OrderCondition.java index e7e3e7cc..3928608b 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/local/OrderCondition.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/OrderCondition.java @@ -1,6 +1,5 @@ -package cc.allio.uno.data.orm.sql.dml.local; +package cc.allio.uno.data.orm.dsl; -import cc.allio.uno.data.orm.sql.Condition; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLPrepareOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/PrepareOperator.java similarity index 71% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLPrepareOperator.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/PrepareOperator.java index 7c8c4ab4..006db1a1 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLPrepareOperator.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/PrepareOperator.java @@ -1,5 +1,6 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; +import cc.allio.uno.core.bean.ValueWrapper; import cc.allio.uno.core.util.CollectionUtils; import com.google.common.collect.Maps; @@ -17,14 +18,14 @@ * @see PreparedStatement * @since 1.1.4 */ -public interface SQLPrepareOperator> extends SQLOperator { +public interface PrepareOperator> extends Operator { /** - * 获取prepare sql,形如(select * from dual where a > ?) + * 获取prepare dsl,形如(select * xxxx dual where a > ?) * * @return String */ - String getPrepareSQL(); + String getPrepareDSL(); /** * 获取prepare sql对应的参数 @@ -64,4 +65,17 @@ default List getListValue() { } return Collections.emptyList(); } + + /** + * 获取真实值,给定的参数可能由某一些对象进行报装生成,该方法拆分该包装,还原真实的值 + * + * @param fake fake + * @return real value + */ + default Object getRealityValue(Object fake) { + if (ValueWrapper.EMPTY_VALUE.equals(fake)) { + return null; + } + return fake; + } } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/PrepareOperatorImpl.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/PrepareOperatorImpl.java new file mode 100644 index 00000000..90dbd9b2 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/PrepareOperatorImpl.java @@ -0,0 +1,98 @@ +package cc.allio.uno.data.orm.dsl; + +import com.google.common.collect.Lists; +import org.apache.commons.lang3.ArrayUtils; + +import java.util.Arrays; +import java.util.List; + +/** + * SQLPrepareOperatorImpl + * + * @author jiangwei + * @date 2023/4/16 18:19 + * @since 1.1.4 + */ +public abstract class PrepareOperatorImpl> implements PrepareOperator { + private static final int DEFAULT_CAPACITY = 0; + protected PrepareValue[] prepareValues; + protected int prepareIndex; + + protected PrepareOperatorImpl() { + this.prepareValues = new PrepareValue[DEFAULT_CAPACITY]; + this.prepareIndex = 0; + } + + /** + * 添加预处理SQL + * + * @param value value + */ + protected void addPrepareValue(String column, Object value) { + // ensure数组容量 + ensureExplicitCapacity(prepareValues.length + 1); + try { + prepareValues[prepareIndex] = PrepareValue.of(prepareIndex, column, getRealityValue(value)); + } finally { + incrementPrepareIndex(); + } + } + + /** + * 根据指定index设置值 + * + * @param index index + * @param column column + * @param value value + */ + protected void setPrepareValue(int index, String column, Object value) { + if (index > prepareValues.length - 1) { + ensureExplicitCapacity(index + 1); + } + prepareValues[index] = PrepareValue.of(index, column, getRealityValue(value)); + } + + @Override + public List getPrepareValues() { + return Lists.newArrayList(prepareValues); + } + + @Override + public void reset() { + prepareValues = new PrepareValue[DEFAULT_CAPACITY]; + prepareIndex = 0; + } + + protected void incrementPrepareIndex() { + prepareIndex++; + } + + /** + * 数组从某个index开始,向后移动length位数 + * + * @param index index + * @param digit digit + */ + protected void backward(int index, int digit) { + ensureExplicitCapacity(prepareValues.length + digit); + ArrayUtils.shift(prepareValues, index, prepareValues.length, digit); + } + + protected void ensureExplicitCapacity(int minCapacity) { + // overflow-conscious code + if (minCapacity - prepareValues.length > 0) + grow(minCapacity); + } + + /** + * Increases the capacity to ensure that it can hold at least the + * number of elements specified by the minimum capacity argument. + * + * @param minCapacity the desired minimum capacity + */ + private void grow(int minCapacity) { + // overflow-conscious code + // minCapacity is usually close to size, so this is a win: + prepareValues = Arrays.copyOf(prepareValues, minCapacity); + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/PrepareValue.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/PrepareValue.java similarity index 86% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/PrepareValue.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/PrepareValue.java index 543e618c..2b205c1e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/PrepareValue.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/PrepareValue.java @@ -1,16 +1,16 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.type.JavaType; -import cc.allio.uno.data.orm.type.JdbcType; -import cc.allio.uno.data.orm.type.TypeRegistry; +import cc.allio.uno.data.orm.dsl.type.JavaType; +import cc.allio.uno.data.orm.dsl.type.JdbcType; +import cc.allio.uno.data.orm.dsl.type.TypeRegistry; import lombok.AllArgsConstructor; import lombok.Data; import java.util.Collection; /** - * 预处理SQL + * 预处理SQL值对象 * * @author jiangwei * @date 2023/4/16 15:47 @@ -41,7 +41,6 @@ public class PrepareValue { */ private Collection jdbcType; - /** * 获取原始的column(去掉column_index) * diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/SPIOperatorHelper.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/SPIOperatorHelper.java new file mode 100644 index 00000000..7b34d245 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/SPIOperatorHelper.java @@ -0,0 +1,216 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.function.SupplierAction; +import cc.allio.uno.core.function.VoidConsumer; +import cc.allio.uno.core.util.ClassUtils; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.annotation.AnnotationUtils; + +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Helper + * + * @author jiangwei + * @date 2024/1/3 22:25 + * @since 1.1.6 + */ +@Slf4j +public final class SPIOperatorHelper { + + private SPIOperatorHelper() { + } + + private static final Map OTG_CACHES = Maps.newConcurrentMap(); + private static final ReadWriteLock lock = new ReentrantReadWriteLock(); + + /** + * @see #lazyGet(Class, OperatorKey, DBType) + */ + public static > T lazyGet(Class operatorClass, OperatorKey operatorKey) { + return lazyGet(operatorClass, operatorKey, null); + } + + /** + * 懒加载获取{@link Operator}实例 + * + * @param operatorClass operatorClass + * @param operatorKey operator 分组key + * @param dbType dbType maybe null + * @param + * @return instance or null + * @throws DSLException 当通过SPI没有找到获取实例化失败时抛出 + * @throws IllegalArgumentException operatorClass or groupKey为null时抛出 + */ + public static > T lazyGet(Class operatorClass, OperatorKey operatorKey, DBType dbType) { + if (operatorClass == null || operatorKey == null) { + throw new IllegalArgumentException("The parameter operatorClass or groupKey is null"); + } + return ifNullThenAgain( + () -> { + OperatorTraitGroup operatorTraitGroup = OTG_CACHES.get(operatorKey); + OperatorTrait operatorTrait; + Lock readLock = lock.readLock(); + try { + readLock.lock(); + operatorTrait = operatorTraitGroup.find(operatorClass); + if (operatorTrait == null) { + throw new DSLException(String.format("On the basis of SPI load operator %s and %s, " + + "but not found counterpart Impl, " + + "Please Check the Impl Has Annotation @AutoService", operatorKey.key(), operatorClass.getName())); + } + } finally { + readLock.unlock(); + } + return operatorTrait.newInstance(dbType); + }, + () -> loadOperatorBySPI(operatorClass), + null); + } + + /** + * 当第一次执行action时,如果失败或者抛出异常首先会执行'补偿'机制后,然后再次执行,如果第二次执行如果还是为null,则根据第一次执行的是否有异常(如果参数异常不为null)则抛出 + * + * @param action action + * @param compensate compensate + * @param failErr 执行失败异常信息 + * @return 如果执行不为null则返回,或者没有异常则返回null + * @throws DSLException 包装异常信息 + */ + private static T ifNullThenAgain(SupplierAction action, VoidConsumer compensate, Throwable failErr) { + Throwable err = null; + T result = null; + try { + result = action.get(); + } catch (Throwable ex) { + err = ex; + } + if (result == null || err != null) { + try { + compensate.doAccept(); + result = action.get(); + } catch (Throwable ex) { + err = ex; + } + } + if (result != null) { + return result; + } + if (failErr != null) { + err = failErr; + } + if (err != null) { + throw new DSLException(err); + } + return null; + } + + /** + * 基于SPI加载{@link Operator}的类型,放入缓存 + */ + private static void loadOperatorBySPI(Class> operatorClazz) { + ServiceLoader.load(operatorClazz, ClassLoader.getSystemClassLoader()) + .stream() + .forEach(provider -> { + Class> type = provider.type(); + Operator.Group group = AnnotationUtils.findAnnotation(type, Operator.Group.class); + if (group == null) { + throw new IllegalArgumentException(String.format("Operator %s without Annotation @SQLOperator.Group", type.getName())); + } + String groupKey = group.value(); + Lock writeLock = lock.writeLock(); + writeLock.lock(); + try { + OperatorTraitGroup operatorTraitGroup = OTG_CACHES.computeIfAbsent(OperatorKey.returnKey(groupKey), k -> new OperatorTraitGroup()); + if (log.isDebugEnabled()) { + log.debug("Through SPI load Operator Type [{}]", type.getName()); + } + operatorTraitGroup.append(type); + } finally { + writeLock.unlock(); + } + }); + } + + static class OperatorTraitGroup { + + private final Set traits; + + public OperatorTraitGroup() { + this.traits = Sets.newConcurrentHashSet(); + } + + public OperatorTrait find(Class> operatorClazz) { + return this.traits.stream() + .filter(trait -> trait.getSuperClazz().equals(operatorClazz)) + .findFirst() + .orElse(null); + } + + public void append(Class> implClazz) { + this.append(new OperatorTrait(implClazz)); + } + + public void append(OperatorTrait trait) { + if (trait == null) { + throw new IllegalArgumentException("parameter OperatorTrait is null"); + } + if (this.traits.contains(trait)) { + throw new IllegalArgumentException(String.format("repetitive operator %s, make sure only one operator impl by specific OperatorKey", trait.getClazz().getName())); + } + this.traits.add(trait); + } + + } + + @Data + @EqualsAndHashCode(of = "superClazz") + static class OperatorTrait { + + private final Class> clazz; + private Class> superClazz; + + public OperatorTrait(Class> clazz) { + this.clazz = clazz; + Class[] interfaces = this.clazz.getInterfaces(); + for (Class in : interfaces) { + if (Operator.class.isAssignableFrom(in)) { + this.superClazz = (Class>) in; + break; + } + } + if (superClazz == null) { + throw new DSLException(String.format("operator impl %s not implement any SQLOperator", clazz.getName())); + } + } + + public > T newInstance() { + return this.newInstance(null); + } + + public > T newInstance(DBType dbType) { + Operator sqlOperator = null; + try { + if (dbType == null) { + sqlOperator = ClassUtils.newInstance(clazz); + } else { + sqlOperator = ClassUtils.newInstance(clazz, dbType); + } + } catch (Throwable ex) { + throw new DSLException(String.format("Instance SQLOperator %s failed, please invoke method Is it right?", clazz.getName()), ex); + } + return (T) sqlOperator; + } + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Table.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Table.java similarity index 65% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/Table.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Table.java index 6e27f778..30729bf2 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Table.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Table.java @@ -1,6 +1,7 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; import lombok.Data; +import lombok.experimental.Accessors; /** * 表 @@ -10,19 +11,22 @@ * @since 1.1.4 */ @Data +@Accessors(chain = true) public class Table { /** * 表名 */ - private SQLName name; + private DSLName name; /** * 别名 */ private String alias; - + private String schema = "PUBLIC"; private String catalog; + private String type; + private String comment; /** * 根据表名创建{@link Table}实例 @@ -31,22 +35,22 @@ public class Table { */ public static Table of(String name) { Table table = new Table(); - table.setName(SQLName.of(name)); + table.setName(DSLName.of(name)); return table; } public static Table of(String name, String alias) { Table table = new Table(); - table.setName(SQLName.of(name)); + table.setName(DSLName.of(name)); table.setAlias(alias); return table; } - public static Table of(SQLName name) { + public static Table of(DSLName name) { return of(name, null); } - public static Table of(SQLName name, String alias) { + public static Table of(DSLName name, String alias) { Table table = new Table(); table.setName(name); table.setAlias(alias); diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/TableOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/TableOperator.java new file mode 100644 index 00000000..0a423b02 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/TableOperator.java @@ -0,0 +1,82 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.api.Self; +import cc.allio.uno.data.orm.dsl.helper.PojoWrapper; + +import java.util.function.UnaryOperator; + +/** + * Table Operator (xxxx xxx) + * + * @author jiangwei + * @date 2023/4/16 18:07 + * @since 1.1.4 + */ +public interface TableOperator> extends Self { + + /** + * FROM XX + * + * @param name xxxx name + * @return Operator + */ + default T from(String name) { + return from(Table.of(name)); + } + + /** + * FROM XX + * + * @param name xxxx name + * @return Operator + */ + default T from(DSLName name) { + return from(Table.of(name)); + } + + /** + * FROM XX + * + * @param name xxxx name + * @param alias xxxx alias + * @return Operator + */ + default T from(String name, String alias) { + return from(Table.of(name, alias)); + } + + /** + * FROM XX + * + * @param entityClass entityClass + * @return Operator + */ + default

    T from(Class

    entityClass) { + return from(PojoWrapper.findTable(entityClass)); + } + + /** + * FROM XX + * + * @param func func + * @return Operator + */ + default T from(UnaryOperator func) { + return from(func.apply(new Table())); + } + + /** + * FROM XX + * + * @param table xxxx + * @return Operator + */ + T from(Table table); + + /** + * 获取table对象 + * + * @return Table + */ + Table getTable(); +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Token.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Token.java similarity index 98% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/Token.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Token.java index 20d96668..bcd8723c 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/Token.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/Token.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; /** * SQL 相关字符 diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/TokenOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/TokenOperator.java similarity index 98% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/TokenOperator.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/TokenOperator.java index fdf3c0b7..9bf5512e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/TokenOperator.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/TokenOperator.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; import lombok.AllArgsConstructor; import lombok.Getter; @@ -77,7 +77,5 @@ public enum TokenOperator { ASSIGNMENT(":="), PG_And("&&"), PG_ST_DISTANCE("<->"); - - private final String name; } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/TokenOperatorAdapter.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/TokenOperatorAdapter.java new file mode 100644 index 00000000..cc74eb54 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/TokenOperatorAdapter.java @@ -0,0 +1,13 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.api.Adapter; + +/** + * SQL operator + * + * @author jiangwei + * @date 2023/4/13 13:13 + * @since 1.1.4 + */ +public interface TokenOperatorAdapter extends Adapter { +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLUnaryOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/UnaryOperator.java similarity index 87% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLUnaryOperator.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/UnaryOperator.java index e4d8c6fa..71f24ec2 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLUnaryOperator.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/UnaryOperator.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; import lombok.AllArgsConstructor; import lombok.Getter; @@ -12,7 +12,7 @@ */ @Getter @AllArgsConstructor -public enum SQLUnaryOperator { +public enum UnaryOperator { PLUS("+"), NEGATIVE("-"), not("!"), diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLWhereOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/WhereOperator.java similarity index 63% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLWhereOperator.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/WhereOperator.java index b9ff4e92..6decb5f8 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLWhereOperator.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/WhereOperator.java @@ -1,4 +1,7 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.api.Self; +import cc.allio.uno.core.function.lambda.MethodReferenceColumn; /** * where eq1=eq2... @@ -7,7 +10,7 @@ * @date 2023/4/16 18:14 * @since 1.1.4 */ -public interface SQLWhereOperator> extends Operator { +public interface WhereOperator> extends Self { /** * > condition @@ -28,7 +31,7 @@ default T gt(MethodReferenceColumn reference, Object value) { * @return SQLWhereOperator */ default T gt(String fieldName, Object value) { - return gt(SQLName.of(fieldName), value); + return gt(DSLName.of(fieldName), value); } /** @@ -38,7 +41,7 @@ default T gt(String fieldName, Object value) { * @param value 比较数据值 * @return SQLWhereOperator */ - T gt(SQLName sqlName, Object value); + T gt(DSLName sqlName, Object value); /** * >= condition @@ -59,7 +62,7 @@ default T gte(MethodReferenceColumn reference, Object value) { * @return SQLWhereOperator */ default T gte(String fieldName, Object value) { - return gte(SQLName.of(fieldName), value); + return gte(DSLName.of(fieldName), value); } /** @@ -69,7 +72,7 @@ default T gte(String fieldName, Object value) { * @param value 比较数据值 * @return SQLWhereOperator */ - T gte(SQLName sqlName, Object value); + T gte(DSLName sqlName, Object value); /** * < condition @@ -90,7 +93,7 @@ default T lt(MethodReferenceColumn reference, Object value) { * @return SQLWhereOperator */ default T lt(String fieldName, Object value) { - return lt(SQLName.of(fieldName), value); + return lt(DSLName.of(fieldName), value); } /** @@ -100,7 +103,7 @@ default T lt(String fieldName, Object value) { * @param value 比较数据值 * @return SQLWhereOperator */ - T lt(SQLName sqlName, Object value); + T lt(DSLName sqlName, Object value); /** * <= condition @@ -121,7 +124,7 @@ default T lte(MethodReferenceColumn reference, Object value) { * @return SQLWhereOperator */ default T lte(String fieldName, Object value) { - return lte(SQLName.of(fieldName), value); + return lte(DSLName.of(fieldName), value); } /** @@ -131,7 +134,7 @@ default T lte(String fieldName, Object value) { * @param value 比较数据值 * @return SQLWhereOperator */ - T lte(SQLName sqlName, Object value); + T lte(DSLName sqlName, Object value); /** * = condition @@ -152,7 +155,7 @@ default T eq(MethodReferenceColumn reference, Object value) { * @return SQLWhereOperator */ default T eq(String fieldName, Object value) { - return eq(SQLName.of(fieldName), value); + return eq(DSLName.of(fieldName), value); } /** @@ -162,7 +165,38 @@ default T eq(String fieldName, Object value) { * @param value 比较数据值 * @return SQLWhereOperator */ - T eq(SQLName sqlName, Object value); + T eq(DSLName sqlName, Object value); + + /** + * != condition + * + * @param reference 方法引用 + * @param value 比较数据值 + * @return SQLWhereOperator + */ + default T neq(MethodReferenceColumn reference, Object value) { + return neq(reference.getColumn(), value); + } + + /** + * != condition + * + * @param fieldName java variable name + * @param value 比较数据值 + * @return SQLWhereOperator + */ + default T neq(String fieldName, Object value) { + return neq(DSLName.of(fieldName), value); + } + + /** + * != condition + * + * @param sqlName sqlName + * @param value 比较数据值 + * @return SQLWhereOperator + */ + T neq(DSLName sqlName, Object value); /** * is not null condition @@ -181,7 +215,7 @@ default T notNull(MethodReferenceColumn reference) { * @return SQLWhereOperator */ default T notNull(String fieldName) { - return notNull(SQLName.of(fieldName)); + return notNull(DSLName.of(fieldName)); } /** @@ -190,26 +224,20 @@ default T notNull(String fieldName) { * @param sqlName sqlName * @return SQLWhereOperator */ - T notNull(SQLName sqlName); + T notNull(DSLName sqlName); /** - * is null condition - * - * @param reference 方法引用 - * @return where + * @see #isNull(DSLName) */ default T isNull(MethodReferenceColumn reference) { return isNull(reference.getColumn()); } /** - * is null condition - * - * @param fieldName java variable name - * @return where + * @see #isNull(DSLName) */ default T isNull(String fieldName) { - return isNull(SQLName.of(fieldName)); + return isNull(DSLName.of(fieldName)); } /** @@ -218,38 +246,53 @@ default T isNull(String fieldName) { * @param sqlName sqlName * @return where */ - T isNull(SQLName sqlName); + T isNull(DSLName sqlName); /** - * 'in'条件 - * - * @param reference 方法引用 - * @param values 数值数据 - * @return SQLWhereOperator + * @see #in(DSLName, Object...) */ - default T in(MethodReferenceColumn reference, Object... values) { + default T in(MethodReferenceColumn reference, V... values) { return in(reference.getColumn(), values); } + /** + * @see #in(DSLName, Object...) + */ + default T in(String fieldName, V... values) { + return in(DSLName.of(fieldName), values); + } + /** * 'in'条件 * - * @param fieldName java variable name - * @param values 数值数据 + * @param sqlName sqlName + * @param values 数值数据 * @return SQLWhereOperator */ - default T in(String fieldName, Object... values) { - return in(SQLName.of(fieldName), values); + T in(DSLName sqlName, V... values); + + /** + * @see #notIn(DSLName, Object...) + */ + default T notIn(MethodReferenceColumn reference, V... values) { + return notIn(reference.getColumn(), values); } /** - * 'in'条件 + * @see #notIn(DSLName, Object...) + */ + default T notIn(String fieldName, V... values) { + return notIn(DSLName.of(fieldName), values); + } + + /** + * 'not in'条件 * * @param sqlName sqlName * @param values 数值数据 * @return SQLWhereOperator */ - T in(SQLName sqlName, Object... values); + T notIn(DSLName sqlName, V... values); /** * between condition @@ -272,7 +315,7 @@ default T between(MethodReferenceColumn reference, Object withValue, Obje * @return SQLWhereOperator */ default T between(String fieldName, Object withValue, Object endValue) { - return between(SQLName.of(fieldName), withValue, endValue); + return between(DSLName.of(fieldName), withValue, endValue); } /** @@ -283,7 +326,7 @@ default T between(String fieldName, Object withValue, Object endValue) { * @param endValue between结束值 * @return SQLWhereOperator */ - T between(SQLName sqlName, Object withValue, Object endValue); + T between(DSLName sqlName, Object withValue, Object endValue); /** * not between condition @@ -306,7 +349,7 @@ default T notBetween(MethodReferenceColumn reference, Object withValue, O * @return SQLWhereOperator */ default T notBetween(String fieldName, Object withValue, Object endValue) { - return notBetween(SQLName.of(fieldName), withValue, endValue); + return notBetween(DSLName.of(fieldName), withValue, endValue); } /** @@ -317,7 +360,7 @@ default T notBetween(String fieldName, Object withValue, Object endValue) { * @param endValue between结束值 * @return SQLWhereOperator */ - T notBetween(SQLName sqlName, Object withValue, Object endValue); + T notBetween(DSLName sqlName, Object withValue, Object endValue); /** * 'field' @@ -349,7 +392,7 @@ default T like(MethodReferenceColumn reference, Object value) { * @return SQLWhereOperator */ default T like(String fieldName, Object value) { - return like(SQLName.of(fieldName), value); + return like(DSLName.of(fieldName), value); } /** @@ -359,7 +402,7 @@ default T like(String fieldName, Object value) { * @param value like值 * @return SQLWhereOperator */ - T like(SQLName sqlName, Object value); + T like(DSLName sqlName, Object value); /** * '%field' @@ -369,7 +412,7 @@ default T like(String fieldName, Object value) { * @return SQLWhereOperator */ default T $like(String fieldName, Object value) { - return $like(SQLName.of(fieldName), value); + return $like(DSLName.of(fieldName), value); } /** @@ -379,7 +422,7 @@ default T like(String fieldName, Object value) { * @param value like值 * @return SQLWhereOperator */ - T $like(SQLName sqlName, Object value); + T $like(DSLName sqlName, Object value); /** * 'field%' @@ -400,7 +443,7 @@ default T like(String fieldName, Object value) { * @return SQLWhereOperator */ default T like$(String fieldName, Object value) { - return like$(SQLName.of(fieldName), value); + return like$(DSLName.of(fieldName), value); } /** @@ -410,7 +453,7 @@ default T like(String fieldName, Object value) { * @param value like值 * @return SQLWhereOperator */ - T like$(SQLName sqlName, Object value); + T like$(DSLName sqlName, Object value); /** @@ -432,7 +475,7 @@ default T like(String fieldName, Object value) { * @return SQLWhereOperator */ default T $like$(String fieldName, Object value) { - return $like$(SQLName.of(fieldName), value); + return $like$(DSLName.of(fieldName), value); } /** @@ -442,17 +485,109 @@ default T like(String fieldName, Object value) { * @param value like值 * @return SQLWhereOperator */ - T $like$(SQLName sqlName, Object value); + T $like$(DSLName sqlName, Object value); + + /** + * @see #notLike(DSLName, Object) + */ + default T notLike(MethodReferenceColumn reference, Object value) { + return notLike(reference.getColumn(), value); + } + + /** + * @see #notLike(DSLName, Object) + */ + default T notLike(String fieldName, Object value) { + return notLike(DSLName.of(fieldName), value); + } + + /** + * 'not field' + * + * @param sqlName sqlName + * @param value like值 + * @return SQLWhereOperator + */ + T notLike(DSLName sqlName, Object value); + + /** + * @see #$notLike(DSLName, Object) + */ + default T $notLike(MethodReferenceColumn reference, Object value) { + return $notLike(reference.getColumn(), value); + } + + /** + * @see #$notLike(DSLName, Object) + */ + default T $notLike(String fieldName, Object value) { + return $notLike(DSLName.of(fieldName), value); + } + + /** + * 'not %field' + * + * @param sqlName sqlName + * @param value like值 + * @return SQLWhereOperator + */ + T $notLike(DSLName sqlName, Object value); + + /** + * @see #notLike$(DSLName, Object) + */ + default T notLike$(MethodReferenceColumn reference, Object value) { + return notLike$(reference.getColumn(), value); + } + + /** + * @see #notLike$(DSLName, Object) + */ + default T notLike$(String fieldName, Object value) { + return notLike$(DSLName.of(fieldName), value); + } + + /** + * 'not field%' + * + * @param sqlName sqlName + * @param value like值 + * @return SQLWhereOperator + */ + T notLike$(DSLName sqlName, Object value); + + /** + * @see #$notLike$(DSLName, Object) + */ + default T $notLike$(MethodReferenceColumn reference, Object value) { + return $notLike$(reference.getColumn(), value); + } + + /** + * @see #$notLike$(DSLName, Object) + */ + default T $notLike$(String fieldName, Object value) { + return $notLike$(DSLName.of(fieldName), value); + } + + /** + * '%not like%' + * + * @param sqlName sqlName + * @param value like值 + * @return SQLWhereOperator + */ + T $notLike$(DSLName sqlName, Object value); /** - * 逻辑'or'控制。当使用后,新加的条件语句将会与之前的做为or条件,直到用{@link #and()} + * logic predicate 'or' * * @return SQLWhereOperator */ T or(); /** - * 逻辑'and'控制。当使用,新加的条件语句将会与之前的作and条件,直到用{@link #or()} + * logic predicate 'and' * * @return SQLWhereOperator */ diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/AlterTableOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/AlterTableOperator.java new file mode 100644 index 00000000..de98b265 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/AlterTableOperator.java @@ -0,0 +1,128 @@ +package cc.allio.uno.data.orm.dsl.ddl; + +import cc.allio.uno.core.api.Self; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.helper.PojoWrapper; + +import java.util.Arrays; +import java.util.Collection; +import java.util.function.UnaryOperator; + +/** + * DSL修改表以及相关字段操作 + * + * @author jiangwei + * @date 2023/6/8 19:21 + * @since 1.1.4 + */ +public interface AlterTableOperator extends Operator, Self, TableOperator { + + /** + * @see #alertColumns(Collection) + */ + default AlterTableOperator alertColumn(ColumnDef columnDef) { + return alertColumns(columnDef); + } + + /** + * @see #alertColumns(Collection) + */ + default AlterTableOperator alertColumns(ColumnDef... columnDefs) { + return alertColumns(Arrays.stream(columnDefs).toList()); + } + + /** + * 修改列 + * + * @param columnDefs columnDefs + * @return AlterTableOperator + */ + AlterTableOperator alertColumns(Collection columnDefs); + + /** + * @see #addColumns(Collection) + */ + default AlterTableOperator addColumn(ColumnDef columnDef) { + return addColumns(columnDef); + } + + /** + * @see #addColumns(Collection) + */ + default AlterTableOperator addColumns(ColumnDef... columnDefs) { + return addColumns(Arrays.stream(columnDefs).toList()); + } + + /** + * 添加column + * + * @param columnDefs columnDefs + * @return AlterTableOperator + */ + AlterTableOperator addColumns(Collection columnDefs); + + /** + * @see #deleteColumn(DSLName) + */ + default AlterTableOperator deleteColumn(String column) { + return deleteColumn(DSLName.of(column)); + } + + /** + * @see #deleteColumns(Collection) + */ + default AlterTableOperator deleteColumn(DSLName column) { + return deleteColumns(column); + } + + /** + * @see #deleteColumns(Collection) + */ + default AlterTableOperator deleteColumns(DSLName... columns) { + return deleteColumns(Arrays.stream(columns).toList()); + } + + /** + * 删除列 + * + * @param columns columns + * @return AlterTableOperator + */ + AlterTableOperator deleteColumns(Collection columns); + + /** + * @see #rename(Table) + */ + default AlterTableOperator rename(String table) { + return rename(Table.of(table)); + } + + /** + * @see #rename(Table) + */ + default AlterTableOperator rename(DSLName table) { + return rename(Table.of(table)); + } + + /** + * @see #rename(Table) + */ + default AlterTableOperator rename(Class pojoClass) { + return rename(PojoWrapper.findTable(pojoClass)); + } + + /** + * @see #rename(Table) + */ + default AlterTableOperator rename(UnaryOperator
    func) { + return rename(func.apply(new Table())); + } + + /** + * 重命名表名 + * + * @param to to + * @return AlterTableOperator + */ + AlterTableOperator rename(Table to); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/CreateTableOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/CreateTableOperator.java new file mode 100644 index 00000000..03660f4c --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/CreateTableOperator.java @@ -0,0 +1,88 @@ +package cc.allio.uno.data.orm.dsl.ddl; + +import cc.allio.uno.core.util.CollectionUtils; +import cc.allio.uno.data.orm.dsl.helper.PojoWrapper; +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.TableOperator; + +import java.util.List; +import java.util.function.UnaryOperator; + +/** + * SQL创建操作 + * + * @author jiangwei + * @date 2023/4/12 19:42 + * @since 1.1.4 + */ +public interface CreateTableOperator extends Operator, TableOperator { + + /** + * 根据pojo的clas创表实例 + * + * @param pojoClass the pojoClass + * @return SQLCreateTableOperator + */ + default CreateTableOperator fromPojo(Class pojoClass) { + PojoWrapper pojoWrapper = PojoWrapper.getInstance(pojoClass); + List columnDefs = pojoWrapper.getColumnDefs(); + return from(pojoWrapper.getTable()).columns(columnDefs); + } + + /** + * 字段 + * + * @param columnDefs 集合 + * @return CreateTableOperator + */ + default CreateTableOperator columns(ColumnDef... columnDefs) { + if (columnDefs != null) { + for (ColumnDef columnDef : columnDefs) { + column(columnDef); + } + } + return self(); + } + + /** + * 字段 + * + * @param columnDefs 集合 + * @return CreateTableOperator + */ + default CreateTableOperator columns(List columnDefs) { + if (CollectionUtils.isNotEmpty(columnDefs)) { + for (ColumnDef columnDef : columnDefs) { + column(columnDef); + } + } + return self(); + } + + /** + * 字段 + * + * @param builder the builder + * @return CreateTableOperator + */ + default CreateTableOperator column(UnaryOperator builder) { + return column(builder.apply(ColumnDef.builder()).build()); + } + + /** + * 字段 + * + * @param columnDef SQLColumnDef + * @return CreateTableOperator + */ + CreateTableOperator column(ColumnDef columnDef); + + /** + * 注释 + * + * @param comment 注释 + * @return CreateTableOperator + */ + CreateTableOperator comment(String comment); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/DropTableOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/DropTableOperator.java new file mode 100644 index 00000000..2492113e --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/DropTableOperator.java @@ -0,0 +1,22 @@ +package cc.allio.uno.data.orm.dsl.ddl; + +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.TableOperator; + +/** + * Drop xxxx + * + * @author jiangwei + * @date 2023/4/16 12:52 + * @since 1.1.4 + */ +public interface DropTableOperator extends Operator, TableOperator { + + /** + * Drop xxxx if exist + * + * @param ifExist ifExist + * @return SQLDropTableOperator + */ + DropTableOperator ifExist(Boolean ifExist); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/ExistTableOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/ExistTableOperator.java new file mode 100644 index 00000000..30042371 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/ExistTableOperator.java @@ -0,0 +1,15 @@ +package cc.allio.uno.data.orm.dsl.ddl; + +import cc.allio.uno.data.orm.dsl.PrepareOperator; +import cc.allio.uno.data.orm.dsl.TableOperator; + +/** + * SQL 查询是否存在指定表 + * + * @author jiangwei + * @date 2023/4/17 09:46 + * @since 1.1.4 + */ +public interface ExistTableOperator extends PrepareOperator, TableOperator { + +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/ShowColumnsOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/ShowColumnsOperator.java new file mode 100644 index 00000000..a33bf597 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/ShowColumnsOperator.java @@ -0,0 +1,42 @@ +package cc.allio.uno.data.orm.dsl.ddl; + +import cc.allio.uno.data.orm.dsl.DataBaseOperator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.PrepareOperator; +import cc.allio.uno.data.orm.dsl.TableOperator; +import cc.allio.uno.data.query.stream.SQLCommandExecutorStream; + +/** + * SQL表结构查询 + * + * @author jiangwei + * @date 2023/6/8 19:19 + * @since SWP-2.0.1 + */ +public interface ShowColumnsOperator + extends PrepareOperator, + TableOperator, + DataBaseOperator { + + String TABLE_CATALOG_FIELD = "TABLE_CATALOG"; + String TABLE_SCHEMA_FILED = "TABLE_SCHEMA"; + String TABLE_NAME_FILED = "TABLE_NAME"; + String COLUMN_NAME_FIELD = "COLUMN_NAME"; + String ORDINAL_POSITION_FIELD = "ORDINAL_POSITION"; + String COLUMN_DEFAULT_FIELD = "COLUMN_DEFAULT"; + String IS_NULLABLE_FIELD = "IS_NULLABLE"; + String DATA_TYPE_FIELD = "DATA_TYPE"; + String CHARACTER_MAXIMUM_LENGTH_FIELD = "CHARACTER_MAXIMUM_LENGTH"; + String CHARACTER_OCTET_LENGTH_FIELD = "CHARACTER_OCTET_LENGTH"; + String NUMERIC_PRECISION_FIELD = "NUMERIC_PRECISION"; + String NUMERIC_SCALE_FIELD = "NUMERIC_SCALE"; + String DATETIME_PRECISION_FIELD = "DATETIME_PRECISION"; + + + /** + * 转换为{@link QueryOperator} + * + * @return SQLQueryOperator for instance + */ + QueryOperator toQueryOperator(); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/ShowTablesOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/ShowTablesOperator.java new file mode 100644 index 00000000..f5242b9f --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/ddl/ShowTablesOperator.java @@ -0,0 +1,45 @@ +package cc.allio.uno.data.orm.dsl.ddl; + +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; + +/** + * 数据库表结构 + * + * @author jiangwei + * @date 2024/1/4 16:56 + * @since 1.1.6 + */ +public interface ShowTablesOperator + extends TableOperator, + PrepareOperator, DataBaseOperator { + + String TABLE_CATALOG_FILED = "TABLE_CATALOG"; + String TABLE_SCHEMA_FILED = "TABLE_SCHEMA"; + String TABLE_NAME_FILED = "TABLE_NAME"; + String TABLE_TYPE_FILED = "TABLE_TYPE"; + + /** + * 转换为{@link QueryOperator} + * + * @return SQLQueryOperator for instance + */ + QueryOperator toQueryOperator(); + + /** + * schema + * + * @param schema schema + * @return ShowTablesOperator + */ + ShowTablesOperator schema(String schema); + + /** + * 作为库表查询的过滤,可以多次使用,如果多次则查询这多个信息 + * + * @param table xxxx + * @return ShowTablesOperator + */ + @Override + ShowTablesOperator from(Table table); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dialect/TypeTranslator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dialect/TypeTranslator.java new file mode 100644 index 00000000..6b99acf1 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dialect/TypeTranslator.java @@ -0,0 +1,53 @@ +package cc.allio.uno.data.orm.dsl.dialect; + +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DSLType; + +/** + * 不同数据类型方言转换器 + * + * @author jiangwei + * @date 2024/1/8 19:33 + * @since 1.1.6 + */ +public interface TypeTranslator { + + /** + * 类型转换 + * + * @param dslType 原始类型 + * @return 翻译后的类型 + */ + DSLType translate(DSLType dslType); + + /** + * 类型转换 + * + * @param dslType 原始类型 + * @param precision precision + * @param scale scale + * @return 翻译后的类型 + */ + DSLType translate(DSLType dslType, Integer precision, Integer scale); + + /** + * 给定dsl type name 反转为{@link DSLType}实例 + *

    基于{@link cc.allio.uno.data.orm.dsl.type.DSLType.DefaultDSLType}的数据进行获取

    + * + * @param dslTypeName dslTypeName + * @return DSLType instance if find + */ + default DSLType reserve(String dslTypeName) { + for (DSLType.DefaultDSLType dslType : DSLType.DefaultDSLType.values()) { + if (dslType.getName().equalsIgnoreCase(dslTypeName)) { + return translate(dslType); + } + } + return null; + } + + /** + * 获取数据库类型 + */ + DBType getDBType(); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dialect/TypeTranslatorHolder.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dialect/TypeTranslatorHolder.java new file mode 100644 index 00000000..34de6a81 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dialect/TypeTranslatorHolder.java @@ -0,0 +1,30 @@ +package cc.allio.uno.data.orm.dsl.dialect; + +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.ServiceLoader; + +public final class TypeTranslatorHolder { + private static final Map TRANSLATORS = Maps.newConcurrentMap(); + + static { + for (TypeTranslator translator : ServiceLoader.load(TypeTranslator.class)) { + TRANSLATORS.put(translator.getDBType().getName(), translator); + } + } + + public static TypeTranslator getTypeTranslator() { + return getTypeTranslator(DBType.getSystemDbType()); + } + + public static TypeTranslator getTypeTranslator(DBType dbType) { + TypeTranslator translator = TRANSLATORS.get(dbType.getName()); + if (translator == null) { + throw new DSLException("DBType " + dbType.getName() + " not supported"); + } + return translator; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/DeleteOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/DeleteOperator.java new file mode 100644 index 00000000..5d586075 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/DeleteOperator.java @@ -0,0 +1,16 @@ +package cc.allio.uno.data.orm.dsl.dml; + +import cc.allio.uno.data.orm.dsl.PrepareOperator; +import cc.allio.uno.data.orm.dsl.TableOperator; +import cc.allio.uno.data.orm.dsl.WhereOperator; + +/** + * SQLDeleteOperator + * + * @author jiangwei + * @date 2023/4/16 18:42 + * @since 1.1.4 + */ +public interface DeleteOperator extends + PrepareOperator, TableOperator, WhereOperator { +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/InsertOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/InsertOperator.java new file mode 100644 index 00000000..791da766 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/InsertOperator.java @@ -0,0 +1,266 @@ +package cc.allio.uno.data.orm.dsl.dml; + +import cc.allio.uno.core.function.lambda.MethodReferenceColumn; +import cc.allio.uno.core.util.id.IdGenerator; +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.PrepareOperator; +import cc.allio.uno.data.orm.dsl.TableOperator; +import cc.allio.uno.data.orm.dsl.helper.PojoWrapper; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import reactor.util.function.Tuple2; +import reactor.util.function.Tuples; + +import java.util.*; +import java.util.function.Supplier; + +/** + * SQL INSERT。 + *

    值得注意的是每调用一次{@link #insert(String, Object)}API,都会生成一个VALUES。建议调用{@link #batchInserts(List, List)}API批量生成

    + * + * @author jiangwei + * @date 2023/4/13 15:25 + * @since 1.1.4 + */ +public interface InsertOperator extends PrepareOperator, TableOperator { + + /** + * INSERT VALUES + * + * @param reference key + * @param value value + * @return InsertOperator + */ + default InsertOperator insert(MethodReferenceColumn reference, Object value) { + return insert(reference.getColumn(), value); + } + + /** + * INSERT VALUES + * + * @param fieldName fieldName + * @param value value + * @return InsertOperator + */ + default InsertOperator insert(String fieldName, Object value) { + return insert(Map.of(fieldName, getValueIfNullThenNullValue(value))); + } + + /** + * INSERT VALUES + * + * @param f1 f1 + * @param v1 v1 + * @return InsertOperator + */ + default InsertOperator insert(String f1, Object v1, String f2, Object v2) { + return insert(Tuples.of(f1, getValueIfNullThenNullValue(v1)), Tuples.of(f2, getValueIfNullThenNullValue(v2))); + } + + /** + * INSERT VALUES + * + * @param f1 f1 + * @param v1 v1 + * @param f2 f2 + * @param v2 v2 + * @return InsertOperator + */ + default InsertOperator insert(String f1, Object v1, String f2, Object v2, String f3, Object v3) { + return insert( + Tuples.of(f1, getValueIfNullThenNullValue(v1)), + Tuples.of(f2, getValueIfNullThenNullValue(v2)), + Tuples.of(f3, getValueIfNullThenNullValue(v3))); + } + + /** + * INSERT VALUES + * + * @param f1 f1 + * @param v1 v1 + * @param f2 f2 + * @param v2 v2 + * @param f3 f3 + * @param v3 v3 + * @param f4 f4 + * @param v4 v4 + * @return InsertOperator + */ + default InsertOperator insert(String f1, Object v1, String f2, Object v2, String f3, Object v3, String f4, Object v4) { + return insert( + Tuples.of(f1, getValueIfNullThenNullValue(v1)), + Tuples.of(f2, getValueIfNullThenNullValue(v2)), + Tuples.of(f3, getValueIfNullThenNullValue(v3)), + Tuples.of(f4, getValueIfNullThenNullValue(v4))); + } + + /** + * INSERT VALUES + * + * @param tuple2s Key value + * @return InsertOperator + */ + default InsertOperator insert(Tuple2... tuple2s) { + Map values = Maps.newHashMap(); + for (Tuple2 tuple2 : tuple2s) { + values.put(tuple2.getT1(), tuple2.getT2()); + } + return insert(values); + } + + /** + * 基于POJO实体动态构建INSERT VALUES,如果该实体某个字段没有值将不会加入到INSERT中 + * + * @param pojo pojo + * @return SQLInsertOperator + */ + default InsertOperator insertPojo(T pojo) { + PojoWrapper pojoWrapper = PojoWrapper.getInstance(pojo); + String pkName = pojoWrapper.getPkColumn().getDslName().format(DSLName.HUMP_FEATURE); + ColumnDef pkColumn = pojoWrapper.getPkColumn(); + Object pkValue = pkColumn.castValue(IdGenerator.defaultGenerator().getNextId()); + pojoWrapper.setForceCoverage(pkName, false, pkValue); + Collection columns = pojoWrapper.getColumnDSLName(); + List values = pojoWrapper.getColumnValues(); + return columns(columns).values(values); + } + + /** + * INSERT VALUES + * + * @param values Key value + * @return InsertOperator + */ + default InsertOperator insert(Map values) { + Map inserts = Maps.newLinkedHashMap(); + for (Map.Entry entry : values.entrySet()) { + inserts.put(DSLName.of(entry.getKey()), getValueIfNullThenNullValue(entry.getValue())); + } + return inserts(inserts); + } + + /** + * INSERT VALUES + * + * @param values Key value + * @return InsertOperator + */ + default InsertOperator inserts(Map values) { + Set sqlNames = values.keySet(); + Collection value = values.values(); + return columns(sqlNames.stream().toList()).values(Lists.newArrayList(value)); + } + + /** + * 基于POJO实体动态构建INSERT VALUES,如果该实体某个字段没有值将不会加入到INSERT中 + * + * @param pojos pojos list + * @return SQLInsertOperator + */ + default InsertOperator batchInsertPojos(List pojos) { + for (T pojo : pojos) { + insertPojo(pojo); + } + return self(); + } + + /** + * INSERT VALUES,VALUES,VALUES + * + * @param values values + * @return SQLInsertOperator + */ + default InsertOperator batchInsert(List columns, List> values) { + return batchInserts(columns.stream().map(DSLName::of).toList(), values); + } + + /** + * INSERT VALUES,VALUES,VALUES + * + * @param values values + * @return SQLInsertOperator + */ + default InsertOperator batchInserts(List columns, List> values) { + columns(columns); + for (List value : values) { + values(value); + } + return self(); + } + + /** + * @see #strictFill(String, Supplier) + */ + default InsertOperator strictFill(String f, Object v) { + return strictFill(f, () -> v); + } + + /** + * 当使用了{@link #insert(Map)}或者{@link #batchInserts(List, List)}等插入数据API时, + * 如果需要对某一个或多个字段进行其他方式的设置值,此时需要调用该API进行重新填充。 + *

    使用该API的值懒加载,可以避免相同字段都是同一值的情况.

    + * + * @param f 字段名 + * @param v 字段值 + * @return SQLInsertOperator + */ + InsertOperator strictFill(String f, Supplier v); + + /** + * 提供insert column + * + * @param columns columns + * @return SQLInsertOperator + */ + default InsertOperator columns(String... columns) { + return columns(Lists.newArrayList(columns).stream().map(DSLName::of).toList()); + } + + /** + * 提供insert column + * + * @param columns columns + * @return SQLInsertOperator + */ + default InsertOperator columns(DSLName... columns) { + return columns(Lists.newArrayList(columns)); + } + + /** + * 提供insert column + * + * @param columns columns + * @return SQLInsertOperator + */ + InsertOperator columns(Collection columns); + + /** + * @see #values(List) + */ + default InsertOperator values(Object... values) { + return values(Lists.newArrayList(values)); + } + + /** + * 提供insert values。 + *
      + *
    • 调用该API前提需要调用{@link #columns(DSLName...)}生成insert column
    • + *
    • 每调用一次生成一条数据
    • + *
    • 如果values的长度大于columns的长度,会忽略values的最后的值
    • + *
    • 如果values的长度小于columns的长度,会使用null进行填充
    • + *
    • 如果两次或多次values之间有使用{@link #columns(DSLName...)},那么在使用{@link #columns(DSLName...)}之前之后的值将以新的column作为基础
    • + *
    + * + * @param values values + * @return SQLInsertOperator + */ + InsertOperator values(List values); + + /** + * 是否是批量插入 + * + * @return true is + */ + boolean isBatched(); +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLQueryOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/QueryOperator.java similarity index 69% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLQueryOperator.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/QueryOperator.java index a4e11513..9687c3db 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/SQLQueryOperator.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/QueryOperator.java @@ -1,14 +1,13 @@ -package cc.allio.uno.data.orm.sql.dml; +package cc.allio.uno.data.orm.dsl.dml; import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.dialect.func.Func; -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.dml.local.OrderCondition; -import cc.allio.uno.data.orm.sql.word.Distinct; +import cc.allio.uno.core.function.lambda.MethodReferenceColumn; +import cc.allio.uno.data.orm.dsl.Func; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.word.Distinct; import com.google.common.collect.Lists; import java.util.Collection; -import java.util.stream.Collectors; /** * SQL Query Operator @@ -17,7 +16,7 @@ * @date 2023/4/12 23:02 * @since 1.1.4 */ -public interface SQLQueryOperator extends SQLPrepareOperator, SQLTableOperator, SQLWhereOperator { +public interface QueryOperator extends PrepareOperator, TableOperator, WhereOperator { // ============================== SELECT PART ============================== @@ -27,7 +26,7 @@ public interface SQLQueryOperator extends SQLPrepareOperator, * @param reference 方法引用 * @return Select */ - default SQLQueryOperator select(MethodReferenceColumn reference) { + default QueryOperator select(MethodReferenceColumn reference) { return select(reference.getColumn()); } @@ -38,7 +37,7 @@ default SQLQueryOperator select(MethodReferenceColumn reference) { * @param alias alias * @return Select */ - default SQLQueryOperator select(MethodReferenceColumn reference, String alias) { + default QueryOperator select(MethodReferenceColumn reference, String alias) { return select(reference.getColumn(), alias); } @@ -47,7 +46,7 @@ default SQLQueryOperator select(MethodReferenceColumn reference, String a * * @return Select */ - default SQLQueryOperator selectAll() { + default QueryOperator selectAll() { return select(StringPool.ASTERISK); } @@ -57,8 +56,8 @@ default SQLQueryOperator selectAll() { * @param fieldName java variable name * @return Select */ - default SQLQueryOperator select(String fieldName) { - return select(SQLName.of(fieldName)); + default QueryOperator select(String fieldName) { + return select(DSLName.of(fieldName)); } /** @@ -67,7 +66,7 @@ default SQLQueryOperator select(String fieldName) { * @param sqlName sqlName * @return Select */ - SQLQueryOperator select(SQLName sqlName); + QueryOperator select(DSLName sqlName); /** * 添加'SELECT'条件 @@ -76,8 +75,8 @@ default SQLQueryOperator select(String fieldName) { * @param alias alias * @return Select */ - default SQLQueryOperator select(String fieldName, String alias) { - return select(SQLName.of(fieldName), alias); + default QueryOperator select(String fieldName, String alias) { + return select(DSLName.of(fieldName), alias); } /** @@ -87,7 +86,7 @@ default SQLQueryOperator select(String fieldName, String alias) { * @param alias alias * @return Select */ - SQLQueryOperator select(SQLName sqlName, String alias); + QueryOperator select(DSLName sqlName, String alias); /** @@ -96,7 +95,7 @@ default SQLQueryOperator select(String fieldName, String alias) { * @param fieldNames java variable name * @return Select */ - default SQLQueryOperator select(String[] fieldNames) { + default QueryOperator select(String[] fieldNames) { return select(Lists.newArrayList(fieldNames)); } @@ -106,8 +105,8 @@ default SQLQueryOperator select(String[] fieldNames) { * @param fieldNames java variable name * @return Select */ - default SQLQueryOperator select(Collection fieldNames) { - return selects(fieldNames.stream().map(SQLName::of).collect(Collectors.toList())); + default QueryOperator select(Collection fieldNames) { + return selects(fieldNames.stream().map(DSLName::of).toList()); } /** @@ -116,14 +115,14 @@ default SQLQueryOperator select(Collection fieldNames) { * @param sqlNames sqlNames * @return Select */ - SQLQueryOperator selects(Collection sqlNames); + QueryOperator selects(Collection sqlNames); /** * 添加 distinct * * @return Select */ - SQLQueryOperator distinct(); + QueryOperator distinct(); /** * 添加 distinct on @@ -132,7 +131,7 @@ default SQLQueryOperator select(Collection fieldNames) { * @param 实体类型 * @return Select */ - default SQLQueryOperator distinctOn(MethodReferenceColumn reference) { + default QueryOperator distinctOn(MethodReferenceColumn reference) { return distinctOn(reference.getColumn()); } @@ -144,7 +143,7 @@ default SQLQueryOperator distinctOn(MethodReferenceColumn reference) { * @param 实体类型 * @return Select */ - default SQLQueryOperator distinctOn(MethodReferenceColumn reference, String alias) { + default QueryOperator distinctOn(MethodReferenceColumn reference, String alias) { return distinctOn(reference.getColumn(), alias); } @@ -154,7 +153,7 @@ default SQLQueryOperator distinctOn(MethodReferenceColumn reference, Stri * @param fieldName java variable name * @return Select */ - default SQLQueryOperator distinctOn(String fieldName) { + default QueryOperator distinctOn(String fieldName) { return distinctOn(fieldName, fieldName); } @@ -165,8 +164,8 @@ default SQLQueryOperator distinctOn(String fieldName) { * @param alias 别名 * @return Select */ - default SQLQueryOperator distinctOn(String fieldName, String alias) { - return distinctOn(SQLName.of(fieldName), alias); + default QueryOperator distinctOn(String fieldName, String alias) { + return distinctOn(DSLName.of(fieldName), alias); } /** @@ -176,7 +175,7 @@ default SQLQueryOperator distinctOn(String fieldName, String alias) { * @param alias 别名 * @return Select */ - SQLQueryOperator distinctOn(SQLName sqlName, String alias); + QueryOperator distinctOn(DSLName sqlName, String alias); /** * 添加 min(field) alias @@ -185,7 +184,7 @@ default SQLQueryOperator distinctOn(String fieldName, String alias) { * @param 实体类型 * @return Select */ - default SQLQueryOperator min(MethodReferenceColumn reference) { + default QueryOperator min(MethodReferenceColumn reference) { return min(reference.getColumn()); } @@ -197,7 +196,7 @@ default SQLQueryOperator min(MethodReferenceColumn reference) { * @param 实体类型 * @return Select */ - default SQLQueryOperator min(MethodReferenceColumn reference, String alias) { + default QueryOperator min(MethodReferenceColumn reference, String alias) { return min(reference.getColumn(), alias); } @@ -207,7 +206,7 @@ default SQLQueryOperator min(MethodReferenceColumn reference, String alia * @param fieldName java variable name * @return Select */ - default SQLQueryOperator min(String fieldName) { + default QueryOperator min(String fieldName) { return min(fieldName, null); } @@ -218,7 +217,7 @@ default SQLQueryOperator min(String fieldName) { * @param alias 别名 * @return Select */ - default SQLQueryOperator min(String fieldName, String alias) { + default QueryOperator min(String fieldName, String alias) { return aggregate(Func.MIN_FUNCTION.getName(), fieldName, alias, null); } @@ -229,7 +228,7 @@ default SQLQueryOperator min(String fieldName, String alias) { * @param 实体类型 * @return Select */ - default SQLQueryOperator max(MethodReferenceColumn reference) { + default QueryOperator max(MethodReferenceColumn reference) { return max(reference.getColumn()); } @@ -241,7 +240,7 @@ default SQLQueryOperator max(MethodReferenceColumn reference) { * @param 实体类型 * @return Select */ - default SQLQueryOperator max(MethodReferenceColumn reference, String alias) { + default QueryOperator max(MethodReferenceColumn reference, String alias) { return max(reference.getColumn(), alias); } @@ -251,7 +250,7 @@ default SQLQueryOperator max(MethodReferenceColumn reference, String alia * @param fieldName java variable name * @return Select */ - default SQLQueryOperator max(String fieldName) { + default QueryOperator max(String fieldName) { return max(fieldName, fieldName); } @@ -262,7 +261,7 @@ default SQLQueryOperator max(String fieldName) { * @param alias 别名 * @return Select */ - default SQLQueryOperator max(String fieldName, String alias) { + default QueryOperator max(String fieldName, String alias) { return aggregate(Func.MAX_FUNCTION.getName(), fieldName, alias, null); } @@ -273,7 +272,7 @@ default SQLQueryOperator max(String fieldName, String alias) { * @param 实体类型 * @return Select */ - default SQLQueryOperator avg(MethodReferenceColumn reference) { + default QueryOperator avg(MethodReferenceColumn reference) { return avg(reference.getColumn()); } @@ -285,7 +284,7 @@ default SQLQueryOperator avg(MethodReferenceColumn reference) { * @param 实体类型 * @return Select */ - default SQLQueryOperator avg(MethodReferenceColumn reference, String alias) { + default QueryOperator avg(MethodReferenceColumn reference, String alias) { return avg(reference.getColumn(), alias); } @@ -295,7 +294,7 @@ default SQLQueryOperator avg(MethodReferenceColumn reference, String alia * @param fieldName java variable name * @return Select */ - default SQLQueryOperator avg(String fieldName) { + default QueryOperator avg(String fieldName) { return avg(fieldName, fieldName); } @@ -306,7 +305,7 @@ default SQLQueryOperator avg(String fieldName) { * @param alias 别名 * @return Select */ - default SQLQueryOperator avg(String fieldName, String alias) { + default QueryOperator avg(String fieldName, String alias) { return aggregate(Func.AVG_FUNCTION.getName(), fieldName, alias, null); } @@ -315,7 +314,7 @@ default SQLQueryOperator avg(String fieldName, String alias) { * * @return Select */ - default SQLQueryOperator count() { + default QueryOperator count() { return count(StringPool.ASTERISK, "count"); } @@ -326,7 +325,7 @@ default SQLQueryOperator count() { * @param 实体类型 * @return Select */ - default SQLQueryOperator count(MethodReferenceColumn reference) { + default QueryOperator count(MethodReferenceColumn reference) { return count(reference.getColumn(), null); } @@ -338,7 +337,7 @@ default SQLQueryOperator count(MethodReferenceColumn reference) { * @param 实体类型 * @return Select */ - default SQLQueryOperator count(MethodReferenceColumn reference, String alias) { + default QueryOperator count(MethodReferenceColumn reference, String alias) { return count(reference.getColumn(), alias); } @@ -348,7 +347,7 @@ default SQLQueryOperator count(MethodReferenceColumn reference, String al * @param fieldName java variable name * @return Select */ - default SQLQueryOperator count(String fieldName) { + default QueryOperator count(String fieldName) { return count(fieldName, null); } @@ -359,7 +358,7 @@ default SQLQueryOperator count(String fieldName) { * @param alias 别名 * @return Select */ - default SQLQueryOperator count(String fieldName, String alias) { + default QueryOperator count(String fieldName, String alias) { return aggregate(Func.COUNT_FUNCTION.getName(), fieldName, alias, null); } @@ -373,7 +372,7 @@ default SQLQueryOperator count(String fieldName, String alias) { * @return Select * @see Func */ - default SQLQueryOperator aggregate(String syntax, String fieldName, String alias, Distinct distinct) { + default QueryOperator aggregate(String syntax, String fieldName, String alias, Distinct distinct) { Func func = Func.of(syntax); if (func != null) { return aggregate(func, fieldName, alias, distinct); @@ -391,8 +390,8 @@ default SQLQueryOperator aggregate(String syntax, String fieldName, String alias * @return Select * @see Func */ - default SQLQueryOperator aggregate(Func syntax, String fieldName, String alias, Distinct distinct) { - return aggregate(syntax, SQLName.of(fieldName), alias, distinct); + default QueryOperator aggregate(Func syntax, String fieldName, String alias, Distinct distinct) { + return aggregate(syntax, DSLName.of(fieldName), alias, distinct); } /** @@ -405,7 +404,7 @@ default SQLQueryOperator aggregate(Func syntax, String fieldName, String alias, * @return Select * @see Func */ - SQLQueryOperator aggregate(Func syntax, SQLName sqlName, String alias, Distinct distinct); + QueryOperator aggregate(Func syntax, DSLName sqlName, String alias, Distinct distinct); // ============================== FROM PART ============================== @@ -416,7 +415,7 @@ default SQLQueryOperator aggregate(Func syntax, String fieldName, String alias, * @param alias 查询别名 * @return QueryOperator */ - SQLQueryOperator from(SQLQueryOperator fromTable, String alias); + QueryOperator from(QueryOperator fromTable, String alias); /** * FROM t1 left join t2 on t1.xx = t2.xx @@ -426,7 +425,7 @@ default SQLQueryOperator aggregate(Func syntax, String fieldName, String alias, * @param condition 条件 * @return QueryOperator */ - default SQLQueryOperator leftJoin(Table left, Table right, SQLBinaryCondition condition) { + default QueryOperator leftJoin(Table left, Table right, BinaryCondition condition) { return join(left, JoinType.LEFT_OUTER_JOIN, right, condition); } @@ -438,7 +437,7 @@ default SQLQueryOperator leftJoin(Table left, Table right, SQLBinaryCondition co * @param condition 条件 * @return QueryOperator */ - default SQLQueryOperator rightJoin(Table left, Table right, SQLBinaryCondition condition) { + default QueryOperator rightJoin(Table left, Table right, BinaryCondition condition) { return join(left, JoinType.RIGHT_OUTER_JOIN, right, condition); } @@ -450,7 +449,7 @@ default SQLQueryOperator rightJoin(Table left, Table right, SQLBinaryCondition c * @param condition 条件 * @return QueryOperator */ - default SQLQueryOperator leftJoinThen(String leftAlias, String rightName, SQLBinaryCondition condition) { + default QueryOperator leftJoinThen(String leftAlias, String rightName, BinaryCondition condition) { return leftJoinThen(leftAlias, rightName, rightName, condition); } @@ -463,7 +462,7 @@ default SQLQueryOperator leftJoinThen(String leftAlias, String rightName, SQLBin * @param condition 条件 * @return QueryOperator */ - default SQLQueryOperator leftJoinThen(String leftAlias, String rightName, String rightAlias, SQLBinaryCondition condition) { + default QueryOperator leftJoinThen(String leftAlias, String rightName, String rightAlias, BinaryCondition condition) { return joinThen(leftAlias, JoinType.LEFT_OUTER_JOIN, Table.of(rightName, rightAlias), condition); } @@ -475,7 +474,7 @@ default SQLQueryOperator leftJoinThen(String leftAlias, String rightName, String * @param condition 条件 * @return QueryOperator */ - default SQLQueryOperator rightJoinThen(String leftAlias, String rightName, SQLBinaryCondition condition) { + default QueryOperator rightJoinThen(String leftAlias, String rightName, BinaryCondition condition) { return joinThen(leftAlias, JoinType.RIGHT_OUTER_JOIN, Table.of(rightName, rightName), condition); } @@ -488,7 +487,7 @@ default SQLQueryOperator rightJoinThen(String leftAlias, String rightName, SQLBi * @param condition 条件 * @return QueryOperator */ - default SQLQueryOperator rightJoinThen(String leftAlias, String rightName, String rightAlias, SQLBinaryCondition condition) { + default QueryOperator rightJoinThen(String leftAlias, String rightName, String rightAlias, BinaryCondition condition) { return joinThen(leftAlias, JoinType.RIGHT_OUTER_JOIN, Table.of(rightName, rightAlias), condition); } @@ -500,7 +499,7 @@ default SQLQueryOperator rightJoinThen(String leftAlias, String rightName, Strin * @param condition 条件 * @return QueryOperator */ - default SQLQueryOperator joinThen(JoinType joinType, Table right, SQLBinaryCondition condition) { + default QueryOperator joinThen(JoinType joinType, Table right, BinaryCondition condition) { return joinThen("empty", joinType, right, condition); } @@ -513,7 +512,7 @@ default SQLQueryOperator joinThen(JoinType joinType, Table right, SQLBinaryCondi * @param condition 条件 * @return QueryOperator */ - default SQLQueryOperator joinThen(String leftAlias, JoinType joinType, Table right, SQLBinaryCondition condition) { + default QueryOperator joinThen(String leftAlias, JoinType joinType, Table right, BinaryCondition condition) { return join(Table.of(leftAlias, leftAlias), joinType, right, condition); } @@ -526,7 +525,7 @@ default SQLQueryOperator joinThen(String leftAlias, JoinType joinType, Table rig * @param condition 条件 * @return QueryOperator */ - SQLQueryOperator join(Table left, JoinType joinType, Table right, SQLBinaryCondition condition); + QueryOperator join(Table left, JoinType joinType, Table right, BinaryCondition condition); // ============================== ORDER PART ============================== @@ -536,7 +535,7 @@ default SQLQueryOperator joinThen(String leftAlias, JoinType joinType, Table rig * @param fieldName java variable name * @return Order对象 */ - default SQLQueryOperator by(String fieldName) { + default QueryOperator by(String fieldName) { return byDesc(fieldName); } @@ -546,7 +545,7 @@ default SQLQueryOperator by(String fieldName) { * @param reference 方法引用 * @return Order对象 */ - default SQLQueryOperator by(MethodReferenceColumn reference) { + default QueryOperator by(MethodReferenceColumn reference) { return by(reference.getColumn()); } @@ -556,7 +555,7 @@ default SQLQueryOperator by(MethodReferenceColumn reference) { * @param reference 方法引用 * @return Order对象 */ - default SQLQueryOperator byAsc(MethodReferenceColumn reference) { + default QueryOperator byAsc(MethodReferenceColumn reference) { return byAsc(reference.getColumn()); } @@ -566,7 +565,7 @@ default SQLQueryOperator byAsc(MethodReferenceColumn reference) { * @param fieldName java variable name * @return Order对象 */ - default SQLQueryOperator byAsc(String fieldName) { + default QueryOperator byAsc(String fieldName) { return orderBy(fieldName, OrderCondition.ASC); } @@ -576,7 +575,7 @@ default SQLQueryOperator byAsc(String fieldName) { * @param reference 方法引用 * @return Order对象 */ - default SQLQueryOperator byDesc(MethodReferenceColumn reference) { + default QueryOperator byDesc(MethodReferenceColumn reference) { return byDesc(reference.getColumn()); } @@ -586,7 +585,7 @@ default SQLQueryOperator byDesc(MethodReferenceColumn reference) { * @param fieldName java variable name * @return Order对象 */ - default SQLQueryOperator byDesc(String fieldName) { + default QueryOperator byDesc(String fieldName) { return orderBy(fieldName, OrderCondition.DESC); } @@ -597,7 +596,7 @@ default SQLQueryOperator byDesc(String fieldName) { * @param order 排序 * @return Order对象 */ - default SQLQueryOperator orderBy(MethodReferenceColumn reference, String order) { + default QueryOperator orderBy(MethodReferenceColumn reference, String order) { return orderBy(reference.getColumn(), order); } @@ -608,7 +607,7 @@ default SQLQueryOperator orderBy(MethodReferenceColumn reference, String orde * @param order 排序 * @return Order对象 */ - default SQLQueryOperator orderBy(String fieldName, String order) { + default QueryOperator orderBy(String fieldName, String order) { return orderBy(fieldName, OrderCondition.valueOf(order)); } @@ -619,7 +618,7 @@ default SQLQueryOperator orderBy(String fieldName, String order) { * @param orderCondition 排序条件 * @return Order对象 */ - default SQLQueryOperator orderBy(MethodReferenceColumn reference, OrderCondition orderCondition) { + default QueryOperator orderBy(MethodReferenceColumn reference, OrderCondition orderCondition) { return orderBy(reference.getColumn(), orderCondition); } @@ -630,8 +629,8 @@ default SQLQueryOperator orderBy(MethodReferenceColumn reference, OrderCo * @param orderCondition 排序条件 * @return Order对象 */ - default SQLQueryOperator orderBy(String fieldName, OrderCondition orderCondition) { - return orderBy(SQLName.of(fieldName), orderCondition); + default QueryOperator orderBy(String fieldName, OrderCondition orderCondition) { + return orderBy(DSLName.of(fieldName), orderCondition); } /** @@ -641,7 +640,7 @@ default SQLQueryOperator orderBy(String fieldName, OrderCondition orderCondition * @param orderCondition 排序条件 * @return Order对象 */ - SQLQueryOperator orderBy(SQLName sqlName, OrderCondition orderCondition); + QueryOperator orderBy(DSLName sqlName, OrderCondition orderCondition); // ============================== LIMIT PART ============================== @@ -652,18 +651,18 @@ default SQLQueryOperator orderBy(String fieldName, OrderCondition orderCondition * @param pageSize 页大小 * @return Limit */ - default SQLQueryOperator page(Long current, Long pageSize) { - return limit((current - 1) * pageSize, pageSize); + default QueryOperator page(Long current, Long pageSize) { + return limit(pageSize, (current - 1) * pageSize); } /** * LIMIT { number | ALL } * - * @param limit 起始行数 + * @param limit 限制查询的数量 * @param offset 偏移数 * @return Limit */ - SQLQueryOperator limit(Long limit, Long offset); + QueryOperator limit(Long limit, Long offset); // ============================== WHERE PART ============================== @@ -674,7 +673,7 @@ default SQLQueryOperator page(Long current, Long pageSize) { * @param reference 方法引用 * @return Group对象 */ - default SQLQueryOperator groupByOne(MethodReferenceColumn reference) { + default QueryOperator groupByOne(MethodReferenceColumn reference) { return groupByOnes(reference.getColumn()); } @@ -686,7 +685,7 @@ default SQLQueryOperator groupByOne(MethodReferenceColumn reference) { * @param fieldName java variable name * @return Group对象 */ - default SQLQueryOperator groupByOne(String fieldName) { + default QueryOperator groupByOne(String fieldName) { return groupByOnes(fieldName); } @@ -696,7 +695,7 @@ default SQLQueryOperator groupByOne(String fieldName) { * @param fieldNames java variable name数组 * @return Group对象 */ - default SQLQueryOperator groupByOnes(String... fieldNames) { + default QueryOperator groupByOnes(String... fieldNames) { return groupByOne(Lists.newArrayList(fieldNames)); } @@ -706,8 +705,8 @@ default SQLQueryOperator groupByOnes(String... fieldNames) { * @param fieldNames java variable name集合 * @return Group对象 */ - default SQLQueryOperator groupByOne(Collection fieldNames) { - return groupByOnes(fieldNames.stream().map(SQLName::of).collect(Collectors.toList())); + default QueryOperator groupByOne(Collection fieldNames) { + return groupByOnes(fieldNames.stream().map(DSLName::of).toList()); } /** @@ -716,6 +715,5 @@ default SQLQueryOperator groupByOne(Collection fieldNames) { * @param fieldNames java variable name集合 * @return Group对象 */ - SQLQueryOperator groupByOnes(Collection fieldNames); - + QueryOperator groupByOnes(Collection fieldNames); } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/UpdateOperator.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/UpdateOperator.java new file mode 100644 index 00000000..38f8f352 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/dml/UpdateOperator.java @@ -0,0 +1,162 @@ +package cc.allio.uno.data.orm.dsl.dml; + +import cc.allio.uno.core.function.lambda.MethodReferenceColumn; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.helper.PojoWrapper; +import com.google.common.collect.Maps; +import reactor.util.function.Tuple2; +import reactor.util.function.Tuples; + +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +/** + * SQL Update Operator + * + * @author jiangwei + * @date 2023/4/16 15:19 + * @since 1.1.4 + */ +public interface UpdateOperator extends PrepareOperator, TableOperator, WhereOperator { + + /** + * UPDATE VALUES + * + * @param reference key + * @param value value + * @return SQLUpdateOperator + */ + default UpdateOperator update(MethodReferenceColumn reference, Object value) { + return update(reference.getColumn(), getValueIfNullThenNullValue(value)); + } + + /** + * UPDATE VALUES + * + * @param fieldName fieldName + * @param value value + * @return SQLUpdateOperator + */ + default UpdateOperator update(String fieldName, Object value) { + return update(Tuples.of(fieldName, getValueIfNullThenNullValue(value))); + } + + /** + * UPDATE VALUES + * + * @param f1 f1 + * @param v1 v1 + * @return SQLUpdateOperator + */ + default UpdateOperator update(String f1, Object v1, String f2, Object v2) { + return update(Tuples.of(f1, getValueIfNullThenNullValue(v1)), Tuples.of(f2, getValueIfNullThenNullValue(v2))); + } + + /** + * UPDATE VALUES + * + * @param f1 f1 + * @param v1 v1 + * @param f2 f2 + * @param v2 v2 + * @return SQLUpdateOperator + */ + default UpdateOperator update(String f1, Object v1, String f2, Object v2, String f3, Object v3) { + return update( + Tuples.of(f1, getValueIfNullThenNullValue(v1)), + Tuples.of(f2, getValueIfNullThenNullValue(v2)), + Tuples.of(f3, getValueIfNullThenNullValue(v3))); + } + + /** + * UPDATE VALUES + * + * @param f1 f1 + * @param v1 v1 + * @param f2 f2 + * @param v2 v2 + * @param f3 f3 + * @param v3 v3 + * @param f4 f4 + * @param v4 v4 + * @return SQLUpdateOperator + */ + default UpdateOperator update(String f1, Object v1, String f2, Object v2, String f3, Object v3, String f4, Object v4) { + return update( + Tuples.of(f1, getValueIfNullThenNullValue(v1)), + Tuples.of(f2, getValueIfNullThenNullValue(v2)), + Tuples.of(f3, getValueIfNullThenNullValue(v3)), + Tuples.of(f4, getValueIfNullThenNullValue(v4))); + } + + /** + * UPDATE VALUES + * + * @param tuple2s Key value + * @return SQLUpdateOperator + */ + default UpdateOperator update(Tuple2... tuple2s) { + Map values = Maps.newHashMap(); + for (Tuple2 tuple2 : tuple2s) { + values.put(tuple2.getT1(), tuple2.getT2()); + } + return update(values); + } + + /** + * UPDATE VALUES + * + * @param pojo pojo + * @return SQLUpdateOperator + */ + default UpdateOperator updatePojo(Object pojo) { + PojoWrapper pojoWrapper = PojoWrapper.getInstance(pojo); + List notPkColumns = pojoWrapper.getNotPkColumns(); + Map values = Maps.newLinkedHashMap(); + for (ColumnDef notPkColumn : notPkColumns) { + Object value = pojoWrapper.getValueByColumn(notPkColumn); + values.put(notPkColumn.getDslName(), value); + } + return from(pojoWrapper.getTable()).updates(values); + } + + /** + * UPDATE VALUES,将会过滤为空的值 + * + * @param values Key value + * @return SQLUpdateOperator + */ + default UpdateOperator update(Map values) { + Map updates = Maps.newLinkedHashMap(); + for (Map.Entry entry : values.entrySet()) { + updates.put(DSLName.of(entry.getKey()), entry.getValue()); + } + return updates(updates); + } + + /** + * UPDATE VALUES + * + * @param values Key value + * @return SQLUpdateOperator + */ + UpdateOperator updates(Map values); + + /** + * @see #strictFill(String, Supplier) + */ + default UpdateOperator strictFill(String f, Object v) { + return strictFill(f, () -> v); + } + + /** + * 当使用了{@link #updates(Map)}等API时, + * 如果需要对某一个或多个字段进行其他方式的设置值,此时需要调用该API进行重新填充 + * + * @param f 字段名 + * @param v 字段值 + * @return SQLInsertOperator + */ + UpdateOperator strictFill(String f, Supplier v); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/exception/DDLException.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/exception/DDLException.java new file mode 100644 index 00000000..5d5ea9d8 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/exception/DDLException.java @@ -0,0 +1,31 @@ +package cc.allio.uno.data.orm.dsl.exception; + +/** + * DDL exception 是一个运行时异常 + * + * @author jiangwei + * @date 2024/2/8 13:57 + * @since 1.1.6 + */ +public class DDLException extends RuntimeException { + + public DDLException() { + super(); + } + + public DDLException(String message) { + super(message); + } + + public DDLException(String message, Throwable cause) { + super(message, cause); + } + + public DDLException(Throwable cause) { + super(cause); + } + + protected DDLException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/exception/DMLException.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/exception/DMLException.java new file mode 100644 index 00000000..de13e905 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/exception/DMLException.java @@ -0,0 +1,31 @@ +package cc.allio.uno.data.orm.dsl.exception; + +/** + * DML exception 是一个运行时异常 + * + * @author jiangwei + * @date 2024/2/8 13:58 + * @since 1.1.6 + */ +public class DMLException extends RuntimeException { + + public DMLException() { + super(); + } + + public DMLException(String message) { + super(message); + } + + public DMLException(String message, Throwable cause) { + super(message, cause); + } + + public DMLException(Throwable cause) { + super(cause); + } + + protected DMLException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLException.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/exception/DSLException.java similarity index 54% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLException.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/exception/DSLException.java index 2be39540..adb81835 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/SQLException.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/exception/DSLException.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl.exception; /** * SQL相关操作时抛出的异常,他是一个运行时异常 @@ -7,25 +7,25 @@ * @date 2022/9/30 10:44 * @since 1.1.0 */ -public class SQLException extends RuntimeException { +public class DSLException extends RuntimeException { - public SQLException() { + public DSLException() { super(); } - public SQLException(String message) { + public DSLException(String message) { super(message); } - public SQLException(String message, Throwable cause) { + public DSLException(String message, Throwable cause) { super(message, cause); } - public SQLException(Throwable cause) { + public DSLException(Throwable cause) { super(cause); } - protected SQLException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + protected DSLException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefListResolve.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefListResolve.java new file mode 100644 index 00000000..348b90d1 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefListResolve.java @@ -0,0 +1,18 @@ +package cc.allio.uno.data.orm.dsl.helper; + +import java.lang.annotation.*; + +/** + * 加在pojo上,由它自身提供column的定义 + * + * @author jiangwei + * @date 2024/2/6 20:39 + * @since 1.1.6 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ColumnDefListResolve { + + Class value(); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefListResolver.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefListResolver.java new file mode 100644 index 00000000..5fda6881 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefListResolver.java @@ -0,0 +1,23 @@ +package cc.allio.uno.data.orm.dsl.helper; + +import cc.allio.uno.data.orm.dsl.ColumnDef; + +import java.util.List; + +/** + * 根据class解析出column的定义 + * + * @author jiangwei + * @date 2024/2/6 20:40 + * @since 1.1.6 + */ +public interface ColumnDefListResolver { + + /** + * 解析动作 + * + * @param pojoClass pojoClass + * @return column list + */ + List resolve(Class pojoClass); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefResolve.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefResolve.java new file mode 100644 index 00000000..bea6caa3 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefResolve.java @@ -0,0 +1,18 @@ +package cc.allio.uno.data.orm.dsl.helper; + +import java.lang.annotation.*; + +/** + * 用于在{@link PojoWrapper#getColumnDefs()}进行使用 + * + * @author jiangwei + * @date 2024/2/6 20:07 + * @since 1.1.6 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ColumnDefResolve { + + Class value(); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefResolver.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefResolver.java new file mode 100644 index 00000000..98cbadbe --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/ColumnDefResolver.java @@ -0,0 +1,24 @@ +package cc.allio.uno.data.orm.dsl.helper; + +import cc.allio.uno.data.orm.dsl.ColumnDef; + +import java.lang.reflect.Field; + +/** + * 根据指定的{@link java.lang.reflect.Field}解析出{@link cc.allio.uno.data.orm.dsl.ColumnDef} + * + * @author jiangwei + * @date 2024/2/6 20:08 + * @see ColumnDefResolve + * @since 1.1.6 + */ +public interface ColumnDefResolver { + + /** + * 执行解析动作 + * + * @param field field + * @return ColumnDef instance or null + */ + ColumnDef resolve(Field field); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoInspect.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoInspect.java new file mode 100644 index 00000000..c9494db1 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoInspect.java @@ -0,0 +1,24 @@ +package cc.allio.uno.data.orm.dsl.helper; + +/** + * POJO相关的检查器 + * + * @author jiangwei + * @date 2024/2/16 20:42 + * @since 1.1.6 + */ +public interface PojoInspect { + + /** + * 检查是否是 POJO + * + * @param maybePojo maybePojo + * @return true if pojo + */ + boolean isPojo(Class maybePojo); + + /** + * 是否使用缓存 + */ + boolean useCache(); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoInspection.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoInspection.java new file mode 100644 index 00000000..15c0f90b --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoInspection.java @@ -0,0 +1,18 @@ +package cc.allio.uno.data.orm.dsl.helper; + +import java.lang.annotation.*; + +/** + * 加在实体类,决定该pojo如何进行检查 + * + * @author jiangwei + * @date 2024/2/6 20:39 + * @since 1.1.6 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface PojoInspection { + + Class value(); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoResolver.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoResolver.java new file mode 100644 index 00000000..a0db60a2 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoResolver.java @@ -0,0 +1,38 @@ +package cc.allio.uno.data.orm.dsl.helper; + +/** + * pojo相关的Resolver + * + * @author jiangwei + * @date 2024/2/6 23:32 + * @since 1.1.6 + */ +public interface PojoResolver { + + /** + * 获取TableResolver实例 + * + * @return TableResolver + */ + default TableResolver obtainTableResolver() { + return null; + } + + /** + * 获取ColumnDefListResolver实例 + * + * @return ColumnDefListResolver + */ + default ColumnDefListResolver obtainColumnDefListResolver() { + return null; + } + + /** + * 获取ColumnDefResolver实例 + * + * @return ColumnDefResolver + */ + default ColumnDefResolver obtainColumnDefResolver() { + return null; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoWrapper.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoWrapper.java new file mode 100644 index 00000000..940ffe6c --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/PojoWrapper.java @@ -0,0 +1,550 @@ +package cc.allio.uno.data.orm.dsl.helper; + +import cc.allio.uno.core.StringPool; +import cc.allio.uno.core.api.Step; +import cc.allio.uno.core.bean.MapWrapper; +import cc.allio.uno.core.bean.ObjectWrapper; +import cc.allio.uno.core.bean.ValueWrapper; +import cc.allio.uno.core.type.Types; +import cc.allio.uno.core.util.*; +import cc.allio.uno.core.util.template.ExpressionTemplate; +import cc.allio.uno.core.util.template.Tokenizer; +import cc.allio.uno.data.orm.annotation.LogicDelete; +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Table; +import cc.allio.uno.data.orm.dsl.dialect.TypeTranslator; +import cc.allio.uno.data.orm.dsl.dialect.TypeTranslatorHolder; +import cc.allio.uno.data.orm.dsl.type.DataType; +import cc.allio.uno.data.orm.dsl.type.JdbcType; +import cc.allio.uno.data.orm.dsl.type.DSLType; +import cc.allio.uno.data.orm.dsl.type.TypeRegistry; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import jakarta.persistence.Column; +import jakarta.persistence.Id; +import lombok.Getter; +import org.springframework.core.annotation.AnnotationUtils; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.util.function.Tuple2; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.util.*; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * 定义Pojo与SQL相关的操作 + *

    注:pojo的字段驼峰

    + *

    包含如下操作集(获取基于{@link Object}pojo对象或者{@link Class}pojoClass):

    + *
      + *
    • 获取{@link Table}
    • + *
    • 获取{@link ColumnDef}
    • + *
    • 获取主键的{@link ColumnDef}
    • + *
    • 基于{@link ColumnDef}获取对应的值
    • + *
    + * + * @author jiangwei + * @date 2023/7/4 17:14 + * @see #getInstance(Object) + * @since 1.1.4 + */ +public class PojoWrapper implements ValueWrapper { + + private static final String ID = "id"; + @Getter + private T pojo; + private Class pojoClass; + private List pojoFields; + @Getter + private Table table; + // 字段集合 + @Getter + private List columnDefs; + // 主键字段 + @Getter + private ColumnDef pkColumn; + // 删除标志字段 + @Getter + private ColumnDef deletedColumn; + // 非主键字段 + @Getter + private List notPkColumns; + + // 内置ValueWrapper做装饰作用 + private final ValueWrapper valueWrapper; + + static final ExpressionTemplate DOLLAR_TEMPLATE = ExpressionTemplate.createTemplate(Tokenizer.DOLLAR_BRACE); + static final PojoInspect DEFAULT_POJO_INSPECT = new DefaultPojoInspect(); + static final Map, PojoInspect> POJO_INSPECTS = Maps.newConcurrentMap(); + static final Map, TableResolver> TABLE_RESOLVES = Maps.newConcurrentMap(); + static final Map, ColumnDefListResolver> CLASS_COLUMN_LIST_RESOLVERS = Maps.newConcurrentMap(); + static final Map COLUMN_RESOLVES = Maps.newConcurrentMap(); + // 存储以Class为key,PojoWrapper为实例的Map缓存 + static final Map, PojoWrapper> POJO_INSTANCES = Maps.newConcurrentMap(); + + PojoWrapper(T pojo) { + if (Types.isMap(pojo.getClass())) { + this.valueWrapper = new MapWrapper((Map) pojo); + } else { + this.valueWrapper = new ObjectWrapper(pojo); + } + this.pojo = pojo; + init(pojo.getClass()); + } + + PojoWrapper(Class pojoClass) { + init(pojoClass); + if (Types.isMap(pojoClass)) { + this.valueWrapper = new MapWrapper(); + } else { + this.valueWrapper = new ObjectWrapper(pojoClass); + } + } + + void init(Class pojoClass) { + this.pojoClass = pojoClass; + this.pojoFields = FieldUtils.getAllFieldsList(pojoClass); + this.columnDefs = obtainColumnDefs(); + this.table = obtainTable(); + this.pkColumn = columnDefs.stream().filter(ColumnDef::isPk).findFirst().orElse(null); + this.deletedColumn = columnDefs.stream().filter(ColumnDef::isDeleted).findFirst().orElse(null); + this.notPkColumns = columnDefs.stream().filter(columnDef -> !columnDef.isPk()).toList(); + } + + /** + * 获取Primary Key字段值 + */ + public Object getPKValue() { + ColumnDef id = getPkColumn(); + return getForce(id.getDslName().format(DSLName.HUMP_FEATURE)); + } + + /** + * 根据column名称获取对应的数据 + * + * @param column the column(需要驼峰) + * @return the value + */ + public Object getValueByColumn(String column) { + return getForce(column); + } + + /** + * 根据column名称获取对应的数据 + * + * @param columnDef columnDef + * @return the value + */ + public Object getValueByColumn(ColumnDef columnDef) { + return getForce(DSLName.of(columnDef.getDslName(), DSLName.HUMP_FEATURE).format()); + } + + /** + * 获取该Pojo对象的表名 + *

    按照以下三种步骤进行解析

    + *
      + *
    1. 优先从{@link PojoResolver#obtainTableResolver()}中取值,要求{@link #pojo}不为null
    2. + *
    3. 再次从{@link TableResolve}中取值
    4. + *
    5. 最后尝试按照jpa {@link jakarta.persistence.Table}注解中取值
    6. + *
    + * + * @return Table instance + * @see TableResolve + * @see PojoResolver + */ + private Table obtainTable() { + return Step.
    start() + .then(() -> { + if (pojo instanceof PojoResolver pojoResolver) { + return Optional.ofNullable(pojoResolver.obtainTableResolver()) + .map(c -> c.resolve(pojoClass)) + .orElse(null); + } + return null; + }) + .then(() -> { + TableResolve tableResolve = AnnotationUtils.findAnnotation(pojoClass, TableResolve.class); + return Optional.ofNullable(tableResolve) + .flatMap(e -> { + TableResolver tableResolver = + TABLE_RESOLVES.computeIfAbsent( + pojoClass, + k -> { + Class tableResolverClass = tableResolve.value(); + return Optional.ofNullable(tableResolverClass) + .map(ClassUtils::newInstance) + .orElse(null); + }); + return Optional.ofNullable(tableResolver); + }) + .map(r -> r.resolve(pojoClass)) + .orElse(null); + }) + .then(() -> { + // 取jpa注解 + jakarta.persistence.Table tableAnno = AnnotationUtils.findAnnotation(pojoClass, jakarta.persistence.Table.class); + String indexName = StringPool.EMPTY; + Table table = new Table(); + if (tableAnno != null) { + indexName = tableAnno.name(); + table.setCatalog(tableAnno.catalog()); + table.setSchema(tableAnno.schema()); + } + if (StringUtils.isEmpty(indexName)) { + // 取类名并转换为下划线命名 + indexName = DSLName.of(pojoClass.getSimpleName(), DSLName.UNDERLINE_FEATURE).format(); + } + if (pojo != null) { + indexName = DOLLAR_TEMPLATE.parseTemplate(indexName, findMapValuesForce()); + } + table.setName(DSLName.of(indexName)); + return table; + }) + .stop(); + } + + /** + * 获取该pojo字段的解析的sql字段 + *

    按照以下三种步骤进行解析

    + *
      + *
    1. 优先从{@link PojoResolver#obtainColumnDefListResolver()} 中取值,要求{@link #pojo}不为null
    2. + *
    3. 再次从{@link ColumnDefListResolve}中取值
    4. + *
    5. 或者按照{@link #pojoFields}调用{@link #createColumnDef(Field)}获取
    6. + *
    + */ + private List obtainColumnDefs() { + return Optional.ofNullable(columnDefs) + .orElseGet(() -> + Step.>start() + .then(() -> { + if (pojo instanceof PojoResolver pojoResolver) { + return Optional.ofNullable(pojoResolver.obtainColumnDefListResolver()) + .map(c -> c.resolve(pojoClass)) + .orElse(null); + } + return null; + }) + .then(() -> { + ColumnDefListResolve columnDefListResolve = AnnotationUtils.findAnnotation(pojoClass, ColumnDefListResolve.class); + return Optional.ofNullable(columnDefListResolve) + .flatMap(c -> { + ColumnDefListResolver columnDefListResolver = + CLASS_COLUMN_LIST_RESOLVERS.computeIfAbsent( + pojoClass, + k -> { + Class columnDefResolverClass = columnDefListResolve.value(); + return Optional.ofNullable(columnDefResolverClass) + .map(ClassUtils::newInstance) + .orElse(null); + }); + return Optional.ofNullable(columnDefListResolver); + }) + .map(r -> r.resolve(pojoClass)) + .orElse(Collections.emptyList()); + }) + .then(() -> + pojoFields.stream() + .map(this::createColumnDef) + .toList()) + .stop()); + } + + /** + * 根据java{@link Field}实例创建{@link ColumnDef}实例 + *

    按照以下三种步骤进行解析

    + *
      + *
    1. 优先从{@link PojoResolver#obtainColumnDefResolver()} 中取值,要求{@link #pojo}不为null
    2. + *
    3. 再次从{@link ColumnDefResolve}中取值
    4. + *
    5. + *

      检测指定字段的值是否包含以下jpa注解

      + *
        + *
      • {@link Id}
      • + *
      • {@link Column}
      • + *
      + *
    6. + *
    7. + *

      包含自定义注解

      + *
        + *
      • {@link LogicDelete}
      • + *
      + *
    8. + *
    + * + * @param field the field + */ + private ColumnDef createColumnDef(Field field) { + return Step.start() + .then(() -> { + if (pojo instanceof PojoResolver pojoResolver) { + return Optional.ofNullable(pojoResolver.obtainColumnDefResolver()) + .map(c -> c.resolve(field)) + .orElse(null); + } + return null; + }) + .then(() -> { + ColumnDefResolve columnDefResolve = AnnotationUtils.findAnnotation(field, ColumnDefResolve.class); + // ColumnDefResolve注解上解析器优先级最高 + return Optional.ofNullable(columnDefResolve) + .flatMap(c -> { + ColumnDefResolver columnDefResolver = COLUMN_RESOLVES.computeIfAbsent( + field, + k -> { + Class columnResolverClass = columnDefResolve.value(); + return Optional.ofNullable(columnResolverClass) + .map(ClassUtils::newInstance) + .orElse(null); + }); + return Optional.ofNullable(columnDefResolver); + }) + .map(c -> c.resolve(field)) + .orElse(null); + }) + .then(() -> { + ColumnDef.ColumnDefBuilder builder = ColumnDef.builder(); + // 解析id + Id id = field.getAnnotation(Id.class); + if (id != null) { + builder.isPk(true); + } + // 如果当前没有被@Id注解表示,尝试判断当前字段的名称是否为id + if (id == null && (field.getName().equals(ID))) { + builder.isPk(true); + } + LogicDelete logicDelete = field.getAnnotation(LogicDelete.class); + if (logicDelete != null) { + builder.isDeleted(true); + builder.undeleted(logicDelete.undeleted()); + builder.deleted(logicDelete.deleted()); + } + // 默认按照下划线进行处理 + String maybeColumnName = field.getName(); + builder.dslName(DSLName.of(maybeColumnName, DSLName.UNDERLINE_FEATURE)); + // 解析是否包含@Column or @TableField + Column column = field.getAnnotation(Column.class); + if (column != null) { + builder.isNonNull(!column.nullable()); + builder.isNull(column.nullable()); + builder.isUnique(column.unique()); + String columnName = column.name(); + if (StringUtils.isNotBlank(columnName)) { + builder.dslName(DSLName.of(columnName, DSLName.UNDERLINE_FEATURE)); + } + } + // 解析该字段的类型 + Collection jdbcTypes = TypeRegistry.getInstance().guessJdbcType(field.getType()); + if (CollectionUtils.isNotEmpty(jdbcTypes)) { + // 只匹配第一个 + JdbcType jdbcType = Lists.newArrayList(jdbcTypes).get(0); + DSLType guessSQLType = DSLType.getByJdbcCode(jdbcType.getJdbcCode()); + TypeTranslator translator = TypeTranslatorHolder.getTypeTranslator(); + DSLType sqlType = translator.translate(guessSQLType); + DataType type = DataType.create(sqlType); + builder.dataType(type); + } + return builder.build(); + }) + .stop(); + } + + /** + * 基于{@link #getColumnDefs()}转换为{@link DSLName} + * + * @return dsl name collection + */ + public Collection getColumnDSLName() { + if (ObjectUtils.isNotEmpty(columnDefs)) { + return columnDefs.stream().map(ColumnDef::getDslName).toList(); + } + return Collections.emptyList(); + } + + /** + * 获取columns values 集合 + * + * @return Object + */ + public List getColumnValues() { + return columnDefs.stream() + .map(column -> getForce(column.getDslName().format(DSLName.HUMP_FEATURE))) + .toList(); + } + + @Override + public Boolean contains(String name) { + return valueWrapper.contains(name); + } + + @Override + public PropertyDescriptor find(String name, Class clazz) { + return valueWrapper.find(name, clazz); + } + + @Override + public Mono get(String name, Class fieldType) { + return valueWrapper.get(name, fieldType); + } + + @Override + public Mono set(String name, Object... value) { + return valueWrapper.set(name, value); + } + + @Override + public Mono setCoverage(String name, boolean forceCoverage, Object... value) { + return valueWrapper.setCoverage(name, forceCoverage, value); + } + + @Override + public Flux findAll() { + return valueWrapper.findAll(); + } + + @Override + public Flux> findTupleValues() { + return valueWrapper.findTupleValues(); + } + + @Override + public Object getTarget() { + return valueWrapper.getTarget(); + } + + /** + * 获取{@link PojoWrapper}实例。如果{@link PojoInspect#useCache()}为true,则使用缓存内的{@link PojoWrapper} + * + * @param pojo pojo + * @param 实体类型 + * @return PojoWrapper + * @throws IllegalArgumentException 当通过{@link PojoInspect#isPojo(Class)}不通过时抛出 + */ + public static PojoWrapper getInstance(T pojo) { + check(pojo.getClass()); + // TODO 需要考虑PojoWrapper大量创建的问题,但如果采取缓存则需要考虑加锁设置pojo实例 + return new PojoWrapper<>(pojo); + } + + /** + * 获取{@link PojoWrapper}实例。如果{@link PojoInspect#useCache()}为true,则使用缓存内的{@link PojoWrapper} + * + * @param pojoClass pojoClass + * @param 实体类型 + * @return PojoWrapper + * @throws IllegalArgumentException 当通过{@link PojoInspect#isPojo(Class)}不通过时抛出 + */ + public static PojoWrapper getInstance(Class pojoClass) { + return checkPojoAndGetInstanceUseCache(pojoClass, () -> new PojoWrapper<>(pojoClass)); + } + + /** + * 检查pojo是否合法,如果合法则获取{@link PojoWrapper}实例 + * + * @param pojoClass pojoClass + * @param creator 创建{@link PojoWrapper} + * @param 实例 + * @return PojoWrapper + */ + private static PojoWrapper checkPojoAndGetInstanceUseCache(Class pojoClass, Supplier> creator) { + PojoInspect pojoInspect = getPojoInspection(pojoClass); + check(pojoClass); + boolean useCache = pojoInspect.useCache(); + if (useCache) { + return (PojoWrapper) POJO_INSTANCES.computeIfAbsent(pojoClass, k -> creator.get()); + } else { + return creator.get(); + } + } + + private static void check(Class pojoClass) { + PojoInspect pojoInspect = getPojoInspection(pojoClass); + boolean isPojo = pojoInspect.isPojo(pojoClass); + if (Boolean.FALSE.equals(isPojo)) { + throw new IllegalArgumentException(String.format("given pojo is fake, it is %s", pojoClass)); + } + } + + private static PojoInspect getPojoInspection(Class pojoClass) { + PojoInspection pojoInspection = AnnotationUtils.findAnnotation(pojoClass, PojoInspection.class); + return Optional.ofNullable(pojoInspection) + .map(p -> { + Class pojoInspectClass = p.value(); + return POJO_INSPECTS.computeIfAbsent(pojoClass, k -> Optional.ofNullable(pojoInspectClass).map(ClassUtils::newInstance).orElse(null)); + }) + .orElse(DEFAULT_POJO_INSPECT); + + } + + /** + * 获取Primary Key字段 + * + * @return SQLColumnDef + */ + public static ColumnDef findPKColumn(Class pojoClass) { + return getInstance(pojoClass).getPkColumn(); + } + + /** + * 寻找非PK字段集 + * + * @return 字段集合 + */ + public static List findNotPkColumns(Class pojoClass) { + return getInstance(pojoClass).getNotPkColumns(); + } + + /** + * 获取每个POJO的表名 + * + * @param pojoClass pojoClass + * @return 表名 + */ + public static String findTable(Class pojoClass) { + return getInstance(pojoClass).getTable().getName().format(); + } + + /** + * 根据column名称获取对应的数据 + * + * @param column the column(需要驼峰) + * @return the value + */ + public static Object findValueByColumn(Class pojoClass, String column) { + return getInstance(pojoClass).getValueByColumn(column); + } + + /** + * 获取pojo的所有字段的{@link DSLName} + * + * @param pojoClass pojoClass + * @return the columns + */ + public static Collection findColumns(Class pojoClass) { + return getInstance(pojoClass).getColumnDSLName(); + } + + /** + * 获取pojo的所有字段的{@link DSLName} + * + * @param pojoClass pojoClass + * @return the columns + */ + public static ColumnDef findDeleteColumn(Class pojoClass) { + return getInstance(pojoClass).getDeletedColumn(); + } + + static class DefaultPojoInspect implements PojoInspect { + + @Override + public boolean isPojo(Class maybePojo) { + return Types.isBean(maybePojo); + } + + @Override + public boolean useCache() { + return true; + } + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/TableResolve.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/TableResolve.java new file mode 100644 index 00000000..f7882bf6 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/TableResolve.java @@ -0,0 +1,18 @@ +package cc.allio.uno.data.orm.dsl.helper; + +import java.lang.annotation.*; + +/** + * 在{@link PojoWrapper#findTable(Class)}时使用 + * + * @author jiangwei + * @date 2024/2/6 20:06 + * @since 1.1.6 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface TableResolve { + + Class value(); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/TableResolver.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/TableResolver.java new file mode 100644 index 00000000..01efe3dc --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/helper/TableResolver.java @@ -0,0 +1,22 @@ +package cc.allio.uno.data.orm.dsl.helper; + +import cc.allio.uno.data.orm.dsl.Table; + +/** + * 根据指定的实体类,解析出表名 + * + * @author jiangwei + * @date 2024/2/6 20:05 + * @see TableResolve + * @since 1.1.6 + */ +public interface TableResolver { + + /** + * 执行解析动作 + * + * @param pojoClass pojoClass + * @return table or null + */ + Table resolve(Class pojoClass); +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/ArrayJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ArrayJavaType.java similarity index 72% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/ArrayJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ArrayJavaType.java index f909da87..65cdf700 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/ArrayJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ArrayJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import java.util.Objects; @@ -15,6 +15,11 @@ public Class getJavaType() { throw new UnsupportedOperationException("array non support operator"); } + @Override + public boolean equalsTo(Class otherJavaType) { + return otherJavaType.isArray(); + } + @Override public boolean equals(Object o) { return Objects.equals(this, o); diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/BigDecimalJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/BigDecimalJavaType.java similarity index 65% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/BigDecimalJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/BigDecimalJavaType.java index 593f27a6..2df9b3d1 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/BigDecimalJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/BigDecimalJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -17,4 +17,9 @@ public class BigDecimalJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.BIG_DECIMAL; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return BigDecimal.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/BooleanJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/BooleanJavaType.java similarity index 54% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/BooleanJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/BooleanJavaType.java index e2377cde..10f36fcb 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/BooleanJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/BooleanJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -14,4 +14,10 @@ public class BooleanJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.BOOLEAN; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Boolean.class.isAssignableFrom(otherJavaType) + || boolean.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/ByteJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ByteJavaType.java similarity index 53% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/ByteJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ByteJavaType.java index 3cf1a1c6..f8f24f35 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/ByteJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ByteJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -14,4 +14,10 @@ public class ByteJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.BYTE; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Byte.class.isAssignableFrom(otherJavaType) + || byte.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/CharArrayJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/CharArrayJavaType.java similarity index 80% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/CharArrayJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/CharArrayJavaType.java index e94cbf50..46feb1d1 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/CharArrayJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/CharArrayJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; /** * 标识类,标识为char[]类型 diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DBType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DBType.java new file mode 100644 index 00000000..f04dfca7 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DBType.java @@ -0,0 +1,151 @@ +package cc.allio.uno.data.orm.dsl.type; + +import cc.allio.uno.core.StringPool; +import cc.allio.uno.core.env.Envs; +import cc.allio.uno.core.util.template.ExpressionTemplate; +import cc.allio.uno.core.util.template.Tokenizer; +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import org.springframework.boot.jdbc.DatabaseDriver; + +import java.util.List; + +/** + * 定义数据库类型 + * + * @author jiangwei + * @date 2023/2/23 16:36 + * @since 1.1.4 + */ +public interface DBType { + + /** + * 数据库类型配置标识 + * + * @see #MYSQL + * @see #POSTGRESQL + */ + String DB_TYPE_CONFIG_KEY = "allio.uno.data.orm.dbtype"; + + ExpressionTemplate JDBC_URL_TEMPLATE_PARSER = ExpressionTemplate.createTemplate(Tokenizer.HASH_BRACE); + String ADDRESS = "address"; + String IP_PORTS_TEMPLATE = "#{" + ADDRESS + "}"; + String DATABASE_NAME = "database_name"; + String DATABASE_NAME_TEMPLATE = "#{" + DATABASE_NAME + "}"; + + DBType MYSQL = new DefaultDBType("MySQL", DatabaseDriver.MYSQL.getDriverClassName(), DBCategory.RELATIONAL, "jdbc:mysql://" + IP_PORTS_TEMPLATE + "/" + DATABASE_NAME_TEMPLATE + "?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true"); + DBType POSTGRESQL = new DefaultDBType("PostgreSQL", DatabaseDriver.POSTGRESQL.getDriverClassName(), DBCategory.RELATIONAL, "jdbc:postgresql://" + IP_PORTS_TEMPLATE + "/" + DATABASE_NAME_TEMPLATE + "?stringtype=unspecified"); + DBType SQLSERVER = new DefaultDBType("SQLServer", DatabaseDriver.SQLSERVER.getDriverClassName(), DBCategory.RELATIONAL, "jdbc:sqlserver://" + IP_PORTS_TEMPLATE + ";database=" + DATABASE_NAME_TEMPLATE); + DBType ORACLE = new DefaultDBType("Oracle", DatabaseDriver.ORACLE.getDriverClassName(), DBCategory.RELATIONAL, "jdbc:oracle:thin:@//" + IP_PORTS_TEMPLATE + "/" + DATABASE_NAME_TEMPLATE); + DBType OPEN_GAUSS = new DefaultDBType(" OpenGauss", "org.opengauss.Driver", DBCategory.RELATIONAL, ""); + DBType DB2 = new DefaultDBType(" Db2", DatabaseDriver.DB2.getDriverClassName(), DBCategory.RELATIONAL, "jdbc:db2://" + IP_PORTS_TEMPLATE + "/" + DATABASE_NAME_TEMPLATE); + DBType MARIADB = new DefaultDBType("MariaDB", DatabaseDriver.MARIADB.getDriverClassName(), DBCategory.RELATIONAL, "jdbc:mariadb://" + IP_PORTS_TEMPLATE + "/" + DATABASE_NAME_TEMPLATE); + DBType SQLITE = new DefaultDBType("SQLite", DatabaseDriver.SQLITE.getDriverClassName(), DBCategory.RELATIONAL, "jdbc:sqlite::memory:"); + DBType H2 = new DefaultDBType("H2", DatabaseDriver.H2.getDriverClassName(), DBCategory.RELATIONAL, "jdbc:h2:mem:" + DATABASE_NAME_TEMPLATE + ";IGNORECASE=TRUE"); + DBType ELASTIC_SEARCH = new DefaultDBType("ElasticSearch", StringPool.EMPTY, DBCategory.SEARCH_ENGINES, ""); + DBType MONGODB = new DefaultDBType("Mongodb", "org.mongodb.Driver", DBCategory.DOCUMENT, ""); + DBType TD_ENGINE = new DefaultDBType("TDEngine", StringPool.EMPTY, DBCategory.TIME_SERIES, ""); + DBType INFLUXDB = new DefaultDBType("Influxdb", StringPool.EMPTY, DBCategory.TIME_SERIES, ""); + DBType NEO4J = new DefaultDBType("Neo4j", StringPool.EMPTY, DBCategory.GRAPH, ""); + DBType REDIS = new DefaultDBType("Redis", StringPool.EMPTY, DBCategory.KEY_VALUE, ""); + + /** + * 类型集合 + */ + List ALL_DB_TYPES = Lists.newArrayList(MYSQL, POSTGRESQL, SQLSERVER, ORACLE, OPEN_GAUSS, DB2, MARIADB, SQLITE, H2, ELASTIC_SEARCH, MONGODB, TD_ENGINE, INFLUXDB, NEO4J, REDIS); + + /** + * 获取数据库类型名称 + * + * @return 数据库全名称 + */ + String getName(); + + /** + * 如果存在则获取对应的驱动类名 + */ + String getDriverClassName(); + + /** + * 数据库类别 + * + * @return DBCategory + */ + DBCategory getCategory(); + + /** + * 解析jdbcUrl模板 + * + * @param address 连接ip与端口,如果是集群注意需按照对应集群的ip端口序列写法,比如:'192.168.2.1:3306,192.168.2.2:3306' + * @param dataBaseName 数据名称 + * @return 解析后的模板 + */ + String parseTemplate(String address, String dataBaseName); + + /** + * 获取当前项目中的数据库类型。多数据源采用主数据源作为数据库类型 + * + * @return DBType or H2数据库 + */ + static DBType getSystemDbType() { + String dbtype = Envs.getProperty(DB_TYPE_CONFIG_KEY); + try { + return getDbType(dbtype); + } catch (IllegalArgumentException ex) { + // ignore + return H2; + } + } + + /** + * 根据dbtype的字符串获取DBType。 + * + * @param dbtype dbtype + * @return DBType default {@link #H2} + */ + static DBType getDbType(String dbtype) { + return ALL_DB_TYPES.stream() + .filter(dbType -> dbType.getName().equals(dbtype)) + .findFirst() + .orElse(H2); + } + + /** + * 数据库类型分类 + * + * @see see + */ + @Getter + @AllArgsConstructor + enum DBCategory { + RELATIONAL("Relational", "传统关系型数据库"), + KEY_VALUE("key Value", "键值对数据库"), + DOCUMENT("Document", "文档数据库"), + TIME_SERIES("Time Series", "时序数据库"), + GRAPH("Graph", "图数据库"), + SEARCH_ENGINES("Search Engines", "搜索引擎"), + OBJECT_ORIENTED("Object Oriented", "面对对象数据库"), + VECTOR("Vector", "向量数据库"); + + private final String name; + private final String label; + } + + @Getter + @EqualsAndHashCode(of = "name") + @AllArgsConstructor + class DefaultDBType implements DBType { + + private final String name; + private final String driverClassName; + private final DBCategory category; + private final String jdbcUrlTemplate; + + @Override + public String parseTemplate(String address, String dataBaseName) { + return JDBC_URL_TEMPLATE_PARSER.parseTemplate(getJdbcUrlTemplate(), ADDRESS, address, DATABASE_NAME, dataBaseName); + } + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DBTypeAdapter.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DBTypeAdapter.java new file mode 100644 index 00000000..b285d200 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DBTypeAdapter.java @@ -0,0 +1,13 @@ +package cc.allio.uno.data.orm.dsl.type; + +import cc.allio.uno.core.api.Adapter; + +/** + * SQL 数据库类型适配器 + * + * @author jiangwei + * @date 2023/4/13 13:17 + * @since 1.1.4 + */ +public interface DBTypeAdapter extends Adapter { +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DSLType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DSLType.java new file mode 100644 index 00000000..8f57074c --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DSLType.java @@ -0,0 +1,219 @@ +package cc.allio.uno.data.orm.dsl.type; + +import cc.allio.uno.core.api.EqualsTo; +import cc.allio.uno.data.orm.dsl.dialect.TypeTranslatorHolder; +import com.google.common.base.Objects; +import lombok.*; + +import java.sql.Types; +import java.util.List; +import java.util.Optional; + +/** + * DSL 类型定义,基于{@link DBType#MYSQL}作基础类型进行定义 + *

    建议通过{@link TypeTranslatorHolder#getTypeTranslator()}在进行包装,否则获取的{@link DSLType}实例无法满足指定数据库方言

    + * + * @author jiangwei + * @date 2023/4/12 20:03 + * @see DataType + * @since 1.1.4 + */ +public interface DSLType extends EqualsTo { + + DSLType BIGINT = DefaultDSLType.BIGINT; + + DSLType SMALLINT = DefaultDSLType.SMALLINT; + + DSLType INTEGER = DefaultDSLType.INTEGER; + + DSLType BIT = DefaultDSLType.BIT; + + DSLType TINYINT = DefaultDSLType.TINYINT; + + DSLType NUMBER = DefaultDSLType.NUMBER; + + DSLType DOUBLE = DefaultDSLType.DOUBLE; + + DSLType FLOAT = DefaultDSLType.FLOAT; + + // ====================== 时间型 ====================== + DSLType TIME = DefaultDSLType.TIME; + + DSLType TIMESTAMP = DefaultDSLType.TIMESTAMP; + + DSLType DATE = DefaultDSLType.DATE; + + DSLType DECIMAL = DefaultDSLType.DECIMAL; + + // ====================== 字符型 ====================== + DSLType CHAR = DefaultDSLType.CHAR; + + DSLType VARCHAR = DefaultDSLType.VARCHAR; + + DSLType NVARCHAR = DefaultDSLType.NVARCHAR; + + DSLType LONGVARCHAR = DefaultDSLType.LONGVARCHAR; + + DSLType LONGNVARCHAR = DefaultDSLType.LONGNVARCHAR; + + DSLType VARBINARY = DefaultDSLType.VARBINARY; + + DSLType LONGVARBINARY = DefaultDSLType.LONGVARBINARY; + + // ====================== 高级类型 ====================== + DSLType OBJECT = DefaultDSLType.OBJECT; + + DSLType ARRAY = DefaultDSLType.ARRAY; + + /** + * 获取sql type name + * + * @return String + */ + String getName(); + + /** + * 获取 sql type对应的jdbc type code + * + * @return jdbc code + */ + int getJdbcType(); + + /** + * 获取的Precision + * + * @return Precision + */ + Integer getPrecision(); + + /** + * 获取的Scala + * + * @return Scala + */ + Integer getScale(); + + /** + * 根据jdbc code获取SQLType实例 + * + * @param jdbcCode jdbcCode + * @return SQLType + */ + static DSLType getByJdbcCode(int jdbcCode) { + for (DSLType value : DefaultDSLType.values()) { + if (value.getJdbcType() == jdbcCode) { + return value; + } + } + return null; + } + + /** + * 比较其他的{@link DSLType}对象 + *
      + *
    1. 比较名称
    2. + *
    3. 比较类型
    4. + *
    5. 比较precision
    6. + *
    7. 比较scale
    8. + *
    + */ + @Override + default boolean equalsTo(DSLType other) { + return java.util.Objects.equals(this.getName(), other.getName()); + } + + /** + * 从给定的SQLType创建一个SQLType,该方法将会一个{@link DSLType}实例 + * + * @param dslType dslType + * @param precision precision + * @param scale scale + * @return DSLTypeImpl + * @see DSLTypeImpl + */ + static DSLTypeImpl create(DSLType dslType, Integer precision, Integer scale) { + DSLTypeImpl.DSLTypeImplBuilder builder = DSLTypeImpl.builder() + .name(dslType.getName()) + .jdbcType(dslType.getJdbcType()); + Integer definitePrecision = Optional.ofNullable(precision).orElse(dslType.getPrecision()); + builder.precision(definitePrecision); + Integer definiteScale = Optional.ofNullable(scale).orElse(dslType.getScale()); + builder.scale(definiteScale); + return builder.build(); + } + + /** + * 关联于某一个SQLType + */ + interface DSLLinkType extends DSLType { + + /** + * 关联的SQL Type + * + * @return SQLType + */ + List getParent(); + } + + @Data + @Builder + @EqualsAndHashCode(of = {"name", "jdbcType"}) + class DSLTypeImpl implements DSLType { + private final String name; + private final int jdbcType; + private final Integer precision; + private final Integer scale; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DSLTypeImpl dslType = (DSLTypeImpl) o; + return jdbcType == dslType.jdbcType && Objects.equal(name, dslType.name) && Objects.equal(precision, dslType.precision) && Objects.equal(scale, dslType.scale); + } + + @Override + public int hashCode() { + return Objects.hashCode(name, jdbcType, precision, scale); + } + } + + @Getter + @AllArgsConstructor + enum DefaultDSLType implements DSLType { + // ====================== 数字型 ====================== + BIGINT("bigint", Types.BIGINT, 64, null), + SMALLINT("smallint", Types.SMALLINT, 32, null), + INTEGER("int", Types.INTEGER, 64, null), + BIT("bit", Types.BIT, 4, null), + TINYINT("tinyint", Types.TINYINT, 16, null), + NUMBER("number", Types.NUMERIC, 12, 2), + DOUBLE("double", Types.DOUBLE, 12, 2), + FLOAT("float", Types.FLOAT, 12, 2), + DECIMAL("decimal", Types.DECIMAL, 6, null), + + // ====================== 时间型 ======================, + TIME("time", Types.TIME, 6, null), + TIMESTAMP("timestamp", Types.TIMESTAMP, null, null), + DATE("date", Types.DATE, 6, null), + + // ====================== 字符型 ====================== + CHAR("char", Types.CHAR, 64, null), + CHARACTER("character", Types.CHAR, 64, null), + VARCHAR("varchar", Types.VARCHAR, 64, null), + NVARCHAR("nvarchar", Types.NVARCHAR, 64, null), + LONGVARCHAR("longvarchar", Types.LONGVARCHAR, 1024, null), + LONGNVARCHAR("longnvarchar", Types.LONGNVARCHAR, 1024, null), + VARBINARY("varbinary", Types.VARBINARY, 1024, null), + LONGVARBINARY("longvarchar", Types.LONGVARBINARY, 2048, null), + + // ====================== 高级类型 ====================== + OBJECT("object", Types.JAVA_OBJECT, null, null), + ARRAY("array", Types.ARRAY, null, null); + + private final String name; + private final int jdbcType; + private final Integer precision; + private final Integer scale; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DataType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DataType.java similarity index 58% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/DataType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DataType.java index 8378ae73..16543ef4 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DataType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DataType.java @@ -1,5 +1,6 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; +import cc.allio.uno.core.api.EqualsTo; import lombok.Data; /** @@ -10,26 +11,40 @@ * @since 1.1.4 */ @Data -public class DataType { +public class DataType implements EqualsTo { // SQL类型 - private SQLType sqlType; + private DSLType dslType; // 精度 private Integer precision; // 范围 private Integer scale; + @Override + public boolean equalsTo(DataType other) { + if (other == null) { + return false; + } + if (this == other) { + return true; + } + if (this.getDslType() == null) { + return false; + } + return dslType.equalsTo(other.getDslType()); + } + /** * 创建Data type * * @param sqlType sqlType * @return DataType */ - public static DataType create(SQLType sqlType) { + public static DataType create(DSLType sqlType) { DataType dataType = new DataType(); - dataType.setSqlType(sqlType); - dataType.setPrecision(sqlType.getDefaultPrecision()); - dataType.setScale(sqlType.getDefaultScala()); + dataType.setDslType(sqlType); + dataType.setPrecision(sqlType.getPrecision()); + dataType.setScale(sqlType.getScale()); return dataType; } @@ -40,7 +55,7 @@ public static DataType create(SQLType sqlType) { * @param precision 精度 * @return DataType */ - public static DataType createNumberType(SQLType sqlType, Integer precision) { + public static DataType createNumberType(DSLType sqlType, Integer precision) { return createNumberType(sqlType, precision, null); } @@ -52,9 +67,9 @@ public static DataType createNumberType(SQLType sqlType, Integer precision) { * @param scale 范围 * @return DataType */ - public static DataType createNumberType(SQLType sqlType, Integer precision, Integer scale) { + public static DataType createNumberType(DSLType sqlType, Integer precision, Integer scale) { DataType dataType = new DataType(); - dataType.setSqlType(sqlType); + dataType.setDslType(sqlType); dataType.setPrecision(precision); dataType.setScale(scale); return dataType; @@ -67,9 +82,9 @@ public static DataType createNumberType(SQLType sqlType, Integer precision, Inte * @param precision precision * @return DataType */ - public static DataType createCharType(SQLType sqlType, Integer precision) { + public static DataType createCharType(DSLType sqlType, Integer precision) { DataType dataType = new DataType(); - dataType.setSqlType(sqlType); + dataType.setDslType(sqlType); dataType.setPrecision(precision); return dataType; } @@ -80,10 +95,9 @@ public static DataType createCharType(SQLType sqlType, Integer precision) { * @param sqlType SQLType * @return DataType */ - public static DataType createTimeType(SQLType sqlType) { + public static DataType createTimeType(DSLType sqlType) { DataType dataType = new DataType(); - dataType.setSqlType(sqlType); + dataType.setDslType(sqlType); return dataType; } - } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DataTypeAdapter.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DataTypeAdapter.java new file mode 100644 index 00000000..0cdd417e --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DataTypeAdapter.java @@ -0,0 +1,14 @@ +package cc.allio.uno.data.orm.dsl.type; + +import cc.allio.uno.core.api.Adapter; + +/** + * 适用于不同框架的类型定义 + * + * @author jiangwei + * @date 2023/4/12 20:01 + * @since 1.1.4 + */ +public interface DataTypeAdapter extends Adapter { + +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DateJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DateJavaType.java similarity index 62% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/DateJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DateJavaType.java index 483dfb43..26f7a72c 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DateJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DateJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -16,4 +16,9 @@ public class DateJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.DATE; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Date.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DoubleJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DoubleJavaType.java similarity index 53% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/DoubleJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DoubleJavaType.java index 48d5d91a..c377e65f 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/DoubleJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/DoubleJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -14,4 +14,10 @@ public class DoubleJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.DOUBLE; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Double.class.isAssignableFrom(otherJavaType) + || double.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/EnumJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/EnumJavaType.java similarity index 57% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/EnumJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/EnumJavaType.java index 9678cf89..b6ab9dde 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/EnumJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/EnumJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; /** * enum java type @@ -12,4 +12,9 @@ public class EnumJavaType extends JavaTypeImpl { public Class getJavaType() { return Enum.class; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Enum.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/FloatJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/FloatJavaType.java similarity index 52% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/FloatJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/FloatJavaType.java index 0de3c5f7..d7df03ac 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/FloatJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/FloatJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -15,4 +15,10 @@ public class FloatJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.FLOAT; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Float.class.isAssignableFrom(otherJavaType) + || float.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/IntegerJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/IntegerJavaType.java similarity index 53% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/IntegerJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/IntegerJavaType.java index 57a5a76d..2add35dc 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/IntegerJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/IntegerJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -15,4 +15,10 @@ public class IntegerJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.INTEGER; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Integer.class.isAssignableFrom(otherJavaType) + || int.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/JavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JavaType.java similarity index 79% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/JavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JavaType.java index ba5fe362..6eaeec15 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/JavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import java.io.Serializable; @@ -19,6 +19,14 @@ public interface JavaType extends Serializable { */ Class getJavaType(); + /** + * 比较类型是否属于当前Java类型 + * + * @param otherJavaType otherJavaType + * @return ture ye or nor + */ + boolean equalsTo(Class otherJavaType); + /** * 获取当前Java类型对应的SQL字段的默认长度 * diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/JavaTypeImpl.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JavaTypeImpl.java similarity index 91% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/JavaTypeImpl.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JavaTypeImpl.java index 0a422f0f..686bb01e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/JavaTypeImpl.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JavaTypeImpl.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; /** * java type impl diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/JdbcType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JdbcType.java similarity index 99% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/JdbcType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JdbcType.java index 52d2ec30..8ae60b75 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/JdbcType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JdbcType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.StringPool; import cc.allio.uno.core.util.ObjectUtils; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/JdbcTypeImpl.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JdbcTypeImpl.java similarity index 96% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/JdbcTypeImpl.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JdbcTypeImpl.java index 27d70e4b..6386442e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/JdbcTypeImpl.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/JdbcTypeImpl.java @@ -1,7 +1,7 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.word.KeyWord; +import cc.allio.uno.data.orm.dsl.word.KeyWord; import com.google.common.collect.Lists; import java.util.List; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/ListJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ListJavaType.java similarity index 62% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/ListJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ListJavaType.java index 273e2fce..881f635f 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/ListJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ListJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -16,4 +16,9 @@ public class ListJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.LIST; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return List.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/LongJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/LongJavaType.java similarity index 53% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/LongJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/LongJavaType.java index df169d0b..45933890 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/LongJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/LongJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -15,4 +15,10 @@ public class LongJavaType implements JavaType { public Class getJavaType() { return Types.LONG; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Long.class.isAssignableFrom(otherJavaType) + || long.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/MapJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/MapJavaType.java similarity index 61% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/MapJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/MapJavaType.java index f0ff431f..e68b8d7d 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/MapJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/MapJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -16,4 +16,9 @@ public class MapJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.MAP; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Map.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/QueueJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/QueueJavaType.java similarity index 62% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/QueueJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/QueueJavaType.java index bba09c43..a262e257 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/QueueJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/QueueJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -16,4 +16,9 @@ public class QueueJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.QUEUE; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Queue.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/SetJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/SetJavaType.java similarity index 62% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/SetJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/SetJavaType.java index 17611631..3957208b 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/SetJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/SetJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -17,4 +17,9 @@ public class SetJavaType extends JavaTypeImpl { public Class getJavaType() { return Types.SET; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Set.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/ShortJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ShortJavaType.java similarity index 53% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/ShortJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ShortJavaType.java index fcabfab6..941e7cbe 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/ShortJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/ShortJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.type.Types; @@ -15,4 +15,10 @@ public class ShortJavaType implements JavaType { public Class getJavaType() { return Types.SHORT; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Short.class.isAssignableFrom(otherJavaType) + || short.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/StackJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/StackJavaType.java similarity index 59% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/StackJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/StackJavaType.java index 2cc0707a..a2e82713 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/StackJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/StackJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import java.util.Stack; @@ -14,4 +14,9 @@ public class StackJavaType extends JavaTypeImpl { public Class getJavaType() { return Stack.class; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return Stack.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/StringJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/StringJavaType.java similarity index 58% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/StringJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/StringJavaType.java index defb66ab..3bafccc6 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/StringJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/StringJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; /** * string java type @@ -13,4 +13,9 @@ public class StringJavaType implements JavaType { public Class getJavaType() { return String.class; } + + @Override + public boolean equalsTo(Class otherJavaType) { + return String.class.isAssignableFrom(otherJavaType); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/TypeRegistry.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/TypeRegistry.java similarity index 99% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/TypeRegistry.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/TypeRegistry.java index 930e0b0b..56cb704f 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/TypeRegistry.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/TypeRegistry.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; import cc.allio.uno.core.util.CollectionUtils; import com.google.common.collect.*; @@ -8,7 +8,7 @@ import java.util.stream.Collectors; /** - * type registry + * type register * * @author jiangwei * @date 2023/1/13 16:00 @@ -719,7 +719,7 @@ public JavaType guessJavaType(Class valueType) { for (JavaType javaType : values) { try { - if (javaType.getJavaType().isAssignableFrom(valueType)) { + if (javaType.equalsTo(valueType)) { return javaType; } } catch (Throwable ex) { diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/UnknownJavaType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/UnknownJavaType.java similarity index 59% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/UnknownJavaType.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/UnknownJavaType.java index f3a9af09..df7ce5d7 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/UnknownJavaType.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/type/UnknownJavaType.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.type; +package cc.allio.uno.data.orm.dsl.type; /** * unknown java type @@ -12,4 +12,9 @@ public class UnknownJavaType extends JavaTypeImpl { public Class getJavaType() { throw new UnsupportedOperationException("unknown non support operator"); } + + @Override + public boolean equalsTo(Class otherJavaType) { + throw new UnsupportedOperationException("unknown non support operator"); + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/word/Distinct.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/word/Distinct.java similarity index 82% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/word/Distinct.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/word/Distinct.java index b186ac35..3a2a1551 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/word/Distinct.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/word/Distinct.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql.word; +package cc.allio.uno.data.orm.dsl.word; /** * distinct diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/word/KeyWord.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/word/KeyWord.java similarity index 95% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/word/KeyWord.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/word/KeyWord.java index 699269e4..367d35ba 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/word/KeyWord.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/word/KeyWord.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql.word; +package cc.allio.uno.data.orm.dsl.word; import lombok.AllArgsConstructor; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/word/KeyWords.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/word/KeyWords.java similarity index 92% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/word/KeyWords.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/word/KeyWords.java index b2ac04ca..b1786132 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/word/KeyWords.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/dsl/word/KeyWords.java @@ -1,6 +1,6 @@ -package cc.allio.uno.data.orm.sql.word; +package cc.allio.uno.data.orm.dsl.word; -import cc.allio.uno.data.orm.dialect.func.Func; +import cc.allio.uno.data.orm.dsl.Func; import java.util.Map; import java.util.TreeMap; @@ -19,7 +19,7 @@ private KeyWords() { // Statement public static final KeyWord SELECT = new KeyWord("select"); - public static final KeyWord FROM = new KeyWord("from"); + public static final KeyWord FROM = new KeyWord("xxxx"); // Function diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/AbstractCommandExecutor.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/AbstractCommandExecutor.java new file mode 100644 index 00000000..b13f0177 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/AbstractCommandExecutor.java @@ -0,0 +1,94 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.data.orm.executor.handler.ListResultSetHandler; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; +import cc.allio.uno.data.orm.executor.interceptor.*; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * 实现自{@link CommandExecutor}的基本的类,所有的具体实现类都需要继承该类。 + * + * @author jiangwei + * @date 2024/1/8 10:45 + * @since 1.1.6 + */ +@Slf4j +@Getter +public abstract class AbstractCommandExecutor implements CommandExecutor { + private final ExecutorOptions options; + + protected AbstractCommandExecutor(ExecutorOptions options) { + this.options = options; + } + + @Override + public boolean bool(Operator operator, CommandType commandType, ResultSetHandler resultSetHandler) { + return aspect(operator, commandType, () -> doBool(operator, commandType, resultSetHandler)); + } + + /** + * 子类实现 + * + * @param operator DSLOperator操作 + * @param commandType DSL命令 + * @param resultSetHandler 结果集处理器 + * @return true 成功 false 失败 + */ + protected abstract boolean doBool(Operator operator, CommandType commandType, ResultSetHandler resultSetHandler); + + @Override + public List queryList(QueryOperator queryOperator, CommandType commandType, ListResultSetHandler resultSetHandler) { + return aspect(queryOperator, commandType, () -> doQueryList(queryOperator, commandType, resultSetHandler)); + } + + /** + * 子类实现 + * + * @param queryOperator QueryOperator + * @param commandType 命令类型 + * @param resultSetHandler 结果集处理器 + * @param 返回结果类型 + * @return List + * @throws DSLException query failed throw + */ + protected abstract List doQueryList(QueryOperator queryOperator, CommandType commandType, ListResultSetHandler resultSetHandler); + + /** + * 给定操作的切面并执行 + * + * @param operator operator + * @param commandType commandType + * @param operate 给定操作 + * @param 操作返回类型 + * @return 返回类结果 + */ + private T aspect(Operator operator, CommandType commandType, Supplier operate) { + List interceptors = options.getInterceptors(); + InterceptorAttributes beforeAttributes = new InterceptorAttributes(this, operator, commandType); + var before = Mono.defer(() -> { + // before interceptor + List beforeInterceptors = interceptors.stream().map(BeforeInterceptor::new).collect(Collectors.toList()); + InterceptorChainImpl beforeChain = new InterceptorChainImpl(beforeInterceptors); + return beforeChain.proceed(new InterceptorChainContext(beforeAttributes)); + }); + var after = Mono.defer(() -> { + Mono result = Mono.fromSupplier(operate); + List afterInterceptors = interceptors.stream().map(AfterInterceptor::new).collect(Collectors.toList()); + InterceptorAttributes afterAttributes = new InterceptorAttributes(beforeAttributes, result); + InterceptorChainImpl afterChain = new InterceptorChainImpl(afterInterceptors); + return afterChain.proceed(new InterceptorChainContext(afterAttributes)).then(result); + }); + return before.then(after).block(); + } + +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutor.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutor.java new file mode 100644 index 00000000..0b48ce19 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutor.java @@ -0,0 +1,1168 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.core.bean.ValueWrapper; +import cc.allio.uno.core.env.Envs; +import cc.allio.uno.core.function.lambda.MethodReferenceColumn; +import cc.allio.uno.core.util.CollectionUtils; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.ddl.*; +import cc.allio.uno.data.orm.dsl.dml.DeleteOperator; +import cc.allio.uno.data.orm.dsl.dml.InsertOperator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.dml.UpdateOperator; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.helper.PojoWrapper; +import cc.allio.uno.data.orm.executor.handler.*; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.net.SocketTimeoutException; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.BooleanSupplier; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; + +/** + * Command Executor + * + * @author jiangwei + * @date 2023/4/14 13:43 + * @since 1.1.4 + */ +public interface CommandExecutor { + + /** + * 设置作为command executor key + */ + String DEFAULT_KEY = "key"; + + /** + * 获取{@link ExecutorOptions#isSystemDefault()}时的默认key + * + * @return default key + */ + static String getDefaultKey() { + return Envs.getProperty(DEFAULT_KEY); + } + + + /** + * 基于某个实体作为alter table + * + * @see #alertTable(AlterTableOperator) + */ + default boolean alertTable(Class entityType, UnaryOperator func) { + return alertTable(func.apply(getOperatorGroup().alterTables().from(entityType))); + } + + /** + * @see #alertTable(AlterTableOperator) + */ + default boolean alertTable(UnaryOperator func) { + return alertTable(func.apply(getOperatorGroup().alterTables())); + } + + /** + * @see #bool(Operator, CommandType) + */ + default boolean alertTable(AlterTableOperator alterTableOperator) { + return bool(alterTableOperator, CommandType.ALERT_TABLE); + } + + /** + * alert table + * + * @param alterTableOperator alterTableOperator + * @param resultSetHandler resultSetHandler + * @return true 成功 false 失败 + */ + default boolean alertTable(AlterTableOperator alterTableOperator, ResultSetHandler resultSetHandler) { + return bool(alterTableOperator, CommandType.ALERT_TABLE, resultSetHandler); + } + + /** + * 根据pojo class创建表 + * + * @param pojoClass the pojoClass + * @return true 成功 false 失败 + */ + default

    boolean createTable(Class

    pojoClass) { + PojoWrapper

    pojoWrapper = PojoWrapper.getInstance(pojoClass); + return createTable(o -> o.from(pojoWrapper.getTable()).columns(pojoWrapper.getColumnDefs())); + } + + /** + * 创表 + * + * @param func the func + * @return true 成功 false 失败 + */ + default boolean createTable(UnaryOperator func) { + return createTable(func.apply(getOperatorGroup().createTable(getOptions().getDbType()))); + } + + /** + * 创表 + * + * @param createTableOperator CreateTableOperator + * @return true 成功 false 失败 + */ + default boolean createTable(CreateTableOperator createTableOperator) { + return bool(createTableOperator, CommandType.CREATE_TABLE); + } + + /** + * 创表 + * + * @param createTableOperator CreateTableOperator + * @param resultSetHandler resultSetHandler + * @return true 成功 false 失败 + */ + default boolean createTable(CreateTableOperator createTableOperator, ResultSetHandler resultSetHandler) { + return bool(createTableOperator, CommandType.CREATE_TABLE, resultSetHandler); + } + + /** + * 根据pojo class删除表 + * + * @param tableName the tableName + * @return true 成功 false 失败 + */ + default boolean dropTable(String tableName) { + return dropTable(o -> o.from(tableName)); + } + + /** + * 根据pojo class删除表 + * + * @param tableName the tableName + * @return true 成功 false 失败 + */ + default boolean dropTable(DSLName tableName) { + return dropTable(o -> o.from(tableName)); + } + + /** + * 根据pojo class删除表 + * + * @param table the xxxx + * @return true 成功 false 失败 + */ + default boolean dropTable(Table table) { + return dropTable(o -> o.from(table)); + } + + /** + * 根据pojo class删除表 + * + * @param pojoClass the pojoClass + * @return true 成功 false 失败 + */ + default

    boolean dropTable(Class

    pojoClass) { + PojoWrapper

    pojoWrapper = PojoWrapper.getInstance(pojoClass); + return dropTable(o -> o.from(pojoWrapper.getTable())); + } + + /** + * 删表 + * + * @param func func + * @return true 成功 false 失败 + */ + default boolean dropTable(UnaryOperator func) { + return dropTable(func.apply(getOperatorGroup().dropTable(getOptions().getDbType()))); + } + + /** + * 删表 + * + * @param dropTableOperator dropTableOperator + * @return true 成功 false 失败 + */ + default boolean dropTable(DropTableOperator dropTableOperator) { + return bool(dropTableOperator, CommandType.DELETE_TABLE); + } + + /** + * 删表 + * + * @param dropTableOperator dropTableOperator + * @param resultSetHandler resultSetHandler + * @return true 成功 false 失败 + */ + default boolean dropTable(DropTableOperator dropTableOperator, ResultSetHandler resultSetHandler) { + return bool(dropTableOperator, CommandType.DELETE, resultSetHandler); + } + + /** + * 判断表是否存在 + * + * @param tableName the tableName + * @return true 成功 false 失败 + */ + default boolean existTable(String tableName) { + return existTable(o -> o.from(tableName)); + } + + /** + * 判断表是否存在 + * + * @param table the xxxx + * @return true 成功 false 失败 + */ + default boolean existTable(Table table) { + return existTable(o -> o.from(table)); + } + + /** + * 根据pojoClass判断是否存在 + * + * @param pojoClass pojoClass + * @return true 成功 false 失败 + */ + default

    boolean existTable(Class

    pojoClass) { + PojoWrapper

    pojoWrapper = PojoWrapper.getInstance(pojoClass); + return existTable(o -> o.from(pojoWrapper.getTable())); + } + + /** + * 判断表是否存在 + * + * @param func the func + * @return true 成功 false 失败 + */ + default boolean existTable(UnaryOperator func) { + return existTable(func.apply(getOperatorGroup().existTable(getOptions().getDbType()))); + } + + /** + * 判断表是否存在 + * + * @param existTableOperator ExistTableOperator + * @return true 成功 false 失败 + */ + default boolean existTable(ExistTableOperator existTableOperator) { + return bool(existTableOperator, CommandType.EXIST_TABLE); + } + + /** + * 判断表是否存在 + * + * @param existTableOperator ExistTableOperator + * @param resultSetHandler resultSetHandler + * @return true 成功 false 失败 + */ + default boolean existTable(ExistTableOperator existTableOperator, ResultSetHandler resultSetHandler) { + return bool(existTableOperator, CommandType.EXIST_TABLE, resultSetHandler); + } + + /** + * 获取某个表的字段 + * + * @param pojoClass pojoClass + * @return ColumnDef + */ + default List showColumns(Class pojoClass) { + PojoWrapper pojoWrapper = PojoWrapper.getInstance(pojoClass); + return showColumns(pojoWrapper.getTable()); + } + + /** + * 获取某个表的字段 + * + * @param tableName tableName + * @return ColumnDef + */ + default List showColumns(String tableName) { + return showColumns(o -> o.from(tableName)); + } + + /** + * 获取某个表的字段 + * + * @param table xxxx + * @return ColumnDef + */ + default List showColumns(Table table) { + return showColumns(o -> o.from(table)); + } + + /** + * 获取某个表的字段 + * + * @param func the func + * @return ColumnDef + */ + default List showColumns(UnaryOperator func) { + return showColumns(func.apply(getOperatorGroup().showColumns(getOptions().getDbType()))); + } + + /** + * 获取某个表的字段 + * + * @param showColumnsOperator showColumnsOperator + * @return ColumnDef + */ + default List showColumns(ShowColumnsOperator showColumnsOperator) { + return queryList(showColumnsOperator.toQueryOperator(), CommandType.SHOW_COLUMNS, getOptions().obtainColumnDefListResultSetHandler()); + } + + /** + * 基于{@link ExecutorOptions#getDatabase()}获取数据库表 + * + * @return List

    + */ + default List
    showTables() { + return showTables(o -> o.database(getOptions().getDatabase())); + } + + /** + * 获取某个数据库的表 + * + * @param database database + * @return List
    + */ + default List
    showTables(String database) { + return showTables(o -> o.database(database)); + } + + /** + * 获取某个数据库的表 + * + * @param database database + * @return List
    + */ + default List
    showTables(Database database) { + return showTables(o -> o.database(database)); + } + + /** + * 获取某个数据库的表 + * + * @param func func + * @return List
    + */ + default List
    showTables(UnaryOperator func) { + return showTables(func.apply(getOperatorGroup().showTables(getOptions().getDbType()))); + } + + /** + * 获取某个数据库的表 + * + * @param showTablesOperator showTablesOperator + * @return List
    + */ + default List
    showTables(ShowTablesOperator showTablesOperator) { + return queryList(showTablesOperator.toQueryOperator(), CommandType.SHOW_TABLES, getOptions().obtainTableListResultSetHandler()); + } + + /** + * @see #showOneTable(DSLName) + */ + default Table showOneTable(String tableName) { + return showOneTable(DSLName.of(tableName)); + } + + /** + * 基于某个具体的表明获取唯一表的信息 + * + * @param tableName tableName + * @return table instance or null + */ + default Table showOneTable(DSLName tableName) { + List
    tables = showTables(o -> o.from(tableName)); + return checkCollectionIsOneAndGet(tables); + } + + /** + * 插入数据 + * + * @param pojo pojo + * @return true 成功 false 失败 + */ + default

    boolean insertPojo(P pojo) { + PojoWrapper

    pojoWrapper = PojoWrapper.getInstance(pojo); + return insert(o -> o.from(pojoWrapper.getTable()).insertPojo(pojoWrapper.getPojo())); + } + + /** + * 插入数据(认定为同一个表数据) + * + * @param pojos pojos + * @return true 成功 false 失败 + */ + default

    boolean batchInsertPojos(List

    pojos) { + if (CollectionUtils.isEmpty(pojos)) { + return false; + } + P thePojo = pojos.get(0); + PojoWrapper

    pojoWrapper = PojoWrapper.getInstance(thePojo); + return insert(o -> o.from(pojoWrapper.getTable()).batchInsertPojos(pojos)); + } + + /** + * 插入数据 + * + * @param func the func + * @return true 成功 false 失败 + */ + default boolean insert(UnaryOperator func) { + return insert(func.apply(getOperatorGroup().insert(getOptions().getDbType()))); + } + + /** + * 插入数据 + * + * @param insertOperator insertOperator + * @return true 成功 false 失败 + */ + default boolean insert(InsertOperator insertOperator) { + return bool(insertOperator, CommandType.INSERT); + } + + /** + * 插入数据 + * + * @param insertOperator insertOperator + * @param resultSetHandler resultSetHandler + * @return true 成功 false 失败 + */ + default boolean insert(InsertOperator insertOperator, ResultSetHandler resultSetHandler) { + return bool(insertOperator, CommandType.INSERT, resultSetHandler); + } + + /** + * 更新数据 + * + * @param pojo the pojo + * @return true 成功 false 失败 + */ + default

    boolean updatePojo(P pojo) { + return update(o -> o.updatePojo(pojo)); + } + + /** + * 更新数据 + * + * @param pojo the pojo + * @return true 成功 false 失败 + */ + default boolean updatePojoById(P pojo, ID id) { + PojoWrapper

    pojoWrapper = PojoWrapper.getInstance(pojo); + ColumnDef theId = pojoWrapper.getPkColumn(); + return updatePojoByCondition(pojo, condition -> condition.eq(theId.getDslName(), id)); + } + + /** + * 更新数据根据条件 + * + * @param pojo the pojo + * @return true 成功 false 失败 + */ + default

    boolean updatePojoByCondition(P pojo, UnaryOperator> condition) { + return update(o -> { + PojoWrapper

    pojoWrapper = PojoWrapper.getInstance(pojo); + UpdateOperator updateOperator = o.from(pojoWrapper.getTable()).updatePojo(pojo); + condition.apply(updateOperator); + return updateOperator; + }); + } + + /** + * 更新数据 + * + * @param func the func + * @return true 成功 false 失败 + */ + default boolean update(UnaryOperator func) { + return update(func.apply(getOperatorGroup().update(getOptions().getDbType()))); + } + + /** + * 更新数据 + * + * @param updateOperator updateOperator + * @return true 成功 false 失败 + */ + default boolean update(UpdateOperator updateOperator) { + return bool(updateOperator, CommandType.UPDATE); + } + + /** + * 更新数据 + * + * @param updateOperator updateOperator + * @param resultSetHandler resultSetHandler + * @return true 成功 false 失败 + */ + default boolean update(UpdateOperator updateOperator, ResultSetHandler resultSetHandler) { + return bool(updateOperator, CommandType.UPDATE, resultSetHandler); + } + + /** + * 基于POJO删除数据 + * 需要注意,该API不会直接删除数据,如果存在删除标记,则会把删除标记做更新 + * + * @param pojo pojo + * @return true 成功 false 失败 + * @see #deleteById(Class, Serializable) + */ + default boolean delete(T pojo) { + PojoWrapper pojoWrapper = PojoWrapper.getInstance(pojo); + Object pkValue = ValueWrapper.restore(pojoWrapper.getPKValue()); + return deleteById(pojo.getClass(), (Serializable) pkValue); + } + + /** + * 根据id删除数据 + * 需要注意,该API不会直接删除数据,如果存在删除标记,则会把删除标记做更新 + * + * @param pojoClass pojoClass + * @param id id + * @return true 成功 false 失败 + */ + default boolean deleteById(Class pojoClass, ID id) { + ColumnDef pkColumn = PojoWrapper.findPKColumn(pojoClass); + if (pkColumn == null) { + throw new DSLException("Can not find the primary key column"); + } + UpdateOperator update = getOperatorGroup().update(getOptions().getDbType()); + return bool(update.from(pojoClass).eq(pkColumn.getDslName(), id), CommandType.DELETE); + } + + /** + * 删除所有数据 + * 需要注意,该API不会直接删除数据,如果存在删除标记,则会把删除标记做更新 + * + * @param pojoClass pojoClass + * @return true 成功 false 失败 + */ + default boolean deleteAll(Class pojoClass) { + ColumnDef pkColumn = PojoWrapper.findPKColumn(pojoClass); + if (pkColumn == null) { + throw new DSLException("Can not find the primary key column"); + } + UpdateOperator update = getOperatorGroup().update(getOptions().getDbType()); + return bool(update.from(pojoClass), CommandType.DELETE); + } + + /** + * 删除所有数据 + * 需要注意,该API不会直接删除数据,如果存在删除标记,则会把删除标记做更新 + * + * @param pojoClass pojoClass + * @return true 成功 false 失败 + */ + default boolean deleteAll(Class pojoClass, Iterable pojos) { + return deleteAllById( + pojoClass, + Lists.newArrayList(pojos) + .stream() + .map(pojo -> { + PojoWrapper pojoWrapper = PojoWrapper.getInstance(pojo); + Object pkValue = ValueWrapper.restore(pojoWrapper.getPKValue()); + return (Serializable) pkValue; + }) + .toList()); + } + + /** + * 批量根据id删除数据 + * 需要注意,该API不会直接删除数据,如果存在删除标记,则会把删除标记做更新 + * + * @param pojoClass pojoClass + * @param ids ids + * @return true 成功 false 失败 + */ + default boolean deleteAllById(Class pojoClass, Iterable ids) { + ColumnDef pkColumn = PojoWrapper.findPKColumn(pojoClass); + if (pkColumn == null) { + throw new DSLException("Can not find the primary key column"); + } + UpdateOperator update = getOperatorGroup().update(getOptions().getDbType()); + return bool(update.from(pojoClass).in(pkColumn.getDslName(), ids), CommandType.DELETE); + } + + /** + * 删除数据 + * + * @param func the func + * @return true 成功 false 失败 + */ + default boolean delete(UnaryOperator func) { + return delete(func.apply(getOperatorGroup().delete(getOptions().getDbType()))); + } + + /** + * 删除数据 + * + * @param deleteOperator deleteOperator + * @return true 成功 false 失败 + */ + default boolean delete(DeleteOperator deleteOperator) { + return bool(deleteOperator, CommandType.DELETE); + } + + /** + * 删除数据 + * + * @param deleteOperator deleteOperator + * @param resultSetHandler resultSetHandler + * @return true 成功 false 失败 + */ + default boolean delete(DeleteOperator deleteOperator, ResultSetHandler resultSetHandler) { + return bool(deleteOperator, CommandType.DELETE, resultSetHandler); + } + + /** + * bool操作,包含创建、更新、删除、插入表、删除表... + * + * @param operator Operator操作 + * @param command command + * @return true 成功 false 失败 + */ + default boolean bool(Operator operator, CommandType command) { + return bool(operator, command, getOptions().obtainBoolResultHandler()); + } + + /** + * bool操作,包含创建、更新、删除、插入表、删除表... + * + * @param operator operator + * @param commandType 命令类型 + * @param resultSetHandler 结果集处理器 + * @return true 成功 false 失败 + */ + boolean bool(Operator operator, CommandType commandType, ResultSetHandler resultSetHandler); + + /** + * save or update。根据pojo的id查询是否存在 存在则更新,否则查询 + * + * @param pojo the pojo + * @return true 成功 false 失败 + */ + default

    boolean saveOrUpdate(P pojo) { + PojoWrapper

    pojoWrapper = PojoWrapper.getInstance(pojo); + return saveOrUpdate(pojo, () -> { + Object pkValue = ValueWrapper.restore(pojoWrapper.getPKValue()); + return pkValue != null; + }); + } + + /** + * save or update + * + * @param pojo the pojo + * @param func the func + * @return true 成功 false 失败 + */ + default

    boolean saveOrUpdate(P pojo, BooleanSupplier func) { + return saveOrUpdate(pojo, func, new IdMethodReferenceColumn<>(pojo)); + } + + /** + * save or update + * + * @param pojo the pojo + * @param dataExist the dataExist + * @param eqUpdate 用于比较更新字段 + * @return true 成功 false 失败 + */ + default

    boolean saveOrUpdate(P pojo, BooleanSupplier dataExist, MethodReferenceColumn

    eqUpdate) { + PojoWrapper

    pojoWrapper = PojoWrapper.getInstance(pojo); + return saveOrUpdate( + dataExist, + () -> { + UpdateOperator updateOperator = getOperatorGroup().update(getOptions().getDbType()); + updateOperator.from(pojoWrapper.getTable()); + String column = eqUpdate.getColumn(); + // update for eq + Object eqValue = pojoWrapper.getValueByColumn(column); + if (eqValue != null) { + updateOperator.eq(column, eqValue); + } + // 不调用pojoWrapper.getPojo(),原因可能id会被赋值上,违反唯一约束,应该采用拦截器实现 + updateOperator.updatePojo(pojo); + return updateOperator; + }, + () -> { + InsertOperator insertOperator = getOperatorGroup().insert(getOptions().getDbType()); + insertOperator.from(pojoWrapper.getTable()); + insertOperator.insertPojo(pojoWrapper.getPojo()); + return insertOperator; + }); + } + + /** + * save or update + * + * @param f1 判断数据是否存在的query操作 + * @param f2 如果数据存在则update + * @param f3 如果数据不存在则insert + * @return true 成功 false 失败 + */ + default boolean saveOrUpdate(BooleanSupplier f1, UnaryOperator f2, UnaryOperator f3) { + return saveOrUpdate(f1, () -> f2.apply(getOperatorGroup().update(getOptions().getDbType())), () -> f3.apply(getOperatorGroup().insert(getOptions().getDbType()))); + } + + /** + * save or update + * + * @param dataExist 判断数据是否存在的query操作 + * @param updateOperator 如果数据存在则update + * @param insertOperator 如果数据不存在则insert + * @return true 成功 false 失败 + */ + default boolean saveOrUpdate(BooleanSupplier dataExist, UpdateOperator updateOperator, InsertOperator insertOperator) { + return saveOrUpdate(dataExist, () -> updateOperator, () -> insertOperator); + } + + /** + * save or update + * 延迟模式 + * + * @param dataExist 判断数据是否存在的query操作 + * @param updateOperator 如果数据存在则update + * @param insertOperator 如果数据不存在则insert + * @return true 成功 false 失败 + */ + default boolean saveOrUpdate(BooleanSupplier dataExist, Supplier updateOperator, Supplier insertOperator) { + boolean isExist = dataExist.getAsBoolean(); + if (!isExist) { + return insert(insertOperator.get()); + } + return update(updateOperator.get()); + } + + /** + * 查询一个数据 + * + * @param entityClass entityClass + * @param 实体类型 + * @return 实体 or null + */ + default T queryOneById(Class entityClass, ID id) { + PojoWrapper pojoWrapper = PojoWrapper.getInstance(entityClass); + return queryOne(entityClass, o -> + o.selects(pojoWrapper.getColumnDSLName()) + .from(pojoWrapper.getTable()) + .eq(pojoWrapper.getPkColumn().getDslName(), id)); + } + + /** + * 查询一个数据 + * + * @param entityClass entityClass + * @param 实体类型 + * @return 实体 or null + */ + default T queryOne(Class entityClass) { + return queryOne(entityClass, o -> o.selects(PojoWrapper.findColumns(entityClass)).from(entityClass)); + } + + /** + * 查询一个数据 + * + * @param func the func + * @param entityClass entityClass + * @param 实体类型 + * @return 实体 or null + */ + default T queryOne(Class entityClass, UnaryOperator func) { + return queryOne(func.apply(getOperatorGroup().query(getOptions().getDbType())), getOptions().obtainBeanResultSetHandler(entityClass)); + } + + /** + * 查询一个数据 + * + * @param queryOperator queryOperator + * @param entityClass entityClass + * @param 实体类型 + * @return 实体 or null + */ + default T queryOne(Class entityClass, QueryOperator queryOperator) { + return queryOne(queryOperator, getOptions().obtainBeanResultSetHandler(entityClass)); + } + + /** + * 查询一个结果 + * + * @param func the func + * @return ResultGroup + */ + default ResultGroup queryOne(UnaryOperator func) { + return queryOne(func.apply(getOperatorGroup().query(getOptions().getDbType()))); + } + + /** + * 查询结果Map + * + * @param func the func + * @return map + */ + default Map queryMap(UnaryOperator func) { + return queryMap(func.apply(getOperatorGroup().query(getOptions().getDbType()))); + } + + /** + * 查询结果Map + * + * @param queryOperator queryOperator + * @return map + */ + default Map queryMap(QueryOperator queryOperator) { + return queryOne(queryOperator, getOptions().obtainMapResultSetHandler()); + } + + /** + * 查询一个结果 + * + * @param queryOperator queryOperator + * @return ResultGroup + */ + default ResultGroup queryOne(QueryOperator queryOperator) { + return queryOne(queryOperator, getOptions().obtainDefaultResultSetHandler()); + } + + /** + * 查询一个结果 + * + * @param func the func + * @param 结果集对象 + * @return ResultGroup + */ + default R queryOne(UnaryOperator func, ResultSetHandler resultSetHandler) { + return queryOne(func.apply(getOperatorGroup().query(getOptions().getDbType())), resultSetHandler); + } + + /** + * 查询一个结果 + * + * @param queryOperator queryOperator + * @param 结果集对象 + * @return ResultGroup + * @throws DSLException 当结果集大于1时抛出 + */ + default R queryOne(QueryOperator queryOperator, ResultSetHandler resultSetHandler) { + List resultGroups = queryList(queryOperator); + ResultGroup resultGroup = checkCollectionIsOneAndGet(resultGroups); + return Optional.ofNullable(resultGroup).map(resultSetHandler).orElse(null); + } + + /** + * 查询list实体 + * + * @param entityClass entityClass + * @param 类型 + * @return list + */ + default List queryList(Class entityClass) { + return queryList(entityClass, o -> o.selects(PojoWrapper.findColumns(entityClass)).from(entityClass)); + } + + /** + * 根据ids集合查询list实体 + * + * @param entityClass entityClass + * @param ids ids + * @param 类型 + * @return list + */ + default List queryListByIds(Class entityClass, Iterable ids) { + ColumnDef pkColumn = PojoWrapper.findPKColumn(entityClass); + if (pkColumn == null) { + throw new DSLException("Can not find the primary key column"); + } + return queryList(entityClass, o -> o.selects(PojoWrapper.findColumns(entityClass)).from(entityClass).in(pkColumn.getDslName(), ids)); + } + + /** + * 查询list实体 + * + * @param func the func + * @param entityClass entityClass + * @param 类型 + * @return list + */ + default List queryList(Class entityClass, UnaryOperator func) { + return queryList( + entityClass, + func.apply( + getOperatorGroup() + .query(getOptions().getDbType()) + .selects(PojoWrapper.findColumns(entityClass)) + .from(entityClass) + ) + ); + } + + /** + * 查询list实体 + * + * @param queryOperator queryOperator + * @param entityClass entityClass + * @param 类型 + * @return list + */ + default List queryList(Class entityClass, QueryOperator queryOperator) { + return queryList(queryOperator, getOptions().obtainListBeanResultSetHandler(entityClass)); + } + + /** + * 查询list-Map + * + * @param func the func + * @return list map + */ + default List> queryListMap(UnaryOperator func) { + return queryListMap(func.apply(getOperatorGroup().query(getOptions().getDbType()))); + } + + /** + * 查询list-Map + * + * @param queryOperator queryOperator + * @return list map + */ + default List> queryListMap(QueryOperator queryOperator) { + return queryList(queryOperator, getOptions().obtainListMapResultHandler()); + } + + /** + * 查询list + * + * @param func the func + * @return List + * @throws DSLException query failed throw + */ + default List queryList(UnaryOperator func) { + return queryList(func.apply(getOperatorGroup().query(getOptions().getDbType()))); + } + + /** + * 查询list + * + * @param queryOperator queryOperator + * @return List + * @throws DSLException query failed throw + */ + default List queryList(QueryOperator queryOperator) { + return queryList(queryOperator, getOptions().obtainDefaultListResultSetHandler()); + } + + /** + * 查询list + * + * @param func the func + * @param resultSetHandler 结果集处理器 + * @param 返回结果类型 + * @return List + * @throws DSLException query failed throw + */ + default List queryList(UnaryOperator func, ListResultSetHandler resultSetHandler) { + return queryList(func.apply(getOperatorGroup().query(getOptions().getDbType())), resultSetHandler); + } + + /** + * 查询list + * + * @param queryOperator queryOperator + * @param resultSetHandler 结果集处理器 + * @param 返回结果类型 + * @return List + * @throws DSLException query failed throw + */ + default List queryList(QueryOperator queryOperator, ListResultSetHandler resultSetHandler) { + return queryList(queryOperator, CommandType.SELECT, resultSetHandler); + } + + /** + * 查询list + * + * @param queryOperator queryOperator + * @param commandType 命令类型 + * @param resultSetHandler 结果集处理器 + * @param 返回结果类型 + * @return List + * @throws DSLException query failed throw + */ + List queryList(QueryOperator queryOperator, CommandType commandType, ListResultSetHandler resultSetHandler); + + /** + * 查询分页 + * + * @param page page + * @param func the func + * @param 返回结果类型 + * @return List + * @throws DSLException query failed throw + */ + default IPage queryPage(IPage page, UnaryOperator func, Class entityClass) { + PojoWrapper pojoWrapper = PojoWrapper.getInstance(entityClass); + return queryPage( + page, + func.apply(getOperatorGroup() + .query(getOptions().getDbType()) + .selects(pojoWrapper.getColumnDSLName()) + .from(pojoWrapper.getTable())), + entityClass); + } + + /** + * 查询分页 + * + * @param page page + * @param queryOperator queryOperator + * @param 返回结果类型 + * @return List + * @throws DSLException query failed throw + */ + default IPage queryPage(IPage page, QueryOperator queryOperator, Class entityClass) { + return queryPage(page, queryOperator, getOptions().obtainListBeanResultSetHandler(entityClass)); + } + + /** + * 查询分页 + * + * @param page page + * @param func the func + * @return List + * @throws DSLException query failed throw + */ + default IPage> queryPageMap(IPage page, UnaryOperator func) { + return queryPageMap(page, func.apply(getOperatorGroup().query(getOptions().getDbType()))); + } + + /** + * 查询分页 + * + * @param page page + * @param queryOperator queryOperator + * @return List + * @throws DSLException query failed throw + */ + default IPage> queryPageMap(IPage page, QueryOperator queryOperator) { + return queryPage(page, queryOperator, getOptions().obtainListMapResultHandler()); + } + + /** + * 查询分页 + * + * @param page page + * @param func the func + * @return List + * @throws DSLException query failed throw + */ + default IPage queryPage(IPage page, UnaryOperator func) { + return queryPage(page, func.apply(getOperatorGroup().query(getOptions().getDbType()))); + } + + /** + * 查询分页 + * + * @param page page + * @param queryOperator queryOperator + * @return List + * @throws DSLException query failed throw + */ + default IPage queryPage(IPage page, QueryOperator queryOperator) { + return queryPage(page, queryOperator, getOptions().obtainDefaultListResultSetHandler()); + } + + /** + * 查询分页 + * + * @param page page + * @param func the func + * @param resultSetHandler 结果集处理器 + * @param 返回结果类型 + * @return List + * @throws DSLException query failed throw + * @see #queryList(QueryOperator, ListResultSetHandler) + */ + default IPage queryPage(IPage page, UnaryOperator func, ListResultSetHandler resultSetHandler) { + return queryPage(page, func.apply(getOperatorGroup().query(getOptions().getDbType())), resultSetHandler); + } + + /** + * 查询分页 + * + * @param page page + * @param queryOperator queryOperator + * @param resultSetHandler 结果集处理器 + * @param 返回结果类型 + * @return List + * @throws DSLException query failed throw + * @see #queryList(QueryOperator, ListResultSetHandler) + */ + default IPage queryPage(IPage page, QueryOperator queryOperator, ListResultSetHandler resultSetHandler) { + queryOperator.page(page.getCurrent(), page.getSize()); + List r = queryList(queryOperator, resultSetHandler); + Page rPage = new Page<>(page); + rPage.setTotal(r.size()); + rPage.setRecords(r); + return rPage; + } + + /** + * 检查给定的集合是否只有一个元素 + * + * @param collection 集合 + * @param 集合类型 + * @throws DSLException 当给定的集合大于一时抛出 + */ + default T checkCollectionIsOneAndGet(Collection collection) { + if (CollectionUtils.isNotEmpty(collection)) { + int size = collection.size(); + if (size == 1) { + return collection.stream().findFirst().orElse(null); + } else if (size > 1) { + throw new DSLException("Expected one result (or null) to be returned by queryOne(), but found: " + size); + } else { + return null; + } + } + return null; + } + + /** + * 检查连接是否正常 + * + * @return it ture normal connection + * @throws SocketTimeoutException timeout throws + */ + boolean check() throws SocketTimeoutException; + + /** + * 获取执行器key + * + * @return ExecutorKey + */ + ExecutorKey getKey(); + + /** + * 获取DSL操作元数据。 + * + * @return OperatorMetadata实例 + */ + OperatorGroup getOperatorGroup(); + + /** + * 获取执行器参数 + * + * @return ExecutorOptions + */ + ExecutorOptions getOptions(); + + /** + * 销毁,关闭数据连接通道 + */ + default void destroy() { + + } +} \ No newline at end of file diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorFactory.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorFactory.java new file mode 100644 index 00000000..1c0b3b2e --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorFactory.java @@ -0,0 +1,97 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import lombok.extern.slf4j.Slf4j; + +/** + * DSL Executor factory + * + * @author jiangwei + * @date 2023/4/16 23:38 + * @since 1.1.4 + */ +@Slf4j +public final class CommandExecutorFactory { + + private static CommandExecutorRegistry registry; + + private CommandExecutorFactory() { + } + + /** + * 注册{@link CommandExecutor}实例 + * + * @param commandExecutor commandExecutor + * @param T + * @return command executor + */ + public static T register(T commandExecutor) { + return getRegistry().registerCommandExecutor(commandExecutor.getOptions(), () -> commandExecutor, true); + } + + /** + * 基于{@link ExecutorKey#getSystemExecutorKey()}获取的{@link CommandExecutor}实例 + * + * @return DSLExecutor or null + */ + public static T getDSLExecutor() { + T defaultExecutor = getDSLExecutor(CommandExecutor.getDefaultKey()); + if (defaultExecutor == null) { + return getDSLExecutor(ExecutorKey.getSystemExecutorKey()); + } + return defaultExecutor; + } + + /** + * 获取{@link CommandExecutor}实例 + * + * @param executorKey 判断使用何种执行器key + * @return DSLExecutor + */ + public static T getDSLExecutor(ExecutorKey executorKey) { + return getRegistry().getCommandExecutor(executorKey); + } + + /** + * 根据唯一标识获取{@link CommandExecutor}实例 + * + * @param key key + * @return DSLExecutor + */ + public static T getDSLExecutor(String key) { + return getRegistry().getCommandExecutor(key); + } + + /** + * 移除Command executor + * + * @param executorKey executorKey + * @return if true removed + * @see CommandExecutorRegistry#remove(ExecutorKey) + */ + public static boolean remove(ExecutorKey executorKey) { + return getRegistry().remove(executorKey); + } + + /** + * 移除Command executor + * + * @param key key + * @return if true removed + * @see CommandExecutorRegistry#remove(String) + */ + public static boolean remove(String key) { + return getRegistry().remove(key); + } + + private static CommandExecutorRegistry getRegistry() { + if (registry == null) { + setRegistry(new CommandExecutorRegistryImpl()); + } + return registry; + } + + public static void setRegistry(CommandExecutorRegistry registry) { + CommandExecutorFactory.registry = registry; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorRegistry.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorRegistry.java new file mode 100644 index 00000000..f31eeb3d --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorRegistry.java @@ -0,0 +1,112 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import jakarta.validation.constraints.NotNull; + +import java.util.List; +import java.util.function.Supplier; + +/** + * command executor registry,参考自{@link org.springframework.beans.factory.BeanFactory} + * + * @author jiangwei + * @date 2024/1/29 13:04 + * @since 1.1.6 + */ +public interface CommandExecutorRegistry { + + /** + * 基于给定的{@link ExecutorOptions}从{@link ExecutorLoader} + * + * @param executorOptions executorOptions + * @param command executor type + * @return CommandExecutor instance or null + */ + T crate(@NotNull ExecutorOptions executorOptions); + + /** + * 基于给定的{@link ExecutorOptions}从{@link ExecutorLoader}中创建{@link CommandExecutor}并进行注册 + * + * @param executorOptions executorOptions + * @param command executor type + * @return CommandExecutor instance or null + */ + T createAndRegister(@NotNull ExecutorOptions executorOptions); + + /** + * 注册 command executor,如果存在则不在进行设置 + * + * @param executorOptions executorOptions + * @param commandExecutorSupplier commandExecutorSupplier + * @param ifPresent if true 如果已经存在则进行覆盖 否则不进行覆盖 + */ + T registerCommandExecutor(ExecutorOptions executorOptions, Supplier commandExecutorSupplier, boolean ifPresent); + + /** + * 基于最佳匹配原则获取最可能存在的{@link ExecutorOptions},在基于此获取{@link CommandExecutor}实例 + * + * @param executorKey executorKey + * @return CommandExecutor or null + */ + T getCommandExecutor(ExecutorKey executorKey); + + /** + * 获取{@link CommandExecutor}实例 + * + * @param key key + * @return CommandExecutor + */ + T getCommandExecutor(String key); + + /** + * 基于{@link ExecutorKey}批量移除找到{@link CommandExecutor}实例 + * + * @param executorKey executorKey + * @return if ture removed + */ + boolean remove(ExecutorKey executorKey); + + /** + * 基于唯一标识移除{@link CommandExecutor}实例 + * + * @param key key + * @return if ture removed + */ + boolean remove(String key); + + /** + * 根据给定的key判断是否有{@link CommandExecutor}存在 + * + * @param key key + * @return if true life + */ + boolean has(String key); + + /** + * 根据给定的{@link ExecutorKey}判断是否有{@link CommandExecutor}存在 + * + * @param executorKey executorKey + * @return if true life + */ + boolean has(ExecutorKey executorKey); + + /** + * 获取所有默认的{@link CommandExecutor} + * + * @return all default or empty list + */ + List getAllDefault(); + + /** + * 获取所有的CommandExecutor + * + * @return all or empty list + */ + List getAll(); + + /** + * 情空当前注册表里面所有的内容 + */ + void clear(); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorRegistryAutoConfiguration.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorRegistryAutoConfiguration.java new file mode 100644 index 00000000..db6d5f92 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorRegistryAutoConfiguration.java @@ -0,0 +1,21 @@ +package cc.allio.uno.data.orm.executor; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Collections; +import java.util.List; + +@Configuration +@AutoConfigureAfter(ExecutorInitializerAutoConfiguration.class) +public class CommandExecutorRegistryAutoConfiguration { + + @Bean + public CommandExecutorRegistry commandExecutorRegistry(ObjectProvider> loadProvider) { + CommandExecutorRegistryImpl commandExecutorRegistry = new CommandExecutorRegistryImpl(loadProvider.getIfAvailable(Collections::emptyList)); + CommandExecutorFactory.setRegistry(commandExecutorRegistry); + return commandExecutorRegistry; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorRegistryImpl.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorRegistryImpl.java new file mode 100644 index 00000000..d9fcd750 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandExecutorRegistryImpl.java @@ -0,0 +1,252 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.core.env.Envs; +import cc.allio.uno.core.util.CollectionUtils; +import cc.allio.uno.core.util.StringUtils; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import jakarta.validation.constraints.NotNull; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Supplier; + +/** + * command executor registry + * + * @author jiangwei + * @date 2024/1/25 17:07 + * @since 1.1.6 + */ +@Slf4j +public class CommandExecutorRegistryImpl implements CommandExecutorRegistry { + + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + + // 以唯一标识作为key的Map + private final Map commandExecutorMap = Maps.newConcurrentMap(); + // 以option作为key,获取commandExecutor的的唯一标识 + // option的equals是根据 DBType ExecutorKey OperatorKey + private final Map optionsKeyMap = Maps.newConcurrentMap(); + + private final List loaders; + + public CommandExecutorRegistryImpl() { + this(Collections.emptyList()); + } + + public CommandExecutorRegistryImpl(List loaders) { + this.loaders = loaders; + } + + @Override + public T crate(@NotNull ExecutorOptions executorOptions) { + DBType dbType = executorOptions.getDbType(); + ExecutorLoader executorLoader = + loaders.stream() + .filter(loader -> loader.match(dbType)) + .findFirst() + .orElse(null); + if (executorLoader == null) { + return null; + } + return (T) executorLoader.load(executorOptions); + } + + @Override + public T createAndRegister(@NotNull ExecutorOptions executorOptions) { + DBType dbType = executorOptions.getDbType(); + ExecutorLoader executorLoader = + loaders.stream() + .filter(loader -> loader.match(dbType)) + .findFirst() + .orElse(null); + if (executorLoader == null) { + return null; + } + return (T) registerCommandExecutor(executorOptions, () -> executorLoader.load(executorOptions), true); + } + + @Override + public T registerCommandExecutor(ExecutorOptions executorOptions, Supplier commandExecutorSupplier, boolean ifPresent) { + Lock writeLock = lock.writeLock(); + writeLock.lock(); + try { + String key = executorOptions.getKey(); + if (log.isDebugEnabled()) { + log.debug("register command executor key: {}, executorOptions: {}", key, executorOptions.getKey()); + } + T commandExecutor; + if (ifPresent) { + commandExecutor = (T) commandExecutorMap.compute(key, (k, v) -> commandExecutorSupplier.get()); + optionsKeyMap.compute(executorOptions, (k, v) -> key); + } else { + commandExecutor = (T) commandExecutorMap.computeIfAbsent(key, k -> commandExecutorSupplier.get()); + optionsKeyMap.computeIfAbsent(executorOptions, k -> key); + } + boolean systemDefault = executorOptions.isSystemDefault(); + if (systemDefault) { + Envs.setProperty(ExecutorKey.DSL_EXECUTOR_TYPE_KEY, executorOptions.getExecutorKey().key()); + Envs.setProperty(CommandExecutor.DEFAULT_KEY, key); + } + return commandExecutor; + } finally { + writeLock.unlock(); + } + } + + @Override + public T getCommandExecutor(ExecutorKey executorKey) { + if (executorKey == null) { + return null; + } + Lock readLock = lock.readLock(); + readLock.lock(); + try { + ExecutorOptions options = match(executorKey); + if (options == null) { + return null; + } + String key = optionsKeyMap.get(options); + if (StringUtils.isBlank(key)) { + return null; + } + return getCommandExecutor(key); + } finally { + readLock.unlock(); + } + } + + @Override + public T getCommandExecutor(String key) { + if (StringUtils.isBlank(key)) { + return null; + } + Lock readLock = lock.readLock(); + readLock.lock(); + try { + return (T) commandExecutorMap.get(key); + } finally { + readLock.unlock(); + } + } + + @Override + public boolean remove(ExecutorKey executorKey) { + List executorOptions = matchAll(executorKey); + if (CollectionUtils.isNotEmpty(executorOptions)) { + return executorOptions.stream() + .allMatch(options -> { + String key = optionsKeyMap.get(options); + return remove(key); + }); + } + return false; + } + + @Override + public boolean remove(String key) { + if (StringUtils.isBlank(key)) { + return false; + } + Lock readLock = lock.readLock(); + readLock.lock(); + try { + CommandExecutor commandExecutor = commandExecutorMap.get(key); + if (commandExecutor == null) { + return false; + } + ExecutorOptions options = commandExecutor.getOptions(); + if (log.isDebugEnabled()) { + log.debug("remove command executor {}", options); + } + try { + commandExecutor.destroy(); + } catch (Throwable ex) { + log.error("command executor destroy has error, the command options is {}", options, ex); + } + commandExecutorMap.remove(key); + optionsKeyMap.remove(options); + return true; + } finally { + readLock.unlock(); + } + } + + @Override + public boolean has(String key) { + if (StringUtils.isBlank(key)) { + return false; + } + return commandExecutorMap.containsKey(key); + } + + @Override + public boolean has(ExecutorKey executorKey) { + ExecutorOptions executorOptions = match(executorKey); + return executorOptions != null; + } + + @Override + public List getAllDefault() { + return commandExecutorMap.values() + .stream() + .filter(commandExecutor -> commandExecutor.getOptions().isSystemDefault()) + .toList(); + } + + @Override + public List getAll() { + return Lists.newArrayList(commandExecutorMap.values()); + } + + @Override + public void clear() { + Lock readLock = lock.readLock(); + readLock.lock(); + try { + Collection values = commandExecutorMap.values(); + for (CommandExecutor executor : values) { + remove(executor.getOptions().getKey()); + } + } finally { + readLock.unlock(); + } + } + + /** + * 根据executor key最佳匹配某一个{@link ExecutorOptions} + * + * @param executorKey executorKey + * @return ExecutorOptions or null + */ + private ExecutorOptions match(ExecutorKey executorKey) { + Set executorOptions = optionsKeyMap.keySet(); + for (ExecutorOptions executorOption : executorOptions) { + // 基于 key 进行比较 + if (executorOption.getExecutorKey().equals(executorKey)) { + return executorOption; + } + } + return null; + } + + /** + * 匹配所有包含executorKey的{@link ExecutorOptions} + * + * @param executorKey executorKey + * @return list + */ + private List matchAll(ExecutorKey executorKey) { + return optionsKeyMap.keySet() + .stream() + .filter(options -> options.getExecutorKey().equals(executorKey)) + .toList(); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandType.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandType.java new file mode 100644 index 00000000..b9543858 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandType.java @@ -0,0 +1,23 @@ +package cc.allio.uno.data.orm.executor; + +/** + * 执行命令 + * + * @author jiangwei + * @date 2023/4/14 13:49 + * @since 1.1.4 + */ +public enum CommandType { + UNKNOWN, + ALERT_TABLE, + CREATE_TABLE, + DELETE_TABLE, + EXIST_TABLE, + INSERT, + UPDATE, + DELETE, + SELECT, + FLUSH, + SHOW_COLUMNS, + SHOW_TABLES +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandTypeExecutor.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandTypeExecutor.java new file mode 100644 index 00000000..3f348703 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/CommandTypeExecutor.java @@ -0,0 +1,24 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; + +/** + * 定义DSL命令类型执行器 + * + * @author jiangwei + * @date 2023/5/29 20:41 + * @since 1.1.4 + */ +public interface CommandTypeExecutor { + + /** + * 执行类型 + * + * @param operator 操作器 + * @param resultSetHandler 结果集处理器 + * @return R + * @throws Throwable 执行发生异常时抛出 + */ + R exec(Operator operator, ResultSetHandler resultSetHandler) throws Throwable; +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorAware.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorAware.java new file mode 100644 index 00000000..2ba6c6f2 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorAware.java @@ -0,0 +1,29 @@ +package cc.allio.uno.data.orm.executor; + +/** + * 实现方获取动态获取{@link CommandExecutor}实例。 + *

    + * 该包提供相关API用于具体的实现继承,由具体的executor提供如何动态获取方法。 + *

    + *

    + * 核心思路是采用编程式Aspect创建代理类 + *

    + *

    + * 该接口的实现类必须是Spring Bean + *

    + * + * @author jiangwei + * @date 2024/1/10 18:00 + * @since 1.1.6 + */ +public interface ExecutorAware { + + /** + * 获取CommandExecutor实例 + * + * @return CommandExecutor + */ + default CommandExecutor getExecutor() { + return null; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorFactoryBean.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorFactoryBean.java new file mode 100644 index 00000000..0690fc24 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorFactoryBean.java @@ -0,0 +1,25 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import org.springframework.beans.factory.FactoryBean; + +/** + * 基于当前系统变量的{@link ExecutorKey#DSL_EXECUTOR_TYPE_KEY}获取对应的{@code CommandExecutor} + * + * @author jiangwei + * @date 2024/1/10 18:10 + * @since 1.1.6 + */ +public class ExecutorFactoryBean implements FactoryBean { + + @Override + public CommandExecutor getObject() throws Exception { + ExecutorKey executorKey = ExecutorKey.getSystemExecutorKey(); + return CommandExecutorFactory.getDSLExecutor(executorKey); + } + + @Override + public Class getObjectType() { + return CommandExecutor.class; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorInitializer.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorInitializer.java new file mode 100644 index 00000000..eb68eb74 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorInitializer.java @@ -0,0 +1,32 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import org.springframework.beans.factory.InitializingBean; + +import java.util.List; + +/** + * 初始化{@link CommandExecutor} + * + * @author jiangwei + * @date 2024/1/10 16:04 + * @since 1.1.6 + */ +public final class ExecutorInitializer implements InitializingBean { + + private final List loaders; + private final List interceptors; + + public ExecutorInitializer(List loaders, List interceptors) { + this.loaders = loaders; + this.interceptors = interceptors; + } + + @Override + public void afterPropertiesSet() throws Exception { + for (ExecutorLoader loader : loaders) { + CommandExecutor commandExecutor = loader.load(interceptors); + CommandExecutorFactory.register(commandExecutor); + } + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorInitializerAutoConfiguration.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorInitializerAutoConfiguration.java new file mode 100644 index 00000000..477d222a --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorInitializerAutoConfiguration.java @@ -0,0 +1,26 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Collections; +import java.util.List; + +@Configuration +public class ExecutorInitializerAutoConfiguration { + + @Bean + public ExecutorFactoryBean executorFactoryBean() { + return new ExecutorFactoryBean(); + } + + @Bean + public ExecutorInitializer executorInitializer(ObjectProvider> loaderProvider, + ObjectProvider> interceptorProvider) { + List executorLoaders = loaderProvider.getIfAvailable(Collections::emptyList); + List interceptors = interceptorProvider.getIfAvailable(Collections::emptyList); + return new ExecutorInitializer(executorLoaders, interceptors); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorLoader.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorLoader.java new file mode 100644 index 00000000..7243fd5d --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorLoader.java @@ -0,0 +1,42 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; + +import java.util.List; + +/** + * {@link CommandExecutor}实例加载器 + * + * @author jiangwei + * @date 2024/1/10 16:02 + * @since 1.1.6 + */ +public interface ExecutorLoader { + + /** + * 基于{@link Interceptor}创建{@link CommandExecutor}实例 + * + * @param interceptors interceptors + * @return CommandExecutor + */ + CommandExecutor load(List interceptors); + + /** + * 基于{@link ExecutorOptions}创建{@link CommandExecutor}实例 + * + * @param executorOptions executorOptions + * @return CommandExecutor + */ + CommandExecutor load(ExecutorOptions executorOptions); + + /** + * 判断给定的{@link DBType}当前{@link ExecutorLoader}是否可以加载 + * + * @param dbType dbType + * @return if true loaded + */ + boolean match(DBType dbType); +} + diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorOptionsBuilder.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorOptionsBuilder.java new file mode 100644 index 00000000..aba968a9 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ExecutorOptionsBuilder.java @@ -0,0 +1,213 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.core.util.StringUtils; +import cc.allio.uno.core.util.id.IdGenerator; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.core.api.Self; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import cc.allio.uno.data.orm.executor.options.ExecutorOptionsImpl; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import jakarta.validation.constraints.NotNull; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * {@link ExecutorOptionsImpl}构建 + * + * @author jiangwei + * @date 2024/1/25 17:52 + * @since 1.1.6 + */ +public class ExecutorOptionsBuilder implements Self { + + private String key; + private DBType dbType; + private ExecutorKey executorKey; + private OperatorKey operatorKey; + private boolean systemDefault = false; + private String address; + private String username; + private String password; + private String database; + private final List interceptors = Lists.newArrayList(); + private final Map properties = Maps.newHashMap(); + + public static ExecutorOptionsBuilder create() { + return create(DBType.H2, IdGenerator.defaultGenerator().getNextIdAsString()); + } + + public static ExecutorOptionsBuilder create(String key) { + return create(DBType.H2, key); + } + + public static ExecutorOptionsBuilder create(DBType dbType) { + return create(dbType, null); + } + + public static ExecutorOptionsBuilder create(@NotNull DBType dbType, String key) { + ExecutorOptionsBuilder builder = new ExecutorOptionsBuilder(); + if (StringUtils.isBlank(key)) { + key = IdGenerator.defaultGenerator().getNextIdAsString(); + } + builder.key = key; + builder.dbType = dbType; + builder.setProperty(ExecutorOptionsProperty.DB_TYPE, dbType); + return builder; + } + + /** + * setValue executor key + * + * @param executorKey executorKey + * @return ExecutorOptionsBuilder + */ + public ExecutorOptionsBuilder executorKey(@NotNull ExecutorKey executorKey) { + this.executorKey = executorKey; + setProperty(ExecutorOptionsProperty.EXECUTOR_KEY, executorKey); + return self(); + } + + /** + * setValue operator key + * + * @param operatorKey operatorKey + * @return ExecutorOptionsBuilder + */ + public ExecutorOptionsBuilder operatorKey(@NotNull OperatorKey operatorKey) { + this.operatorKey = operatorKey; + setProperty(ExecutorOptionsProperty.OPERATOR_KEY, operatorKey); + return self(); + } + + /** + * setValue address, like localhost:1000, if cluster address is localhost:1000,localhost:1001 etc... + * + * @param address address + * @return ExecutorOptionsBuilder + */ + public ExecutorOptionsBuilder address(String address) { + this.address = address; + setProperty(ExecutorOptionsProperty.ADDRESS, address); + return self(); + } + + /** + * setValue username + * + * @param username username + * @return ExecutorOptionsBuilder + */ + public ExecutorOptionsBuilder username(String username) { + this.username = username; + setProperty(ExecutorOptionsProperty.USERNAME, username); + return self(); + } + + /** + * setValue password + * + * @param password password + * @return ExecutorOptionsBuilder + */ + public ExecutorOptionsBuilder password(String password) { + this.password = password; + setProperty(ExecutorOptionsProperty.PASSWORD, password); + return self(); + } + + /** + * setValue database + * + * @param database database + * @return ExecutorOptionsBuilder + */ + public ExecutorOptionsBuilder database(String database) { + this.database = database; + setProperty(ExecutorOptionsProperty.DATABASE, database); + return self(); + } + + /** + * setValue system default + * + * @param systemDefault systemDefault + * @return ExecutorOptionsBuilder + */ + public ExecutorOptionsBuilder systemDefault(boolean systemDefault) { + this.systemDefault = systemDefault; + setProperty(ExecutorOptionsProperty.SYSTEM_DEFAULT, systemDefault); + return self(); + } + + /** + * setValue interceptor + * + * @param interceptor interceptor + * @return ExecutorOptionsBuilder + */ + public ExecutorOptionsBuilder interceptor(Interceptor interceptor) { + this.interceptors.add(interceptor); + return self(); + } + + /** + * setValue interceptors + * + * @param interceptors interceptors + * @return ExecutorOptionsBuilder + */ + public ExecutorOptionsBuilder interceptors(Collection interceptors) { + this.interceptors.addAll(interceptors); + return self(); + } + + /** + * setValue options property + * + * @param key 属性名称 + * @param value 属性值 + */ + public ExecutorOptionsBuilder setProperty(String key, Object value) { + properties.put(key, value); + return self(); + } + + /** + * build requirement is {@link #dbType} {@link #executorKey} {@link #operatorKey} not null + * + * @return ExecutorOptions + * @throws IllegalArgumentException if {@code dbType} {@code executorKey} {@code operatorKey} is null + */ + public ExecutorOptions build() { + if (dbType == null || executorKey == null || operatorKey == null) { + throw new IllegalArgumentException("dbType or executorKey or operatorKey is null"); + } + ExecutorOptions executorOptions = new ExecutorOptionsImpl(key, dbType, executorKey, operatorKey); + executorOptions.setSystemDefault(systemDefault); + executorOptions.setAddress(address); + executorOptions.setUsername(username); + executorOptions.setPassword(password); + executorOptions.setDatabase(database); + executorOptions.putAll(properties); + executorOptions.addInterceptors(interceptors); + return executorOptions; + } + + + public interface ExecutorOptionsProperty { + String DB_TYPE = "dbType"; + String EXECUTOR_KEY = "executorKey"; + String OPERATOR_KEY = "operatorKey"; + String ADDRESS = "address"; + String USERNAME = "username"; + String PASSWORD = "password"; + String DATABASE = "database"; + String SYSTEM_DEFAULT = "systemDefault"; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/IPage.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/IPage.java similarity index 78% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/IPage.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/IPage.java index 2fe61927..91af3e83 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/IPage.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/IPage.java @@ -38,11 +38,11 @@ default Map condition() { } /** - * 自动优化 COUNT SQL【 默认:true 】 + * 自动优化 COUNT DSL【 默认:true 】 * * @return true 是 / false 否 */ - default boolean optimizeCountSql() { + default boolean optimizeCountDSL() { return true; } @@ -215,4 +215,48 @@ default String cacheKey() { return key.toString(); } + /** + * 创建{@link IPage}实例 + * + * @see Page#Page(IPage) + */ + static IPage create(IPage page) { + return new Page<>(page); + } + + /** + * 创建{@link IPage}实例 + * + * @see Page#Page(long, long) + */ + static IPage create(long current, long size) { + return new Page<>(current, size); + } + + /** + * 创建{@link IPage}实例 + * + * @see Page#Page(long, long, long) + */ + static IPage create(long current, long size, long total) { + return new Page<>(current, size, total); + } + + /** + * 创建{@link IPage}实例 + * + * @see Page#Page(long, long, boolean) + */ + static IPage create(long current, long size, boolean isSearchCount) { + return new Page<>(current, size, isSearchCount); + } + + /** + * 创建{@link IPage}实例 + * + * @see Page#Page(long, long, long, boolean) + */ + static IPage create(long current, long size, long total, boolean isSearchCount) { + return new Page<>(current, size, total, isSearchCount); + } } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/IdMethodReferenceColumn.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/IdMethodReferenceColumn.java new file mode 100644 index 00000000..14f7b4de --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/IdMethodReferenceColumn.java @@ -0,0 +1,37 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.core.function.lambda.MethodReferenceColumn; +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.helper.PojoWrapper; + +import java.util.Optional; + +/** + * pojo的id方法 + * + * @author jiangwei + * @date 2023/7/11 12:34 + * @since 1.1.4 + */ +public class IdMethodReferenceColumn

    implements MethodReferenceColumn

    { + + private final PojoWrapper

    wrapper; + + public IdMethodReferenceColumn(P pojo) { + this.wrapper = PojoWrapper.getInstance(pojo); + } + + @Override + public String getColumn() { + return Optional.ofNullable(wrapper.getPkColumn()) + .map(ColumnDef::getDslName) + .map(DSLName::getName) + .orElse(null); + } + + @Override + public Object apply(P p) { + return p; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/OrderItem.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/OrderItem.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/OrderItem.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/OrderItem.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/Page.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/Page.java similarity index 94% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/Page.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/Page.java index 3333122e..fd58845c 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/Page.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/Page.java @@ -48,9 +48,9 @@ public class Page implements IPage { protected List orders = new ArrayList<>(); /** - * 自动优化 COUNT SQL + * 自动优化 COUNT DSL */ - protected boolean optimizeCountSql = true; + protected boolean optimizeCountDSL = true; /** * 是否进行 count 查询 */ @@ -250,7 +250,7 @@ public Page setAscs(List ascs) { */ @Deprecated public Page setAsc(String... ascs) { - // 保证原来方法 set 的语意 + // 保证原来方法 setValue 的语意 removeOrder(OrderItem::isAsc); for (String s : ascs) { addOrder(OrderItem.asc(s)); @@ -267,7 +267,7 @@ public Page setAsc(String... ascs) { */ @Deprecated public Page setDescs(List descs) { - // 保证原来方法 set 的语意 + // 保证原来方法 setValue 的语意 if (CollectionUtils.isNotEmpty(descs)) { removeOrder(item -> !item.isAsc()); for (String s : descs) { @@ -297,12 +297,12 @@ public List orders() { } @Override - public boolean optimizeCountSql() { - return optimizeCountSql; + public boolean optimizeCountDSL() { + return optimizeCountDSL; } - public boolean isOptimizeCountSql() { - return optimizeCountSql(); + public boolean isOptimizeCountDSL() { + return optimizeCountDSL(); } @Override @@ -318,8 +318,8 @@ public Page setSearchCount(boolean isSearchCount) { return this; } - public Page setOptimizeCountSql(boolean optimizeCountSql) { - this.optimizeCountSql = optimizeCountSql; + public Page setOptimizeCountDSL(boolean optimizeCountDSL) { + this.optimizeCountDSL = optimizeCountDSL; return this; } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ResultGroup.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ResultGroup.java new file mode 100644 index 00000000..22a46e5c --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ResultGroup.java @@ -0,0 +1,408 @@ +package cc.allio.uno.data.orm.executor; + +import cc.allio.uno.core.StringPool; +import cc.allio.uno.core.type.Types; +import cc.allio.uno.core.util.ClassUtils; +import cc.allio.uno.core.util.JsonUtils; +import cc.allio.uno.core.function.lambda.MethodReferenceColumn; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.helper.PojoWrapper; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import lombok.Data; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * 结果集。保持顺序一致性 + * + * @author jiangwei + * @date 2023/4/14 18:02 + * @since 1.1.4 + */ +@Data +public class ResultGroup { + + private static DSLName.NameFeature lowCaseAndHumpNameFeature = DSLName.NameFeature.aggregate(DSLName.LOWER_CASE_FEATURE, DSLName.HUMP_FEATURE); + private List resultRows = Lists.newArrayList(); + // 以小写、驼峰作为key + private Map resultRowMap = Maps.newHashMap(); + + /** + * 添加{@link ResultRow} + * + * @param row row + */ + public void addRow(ResultRow row) { + resultRows.add(row.getIndex(), row); + resultRowMap.put(row.getColumn().format(lowCaseAndHumpNameFeature), row); + } + + /** + * 添加{@link ResultRow}集合 + * + * @param resultRows the resultRows + */ + public void addAllRows(Collection resultRows) { + resultRows.forEach(this::addRow); + } + + /** + * 根据结果集索引 + * + * @param index index + */ + public ResultRow getRow(int index) { + return resultRows.get(index); + } + + /** + * 基于{@link DSLName}获取。其中{@link DSLName#format(DSLName.NameFeature)}使用{@link #lowCaseAndHumpNameFeature}先转小写在转驼峰。 + *

    保持与map集合中key的存储方式一致

    + * + * @param columnName 字段名称 + * @return ResultRow + */ + public ResultRow getRow(DSLName columnName) { + return resultRowMap.get(columnName.format(lowCaseAndHumpNameFeature)); + } + + /** + * 根据字段名称获取ResultRow + * + * @param columnName 字段名称 + * @return ResultRow + */ + public ResultRow getRow(String columnName) { + return resultRowMap.get(columnName); + } + + /** + * 根据方法索引获取字段名 + * + * @param ref ref + * @return ResultRow + */ + public ResultRow getRow(MethodReferenceColumn ref) { + return getRow(ref.getColumn()); + } + + /** + * 返回实体对象 + * + * @param entity 实体类型 + * @param 实体范型 + * @return T + */ + public T toEntity(Class entity) { + T metadata = ClassUtils.newInstance(entity); + PojoWrapper wrapper = PojoWrapper.getInstance(metadata); + for (ResultRow resultRow : resultRows) { + Object value = resultRow.getValue(); + if (value != null) { + String column = DSLName.of(resultRow.getColumn(), DSLName.LOWER_CASE_FEATURE, DSLName.HUMP_FEATURE).format(); + wrapper.setForce(column, value); + } + } + return metadata; + } + + /** + * 返回map数据 + * + * @return map + */ + public Map toMap() { + Map valuesMap = Maps.newHashMap(); + for (Map.Entry entry : resultRowMap.entrySet()) { + valuesMap.put(entry.getKey(), entry.getValue().getValue()); + } + return valuesMap; + } + + /** + * 返回json数据 + * + * @return json 字符串 + */ + public String toJson() { + return JsonUtils.toJson(toMap()); + } + + /** + * @see #getOptionStringValue(String, Consumer) + */ + public void getOptionStringValue(DSLName columnName, Consumer acceptor) { + getOptionValue(columnName, Types::toString, acceptor); + } + + /** + * 获取字段值,如果存在则回调 acceptor + * + * @param columnName columnName + * @param acceptor acceptor + */ + public void getOptionStringValue(String columnName, Consumer acceptor) { + getOptionValue(columnName, Types::toString, acceptor); + } + + /** + * @see #getOptionValue(String, Function, Consumer) + */ + public void getOptionValue(DSLName columnName, Function transfer, Consumer acceptor) { + Optional.ofNullable(getRow(columnName)) + .map(ResultRow::getValue) + .map(transfer) + .ifPresent(acceptor); + } + + /** + * 获取字段值,如果存在则回调 acceptor + * + * @param columnName columnName + * @param transfer 提供value的Object类型转换为R类型 + * @param acceptor acceptor + */ + public void getOptionValue(String columnName, Function transfer, Consumer acceptor) { + Optional.ofNullable(getRow(columnName)) + .map(ResultRow::getValue) + .map(transfer) + .ifPresent(acceptor); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Integer getIntegerValue(String columnName) { + return getValue(columnName, Types::parseInteger, () -> null); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Integer getIntegerValue(DSLName columnName) { + return getValue(columnName, Types::parseInteger, () -> null); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Integer getIntegerValue(String columnName, Supplier defaultValue) { + return getValue(columnName, Types::parseInteger, defaultValue); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Integer getIntegerValue(DSLName columnName, Supplier defaultValue) { + return getValue(columnName, Types::parseInteger, defaultValue); + } + + /** + * @see #getValue(String, Function, Supplier, Function) + */ + public K getIntegerValue(String columnName, Supplier defaultValue, Function adjuster) { + return getValue(columnName, Types::parseInteger, defaultValue, adjuster); + } + + /** + * @see #getValue(String, Function, Supplier, Function) + */ + public K getIntegerValue(DSLName columnName, Supplier defaultValue, Function adjuster) { + return getValue(columnName, Types::parseInteger, defaultValue, adjuster); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Long getLongValue(String columnName) { + return getValue(columnName, Types::parseLong, () -> null); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Long getLongValue(DSLName columnName) { + return getValue(columnName, Types::parseLong, () -> null); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Long getLongValue(String columnName, Supplier defaultValue) { + return getValue(columnName, Types::parseLong, defaultValue); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Long getLongValue(DSLName columnName, Supplier defaultValue) { + return getValue(columnName, Types::parseLong, defaultValue); + } + + /** + * @see #getValue(String, Function, Supplier, Function) + */ + public K getLongValue(String columnName, Supplier defaultValue, Function adjuster) { + return getValue(columnName, Types::parseLong, defaultValue, adjuster); + } + + /** + * @see #getValue(String, Function, Supplier, Function) + */ + public K getLongValue(DSLName columnName, Supplier defaultValue, Function adjuster) { + return getValue(columnName, Types::parseLong, defaultValue, adjuster); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Boolean getBoolValue(String columnName) { + return getBoolValue(columnName, () -> false); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Boolean getBoolValue(DSLName columnName) { + return getBoolValue(columnName, () -> false); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Boolean getBoolValue(String columnName, Supplier defaultValue) { + return getValue(columnName, Types::parseBoolean, defaultValue); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public Boolean getBoolValue(DSLName columnName, Supplier defaultValue) { + return getValue(columnName, Types::parseBoolean, defaultValue); + } + + /** + * @see #getValue(String, Function, Supplier, Function) + */ + public K getBoolValue(String columnName, Supplier defaultValue, Function adjuster) { + return getValue(columnName, Types::parseBoolean, defaultValue, adjuster); + } + + /** + * @see #getValue(String, Function, Supplier, Function) + */ + public K getBoolValue(DSLName columnName, Supplier defaultValue, Function adjuster) { + return getValue(columnName, Types::parseBoolean, defaultValue, adjuster); + } + + /** + * default value return empty string + * + * @see #getValue(String, Function, Supplier) + */ + public String getStringValue(String columnName) { + return getStringValue(columnName, () -> StringPool.EMPTY); + } + + /** + * default value return empty string + * + * @see #getValue(String, Function, Supplier) + */ + public String getStringValue(DSLName columnName) { + return getStringValue(columnName, () -> StringPool.EMPTY); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public String getStringValue(String columnName, Supplier defaultValue) { + return getValue(columnName, Types::toString, defaultValue); + } + + /** + * @see #getValue(String, Function, Supplier) + */ + public String getStringValue(DSLName columnName, Supplier defaultValue) { + return getValue(columnName, Types::toString, defaultValue); + } + + /** + * @see #getValue(String, Function, Supplier, Function) + */ + public K getStringValue(String columnName, Supplier defaultValue, Function adjuster) { + return getValue(columnName, Types::toString, defaultValue, adjuster); + } + + /** + * @see #getValue(String, Function, Supplier, Function) + */ + public K getStringValue(DSLName columnName, Supplier defaultValue, Function adjuster) { + return getValue(columnName, Types::toString, defaultValue, adjuster); + } + + /** + * default value 返回null + * + * @see #getValue(DSLName, Function, Supplier, Function) + */ + public Object getValue(String columnName) { + return getValue(columnName, f -> f, () -> null, f -> f); + } + + /** + * @see #getValue(DSLName, Function, Supplier, Function) + */ + public Object getValue(String columnName, Supplier defaultValue) { + return getValue(columnName, f -> f, defaultValue, f -> f); + } + + /** + * @see #getValue(DSLName, Function, Supplier, Function) + */ + public R getValue(String columnName, Function transfer, Supplier defaultValue) { + return getValue(columnName, transfer, defaultValue, f -> f); + } + + /** + * @see #getValue(DSLName, Function, Supplier, Function) + */ + public R getValue(DSLName columnName, Function transfer, Supplier defaultValue) { + return getValue(columnName, transfer, defaultValue, f -> f); + } + + /** + * @see #getValue(DSLName, Function, Supplier, Function) + */ + public K getValue(String columnName, Function transfer, Supplier defaultValue, Function adjuster) { + return getValue(DSLName.of(columnName), transfer, defaultValue, adjuster); + } + + /** + * 获取字段值,提供字段转换器,如果为null或者不存在则使用default Value + * 该api提供对返回值的再次加工 + * + * @param columnName columnName + * @param transfer 提供value的Object类型转换为R类型 + * @param defaultValue 默认值 + * @param adjuster 加工器,对值再次进行二次加工 + * @param 返回类型 + * @param 加工返回值的类型 + * @return column value or default value + */ + public K getValue(DSLName columnName, Function transfer, Supplier defaultValue, Function adjuster) { + return Optional.ofNullable(getRow(columnName)) + .map(ResultRow::getValue) + .map(transfer) + .or(() -> Optional.ofNullable(defaultValue.get())) + .map(adjuster) + .orElse(null); + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultRow.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ResultRow.java similarity index 79% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultRow.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ResultRow.java index 2ee606f3..d1991a0a 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultRow.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ResultRow.java @@ -1,7 +1,7 @@ package cc.allio.uno.data.orm.executor; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.type.JavaType; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.type.JavaType; import lombok.Builder; import lombok.Data; @@ -20,7 +20,7 @@ public class ResultRow { // 结果集索引 private int index; // 字段名称 - private SQLName column; + private DSLName column; // 字段值 private Object value; // jdbc类型 diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultSet.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ResultSet.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultSet.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/ResultSet.java diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/BeanResultHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/BeanResultHandler.java new file mode 100644 index 00000000..2deee811 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/BeanResultHandler.java @@ -0,0 +1,23 @@ +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.core.util.ReflectTool; + +/** + * marked bean handler interface + * + * @param bean type + * @author jiangwei + * @date 2024/2/14 16:52 + * @since 1.1.6 + */ +public interface BeanResultHandler extends ResultHandler { + + /** + * 获取bean 类型 + * + * @return Class + */ + default Class getBeanType() { + return (Class) ReflectTool.getGenericType(this, BeanResultHandler.class); + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/BeanResultSetHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/BeanResultSetHandler.java similarity index 61% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/BeanResultSetHandler.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/BeanResultSetHandler.java index feec2e1f..53c0bbb2 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/BeanResultSetHandler.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/BeanResultSetHandler.java @@ -1,4 +1,6 @@ -package cc.allio.uno.data.orm.executor; +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.data.orm.executor.ResultGroup; /** * Java Bean对象处理器 @@ -7,7 +9,7 @@ * @date 2023/4/18 13:17 * @since 1.1.4 */ -public class BeanResultSetHandler implements ResultSetHandler { +public class BeanResultSetHandler extends ExecutorOptionsAwareImpl implements ResultSetHandler, BeanResultHandler { private final Class beanClass; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/BoolResultHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/BoolResultHandler.java similarity index 51% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/BoolResultHandler.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/BoolResultHandler.java index 88ec68f5..a0465c08 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/BoolResultHandler.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/BoolResultHandler.java @@ -1,6 +1,9 @@ -package cc.allio.uno.data.orm.executor; +package cc.allio.uno.data.orm.executor.handler; import cc.allio.uno.core.type.Types; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.executor.ResultGroup; +import cc.allio.uno.data.orm.executor.ResultRow; import com.google.common.collect.Lists; import java.util.List; @@ -12,16 +15,16 @@ * @date 2023/4/18 13:38 * @since 1.1.4 */ -public class BoolResultHandler implements ResultSetHandler { +public class BoolResultHandler extends ExecutorOptionsAwareImpl implements ResultSetHandler { // guess list column name - public static final String GUESS_UPDATE_OR_UPDATE = "update"; - public static final String GUESS_COUNT = "count"; - private static final List GUESS_LIST = Lists.newArrayList(GUESS_UPDATE_OR_UPDATE, GUESS_COUNT); + public static final DSLName GUESS_UPDATE_OR_UPDATE = DSLName.of("UPDATE", DSLName.HUMP_FEATURE); + public static final DSLName GUESS_COUNT = DSLName.of("COUNT", DSLName.HUMP_FEATURE); + private static final List GUESS_LIST = Lists.newArrayList(GUESS_UPDATE_OR_UPDATE, GUESS_COUNT); @Override public Boolean apply(ResultGroup resultGroup) { - for (String guess : GUESS_LIST) { + for (DSLName guess : GUESS_LIST) { ResultRow row = resultGroup.getRow(guess); if (row != null) { try { diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ColumnDefListResultSetHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ColumnDefListResultSetHandler.java new file mode 100644 index 00000000..4bc790c5 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ColumnDefListResultSetHandler.java @@ -0,0 +1,79 @@ +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.core.StringPool; +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.ddl.ShowColumnsOperator; +import cc.allio.uno.data.orm.dsl.dialect.TypeTranslator; +import cc.allio.uno.data.orm.dsl.dialect.TypeTranslatorHolder; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DataType; +import cc.allio.uno.data.orm.dsl.type.DSLType; +import cc.allio.uno.data.orm.executor.ResultGroup; +import cc.allio.uno.data.orm.executor.ResultSet; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import com.google.common.collect.Lists; + +import java.util.List; + +/** + * {@link ColumnDef}结果集处理器 + * + * @author jiangwei + * @date 2023/7/4 14:54 + * @since 1.1.4 + */ +public class ColumnDefListResultSetHandler extends ExecutorOptionsAwareImpl implements ListResultSetHandler { + + protected static final String NULL_YES = "YES"; + protected static final String NULL_NO = "NO"; + + @Override + public List apply(ResultSet resultSet) { + return Lists.newArrayList(resultSet) + .stream() + .map(r -> commonFieldBuilder(r).build()) + .toList(); + } + + protected ColumnDef.ColumnDefBuilder commonFieldBuilder(ResultGroup r) { + ColumnDef.ColumnDefBuilder builder = ColumnDef.builder(); + // column name + DSLName dslName = r.getStringValue(ShowColumnsOperator.COLUMN_NAME_FIELD, () -> StringPool.EMPTY, columnName -> DSLName.of(columnName, DSLName.PLAIN_FEATURE)); + builder.dslName(dslName); + // column type + ExecutorOptions executorOptions = obtainExecutorOptions(); + DBType dbType = executorOptions.getDbType(); + TypeTranslator typeTranslator = TypeTranslatorHolder.getTypeTranslator(dbType); + DSLType dslType = typeTranslator.reserve(r.getStringValue(ShowColumnsOperator.DATA_TYPE_FIELD)); + if (dslType != null) { + DataType dataType = buildDataType(dslType, r); + builder.dataType(dataType); + } + // default + Object defaultValue = r.getValue(ShowColumnsOperator.COLUMN_DEFAULT_FIELD); + builder.defaultValue(defaultValue); + // is null + String nullable = r.getStringValue(ShowColumnsOperator.IS_NULLABLE_FIELD); + builder.isNull(NULL_YES.equals(nullable)); + builder.isNonNull(NULL_NO.equals(nullable)); + return builder; + } + + protected DataType buildDataType(DSLType dslType, ResultGroup r) { + DataType dataType = DataType.create(dslType); + Long characterMaximumLength = r.getLongValue(ShowColumnsOperator.CHARACTER_MAXIMUM_LENGTH_FIELD); + if (characterMaximumLength != null) { + dataType.setPrecision(characterMaximumLength.intValue()); + } + Long numericPrecision = r.getLongValue(ShowColumnsOperator.NUMERIC_PRECISION_FIELD); + if (numericPrecision != null) { + dataType.setPrecision(numericPrecision.intValue()); + } + Long numericScale = r.getLongValue(ShowColumnsOperator.NUMERIC_SCALE_FIELD); + if (numericScale != null) { + dataType.setScale(numericScale.intValue()); + } + return dataType; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/DefaultListResultSetHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/DefaultListResultSetHandler.java similarity index 60% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/DefaultListResultSetHandler.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/DefaultListResultSetHandler.java index 26f0cb3f..d7cc505e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/DefaultListResultSetHandler.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/DefaultListResultSetHandler.java @@ -1,5 +1,7 @@ -package cc.allio.uno.data.orm.executor; +package cc.allio.uno.data.orm.executor.handler; +import cc.allio.uno.data.orm.executor.ResultGroup; +import cc.allio.uno.data.orm.executor.ResultSet; import com.google.common.collect.Lists; import java.util.List; @@ -11,7 +13,7 @@ * @date 2023/4/18 13:33 * @since 1.1.4 */ -public class DefaultListResultSetHandler implements ListResultSetHandler { +public class DefaultListResultSetHandler extends ExecutorOptionsAwareImpl implements ListResultSetHandler { @Override public List apply(ResultSet resultSet) { diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/DefaultResultSetHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/DefaultResultSetHandler.java new file mode 100644 index 00000000..f17623c0 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/DefaultResultSetHandler.java @@ -0,0 +1,18 @@ +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.data.orm.executor.ResultGroup; + +/** + * 不经任何处理 + * + * @author jiangwei + * @date 2023/4/18 13:25 + * @since 1.1.4 + */ +public class DefaultResultSetHandler extends ExecutorOptionsAwareImpl implements ResultSetHandler { + + @Override + public ResultGroup apply(ResultGroup resultGroup) { + return resultGroup; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ExecutorOptionsAware.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ExecutorOptionsAware.java new file mode 100644 index 00000000..fa7944be --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ExecutorOptionsAware.java @@ -0,0 +1,20 @@ +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; + +/** + * 借鉴spring aware机制,实现该接口的实例可以获取到ExecutorOptions实例 + * + * @author jiangwei + * @date 2024/2/14 16:21 + * @since 1.1.6 + */ +public interface ExecutorOptionsAware { + + /** + * set executorOptions + * + * @param executorOptions executorOptions + */ + void setExecutorOptions(ExecutorOptions executorOptions); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ExecutorOptionsAwareImpl.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ExecutorOptionsAwareImpl.java new file mode 100644 index 00000000..af334724 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ExecutorOptionsAwareImpl.java @@ -0,0 +1,17 @@ +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; + +public abstract class ExecutorOptionsAwareImpl implements ExecutorOptionsAware { + + private ExecutorOptions executorOptions; + + @Override + public void setExecutorOptions(ExecutorOptions executorOptions) { + this.executorOptions = executorOptions; + } + + protected ExecutorOptions obtainExecutorOptions() { + return executorOptions; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ExecutorResultHandlerSet.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ExecutorResultHandlerSet.java new file mode 100644 index 00000000..a42917fd --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ExecutorResultHandlerSet.java @@ -0,0 +1,183 @@ +package cc.allio.uno.data.orm.executor.handler; + +/** + * 定义{@link cc.allio.uno.data.orm.executor.CommandExecutor}结果处理器集合 + * + * @author jiangwei + * @date 2024/2/14 16:02 + * @since 1.1.6 + */ +public interface ExecutorResultHandlerSet { + + /** + * 获取{@code boolean}结果处理器 + * + * @return BoolResultHandler + */ + BoolResultHandler obtainBoolResultHandler(); + + /** + * 设置{@link BoolResultHandler}处理器 + * + * @param boolResultHandler boolResultHandler + */ + default void setBoolResultHandler(BoolResultHandler boolResultHandler) { + customizeResultHandler(BoolResultHandler.class, boolResultHandler); + } + + /** + * 获取实体结果处理器 + * + * @param beanClass beanClass 实体class对象 + * @param 实体类型 + * @return BeanResultSetHandler + */ + BeanResultSetHandler obtainBeanResultSetHandler(Class beanClass); + + /** + * 设置{@link BeanResultSetHandler}处理器 + * + * @param beanClass bean type + * @param beanResultSetHandler beanResultSetHandler + * @param 实体类型 + */ + default void setBeanResultSetHandler(Class beanClass, BeanResultSetHandler beanResultSetHandler) { + customizeBeanResultHandler(beanClass, BeanResultSetHandler.class, beanResultSetHandler); + } + + /** + * 获取map结果处理器 + * + * @return MapResultSetHandler + */ + MapResultSetHandler obtainMapResultSetHandler(); + + /** + * 设置{@link MapResultSetHandler} + * + * @param mapResultSetHandler mapResultSetHandler + */ + default void setMapResultSetHandler(MapResultSetHandler mapResultSetHandler) { + customizeResultHandler(MapResultSetHandler.class, mapResultSetHandler); + } + + /** + * 获取默认结果处理器 + * + * @return DefaultResultSetHandler + */ + DefaultResultSetHandler obtainDefaultResultSetHandler(); + + /** + * 设置{@link DefaultResultSetHandler} + * + * @param defaultResultSetHandler defaultResultSetHandler + */ + default void setDefaultResultSetHandler(DefaultResultSetHandler defaultResultSetHandler) { + customizeResultHandler(DefaultResultSetHandler.class, defaultResultSetHandler); + } + + /** + * 获取list实体结果处理器 + * + * @param beanClass beanClass 实体class对象 + * @param 实体类型 + * @return ListBeanResultSetHandler + */ + ListBeanResultSetHandler obtainListBeanResultSetHandler(Class beanClass); + + /** + * 设置{@link ListBeanResultSetHandler} + * + * @param 实体类型 + * @param beanClass beanClass + * @param listBeanResultSetHandler listBeanResultSetHandler + */ + default void setListBeanResultSetHandler(Class beanClass, ListBeanResultSetHandler listBeanResultSetHandler) { + customizeBeanResultHandler(beanClass, ListBeanResultSetHandler.class, listBeanResultSetHandler); + } + + /** + * 获取默认list结果处理器 + * + * @return DefaultListResultSetHandler + */ + DefaultListResultSetHandler obtainDefaultListResultSetHandler(); + + /** + * 设置{@link DefaultListResultSetHandler} + * + * @param defaultListResultSetHandler defaultListResultSetHandler + */ + default void setDefaultListResultSetHandler(DefaultListResultSetHandler defaultListResultSetHandler) { + customizeResultHandler(DefaultListResultSetHandler.class, defaultListResultSetHandler); + } + + /** + * 获取list map结果处理器 + * + * @return ListMapResultHandler + */ + ListMapResultHandler obtainListMapResultHandler(); + + /** + * 设置{@link ListMapResultHandler} + * + * @param listMapResultHandler listMapResultHandler + */ + default void setListMapResultHandler(ListMapResultHandler listMapResultHandler) { + customizeResultHandler(ListMapResultHandler.class, listMapResultHandler); + } + + /** + * 获取列定义结果处理器 + * + * @return ColumnDefListResultSetHandler + */ + ColumnDefListResultSetHandler obtainColumnDefListResultSetHandler(); + + /** + * 设置{@link ColumnDefListResultSetHandler} + * + * @param columnDefListResultSetHandler columnDefListResultSetHandler + */ + default void setColumnDefListResultSetHandler(ColumnDefListResultSetHandler columnDefListResultSetHandler) { + customizeResultHandler(ColumnDefListResultSetHandler.class, columnDefListResultSetHandler); + } + + /** + * 获取表定义结果处理器 + * + * @return TableListResultSetHandler + */ + TableListResultSetHandler obtainTableListResultSetHandler(); + + /** + * 设置{@link TableListResultSetHandler} + * + * @param tableListResultSetHandler tableListResultSetHandler + */ + default void setTableListResultSetHandler(TableListResultSetHandler tableListResultSetHandler) { + customizeResultHandler(TableListResultSetHandler.class, tableListResultSetHandler); + } + + /** + * 自定义{@link ResultHandler} + * + * @param handlerType handler 类型 + * @param handler handler 实例 + * @param ResultHandler类型 + */ + void customizeResultHandler(Class handlerType, H handler); + + /** + * 自定义{@link BeanResultSetHandler} + * + * @param beanClass bean 类型 + * @param handlerType handlerType + * @param handler handler + * @param bean 类型 + * @param handler 类型 + */ + > void customizeBeanResultHandler(Class beanClass, Class handlerType, H handler); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListBeanResultHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListBeanResultHandler.java new file mode 100644 index 00000000..c73d0ff6 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListBeanResultHandler.java @@ -0,0 +1,11 @@ +package cc.allio.uno.data.orm.executor.handler; + +/** + * marked list bean handler interface + * + * @author jiangwei + * @date 2024/2/16 23:41 + * @since 1.1.6 + */ +public interface ListBeanResultHandler extends BeanResultHandler { +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ListBeanResultSetHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListBeanResultSetHandler.java similarity index 67% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/ListBeanResultSetHandler.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListBeanResultSetHandler.java index 03e1b463..c2450c1e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ListBeanResultSetHandler.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListBeanResultSetHandler.java @@ -1,5 +1,7 @@ -package cc.allio.uno.data.orm.executor; +package cc.allio.uno.data.orm.executor.handler; +import cc.allio.uno.data.orm.executor.ResultGroup; +import cc.allio.uno.data.orm.executor.ResultSet; import com.google.common.collect.Lists; import java.util.List; @@ -12,7 +14,7 @@ * @see BeanResultSetHandler * @since 1.1.4 */ -public class ListBeanResultSetHandler implements ListResultSetHandler { +public class ListBeanResultSetHandler extends ExecutorOptionsAwareImpl implements ListResultSetHandler, ListBeanResultHandler { private final BeanResultSetHandler handler; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ListMapResultHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListMapResultHandler.java similarity index 68% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/ListMapResultHandler.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListMapResultHandler.java index 35b9397d..f80d7c05 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ListMapResultHandler.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListMapResultHandler.java @@ -1,5 +1,7 @@ -package cc.allio.uno.data.orm.executor; +package cc.allio.uno.data.orm.executor.handler; +import cc.allio.uno.data.orm.executor.ResultGroup; +import cc.allio.uno.data.orm.executor.ResultSet; import com.google.common.collect.Lists; import java.util.List; @@ -12,7 +14,7 @@ * @date 2023/4/18 13:34 * @since 1.1.4 */ -public class ListMapResultHandler implements ListResultSetHandler> { +public class ListMapResultHandler extends ExecutorOptionsAwareImpl implements ListResultSetHandler> { private final MapResultSetHandler handler; diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ListResultSetHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListResultSetHandler.java similarity index 63% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/ListResultSetHandler.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListResultSetHandler.java index a055461a..b3b4b412 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ListResultSetHandler.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ListResultSetHandler.java @@ -1,4 +1,6 @@ -package cc.allio.uno.data.orm.executor; +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.data.orm.executor.ResultSet; import java.util.List; import java.util.function.Function; @@ -10,5 +12,6 @@ * @date 2023/4/18 13:29 * @since 1.1.4 */ -public interface ListResultSetHandler extends Function> { +public interface ListResultSetHandler extends Function>, ResultHandler { + } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/MapResultSetHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/MapResultSetHandler.java new file mode 100644 index 00000000..cf40f31b --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/MapResultSetHandler.java @@ -0,0 +1,24 @@ +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.data.orm.executor.ResultGroup; + +import java.util.Map; + +/** + * ResultGroup -> map + * + * @author jiangwei + * @date 2023/4/18 13:24 + * @since 1.1.4 + */ +public class MapResultSetHandler extends ExecutorOptionsAwareImpl implements ResultSetHandler> { + + public MapResultSetHandler() { + } + + @Override + public Map apply(ResultGroup resultGroup) { + return resultGroup.toMap(); + } + +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ResultHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ResultHandler.java new file mode 100644 index 00000000..8deb8592 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ResultHandler.java @@ -0,0 +1,11 @@ +package cc.allio.uno.data.orm.executor.handler; + +/** + * marked uno-data collection handler interface + * + * @author jiangwei + * @date 2024/2/14 16:45 + * @since 1.1.6 + */ +public interface ResultHandler extends ExecutorOptionsAware { +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultSetHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ResultSetHandler.java similarity index 53% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultSetHandler.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ResultSetHandler.java index 59c81c3a..80cd9c86 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/ResultSetHandler.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/ResultSetHandler.java @@ -1,14 +1,16 @@ -package cc.allio.uno.data.orm.executor; +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.data.orm.executor.ResultGroup; import java.util.function.Function; /** - * SQL执行结果集处理器 + * DSL执行结果集处理器 * * @author jiangwei * @date 2023/4/18 13:16 * @since 1.1.4 */ -public interface ResultSetHandler extends Function { +public interface ResultSetHandler extends Function, ResultHandler { } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/TableListResultSetHandler.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/TableListResultSetHandler.java new file mode 100644 index 00000000..ccf8eaf8 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/handler/TableListResultSetHandler.java @@ -0,0 +1,39 @@ +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Table; +import cc.allio.uno.data.orm.dsl.ddl.ShowTablesOperator; +import cc.allio.uno.data.orm.executor.ResultSet; +import com.google.common.collect.Lists; + +import java.util.List; + +/** + * {@link Table}结果集处理器 + * + * @author jiangwei + * @date 2024/1/4 18:56 + * @since 1.1.6 + */ +public class TableListResultSetHandler extends ExecutorOptionsAwareImpl implements ListResultSetHandler
    { + + private static final DSLName TABLE_CATALOG_DSL_NAME = DSLName.of(ShowTablesOperator.TABLE_CATALOG_FILED, DSLName.HUMP_FEATURE); + private static final DSLName TABLE_SCHEMA_DSL_NAME = DSLName.of(ShowTablesOperator.TABLE_SCHEMA_FILED, DSLName.HUMP_FEATURE); + private static final DSLName TABLE_NAME_DSL_NAME = DSLName.of(ShowTablesOperator.TABLE_NAME_FILED, DSLName.HUMP_FEATURE); + private static final DSLName TABLE_TYPE_DSL_NAME = DSLName.of(ShowTablesOperator.TABLE_TYPE_FILED, DSLName.HUMP_FEATURE); + + @Override + public List
    apply(ResultSet resultSet) { + return Lists.newArrayList(resultSet) + .stream() + .map(r -> { + Table table = new Table(); + r.getOptionStringValue(TABLE_CATALOG_DSL_NAME, table::setCatalog); + r.getOptionStringValue(TABLE_SCHEMA_DSL_NAME, table::setSchema); + r.getOptionStringValue(TABLE_NAME_DSL_NAME, name -> table.setName(DSLName.of(name, DSLName.PLAIN_FEATURE))); + r.getOptionStringValue(TABLE_TYPE_DSL_NAME, table::setType); + return table; + }) + .toList(); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/AfterInterceptor.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/AfterInterceptor.java new file mode 100644 index 00000000..65bba3d2 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/AfterInterceptor.java @@ -0,0 +1,39 @@ +package cc.allio.uno.data.orm.executor.interceptor; + +import cc.allio.uno.core.type.Types; +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.dsl.Operator; + +/** + * 内置拦截器,在Command操作执行之前进行拦截 + * + * @author jiangwei + * @date 2024/1/8 12:11 + * @since 1.1.6 + */ +public class AfterInterceptor extends InternalInterceptor { + + public AfterInterceptor(Interceptor interceptor) { + super(interceptor); + } + + @Override + protected void onSave(CommandExecutor commandExecutor, Operator operator, Object result) { + interceptor.onSaveAfter(commandExecutor, operator, Types.getBoolean(result)); + } + + @Override + protected void onUpdate(CommandExecutor commandExecutor, Operator operator, Object result) { + interceptor.onSaveAfter(commandExecutor, operator, Types.getBoolean(result)); + } + + @Override + protected void onDelete(CommandExecutor commandExecutor, Operator operator, Object result) { + interceptor.onDeleteAfter(commandExecutor, operator, Types.getBoolean(result)); + } + + @Override + protected void onQuery(CommandExecutor commandExecutor, Operator operator, Object result) { + interceptor.onQueryAfter(commandExecutor, operator, result); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/BeforeInterceptor.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/BeforeInterceptor.java new file mode 100644 index 00000000..d88b5f55 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/BeforeInterceptor.java @@ -0,0 +1,37 @@ +package cc.allio.uno.data.orm.executor.interceptor; + +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.dsl.Operator; + +/** + * 内置拦截器,在command操作之后进行拦截 + * + * @author jiangwei + * @date 2024/1/8 12:14 + * @since 1.1.6 + */ +public class BeforeInterceptor extends InternalInterceptor { + public BeforeInterceptor(Interceptor interceptor) { + super(interceptor); + } + + @Override + protected void onSave(CommandExecutor commandExecutor, Operator operator, Object result) { + interceptor.onSaveBefore(commandExecutor, operator); + } + + @Override + protected void onUpdate(CommandExecutor commandExecutor, Operator operator, Object result) { + interceptor.onUpdateBefore(commandExecutor, operator); + } + + @Override + protected void onDelete(CommandExecutor commandExecutor, Operator operator, Object result) { + interceptor.onDeleteBefore(commandExecutor, operator); + } + + @Override + protected void onQuery(CommandExecutor commandExecutor, Operator operator, Object result) { + interceptor.onQueryBefore(commandExecutor, operator); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/Interceptor.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/Interceptor.java new file mode 100644 index 00000000..bd2e19f9 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/Interceptor.java @@ -0,0 +1,123 @@ +package cc.allio.uno.data.orm.executor.interceptor; + +import cc.allio.uno.core.chain.Chain; +import cc.allio.uno.core.chain.ChainContext; +import cc.allio.uno.core.chain.Node; +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.CommandType; +import cc.allio.uno.data.orm.executor.handler.ListResultSetHandler; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.dml.DeleteOperator; +import cc.allio.uno.data.orm.dsl.dml.InsertOperator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.dml.UpdateOperator; +import reactor.core.publisher.Mono; + +/** + * 允许用户在执行过程中添加自定义代码,参考自 hibernate #Interceptor + * + * @author jiangwei + * @date 2024/1/8 10:22 + * @since 1.1.6 + */ +public interface Interceptor extends Node { + + @Override + default Mono execute(Chain chain, ChainContext context) throws Throwable { + return chain.proceed(context); + } + + /** + * 在保存之前的回调,允许用户动态更改插入内容 + *

    关联的方法集是{@link cc.allio.uno.data.orm.executor.CommandExecutor#insert(InsertOperator)}

    + * + * @param commandExecutor commandExecutor + * @param operator operator + */ + default void onSaveBefore(CommandExecutor commandExecutor, Operator operator) { + } + + /** + * 在保存之后的回调 + *

    关联的方法集是{@link cc.allio.uno.data.orm.executor.CommandExecutor#insert(InsertOperator)}

    + * + * @param commandExecutor commandExecutor + * @param operator operator + * @param result 执行结果 + */ + default void onSaveAfter(CommandExecutor commandExecutor, Operator operator, boolean result) { + } + + /** + * 在更新之前回调,允许用户动态更改更新内容 + *

    关联方法集是{@link cc.allio.uno.data.orm.executor.CommandExecutor#update(UpdateOperator)}

    + * + * @param commandExecutor commandExecutor + * @param operator operator + */ + default void onUpdateBefore(CommandExecutor commandExecutor, Operator operator) { + } + + /** + * 在更新之后的回调 + *

    关联的方法集是{@link cc.allio.uno.data.orm.executor.CommandExecutor#update(UpdateOperator)}

    + * + * @param commandExecutor commandExecutor + * @param operator operator + * @param result 执行结果 + */ + default void onUpdateAfter(CommandExecutor commandExecutor, Operator operator, boolean result) { + } + + /** + * 在删除之前回掉,允许用户动态更改删除内容 + *

    关联方法集是{@link cc.allio.uno.data.orm.executor.CommandExecutor#delete(DeleteOperator)}

    + * + * @param commandExecutor commandExecutor + * @param operator operator + */ + default void onDeleteBefore(CommandExecutor commandExecutor, Operator operator) { + } + + /** + * 在删除之后的回调 + *

    关联的方法集是{@link cc.allio.uno.data.orm.executor.CommandExecutor#delete(DeleteOperator)}L

    + * + * @param commandExecutor commandExecutor + * @param operator operator + * @param result 执行结果 + */ + default void onDeleteAfter(CommandExecutor commandExecutor, Operator operator, boolean result) { + } + + /** + * 在查询之前的回掉,允许用户动态更改查询内容 + *

    关联方法集是{@link cc.allio.uno.data.orm.executor.CommandExecutor#queryList(QueryOperator)}

    + * + * @param commandExecutor commandExecutor + * @param operator operator + */ + default void onQueryBefore(CommandExecutor commandExecutor, Operator operator) { + } + + /** + * 在查询之后的回调 + *

    关联的方法集是{@link cc.allio.uno.data.orm.executor.CommandExecutor#queryList(QueryOperator, CommandType, ListResultSetHandler)}

    + * + * @param commandExecutor commandExecutor + * @param operator operator + * @param result 执行结果 + */ + default void onQueryAfter(CommandExecutor commandExecutor, Operator operator, Object result) { + } + + /** + * 执行不明确命令的回调 + * + * @param commandExecutor commandExecutor + * @param commandType commandType + * @param operator operator + */ + default void onUnknownCommand(CommandExecutor commandExecutor, CommandType commandType, Operator operator) { + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorAttributes.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorAttributes.java new file mode 100644 index 00000000..47c82146 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorAttributes.java @@ -0,0 +1,38 @@ +package cc.allio.uno.data.orm.executor.interceptor; + +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.CommandType; +import cc.allio.uno.data.orm.dsl.Operator; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class InterceptorAttributes { + + private CommandExecutor commandExecutor; + private Operator operator; + private CommandType commandType; + + private Object result; + + public InterceptorAttributes(CommandExecutor commandExecutor, Operator operator, CommandType commandType) { + this.commandExecutor = commandExecutor; + this.operator = operator; + this.commandType = commandType; + } + + public InterceptorAttributes(CommandExecutor commandExecutor, Operator operator, CommandType commandType, Object result) { + this.commandExecutor = commandExecutor; + this.operator = operator; + this.commandType = commandType; + this.result = result; + } + + public InterceptorAttributes(InterceptorAttributes attributes, Object result) { + this.commandExecutor = attributes.commandExecutor; + this.operator = attributes.operator; + this.commandType = attributes.commandType; + this.result = result; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorChain.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorChain.java new file mode 100644 index 00000000..e6e2a2a5 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorChain.java @@ -0,0 +1,13 @@ +package cc.allio.uno.data.orm.executor.interceptor; + +import cc.allio.uno.core.chain.Chain; + +/** + * 拦截器链 + * + * @author jiangwei + * @date 2024/1/8 10:22 + * @since 1.1.6 + */ +public interface InterceptorChain extends Chain { +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorChainContext.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorChainContext.java new file mode 100644 index 00000000..7c511483 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorChainContext.java @@ -0,0 +1,25 @@ +package cc.allio.uno.data.orm.executor.interceptor; + +import cc.allio.uno.core.chain.ChainContext; + +/** + * 拦截器链上下文 + * + * @author jiangwei + * @date 2024/1/8 10:59 + * @since 1.1.6 + */ +public class InterceptorChainContext implements ChainContext { + + private final InterceptorAttributes attributes; + + public InterceptorChainContext(InterceptorAttributes attributes) { + this.attributes = attributes; + } + + @Override + public InterceptorAttributes getIN() { + return attributes; + } + +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorChainImpl.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorChainImpl.java new file mode 100644 index 00000000..fae94d25 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InterceptorChainImpl.java @@ -0,0 +1,13 @@ +package cc.allio.uno.data.orm.executor.interceptor; + +import cc.allio.uno.core.chain.DefaultChain; +import cc.allio.uno.core.chain.Node; + +import java.util.List; + +public class InterceptorChainImpl extends DefaultChain implements InterceptorChain { + + public InterceptorChainImpl(List> nodes) { + super(nodes); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InternalInterceptor.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InternalInterceptor.java new file mode 100644 index 00000000..9e245f03 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/interceptor/InternalInterceptor.java @@ -0,0 +1,68 @@ +package cc.allio.uno.data.orm.executor.interceptor; + +import cc.allio.uno.core.chain.Chain; +import cc.allio.uno.core.chain.ChainContext; +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.CommandType; +import cc.allio.uno.data.orm.dsl.Operator; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.OrderUtils; +import reactor.core.publisher.Mono; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@link Interceptor}装饰器,确定调用事件方法 + * + * @author jiangwei + * @date 2024/1/8 10:51 + * @since 1.1.6 + */ +@Slf4j +public abstract class InternalInterceptor implements Interceptor, Ordered { + + protected final Interceptor interceptor; + + protected InternalInterceptor(Interceptor interceptor) { + this.interceptor = interceptor; + } + + @Override + public Mono execute(Chain chain, ChainContext context) throws Throwable { + InterceptorAttributes attributes = context.getIN(); + CommandExecutor commandExecutor = attributes.getCommandExecutor(); + Operator operator = attributes.getOperator(); + CommandType commandType = attributes.getCommandType(); + Object result = attributes.getResult(); + if (log.isDebugEnabled()) { + log.debug("Internal Interceptor [{}] intercept actual Interceptor [{}] the command [{}]", getClass().getSimpleName(), interceptor.getClass().getSimpleName(), commandType); + } + switch (commandType) { + case INSERT -> this.onSave(commandExecutor, operator, result); + case UPDATE -> this.onUpdate(commandExecutor, operator, result); + case DELETE -> this.onDelete(commandExecutor, operator, result); + case SELECT -> this.onQuery(commandExecutor, operator, result); + default -> interceptor.onUnknownCommand(commandExecutor, commandType, operator); + } + return chain.proceed(context); + } + + @Override + public int getOrder() { + AnnotatedElement element = (interceptor instanceof AnnotatedElement ae ? ae : interceptor.getClass()); + Integer order = OrderUtils.getOrder(element); + if (order == null) { + return 0; + } + return order; + } + + protected abstract void onSave(CommandExecutor commandExecutor, Operator operator, Object result); + + protected abstract void onUpdate(CommandExecutor commandExecutor, Operator operator, Object result); + + protected abstract void onDelete(CommandExecutor commandExecutor, Operator operator, Object result); + + protected abstract void onQuery(CommandExecutor commandExecutor, Operator operator, Object result); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/ExecutorKey.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/ExecutorKey.java new file mode 100644 index 00000000..8373b9c3 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/ExecutorKey.java @@ -0,0 +1,68 @@ +package cc.allio.uno.data.orm.executor.options; + +import cc.allio.uno.core.api.Key; +import cc.allio.uno.core.env.Envs; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * ExecutorKey + * + * @author jiangwei + * @date 2024/1/3 22:59 + * @since 1.1.6 + */ +public interface ExecutorKey extends Key { + + String DSL_EXECUTOR_TYPE_KEY = "allio.uno.data.orm.executor.key"; + + ExecutorKey DB = returnKey("db"); + ExecutorKey ELASTICSEARCH = returnKey(OperatorKey.ELASTICSEARCH); + ExecutorKey INFLUXDB = returnKey(OperatorKey.INFLUXDB); + ExecutorKey MONGODB = returnKey(OperatorKey.MONGODB); + ExecutorKey NEO4j = returnKey(OperatorKey.NEO4j); + ExecutorKey REDIS = returnKey(OperatorKey.REDIS); + + @Override + default String getProperties() { + return DSL_EXECUTOR_TYPE_KEY; + } + + static ExecutorKey returnKey(String key) { + return new DefaultExecutorKey(key); + } + + static ExecutorKey returnKey(OperatorKey key) { + return new DefaultExecutorKey(key); + } + + /** + * 获取系统默认executor key + * + * @return ExecutorKey + */ + static ExecutorKey getSystemExecutorKey() { + String executorKey = Envs.getProperty(DSL_EXECUTOR_TYPE_KEY); + return ExecutorKey.returnKey(executorKey); + } + + @Data + @EqualsAndHashCode(of = "key", callSuper = false) + class DefaultExecutorKey implements ExecutorKey { + private final String key; + + public DefaultExecutorKey(String key) { + this.key = key; + } + + public DefaultExecutorKey(OperatorKey operatorKey) { + this.key = operatorKey.key(); + } + + @Override + public String key() { + return key; + } + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/ExecutorOptions.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/ExecutorOptions.java new file mode 100644 index 00000000..cebbc4f9 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/ExecutorOptions.java @@ -0,0 +1,165 @@ +package cc.allio.uno.data.orm.executor.options; + +import cc.allio.uno.core.api.OptionalContext; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.executor.handler.ExecutorResultHandlerSet; +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; + +import java.util.List; + +/** + * 执行器{@link cc.allio.uno.data.orm.executor.CommandExecutor}相关参数 + * + * @author jiangwei + * @date 2024/2/14 21:07 + * @since 1.1.6 + */ +public interface ExecutorOptions extends ExecutorResultHandlerSet, OptionalContext { + + String KEY_MARK = "key"; + String DB_TYPE_MARK = "db type"; + String EXECUTOR_KEY_MARK = "executor"; + String OPERATOR_KEY_MARK = "operator"; + String USERNAME_MARK = "username"; + String PASSWORD_MARK = "password"; + String DATABASE_MARK = "database"; + String ADDRESS_MARK = "address"; + String SYSTEM_DEFAULT_MARK = "system default"; + + /** + * 唯一标识 + * + * @return key + */ + default String getKey() { + return getForce(KEY_MARK, String.class); + } + + /** + * set key + * + * @param key key + */ + default void setKey(String key) { + putAttribute(KEY_MARK, key); + } + + /** + * 获取db type + */ + default DBType getDbType() { + return getForce(DB_TYPE_MARK, DBType.class); + } + + /** + * 获取{@link ExecutorKey} + */ + default ExecutorKey getExecutorKey() { + return getForce(EXECUTOR_KEY_MARK, ExecutorKey.class); + } + + /** + * 获取{@link OperatorKey} + */ + default OperatorKey getOperatorKey() { + return getForce(OPERATOR_KEY_MARK, OperatorKey.class); + } + + /** + * 获取 data username + */ + default String getUsername() { + return getForce(USERNAME_MARK, String.class); + } + + /** + * set data username + * + * @param username username + */ + default void setUsername(String username) { + putAttribute(USERNAME_MARK, username); + } + + /** + * 获取 data address + */ + default String getAddress() { + return getForce(ADDRESS_MARK, String.class); + } + + /** + * set data address + * + * @param address address + */ + default void setAddress(String address) { + putAttribute(ADDRESS_MARK, address); + } + + /** + * 获取 data password + */ + default String getPassword() { + return getForce(PASSWORD_MARK, String.class); + } + + /** + * set data password + * + * @param password password + */ + default void setPassword(String password) { + putAttribute(PASSWORD_MARK, password); + } + + /** + * 获取 db database + */ + default String getDatabase() { + return getForce(DATABASE_MARK, String.class); + } + + /** + * set data database + * + * @param database database + */ + default void setDatabase(String database) { + putAttribute(DATABASE_MARK, database); + } + + /** + * 是否默认 + */ + default boolean isSystemDefault() { + return getForce(SYSTEM_DEFAULT_MARK, Boolean.class); + } + + /** + * set system default + */ + default void setSystemDefault(boolean systemDefault) { + putAttribute(SYSTEM_DEFAULT_MARK, systemDefault); + } + + /** + * 添加拦截器 + * + * @param interceptor interceptor + */ + void addInterceptor(Interceptor interceptor); + + /** + * 添加拦截器 + * + * @param interceptors interceptors + */ + void addInterceptors(List interceptors); + + /** + * 获取{@link Interceptor} list + */ + List getInterceptors(); +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/ExecutorOptionsImpl.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/ExecutorOptionsImpl.java new file mode 100644 index 00000000..f373c2fc --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/ExecutorOptionsImpl.java @@ -0,0 +1,100 @@ +package cc.allio.uno.data.orm.executor.options; + +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.core.util.id.IdGenerator; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.google.common.base.Objects; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import jakarta.validation.constraints.NotNull; +import org.springframework.context.ApplicationContext; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * 执行器相关参数集合 + * + * @author jiangwei + * @date 2024/1/8 10:30 + * @since 1.1.6 + */ +public final class ExecutorOptionsImpl extends SPIExecutorOptionsResultHandlerSet implements ExecutorOptions { + + private final List interceptors = Lists.newCopyOnWriteArrayList(); + private final Map properties = Maps.newConcurrentMap(); + + public ExecutorOptionsImpl(@NotNull DBType dbType, @NotNull ExecutorKey executorKey, @NotNull OperatorKey operatorKey) { + this(IdGenerator.defaultGenerator().getNextIdAsString(), dbType, executorKey, operatorKey); + } + + public ExecutorOptionsImpl(@NotNull String key, @NotNull DBType dbType, @NotNull ExecutorKey executorKey, @NotNull OperatorKey operatorKey) { + super(); + setKey(key); + putAttribute(DB_TYPE_MARK, dbType); + putAttribute(EXECUTOR_KEY_MARK, executorKey); + putAttribute(OPERATOR_KEY_MARK, operatorKey); + } + + /** + * 添加拦截器 + * + * @param interceptor interceptor + */ + @Override + public void addInterceptor(Interceptor interceptor) { + this.interceptors.add(interceptor); + } + + /** + * 添加拦截器 + * + * @param interceptors interceptors + */ + @Override + public void addInterceptors(List interceptors) { + this.interceptors.addAll(interceptors); + } + + @Override + public List getInterceptors() { + return interceptors; + } + + @Override + public Optional get(String key) { + return Optional.ofNullable(this.properties.get(key)); + } + + @Override + public void putAttribute(String key, Object obj) { + this.properties.put(key, obj); + } + + @Override + public Optional getApplicationContext() { + throw Exceptions.unOperate("getApplicationContext"); + } + + @Override + public Map getAll() { + return properties; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ExecutorOptionsImpl that = (ExecutorOptionsImpl) o; + return Objects.equal(getDbType(), that.getDbType()) && Objects.equal(getExecutorKey(), that.getExecutorKey()) && Objects.equal(getOperatorKey(), that.getOperatorKey()); + } + + @Override + public int hashCode() { + return Objects.hashCode(getDbType(), getExecutorKey(), getOperatorKey()); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/SPIExecutorOptionsResultHandlerSet.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/SPIExecutorOptionsResultHandlerSet.java new file mode 100644 index 00000000..b72ae998 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/orm/executor/options/SPIExecutorOptionsResultHandlerSet.java @@ -0,0 +1,261 @@ +package cc.allio.uno.data.orm.executor.options; + +import cc.allio.uno.core.util.ClassUtils; +import cc.allio.uno.data.orm.executor.handler.*; +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.ServiceLoader; +import java.util.function.Supplier; + +/** + * 基于SPI机制,获取每一个类型处理器的实例,如果没有值则采用默认处理器 + * + * @author jiangwei + * @date 2024/2/14 16:12 + * @since 1.1.6 + */ +public abstract class SPIExecutorOptionsResultHandlerSet implements ExecutorOptions { + + private final Map, ResultHandler> handlerSets; + private final ClassLoader classLoader; + + protected SPIExecutorOptionsResultHandlerSet() { + this.handlerSets = Maps.newConcurrentMap(); + this.classLoader = this.getClass().getClassLoader(); + } + + @Override + public BoolResultHandler obtainBoolResultHandler() { + return obtainSPIHandler( + BoolResultHandler.class, + () -> { + BoolResultHandler boolResultHandler = new BoolResultHandler(); + boolResultHandler.setExecutorOptions(this); + return boolResultHandler; + }); + } + + @Override + public BeanResultSetHandler obtainBeanResultSetHandler(Class beanClass) { + BeanResultHandlerDelegate beanResultHandler = obtainSPIHandler(BeanResultHandlerDelegate.class, () -> new BeanResultHandlerDelegate(this)); + return beanResultHandler.obtainBeanResultSetHandler(beanClass, BeanResultSetHandler.class, () -> new BeanResultSetHandler<>(beanClass)); + } + + @Override + public MapResultSetHandler obtainMapResultSetHandler() { + return obtainSPIHandler( + MapResultSetHandler.class, + () -> { + MapResultSetHandler mapResultSetHandler = new MapResultSetHandler(); + mapResultSetHandler.setExecutorOptions(this); + return mapResultSetHandler; + }); + } + + @Override + public DefaultResultSetHandler obtainDefaultResultSetHandler() { + return obtainSPIHandler( + DefaultResultSetHandler.class, + () -> { + DefaultResultSetHandler defaultResultSetHandler = new DefaultResultSetHandler(); + defaultResultSetHandler.setExecutorOptions(this); + return defaultResultSetHandler; + }); + } + + @Override + public ListBeanResultSetHandler obtainListBeanResultSetHandler(Class beanClass) { + ListBeanResultHandlerDelegate listBeanResultHandlerDelegate = obtainSPIHandler(ListBeanResultHandlerDelegate.class, () -> new ListBeanResultHandlerDelegate(this)); + return listBeanResultHandlerDelegate.obtainListBeanResultSetHandler(beanClass, ListBeanResultSetHandler.class, () -> new ListBeanResultSetHandler<>(beanClass)); + } + + @Override + public DefaultListResultSetHandler obtainDefaultListResultSetHandler() { + return obtainSPIHandler( + DefaultListResultSetHandler.class, + () -> { + DefaultListResultSetHandler defaultListResultSetHandler = new DefaultListResultSetHandler(); + defaultListResultSetHandler.setExecutorOptions(this); + return defaultListResultSetHandler; + }); + + } + + @Override + public ListMapResultHandler obtainListMapResultHandler() { + return obtainSPIHandler( + ListMapResultHandler.class, + () -> { + ListMapResultHandler listMapResultHandler = new ListMapResultHandler(); + listMapResultHandler.setExecutorOptions(this); + return listMapResultHandler; + }); + + } + + @Override + public ColumnDefListResultSetHandler obtainColumnDefListResultSetHandler() { + return obtainSPIHandler( + ColumnDefListResultSetHandler.class, + () -> { + ColumnDefListResultSetHandler columnDefListResultSetHandler = new ColumnDefListResultSetHandler(); + columnDefListResultSetHandler.setExecutorOptions(this); + return columnDefListResultSetHandler; + }); + } + + @Override + public TableListResultSetHandler obtainTableListResultSetHandler() { + return obtainSPIHandler( + TableListResultSetHandler.class, + () -> { + TableListResultSetHandler tableListResultSetHandler = new TableListResultSetHandler(); + tableListResultSetHandler.setExecutorOptions(this); + return tableListResultSetHandler; + }); + } + + @Override + public void customizeResultHandler(Class handlerType, H handler) { + forcePut(handlerType, handler); + } + + @Override + public > void customizeBeanResultHandler(Class beanClass, Class handlerType, H handler) { + BeanResultHandlerDelegate beanResultHandler = obtainSPIHandler(BeanResultHandlerDelegate.class, () -> new BeanResultHandlerDelegate(this)); + beanResultHandler.forcePut(beanClass, handler); + } + + /** + * 从SPI中加载Handler,如果为null则返回默认值 + * + * @param handlerClass handlerClass + * @param defaultHandler defaultHandler + * @param 处理器类型 + * @return Handler 实例 + */ + private H obtainSPIHandler(Class handlerClass, Supplier defaultHandler) { + return (H) handlerSets.computeIfAbsent( + handlerClass, + k -> { + ServiceLoader boolResultHandlers = ServiceLoader.load(handlerClass, classLoader); + H handler = boolResultHandlers.stream() + .findFirst() + .map(ServiceLoader.Provider::get) + .orElse(null); + if (handler != null) { + handler.setExecutorOptions(this); + return handler; + } + return defaultHandler.get(); + }); + } + + /** + * 基于{@link Class#getConstructors()}创建handler + * + * @param handlerClass handlerClass + * @param defaultHandler defaultHandler + * @param 处理器类型 + * @return Handler 实例 + */ + private H obtainConstructorHandler(Class handlerClass, Supplier defaultHandler, Object[] params) { + return (H) handlerSets.computeIfAbsent( + handlerClass, + k -> { + H handler = ClassUtils.newInstance(handlerClass, params); + if (handler != null) { + handler.setExecutorOptions(this); + return handler; + } + return defaultHandler.get(); + }); + } + + /** + * 强制添加指定类型的handler + * + * @param handlerClass handlerClass + * @param handler handler + * @param 处理器类型 + */ + private void forcePut(Class handlerClass, H handler) { + handlerSets.put(handlerClass, handler); + } + + /** + * bean 结果集处理器代理。其内部用于维护bean class与对应handler的关系 + */ + public static class BeanResultHandlerDelegate extends ExecutorOptionsAwareImpl implements BeanResultHandler { + + private final SPIExecutorOptionsResultHandlerSet executorResultHandlerSet; + private final Map, BeanResultHandler> beanHandlers; + + public BeanResultHandlerDelegate(SPIExecutorOptionsResultHandlerSet executorResultHandlerSet) { + this.executorResultHandlerSet = executorResultHandlerSet; + this.beanHandlers = Maps.newConcurrentMap(); + } + + /** + * 获取bean result handler + * + * @param beanClass bean class + * @param defaultValue 默认值 + * @param 实体类型 + * @param bean handler type + * @return BeanResultSetHandler + */ + > H obtainBeanResultSetHandler(Class beanClass, Class beanResultHandlerClass, Supplier defaultValue) { + return (H) beanHandlers.computeIfAbsent( + beanClass, + k -> { + H handler = executorResultHandlerSet.obtainConstructorHandler(beanResultHandlerClass, defaultValue, new Object[]{beanClass}); + handler.setExecutorOptions(executorResultHandlerSet); + return handler; + }); + } + + /** + * 强制put bean class handler + * + * @param beanClass beanClass + * @param handler handler + * @param 实体类型 + * @param bean handler type + */ + public > void forcePut(Class beanClass, H handler) { + beanHandlers.put(beanClass, handler); + } + } + + public static class ListBeanResultHandlerDelegate extends ExecutorOptionsAwareImpl implements ListBeanResultHandler { + + private final SPIExecutorOptionsResultHandlerSet executorResultHandlerSet; + private final Map, BeanResultHandler> beanHandlers; + + public ListBeanResultHandlerDelegate(SPIExecutorOptionsResultHandlerSet executorResultHandlerSet) { + this.executorResultHandlerSet = executorResultHandlerSet; + this.beanHandlers = Maps.newConcurrentMap(); + } + + /** + * 获取list bean result handler + * + * @param beanClass bean class + * @param defaultValue 默认值 + * @param 实体类型 + * @param bean handler type + * @return BeanResultSetHandler + */ + > H obtainListBeanResultSetHandler(Class beanClass, Class beanResultHandlerClass, Supplier defaultValue) { + return (H) beanHandlers.computeIfAbsent( + beanClass, + k -> { + H handler = executorResultHandlerSet.obtainConstructorHandler(beanResultHandlerClass, defaultValue, new Object[]{beanClass}); + handler.setExecutorOptions(executorResultHandlerSet); + return handler; + }); + } + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/BaseHigherQuery.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/BaseHigherQuery.java similarity index 92% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/BaseHigherQuery.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/BaseHigherQuery.java index 535be540..3fd00f27 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/BaseHigherQuery.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/BaseHigherQuery.java @@ -1,6 +1,6 @@ -package cc.allio.uno.data.query.mybatis; +package cc.allio.uno.data.query; -import cc.allio.uno.data.orm.executor.SQLCommandExecutor; +import cc.allio.uno.data.orm.executor.CommandExecutor; import cc.allio.uno.data.query.stream.*; import java.util.Collection; @@ -15,9 +15,9 @@ */ public class BaseHigherQuery implements HigherQuery { - private final SQLCommandExecutor sqlExecutor; + private final CommandExecutor sqlExecutor; - public BaseHigherQuery(SQLCommandExecutor sqlExecutor) { + public BaseHigherQuery(CommandExecutor sqlExecutor) { this.sqlExecutor = sqlExecutor; } diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/BaseQueryFilter.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/BaseQueryFilter.java new file mode 100644 index 00000000..d112b45d --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/BaseQueryFilter.java @@ -0,0 +1,252 @@ +package cc.allio.uno.data.query; + +import cc.allio.uno.data.orm.dsl.Func; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.word.Distinct; +import cc.allio.uno.data.orm.dsl.type.DBType; + +import java.util.Collection; +import java.util.List; + +/** + * 基于{@link QueryOperator}实现的{@link QueryFilter} + * + * @author jiangwei + * @date 2023/4/17 18:21 + * @since 1.1.4 + */ +public class BaseQueryFilter implements QueryFilter, QueryOperator { + + private QueryWrapper queryWrapper; + private final QueryOperator queryOperator; + + public BaseQueryFilter(DBType dbType, OperatorKey operatorMetadataKey) { + queryOperator = OperatorGroup.getOperator(QueryOperator.class, operatorMetadataKey, dbType); + } + + @Override + public String getDSL() { + return queryOperator.getDSL(); + } + + @Override + public QueryOperator parse(String dsl) { + return queryOperator.parse(dsl); + } + + @Override + public void reset() { + queryOperator.reset(); + } + + @Override + public void setDBType(DBType dbType) { + + } + + @Override + public DBType getDBType() { + return null; + } + + @Override + public void setQueryWrapper(QueryWrapper queryWrapper) { + this.queryWrapper = queryWrapper; + } + + @Override + public QueryWrapper getQueryWrapper() { + return queryWrapper; + } + + @Override + public String getPrepareDSL() { + return queryOperator.getPrepareDSL(); + } + + @Override + public List getPrepareValues() { + return queryOperator.getPrepareValues(); + } + + @Override + public QueryOperator from(Table table) { + return queryOperator.from(table); + } + + @Override + public Table getTable() { + return queryOperator.getTable(); + } + + @Override + public QueryOperator gt(DSLName sqlName, Object value) { + return queryOperator.gt(sqlName, value); + } + + @Override + public QueryOperator gte(DSLName sqlName, Object value) { + return queryOperator.gte(sqlName, value); + } + + @Override + public QueryOperator lt(DSLName sqlName, Object value) { + return queryOperator.lt(sqlName, value); + } + + @Override + public QueryOperator lte(DSLName sqlName, Object value) { + return queryOperator.lte(sqlName, value); + } + + @Override + public QueryOperator eq(DSLName sqlName, Object value) { + return queryOperator.eq(sqlName, value); + } + + @Override + public QueryOperator neq(DSLName sqlName, Object value) { + return queryOperator.neq(sqlName, value); + } + + @Override + public QueryOperator notNull(DSLName sqlName) { + return queryOperator.notNull(sqlName); + } + + @Override + public QueryOperator isNull(DSLName sqlName) { + return queryOperator.isNull(sqlName); + } + + @Override + public QueryOperator in(DSLName sqlName, Object... values) { + return queryOperator.in(sqlName, values); + } + + @Override + public QueryOperator notIn(DSLName sqlName, Object... values) { + return queryOperator.notIn(sqlName, values); + } + + @Override + public QueryOperator between(DSLName sqlName, Object withValue, Object endValue) { + return queryOperator.between(sqlName, withValue, endValue); + } + + @Override + public QueryOperator notBetween(DSLName sqlName, Object withValue, Object endValue) { + return queryOperator.notBetween(sqlName, withValue, endValue); + } + + @Override + public QueryOperator like(DSLName sqlName, Object value) { + return queryOperator.like(sqlName, value); + } + + @Override + public QueryOperator $like(DSLName sqlName, Object value) { + return queryOperator.$like(sqlName, value); + } + + @Override + public QueryOperator like$(DSLName sqlName, Object value) { + return queryOperator.like$(sqlName, value); + } + + @Override + public QueryOperator $like$(DSLName sqlName, Object value) { + return queryOperator.$like$(sqlName, value); + } + + @Override + public QueryOperator notLike(DSLName sqlName, Object value) { + return queryOperator.notLike(sqlName, value); + } + + @Override + public QueryOperator $notLike(DSLName sqlName, Object value) { + return queryOperator.$notLike(sqlName, value); + } + + @Override + public QueryOperator notLike$(DSLName sqlName, Object value) { + return queryOperator.notLike$(sqlName, value); + } + + @Override + public QueryOperator $notLike$(DSLName sqlName, Object value) { + return queryOperator.$notLike$(sqlName, value); + } + + @Override + public QueryOperator or() { + return queryOperator.or(); + } + + @Override + public QueryOperator and() { + return queryOperator.and(); + } + + @Override + public QueryOperator select(DSLName sqlName) { + return queryOperator.select(sqlName); + } + + @Override + public QueryOperator select(DSLName sqlName, String alias) { + return queryOperator.select(sqlName, alias); + } + + @Override + public QueryOperator selects(Collection sqlNames) { + return queryOperator.selects(sqlNames); + } + + @Override + public QueryOperator distinct() { + return queryOperator.distinct(); + } + + @Override + public QueryOperator distinctOn(DSLName sqlName, String alias) { + return queryOperator.distinctOn(sqlName, alias); + } + + @Override + public QueryOperator aggregate(Func syntax, DSLName sqlName, String alias, Distinct distinct) { + return queryOperator.aggregate(syntax, sqlName, alias, distinct); + } + + @Override + public QueryOperator from(QueryOperator fromTable, String alias) { + return queryOperator.from(fromTable, alias); + } + + @Override + public QueryOperator join(Table left, JoinType joinType, Table right, BinaryCondition condition) { + return queryOperator.join(left, joinType, right, condition); + } + + @Override + public QueryOperator orderBy(DSLName sqlName, OrderCondition orderCondition) { + return queryOperator.orderBy(sqlName, orderCondition); + } + + @Override + public QueryOperator limit(Long limit, Long offset) { + return queryOperator.limit(limit, offset); + } + + @Override + public QueryOperator groupByOnes(Collection fieldNames) { + return queryOperator.groupByOnes(fieldNames); + } + + @Override + public QueryOperator self() { + return queryOperator; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/HigherQuery.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/HigherQuery.java similarity index 97% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/HigherQuery.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/HigherQuery.java index cd943ec5..33182c06 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/HigherQuery.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/HigherQuery.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.query.mybatis; +package cc.allio.uno.data.query; import cc.allio.uno.data.query.stream.ValueTime; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/Query.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/Query.java similarity index 81% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/Query.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/Query.java index d312fd67..0bdf6a16 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/Query.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/Query.java @@ -1,6 +1,4 @@ -package cc.allio.uno.data.query.mybatis; - -import cc.allio.uno.data.query.mybatis.mapper.QueryMapper; +package cc.allio.uno.data.query; import java.lang.annotation.Documented; import java.lang.annotation.Inherited; @@ -16,7 +14,6 @@ * * @author jiangwei * @date 2022/9/30 16:40 - * @see QueryMapper * @since 1.1.0 */ @Inherited diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/QueryFilter.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/QueryFilter.java similarity index 81% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/QueryFilter.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/QueryFilter.java index ab1cdf67..7ed9c46f 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/QueryFilter.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/QueryFilter.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.query.mybatis; +package cc.allio.uno.data.query; /** * QueryFilter @@ -14,10 +14,10 @@ public interface QueryFilter { * * @return sql */ - String getSQL(); + String getDSL(); /** - * set query wrapper + * setValue query wrapper * */ void setQueryWrapper(QueryWrapper queryWrapper); diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/QueryWrapper.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/QueryWrapper.java similarity index 96% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/QueryWrapper.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/QueryWrapper.java index bd988369..34679f5b 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/QueryWrapper.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/QueryWrapper.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.query.mybatis; +package cc.allio.uno.data.query; import cc.allio.uno.data.query.param.DateDimension; import cc.allio.uno.data.query.param.QuerySetting; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/exception/QueryException.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/exception/QueryException.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/query/exception/QueryException.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/exception/QueryException.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/param/Action.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/Action.java similarity index 94% rename from uno-data/src/main/java/cc/allio/uno/data/query/param/Action.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/Action.java index 3082b121..d5cb349a 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/param/Action.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/Action.java @@ -1,6 +1,5 @@ package cc.allio.uno.data.query.param; -import com.baomidou.mybatisplus.annotation.EnumValue; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; @@ -32,7 +31,6 @@ public enum Action { * 动作标识 */ @JsonValue - @EnumValue private final String value; /** diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java similarity index 85% rename from uno-data/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java index 49220d00..562ac1f8 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/AddDiluteAction.java @@ -2,7 +2,7 @@ import cc.allio.uno.core.bean.ObjectWrapper; import cc.allio.uno.core.type.TypeOperatorFactory; -import cc.allio.uno.data.query.mybatis.QueryWrapper; +import cc.allio.uno.data.query.QueryWrapper; import lombok.extern.slf4j.Slf4j; /** @@ -24,7 +24,7 @@ public void trigger(QueryWrapper queryWrapper, Object o, Object t) { Object oField = oWrapper.getForce(dataField); ObjectWrapper tWrapper = new ObjectWrapper(t); Object tField = tWrapper.getForce(dataField); - Object result = TypeOperatorFactory.translator(oField.getClass()).add(oField, tField); + Object result = TypeOperatorFactory.translator((Class) oField.getClass()).add(oField, tField); oWrapper.setForce(dataField, result); } catch (Throwable ex) { // ignore diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/param/DataDilute.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DataDilute.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/query/param/DataDilute.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DataDilute.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/param/DateDimension.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DateDimension.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/query/param/DateDimension.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DateDimension.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/param/DefaultDiluteAction.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DefaultDiluteAction.java similarity index 86% rename from uno-data/src/main/java/cc/allio/uno/data/query/param/DefaultDiluteAction.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DefaultDiluteAction.java index 3d1ee293..b6478b1e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/param/DefaultDiluteAction.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DefaultDiluteAction.java @@ -1,6 +1,6 @@ package cc.allio.uno.data.query.param; -import cc.allio.uno.data.query.mybatis.QueryWrapper; +import cc.allio.uno.data.query.QueryWrapper; /** * 默认抽稀动作,不实现任何动作 diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/param/DiluteAction.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DiluteAction.java similarity index 89% rename from uno-data/src/main/java/cc/allio/uno/data/query/param/DiluteAction.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DiluteAction.java index 68127901..013234f0 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/param/DiluteAction.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/DiluteAction.java @@ -1,6 +1,6 @@ package cc.allio.uno.data.query.param; -import cc.allio.uno.data.query.mybatis.QueryWrapper; +import cc.allio.uno.data.query.QueryWrapper; /** * 数据抽稀动作 diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/param/QuerySetting.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/QuerySetting.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/query/param/QuerySetting.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/QuerySetting.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/param/TimeDimension.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/TimeDimension.java similarity index 81% rename from uno-data/src/main/java/cc/allio/uno/data/query/param/TimeDimension.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/TimeDimension.java index f49668ee..370afaa0 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/param/TimeDimension.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/TimeDimension.java @@ -1,8 +1,7 @@ package cc.allio.uno.data.query.param; -import cc.allio.uno.core.util.CalendarUtil; +import cc.allio.uno.core.util.CalendarUtils; import cc.allio.uno.core.util.DateUtil; -import com.baomidou.mybatisplus.annotation.EnumValue; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; @@ -23,15 +22,14 @@ @AllArgsConstructor public enum TimeDimension { - YEAR("YEAR", "年", time -> DateUtil.parse(time, DateUtil.PATTERN_YEAR), CalendarUtil::getFirstDayOfYear, CalendarUtil::getLastDayOfYear), - MONTH("MONTH", "月", time -> DateUtil.parse(time, DateUtil.PATTERN_MONTH), CalendarUtil::getFirstDayOfMonth, CalendarUtil::getLastDayOfMonth), - DAY("DAY", "日", time -> DateUtil.parse(time, DateUtil.PATTERN_DATE), CalendarUtil::getFirstDay, CalendarUtil::getLastSecondOfDay); + YEAR("YEAR", "年", time -> DateUtil.parse(time, DateUtil.PATTERN_YEAR), CalendarUtils::getFirstDayOfYear, CalendarUtils::getLastDayOfYear), + MONTH("MONTH", "月", time -> DateUtil.parse(time, DateUtil.PATTERN_MONTH), CalendarUtils::getFirstDayOfMonth, CalendarUtils::getLastDayOfMonth), + DAY("DAY", "日", time -> DateUtil.parse(time, DateUtil.PATTERN_DATE), CalendarUtils::getFirstDay, CalendarUtils::getLastSecondOfDay); /** * 时间维度标识 */ @JsonValue - @EnumValue private final String value; /** diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/param/Window.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/Window.java similarity index 96% rename from uno-data/src/main/java/cc/allio/uno/data/query/param/Window.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/Window.java index 6f326522..f38f8004 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/param/Window.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/param/Window.java @@ -1,6 +1,5 @@ package cc.allio.uno.data.query.param; -import com.baomidou.mybatisplus.annotation.EnumValue; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; @@ -66,7 +65,6 @@ public enum Window { * 时间维度标识 */ @JsonValue - @EnumValue private final String value; /** diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/AsyncStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/AsyncStream.java similarity index 95% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/AsyncStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/AsyncStream.java index c5c1ccfa..d3ca7841 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/AsyncStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/AsyncStream.java @@ -1,6 +1,6 @@ package cc.allio.uno.data.query.stream; -import cc.allio.uno.data.query.mybatis.QueryFilter; +import cc.allio.uno.data.query.QueryFilter; import cc.allio.uno.data.query.exception.QueryException; import java.util.Collection; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStream.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStream.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStreamImpl.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStreamImpl.java similarity index 91% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStreamImpl.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStreamImpl.java index 9523a61e..bd13653a 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStreamImpl.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/CollectionTimeStreamImpl.java @@ -1,6 +1,6 @@ package cc.allio.uno.data.query.stream; -import cc.allio.uno.data.query.mybatis.QueryFilter; +import cc.allio.uno.data.query.QueryFilter; import reactor.core.publisher.Flux; import java.util.List; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousStream.java similarity index 95% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousStream.java index 80f960dc..ee09aed1 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousStream.java @@ -1,9 +1,9 @@ package cc.allio.uno.data.query.stream; import cc.allio.uno.core.util.CollectionUtils; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.QueryWrapper; import cc.allio.uno.core.util.ObjectUtils; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.QueryWrapper; import cc.allio.uno.data.query.exception.QueryException; import cc.allio.uno.data.query.param.DateDimension; import com.google.common.collect.Maps; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousValueTimeStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousValueTimeStream.java similarity index 89% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousValueTimeStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousValueTimeStream.java index a68cf327..2d975818 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousValueTimeStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ContemporaneousValueTimeStream.java @@ -1,7 +1,6 @@ package cc.allio.uno.data.query.stream; -import cc.allio.uno.data.query.mybatis.mapper.QueryMapper; -import cc.allio.uno.data.query.mybatis.QueryFilter; +import cc.allio.uno.data.query.QueryFilter; import reactor.core.publisher.Flux; import java.util.Collection; @@ -27,7 +26,6 @@ public ContemporaneousValueTimeStream(ContemporaneousStream stream) { * Map类型的实体数据转换为时间数据 * * @param queryFilter 原始map数据 - * @see QueryMapper#queryContemporaneous(QueryFilter) * @see ValueTimeStream */ @Override diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/DataStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/DataStream.java similarity index 97% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/DataStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/DataStream.java index 520b834b..0e31bda0 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/DataStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/DataStream.java @@ -1,8 +1,8 @@ package cc.allio.uno.data.query.stream; import cc.allio.uno.core.bean.ValueWrapper; -import cc.allio.uno.data.query.mybatis.QueryFilter; import cc.allio.uno.core.type.TypeOperatorFactory; +import cc.allio.uno.data.query.QueryFilter; import java.util.Arrays; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/DiluentTimeStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/DiluentTimeStream.java similarity index 95% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/DiluentTimeStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/DiluentTimeStream.java index 6728d941..e45f416b 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/DiluentTimeStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/DiluentTimeStream.java @@ -1,9 +1,9 @@ package cc.allio.uno.data.query.stream; import cc.allio.uno.core.bean.ValueWrapper; -import cc.allio.uno.core.util.CoreBeanUtil; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.QueryWrapper; +import cc.allio.uno.core.util.BeanUtils; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.QueryWrapper; import cc.allio.uno.data.query.param.DataDilute; import cc.allio.uno.data.query.param.QuerySetting; import reactor.core.publisher.Flux; @@ -148,7 +148,7 @@ public void fire() { public void reloadTimePoint() { T last = getLast(); // 赋值下一个时间点数据 - timePoint = (T) CoreBeanUtil.copy(last, last.getClass()); + timePoint = (T) BeanUtils.copy(last, last.getClass()); ValueWrapper pointWrapper = ValueWrapper.get(timePoint); Date watermark = timeStream.dateTime(pointWrapper.getForce(timeField)); timeStream.setTimeData(timeField, pointWrapper, watermark); diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/FunctionalityTimeStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/FunctionalityTimeStream.java similarity index 96% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/FunctionalityTimeStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/FunctionalityTimeStream.java index eede9644..c800f5d3 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/FunctionalityTimeStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/FunctionalityTimeStream.java @@ -1,9 +1,9 @@ package cc.allio.uno.data.query.stream; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.QueryWrapper; import cc.allio.uno.core.util.ObjectUtils; import cc.allio.uno.core.util.StringUtils; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.QueryWrapper; import reactor.core.publisher.Flux; /** diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/OutliersIgnoreTimeStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/OutliersIgnoreTimeStream.java similarity index 95% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/OutliersIgnoreTimeStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/OutliersIgnoreTimeStream.java index 1b0c90df..4f12881b 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/OutliersIgnoreTimeStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/OutliersIgnoreTimeStream.java @@ -2,8 +2,8 @@ import cc.allio.uno.core.bean.ValueWrapper; import cc.allio.uno.core.type.Types; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.QueryWrapper; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.QueryWrapper; import cc.allio.uno.data.query.param.QuerySetting; import reactor.core.publisher.Flux; diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/SQLCommandExecutorStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/SQLCommandExecutorStream.java new file mode 100644 index 00000000..bbe2c6a9 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/SQLCommandExecutorStream.java @@ -0,0 +1,32 @@ +package cc.allio.uno.data.query.stream; + +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.query.QueryFilter; +import reactor.core.publisher.Flux; + +import java.util.Map; + +/** + * 基于{@link CommandExecutor}的流 + * + * @author jiangwei + * @date 2023/4/21 13:21 + * @since 1.1.4 + */ +public class SQLCommandExecutorStream implements CollectionTimeStream> { + + private final CommandExecutor commandExecutor; + + public SQLCommandExecutorStream(CommandExecutor commandExecutor) { + this.commandExecutor = commandExecutor; + } + + @Override + public Flux> read(QueryFilter queryFilter) throws Throwable { + if (queryFilter instanceof QueryOperator) { + return new CollectionTimeStreamImpl<>(commandExecutor.queryListMap((QueryOperator) queryFilter)).read(queryFilter); + } + return Flux.empty(); + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/Sampling.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/Sampling.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/Sampling.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/Sampling.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/SortStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/SortStream.java similarity index 91% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/SortStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/SortStream.java index a390c2c7..8553f12c 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/SortStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/SortStream.java @@ -2,8 +2,8 @@ import cc.allio.uno.core.bean.ValueWrapper; import cc.allio.uno.core.util.ObjectUtils; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.QueryWrapper; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.QueryWrapper; import reactor.core.publisher.Flux; import java.util.Date; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/StreamBuilder.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/StreamBuilder.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/StreamBuilder.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/StreamBuilder.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/SupplementTimeStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/SupplementTimeStream.java similarity index 95% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/SupplementTimeStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/SupplementTimeStream.java index 4413531f..d0192276 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/SupplementTimeStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/SupplementTimeStream.java @@ -1,17 +1,19 @@ package cc.allio.uno.data.query.stream; import cc.allio.uno.core.bean.ValueWrapper; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.QueryWrapper; -import cc.allio.uno.core.util.CoreBeanUtil; +import cc.allio.uno.core.util.BeanUtils; +import cc.allio.uno.data.orm.dsl.OrderCondition; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.QueryWrapper; import cc.allio.uno.data.query.param.QuerySetting; import cc.allio.uno.data.query.param.Window; -import cc.allio.uno.data.orm.sql.dml.local.OrderCondition; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.time.Duration; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; import java.util.concurrent.atomic.AtomicLong; /** @@ -160,7 +162,7 @@ public boolean add(T o) { } while (Math.abs(watermark.getTime() - currentData.getTime()) > timeSpacing) { watermark = timeStream.nextStepDate(watermark, timeSpacing, OrderCondition.DESC); - T increment = (T) CoreBeanUtil.copy(o, o.getClass()); + T increment = (T) BeanUtils.copy(o, o.getClass()); ValueWrapper incrementWrapper = ValueWrapper.get(increment); // 设置时间 timeStream.setTimeData(timeField, incrementWrapper, watermark); diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/TimeStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/TimeStream.java similarity index 95% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/TimeStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/TimeStream.java index fa378974..894ec9b0 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/TimeStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/TimeStream.java @@ -2,8 +2,8 @@ import cc.allio.uno.core.bean.ValueWrapper; import cc.allio.uno.core.util.DateUtil; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.dml.local.OrderCondition; +import cc.allio.uno.data.orm.dsl.OrderCondition; +import cc.allio.uno.data.orm.dsl.exception.DSLException; import java.beans.PropertyDescriptor; import java.util.Date; @@ -97,7 +97,7 @@ default Date dateTime(Object maybeTime) { } else if (Long.class.isAssignableFrom(maybeTime.getClass())) { return new Date((Long) maybeTime); } - throw new SQLException("query datetime neither 'String' and not 'Date' and not 'Long'"); + throw new DSLException("query datetime neither 'String' and not 'Date' and not 'Long'"); } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/ValueTime.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ValueTime.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/ValueTime.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ValueTime.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/stream/ValueTimeStream.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ValueTimeStream.java similarity index 89% rename from uno-data/src/main/java/cc/allio/uno/data/query/stream/ValueTimeStream.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ValueTimeStream.java index 68da4945..7803b724 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/stream/ValueTimeStream.java +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/query/stream/ValueTimeStream.java @@ -1,15 +1,17 @@ package cc.allio.uno.data.query.stream; import cc.allio.uno.core.bean.ValueWrapper; -import cc.allio.uno.data.query.mybatis.mapper.QueryMapper; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.QueryWrapper; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.QueryWrapper; import com.google.common.collect.Maps; import reactor.core.publisher.Flux; import reactor.util.function.Tuple2; import reactor.util.function.Tuples; -import java.util.*; +import java.util.Collection; +import java.util.Date; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; /** @@ -29,11 +31,9 @@ public ValueTimeStream(CollectionTimeStream stream) { /** * 列表实体数据转换为时间数据,如某个对象实体 包含test、time字段。则返回只有包含这个字段. - * 主用于{@link QueryMapper#queryList(QueryFilter)}参数转换 * * @param queryFilter 查询过滤器 * @return 转换为当前结构:test:[{"time":"xxxx","value":"test"}] ... - * @see QueryMapper#queryList(QueryFilter) */ @Override public Map> read(QueryFilter queryFilter) throws Throwable { diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/BaseTransactionBehavior.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/BaseTransactionBehavior.java new file mode 100644 index 00000000..9b2c9d85 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/BaseTransactionBehavior.java @@ -0,0 +1,59 @@ +package cc.allio.uno.data.tx; + +import cc.allio.uno.core.exception.Exceptions; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; + +/** + * 基于{@link InternalTransactionBehavior}实现 + * + * @author jiangwei + * @date 2024/2/11 12:39 + * @since 1.1.6 + */ +public abstract class BaseTransactionBehavior> implements TxDefinition { + + protected final InternalTransactionBehavior internalTransactionBehavior; + + protected BaseTransactionBehavior(PlatformTransactionManager platformTransactionManager) { + if (platformTransactionManager == null) { + throw Exceptions.unchecked(new NullPointerException("platformTransactionManager must not null")); + } + this.internalTransactionBehavior = new InternalTransactionBehavior(platformTransactionManager); + } + + @Override + public T propagationBehavior(int propagation) { + internalTransactionBehavior.propagationBehavior(propagation); + return self(); + } + + @Override + public T isolationLevel(int isolationLevel) { + internalTransactionBehavior.isolationLevel(isolationLevel); + return self(); + } + + @Override + public T timeout(int timeout) { + internalTransactionBehavior.timeout(timeout); + return self(); + } + + @Override + public T readonly(boolean readonly) { + internalTransactionBehavior.readonly(readonly); + return self(); + } + + @Override + public T name(String name) { + internalTransactionBehavior.name(name); + return self(); + } + + @Override + public TransactionDefinition getTransactionDefinition() { + return internalTransactionBehavior.getTransactionDefinition(); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/BoolTransactionBehavior.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/BoolTransactionBehavior.java new file mode 100644 index 00000000..aa2f73e0 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/BoolTransactionBehavior.java @@ -0,0 +1,69 @@ +package cc.allio.uno.data.tx; + +import cc.allio.uno.core.function.lambda.MethodVoidPredicate; +import com.google.common.collect.Lists; +import org.springframework.transaction.PlatformTransactionManager; + +import java.util.List; +import java.util.stream.Stream; + +/** + * bool + * + * @author jiangwei + * @date 2024/2/11 12:42 + * @since 1.1.6 + */ +public class BoolTransactionBehavior extends BaseTransactionBehavior { + + private final List predicates = Lists.newArrayList(); + private final Mode mode; + + public BoolTransactionBehavior(PlatformTransactionManager platformTransactionManager) { + this(platformTransactionManager, Mode.ALL_MATCH); + } + + public BoolTransactionBehavior(PlatformTransactionManager platformTransactionManager, Mode mode) { + super(platformTransactionManager); + this.mode = mode; + } + + /** + * 提供事物行为动作 + * + * @param predicate predicate + * @return BoolTransactionBehavior + */ + public BoolTransactionBehavior then(MethodVoidPredicate predicate) { + this.predicates.add(predicate); + return self(); + } + + /** + * 提交事物行为 + */ + public boolean commit() { + return TransactionContext.execute(() -> { + Stream predicatesStreams = predicates.stream(); + if (Mode.ALL_MATCH == mode) { + return predicatesStreams.allMatch(MethodVoidPredicate::test); + } else if (Mode.ANY_MATCH == mode) { + return predicatesStreams.anyMatch(MethodVoidPredicate::test); + } else if (Mode.NONE_MATCH == mode) { + return predicatesStreams.noneMatch(MethodVoidPredicate::test); + } + return false; + }); + } + + + public enum Mode { + // 所有进行匹配,如果其中一个返回false则不在进行后续动作 + ALL_MATCH, + // 任意匹配 + ANY_MATCH, + // 不匹配任意一个 + NONE_MATCH; + } + +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/InternalTransactionBehavior.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/InternalTransactionBehavior.java new file mode 100644 index 00000000..f8f2ccb3 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/InternalTransactionBehavior.java @@ -0,0 +1,69 @@ +package cc.allio.uno.data.tx; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.TransactionSystemException; + +@Slf4j +class InternalTransactionBehavior extends TxDefinitionImpl { + private final PlatformTransactionManager transactionManager; + + public InternalTransactionBehavior(PlatformTransactionManager transactionManager) { + this.transactionManager = transactionManager; + } + + /** + * 基于Spring事物管理,执行事物代码,当执行过程中抛出异常将会捕获,并且回滚事物。 + * + * @param voidTransaction 可执行事物代码块,非空 + * @throws NoSuchBeanDefinitionException 在IOC容器中没有找到{@link PlatformTransactionManager}实例抛出 + */ + public void execute(VoidTransactionAction voidTransaction) { + if (transactionManager != null) { + TransactionDefinition definition = getTransactionDefinition(); + TransactionStatus status = transactionManager.getTransaction(definition); + synchronized (TransactionContext.class) { + if (voidTransaction == null) { + throw new TransactionSystemException("transaction is empty"); + } + try { + voidTransaction.around(); + transactionManager.commit(status); + } catch (Exception e) { + log.error("transaction execute failed, data will be rollback", e); + transactionManager.rollback(status); + } + } + } + } + + /** + * 基于Spring事物管理,执行事物代码,当执行过程中抛出异常将会捕获,并且回滚事物。 + * + * @param transaction 可执行事物代码块,非空 + * @throws NoSuchBeanDefinitionException 在IOC容器中没有找到{@link PlatformTransactionManager}实例抛出 + */ + public R execute(Transaction transaction) { + if (transactionManager != null) { + TransactionDefinition definition = getTransactionDefinition(); + TransactionStatus status = transactionManager.getTransaction(definition); + synchronized (TransactionContext.class) { + if (transaction == null) { + throw new TransactionSystemException("transaction is empty"); + } + try { + R r = transaction.around(); + transactionManager.commit(status); + return r; + } catch (Exception e) { + log.error("transaction execute failed, data will be rollback", e); + transactionManager.rollback(status); + } + } + } + return null; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/Transaction.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/Transaction.java new file mode 100644 index 00000000..2ef3a186 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/Transaction.java @@ -0,0 +1,20 @@ +package cc.allio.uno.data.tx; + +/** + * 事物的代码块 + * + * @author jiangwei + * @date 2024/2/11 11:15 + * @since 1.1.6 + */ +@FunctionalInterface +public interface Transaction { + + /** + * 在事物之中执行代码逻辑 + * + * @return 返回执行结果,如果存在任何异常将返回null + * @throws Exception 代码块存在异常时抛出 + */ + R around() throws Exception; +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TransactionAction.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TransactionAction.java new file mode 100644 index 00000000..a94e4c6f --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TransactionAction.java @@ -0,0 +1,19 @@ +package cc.allio.uno.data.tx; + +/** + * 定义事物动作 + * + * @author jiangwei + * @date 2024/2/11 12:34 + * @since 1.1.6 + */ +public interface TransactionAction { + + /** + * 将带着事物执行的代码块 + * + * @return 动作执行结果 + * @throws Exception 代码块存在异常时抛出 + */ + R around() throws Exception; +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TransactionContext.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TransactionContext.java new file mode 100644 index 00000000..e5b27646 --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TransactionContext.java @@ -0,0 +1,123 @@ +package cc.allio.uno.data.tx; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.transaction.*; + +import java.util.function.UnaryOperator; + +/** + * 基于Spring编程式事物工具 + * + * @author jiangwei + * @date 2022/1/10 21:57 + * @since 1.0 + */ +@Slf4j +public final class TransactionContext { + + private static PlatformTransactionManager transactionManager; + + public TransactionContext(PlatformTransactionManager transactionManager) { + TransactionContext.transactionManager = transactionManager; + } + + /** + * @see #execute(VoidTransactionAction, TxDefinition) + */ + public static void execute(VoidTransactionAction voidTransaction) { + execute(voidTransaction, f -> f); + } + + /** + * @see #execute(VoidTransactionAction, TxDefinition) + */ + public static void execute(VoidTransactionAction voidTransaction, UnaryOperator> func) { + execute(voidTransaction, func.apply(TxDefinition.withDefault())); + } + + /** + * 基于Spring事物管理,执行事物代码,当执行过程中抛出异常将会捕获,并且回滚事物。 + * + * @param voidTransaction 可执行事物代码块,非空 + * @param txDefinition 事物定义 + * @throws NoSuchBeanDefinitionException 在IOC容器中没有找到{@link PlatformTransactionManager}实例抛出 + */ + public static void execute(VoidTransactionAction voidTransaction, TxDefinition txDefinition) { + InternalTransactionBehavior transactionBehavior = new InternalTransactionBehavior(transactionManager); + transactionBehavior.withOther(txDefinition); + transactionBehavior.execute(voidTransaction); + } + + /** + * @see #execute(Transaction, TxDefinition) + */ + public static R execute(Transaction transaction) { + return execute(transaction, f -> f); + } + + /** + * @see #execute(Transaction, TxDefinition) + */ + public static R execute(Transaction transaction, UnaryOperator> func) { + return execute(transaction, func.apply(TxDefinition.withDefault())); + } + + /** + * 基于Spring事物管理,执行事物代码,当执行过程中抛出异常将会捕获,并且回滚事物。 + * + * @param transaction 可执行事物代码块,非空 + * @param txDefinition 事物定义 + * @throws NoSuchBeanDefinitionException 在IOC容器中没有找到{@link PlatformTransactionManager}实例抛出 + */ + public static R execute(Transaction transaction, TxDefinition txDefinition) { + InternalTransactionBehavior transactionBehavior = new InternalTransactionBehavior(transactionManager); + transactionBehavior.withOther(txDefinition); + return transactionBehavior.execute(transaction); + } + + /** + * 开启一个新的事物,该方法将返回{@link VoidTransactionBehavior}对象 + */ + public static VoidTransactionBehavior open() { + if (transactionManager == null) { + throw new IllegalArgumentException("transactionManager is null, please set TransactionManger through out TransactionContext.transactionManager = xxx"); + } + return new VoidTransactionBehavior(transactionManager); + } + + /** + * 开启一个新的事物,该方法将返回{@link BoolTransactionBehavior}对象。 + */ + public static BoolTransactionBehavior boolOpen() { + if (transactionManager == null) { + throw new IllegalArgumentException("transactionManager is null, please set TransactionManger through out TransactionContext.transactionManager = xxx"); + } + return new BoolTransactionBehavior(transactionManager); + } + + + /** + * 开启一个新的事物,该方法将返回{@link BoolTransactionBehavior}对象。 + */ + public static BoolTransactionBehavior allMatchOpen() { + if (transactionManager == null) { + throw new IllegalArgumentException("transactionManager is null, please set TransactionManger through out TransactionContext.transactionManager = xxx"); + } + return new BoolTransactionBehavior(transactionManager, BoolTransactionBehavior.Mode.ALL_MATCH); + } + + public static BoolTransactionBehavior anyMatchOpen() { + if (transactionManager == null) { + throw new IllegalArgumentException("transactionManager is null, please set TransactionManger through out TransactionContext.transactionManager = xxx"); + } + return new BoolTransactionBehavior(transactionManager, BoolTransactionBehavior.Mode.ANY_MATCH); + } + + public static BoolTransactionBehavior noneMatchOpen() { + if (transactionManager == null) { + throw new IllegalArgumentException("transactionManager is null, please set TransactionManger through out TransactionContext.transactionManager = xxx"); + } + return new BoolTransactionBehavior(transactionManager, BoolTransactionBehavior.Mode.NONE_MATCH); + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/tx/TxAutoConfiguration.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TxAutoConfiguration.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/tx/TxAutoConfiguration.java rename to uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TxAutoConfiguration.java diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TxDefinition.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TxDefinition.java new file mode 100644 index 00000000..42d708eb --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TxDefinition.java @@ -0,0 +1,85 @@ +package cc.allio.uno.data.tx; + +import cc.allio.uno.core.api.Self; +import org.springframework.transaction.TransactionDefinition; + +/** + * 事物定义 + * + * @author jiangwei + * @date 2024/2/11 11:17 + * @since 1.1.6 + */ +public interface TxDefinition> extends Self { + + /** + * 定义事物的传播级别 + * + * @param propagation propagation + * @return SELF + * @see TransactionDefinition#getPropagationBehavior() + */ + T propagationBehavior(int propagation); + + /** + * 定义事物的隔离级别 + * + * @param isolationLevel isolationLevel + * @return SELF + * @see TransactionDefinition#getIsolationLevel() + */ + T isolationLevel(int isolationLevel); + + /** + * 定义事物的超时时间 + * + * @param timeout timeout + * @return SELF + * @see TransactionDefinition#getTimeout() + */ + T timeout(int timeout); + + /** + * 定义事物的只读 + * + * @param readonly readonly + * @return SELF + * @see TransactionDefinition#isReadOnly() + */ + T readonly(boolean readonly); + + /** + * 定义事物的超时时间 + * + * @param name name + * @return SELF + * @see TransactionDefinition#getName() + */ + T name(String name); + + /** + * 基于{@link #isolationLevel(int)}、{@link #propagationBehavior(int)}、{@link #timeout(int)}、{@link #name(String)}获取自定义化的事物配置 + * 或者采取默认的配置 + * + * @return TransactionDefinition or default + */ + TransactionDefinition getTransactionDefinition(); + + default TxDefinition withOther(TxDefinition other) { + TransactionDefinition transactionDefinition = other.getTransactionDefinition(); + return propagationBehavior(transactionDefinition.getPropagationBehavior()) + .isolationLevel(transactionDefinition.getIsolationLevel()) + .timeout(transactionDefinition.getTimeout()) + .readonly(transactionDefinition.isReadOnly()) + .name(transactionDefinition.getName()); + } + + /** + * 获取默认的{@link TxDefinition}实例 + * + * @return TxDefinition + */ + static TxDefinition withDefault() { + return new TxDefinitionImpl<>(); + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TxDefinitionImpl.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TxDefinitionImpl.java new file mode 100644 index 00000000..2d55f03d --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/TxDefinitionImpl.java @@ -0,0 +1,61 @@ +package cc.allio.uno.data.tx; + +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.support.DefaultTransactionDefinition; + +/** + * 基于{@link org.springframework.transaction.support.DefaultTransactionDefinition} + * + * @author jiangwei + * @date 2024/2/11 11:35 + * @since 1.1.6 + */ +public class TxDefinitionImpl> implements TxDefinition { + + private int propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRES_NEW; + private int isolationLevel = TransactionDefinition.ISOLATION_DEFAULT; + private int timeout = TransactionDefinition.TIMEOUT_DEFAULT; + private String name = TxDefinitionImpl.class.getSimpleName(); + private boolean readonly = false; + + @Override + public T propagationBehavior(int propagation) { + this.propagationBehavior = propagation; + return self(); + } + + @Override + public T isolationLevel(int isolationLevel) { + this.isolationLevel = isolationLevel; + return self(); + } + + @Override + public T timeout(int timeout) { + this.timeout = timeout; + return self(); + } + + @Override + public T name(String name) { + this.name = name; + return self(); + } + + @Override + public T readonly(boolean readonly) { + this.readonly = readonly; + return self(); + } + + @Override + public TransactionDefinition getTransactionDefinition() { + DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); + transactionDefinition.setPropagationBehavior(propagationBehavior); + transactionDefinition.setIsolationLevel(isolationLevel); + transactionDefinition.setReadOnly(readonly); + transactionDefinition.setName(name); + transactionDefinition.setTimeout(timeout); + return transactionDefinition; + } +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/VoidTransactionAction.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/VoidTransactionAction.java new file mode 100644 index 00000000..7c0fbb5c --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/VoidTransactionAction.java @@ -0,0 +1,19 @@ +package cc.allio.uno.data.tx; + +/** + * 事物的代码块 + * + * @author jiangwei + * @date 2024/2/11 11:14 + * @since 1.1.6 + */ +@FunctionalInterface +public interface VoidTransactionAction { + + /** + * 在事物之中执行代码逻辑 + * + * @throws Exception 代码块存在异常时抛出 + */ + void around() throws Exception; +} diff --git a/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/VoidTransactionBehavior.java b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/VoidTransactionBehavior.java new file mode 100644 index 00000000..88c1997b --- /dev/null +++ b/uno-data/uno-data-api/src/main/java/cc/allio/uno/data/tx/VoidTransactionBehavior.java @@ -0,0 +1,41 @@ +package cc.allio.uno.data.tx; + +import cc.allio.uno.core.function.VoidConsumer; +import com.google.common.collect.Lists; +import org.springframework.transaction.PlatformTransactionManager; + +import java.util.List; + +/** + * void transaction behavior + * + * @author jiangwei + * @date 2024/2/11 12:37 + * @since 1.1.6 + */ +public class VoidTransactionBehavior extends BaseTransactionBehavior { + + private final List actions = Lists.newArrayList(); + + public VoidTransactionBehavior(PlatformTransactionManager platformTransactionManager) { + super(platformTransactionManager); + } + + /** + * 提供事物行为动作 + * + * @param action action + * @return VoidTransactionBehavior + */ + public VoidTransactionBehavior then(VoidConsumer action) { + this.actions.add(action); + return self(); + } + + /** + * 提交事物行为 + */ + public void commit() { + internalTransactionBehavior.execute(() -> actions.forEach(VoidConsumer::doAccept)); + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/executor.puml b/uno-data/uno-data-api/src/main/resources/uml/executor.puml similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/executor.puml rename to uno-data/uno-data-api/src/main/resources/uml/executor.puml diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/higher-query.puml b/uno-data/uno-data-api/src/main/resources/uml/higher-query.puml similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/higher-query.puml rename to uno-data/uno-data-api/src/main/resources/uml/higher-query.puml diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/operator.puml b/uno-data/uno-data-api/src/main/resources/uml/operator.puml similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/operator.puml rename to uno-data/uno-data-api/src/main/resources/uml/operator.puml diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/sql.puml b/uno-data/uno-data-api/src/main/resources/uml/sql.puml similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/sql.puml rename to uno-data/uno-data-api/src/main/resources/uml/sql.puml diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/type.puml b/uno-data/uno-data-api/src/main/resources/uml/type.puml similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/type.puml rename to uno-data/uno-data-api/src/main/resources/uml/type.puml diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/User.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/User.java new file mode 100644 index 00000000..806b40da --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/User.java @@ -0,0 +1,7 @@ +package cc.allio.uno.data.orm; + +import lombok.Data; + +@Data +public class User { +} diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/ADruidSQLCreateOperator.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/ADruidSQLCreateOperator.java new file mode 100644 index 00000000..6939e17d --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/ADruidSQLCreateOperator.java @@ -0,0 +1,54 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.ddl.CreateTableOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; + +@AutoService(CreateTableOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class ADruidSQLCreateOperator implements CreateTableOperator { + @Override + public String getDSL() { + return null; + } + + @Override + public CreateTableOperator parse(String dsl) { + return null; + } + + @Override + public void reset() { + + } + + @Override + public void setDBType(DBType dbType) { + + } + + @Override + public DBType getDBType() { + return null; + } + + @Override + public CreateTableOperator from(Table table) { + return null; + } + + @Override + public Table getTable() { + return null; + } + + @Override + public CreateTableOperator column(ColumnDef columnDef) { + return null; + } + + @Override + public CreateTableOperator comment(String comment) { + return null; + } +} diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/BDruidSQLCreateOperator.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/BDruidSQLCreateOperator.java new file mode 100644 index 00000000..852d18f2 --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/BDruidSQLCreateOperator.java @@ -0,0 +1,54 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.ddl.CreateTableOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; + +@AutoService(CreateTableOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class BDruidSQLCreateOperator implements CreateTableOperator { + @Override + public String getDSL() { + return null; + } + + @Override + public CreateTableOperator parse(String dsl) { + return null; + } + + @Override + public void reset() { + + } + + @Override + public void setDBType(DBType dbType) { + + } + + @Override + public DBType getDBType() { + return null; + } + + @Override + public CreateTableOperator from(Table table) { + return null; + } + + @Override + public Table getTable() { + return null; + } + + @Override + public CreateTableOperator column(ColumnDef columnDef) { + return null; + } + + @Override + public CreateTableOperator comment(String comment) { + return null; + } +} diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/DruidShowColumnsOperator.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/DruidShowColumnsOperator.java new file mode 100644 index 00000000..b201301c --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/DruidShowColumnsOperator.java @@ -0,0 +1,67 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.ddl.ShowColumnsOperator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; + +import java.util.List; + +@AutoService(ShowColumnsOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class DruidShowColumnsOperator implements ShowColumnsOperator { + @Override + public String getDSL() { + return null; + } + + @Override + public ShowColumnsOperator parse(String dsl) { + return null; + } + + @Override + public void reset() { + + } + + @Override + public void setDBType(DBType dbType) { + + } + + @Override + public DBType getDBType() { + return null; + } + + @Override + public String getPrepareDSL() { + return null; + } + + @Override + public List getPrepareValues() { + return null; + } + + @Override + public ShowColumnsOperator from(Table table) { + return null; + } + + @Override + public Table getTable() { + return null; + } + + @Override + public QueryOperator toQueryOperator() { + return null; + } + + @Override + public ShowColumnsOperator database(Database database) { + return null; + } +} diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/RedisSQLInsertOperator.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/RedisSQLInsertOperator.java new file mode 100644 index 00000000..dd9d3155 --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/RedisSQLInsertOperator.java @@ -0,0 +1,78 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.dml.InsertOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; + +import java.util.Collection; +import java.util.List; +import java.util.function.Supplier; + +@AutoService(InsertOperator.class) +@Operator.Group(OperatorKey.REDIS_LITERAL) +public class RedisSQLInsertOperator implements InsertOperator { + @Override + public String getDSL() { + return null; + } + + @Override + public InsertOperator parse(String dsl) { + return null; + } + + @Override + public void reset() { + + } + + @Override + public void setDBType(DBType dbType) { + + } + + @Override + public DBType getDBType() { + return null; + } + + @Override + public String getPrepareDSL() { + return null; + } + + @Override + public List getPrepareValues() { + return null; + } + + @Override + public InsertOperator from(Table table) { + return null; + } + + @Override + public Table getTable() { + return null; + } + + @Override + public InsertOperator strictFill(String f, Supplier v) { + return null; + } + + @Override + public InsertOperator columns(Collection columns) { + return null; + } + + @Override + public InsertOperator values(List values) { + return null; + } + + @Override + public boolean isBatched() { + return false; + } +} diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/RedisShowColumnsOperator.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/RedisShowColumnsOperator.java new file mode 100644 index 00000000..47002f96 --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/RedisShowColumnsOperator.java @@ -0,0 +1,68 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.ddl.ShowColumnsOperator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; + +import java.util.List; + +@AutoService(ShowColumnsOperator.class) +@Operator.Group(OperatorKey.REDIS_LITERAL) +public class RedisShowColumnsOperator implements ShowColumnsOperator { + + @Override + public String getDSL() { + return null; + } + + @Override + public ShowColumnsOperator parse(String dsl) { + return null; + } + + @Override + public void reset() { + + } + + @Override + public void setDBType(DBType dbType) { + + } + + @Override + public DBType getDBType() { + return null; + } + + @Override + public String getPrepareDSL() { + return null; + } + + @Override + public List getPrepareValues() { + return null; + } + + @Override + public ShowColumnsOperator from(Table table) { + return null; + } + + @Override + public Table getTable() { + return null; + } + + @Override + public QueryOperator toQueryOperator() { + return null; + } + + @Override + public ShowColumnsOperator database(Database database) { + return null; + } +} diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/SPIOperatorHelperTest.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/SPIOperatorHelperTest.java new file mode 100644 index 00000000..d7446236 --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/SPIOperatorHelperTest.java @@ -0,0 +1,43 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.data.orm.dsl.ddl.CreateTableOperator; +import cc.allio.uno.data.orm.dsl.ddl.ShowColumnsOperator; +import cc.allio.uno.data.orm.dsl.dml.InsertOperator; +import cc.allio.uno.data.orm.dsl.dml.UpdateOperator; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class SPIOperatorHelperTest extends BaseTestCase { + + @Test + void testJustFindOne() { + InsertOperator sqlInsertOperator = SPIOperatorHelper.lazyGet(InsertOperator.class, OperatorKey.REDIS); + assertNotNull(sqlInsertOperator); + } + + @Test + void testFindMulti() { + assertThrows(DSLException.class, () -> SPIOperatorHelper.lazyGet(CreateTableOperator.class, OperatorKey.SQL)); + } + + @Test + void testMultiOperatorKey() { + var insert = SPIOperatorHelper.lazyGet(ShowColumnsOperator.class, OperatorKey.REDIS); + assertNotNull(insert); + } + + @Test + void testSameKeySecondOperator() { + var show = SPIOperatorHelper.lazyGet(ShowColumnsOperator.class, OperatorKey.REDIS); + assertNotNull(show); + + var insertOperator = SPIOperatorHelper.lazyGet(InsertOperator.class, OperatorKey.REDIS); + assertNotNull(insertOperator); + } + + @Test + void testNotFoundOperator() { + assertThrows(DSLException.class, () -> SPIOperatorHelper.lazyGet(UpdateOperator.class, OperatorKey.SQL)); + } +} diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/SQLNameTest.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/SQLNameTest.java similarity index 69% rename from uno-data/src/test/java/cc/allio/uno/data/orm/sql/SQLNameTest.java rename to uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/SQLNameTest.java index 5a80eba8..cfc21293 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/SQLNameTest.java +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/dsl/SQLNameTest.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql; +package cc.allio.uno.data.orm.dsl; import cc.allio.uno.test.BaseTestCase; import org.junit.jupiter.api.Test; @@ -8,11 +8,11 @@ public class SQLNameTest extends BaseTestCase { @Test void testTurnHumpInUppercase() { String mot = "MOT"; - SQLName motFormat = SQLName.of(mot, SQLName.HUMP_FEATURE); + DSLName motFormat = DSLName.of(mot, DSLName.HUMP_FEATURE); assertEquals("mot", motFormat.format()); String motTest = "MOT_TEST"; - SQLName motTestFormat = SQLName.of(motTest, SQLName.HUMP_FEATURE); + DSLName motTestFormat = DSLName.of(motTest, DSLName.HUMP_FEATURE); assertEquals("motTest", motTestFormat.format()); } } diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/executor/handler/ExecutorResultHandlerSetTest.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/executor/handler/ExecutorResultHandlerSetTest.java new file mode 100644 index 00000000..dcbd78e7 --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/executor/handler/ExecutorResultHandlerSetTest.java @@ -0,0 +1,71 @@ +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.data.orm.User; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import cc.allio.uno.data.orm.executor.options.ExecutorOptionsImpl; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class ExecutorResultHandlerSetTest extends BaseTestCase { + + ExecutorOptions executorOptions = new ExecutorOptionsImpl(DBType.H2, ExecutorKey.DB, OperatorKey.SQL); + + @Test + void testObtainBoolResultHandler() { + BoolResultHandler boolResultHandler = executorOptions.obtainBoolResultHandler(); + assertNotNull(boolResultHandler); + + assertEquals(SPIBoolResultHandler.class, boolResultHandler.getClass()); + } + + @Test + void testObtainBeanResultSetHandler() { + BeanResultSetHandler userBeanResultSetHandler = executorOptions.obtainBeanResultSetHandler(User.class); + assertNotNull(userBeanResultSetHandler); + } + + @Test + void testObtainMapResultSetHandler() { + MapResultSetHandler mapResultSetHandler = executorOptions.obtainMapResultSetHandler(); + assertNotNull(mapResultSetHandler); + } + + @Test + void testObtainDefaultResultSetHandler() { + DefaultResultSetHandler defaultResultSetHandler = executorOptions.obtainDefaultResultSetHandler(); + assertNotNull(defaultResultSetHandler); + } + + @Test + void testObtainListBeanResultSetHandler() { + ListBeanResultSetHandler userListBeanResultSetHandler = executorOptions.obtainListBeanResultSetHandler(User.class); + assertNotNull(userListBeanResultSetHandler); + } + + @Test + void testObtainDefaultListResultSetHandler() { + DefaultListResultSetHandler defaultListResultSetHandler = executorOptions.obtainDefaultListResultSetHandler(); + assertNotNull(defaultListResultSetHandler); + } + + @Test + void testObtainListMapResultHandler() { + ListMapResultHandler listMapResultHandler = executorOptions.obtainListMapResultHandler(); + assertNotNull(listMapResultHandler); + } + + @Test + void testObtainColumnDefListResultSetHandler() { + ColumnDefListResultSetHandler columnDefListResultSetHandler = executorOptions.obtainColumnDefListResultSetHandler(); + assertNotNull(columnDefListResultSetHandler); + } + + @Test + void testObtainTableListResultSetHandler() { + TableListResultSetHandler tableListResultSetHandler = executorOptions.obtainTableListResultSetHandler(); + assertNotNull(tableListResultSetHandler); + } +} diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/executor/handler/SPIBoolResultHandler.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/executor/handler/SPIBoolResultHandler.java new file mode 100644 index 00000000..63df9aca --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/executor/handler/SPIBoolResultHandler.java @@ -0,0 +1,7 @@ +package cc.allio.uno.data.orm.executor.handler; + +import cc.allio.uno.auto.service.AutoService; + +@AutoService(BoolResultHandler.class) +public class SPIBoolResultHandler extends BoolResultHandler { +} diff --git a/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/executor/options/ExecutorOptionsTest.java b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/executor/options/ExecutorOptionsTest.java new file mode 100644 index 00000000..49de8ec0 --- /dev/null +++ b/uno-data/uno-data-api/src/test/java/cc/allio/uno/data/orm/executor/options/ExecutorOptionsTest.java @@ -0,0 +1,29 @@ +package cc.allio.uno.data.orm.executor.options; + +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class ExecutorOptionsTest extends BaseTestCase { + + @Test + public void testOptionsObtains() { + ExecutorOptions executorOptions = new ExecutorOptionsImpl(DBType.H2, ExecutorKey.DB, OperatorKey.SQL); + + DBType dbType = executorOptions.getDbType(); + + assertEquals(DBType.H2, dbType); + + ExecutorKey executorKey = executorOptions.getExecutorKey(); + + assertEquals(ExecutorKey.DB, executorKey); + + OperatorKey operatorKey = executorOptions.getOperatorKey(); + assertEquals(OperatorKey.SQL, operatorKey); + + String address = executorOptions.getAddress(); + + assertNull(address); + } +} diff --git a/uno-data/uno-data-db/pom.xml b/uno-data/uno-data-db/pom.xml new file mode 100644 index 00000000..5abfabfd --- /dev/null +++ b/uno-data/uno-data-db/pom.xml @@ -0,0 +1,61 @@ + + + + cc.allio + uno-data + 1.1.6-beta.1 + ../pom.xml + + 4.0.0 + jar + uno-data-db + + + + cc.allio + uno-data-api + + + com.baomidou + mybatis-plus-boot-starter + provided + + + com.baomidou + dynamic-datasource-spring-boot-starter + provided + + + cc.allio + uno-data-sql + + + cc.allio + uno-data-test + test + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + provided + + + com.alibaba + druid-spring-boot-starter + provided + + + com.h2database + h2 + test + + + org.postgresql + postgresql + test + + + + \ No newline at end of file diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/config/DbAutoConfiguration.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/config/DbAutoConfiguration.java new file mode 100644 index 00000000..27e218a5 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/config/DbAutoConfiguration.java @@ -0,0 +1,40 @@ +package cc.allio.uno.data.orm.config; + +import cc.allio.uno.data.orm.executor.ExecutorInitializerAutoConfiguration; +import cc.allio.uno.data.orm.executor.db.DbCommandExecutorLoader; +import cc.allio.uno.data.orm.executor.db.DbExecutorProcessor; +import cc.allio.uno.data.orm.executor.db.MybatisConfiguration; +import com.alibaba.druid.pool.DruidDataSource; +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.zaxxer.hikari.HikariDataSource; +import org.apache.ibatis.session.SqlSessionFactory; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +@AutoConfigureBefore(ExecutorInitializerAutoConfiguration.class) +@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisPlusAutoConfiguration.class}) +@ConditionalOnClass({DruidDataSource.class, HikariDataSource.class}) +public class DbAutoConfiguration { + + @Bean + @ConditionalOnClass(MybatisSqlSessionFactoryBean.class) + @ConditionalOnMissingBean + public DbCommandExecutorLoader dbCommandExecutorLoader(SqlSessionFactory sqlSessionFactory) { + return new DbCommandExecutorLoader(new MybatisConfiguration(sqlSessionFactory.getConfiguration())); + } + + @Bean + @ConditionalOnBean(DbCommandExecutorLoader.class) + public DbExecutorProcessor dbExecutorProcessor() { + return new DbExecutorProcessor(); + } + +} diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DataSourceHelper.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DataSourceHelper.java new file mode 100644 index 00000000..43b0dda5 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DataSourceHelper.java @@ -0,0 +1,184 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.core.env.Envs; +import cc.allio.uno.core.util.StringUtils; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DruidDbTypeAdapter; +import com.alibaba.druid.DbType; +import com.alibaba.druid.pool.DruidDataSource; +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.boot.jdbc.DataSourceBuilder; + +import javax.sql.DataSource; +import java.util.function.UnaryOperator; + +/** + * db command executor相关帮助类,包括: + *
      + *
    • 基于{@link javax.sql.DataSource}获取{@link cc.allio.uno.data.orm.dsl.type.DBType}
    • + *
    + * + * @author jiangwei + * @date 2024/1/25 13:10 + * @since 1.1.6 + */ +public final class DataSourceHelper { + + public static T createDataSource(String username, String password, String jdbcUrl) { + return createDataSource(builder -> (DataSourceBuilder) builder.type(HikariDataSource.class) + .username(username) + .password(password) + .url(jdbcUrl)); + } + + public static T createDataSource(UnaryOperator> operator) { + return createDataSource(operator.apply((DataSourceBuilder) DataSourceBuilder.create(ClassLoader.getSystemClassLoader()))); + } + + public static T createDataSource(DataSourceBuilder dataSourceBuilder) { + return dataSourceBuilder.build(); + } + + /** + * 获取username + * + * @param dataSource dataSource + * @return username or null + */ + public static String getUsername(DataSource dataSource) { + if (dataSource instanceof DruidDataSource druidDataSource) { + return druidDataSource.getUsername(); + } + if (dataSource instanceof HikariDataSource hikariDataSource) { + return hikariDataSource.getUsername(); + } + return null; + } + + /** + * 获取password + * + * @param dataSource dataSource + * @return password or null + */ + public static String getPassword(DataSource dataSource) { + if (dataSource instanceof DruidDataSource druidDataSource) { + return druidDataSource.getPassword(); + } + if (dataSource instanceof HikariDataSource hikariDataSource) { + return hikariDataSource.getPassword(); + } + return null; + } + + /** + * 获取连接address + * + * @param dataSource dataSource + * @return address or null + * @see DBType + */ + public static String getAddress(DataSource dataSource) { + String jdbcUrl = null; + if (dataSource instanceof DruidDataSource druidDataSource) { + jdbcUrl = druidDataSource.getUrl(); + } + if (dataSource instanceof HikariDataSource hikariDataSource) { + jdbcUrl = hikariDataSource.getJdbcUrl(); + } + if (StringUtils.isBlank(jdbcUrl)) { + return null; + } + int addressIndex = jdbcUrl.indexOf("//"); + if (addressIndex < 0) { + return null; + } + String cropJdbcUrl = jdbcUrl.substring(addressIndex + 2); + if (StringUtils.isBlank(cropJdbcUrl)) { + return null; + } + int databaseIndex = cropJdbcUrl.indexOf("/"); + if (databaseIndex < 0) { + return null; + } + return cropJdbcUrl.substring(0, databaseIndex); + } + + /** + * 获取数据库 name + * + * @param dataSource dataSource + * @return database + */ + public static String getDatabase(DataSource dataSource) { + String jdbcUrl = null; + if (dataSource instanceof DruidDataSource druidDataSource) { + jdbcUrl = druidDataSource.getUrl(); + } + if (dataSource instanceof HikariDataSource hikariDataSource) { + jdbcUrl = hikariDataSource.getJdbcUrl(); + } + if (StringUtils.isBlank(jdbcUrl)) { + return null; + } + int addressIndex = jdbcUrl.indexOf("//"); + if (addressIndex < 0) { + return null; + } + String cropJdbcUrl = jdbcUrl.substring(addressIndex + 2); + if (StringUtils.isBlank(cropJdbcUrl)) { + return null; + } + int paramsIndex = cropJdbcUrl.indexOf("?"); + if (paramsIndex > 0) { + return cropJdbcUrl.substring(0, paramsIndex); + } + int slashIndex = cropJdbcUrl.indexOf("/"); + if (slashIndex < 0) { + return cropJdbcUrl; + } + return cropJdbcUrl.substring(slashIndex + 1); + } + + /** + * 根据{@link DataSource}获取{@link DBType} + * + * @param dataSource dataSource + * @return Dbtype + */ + public static DBType getDbType(DataSource dataSource) { + DBType dbType = null; + // druid + if (dataSource instanceof DruidDataSource druidDataSource) { + DbType druidDbType = DbType.of(druidDataSource.getDbType()); + dbType = DruidDbTypeAdapter.getInstance().reverse(druidDbType); + } + // hikari + if (dataSource instanceof HikariDataSource hikariDataSource) { + String driverClassName = hikariDataSource.getDriverClassName(); + dbType = fetchDriveClassName(driverClassName); + } + if (dbType == null) { + dbType = DBType.H2; + } + Envs.setProperty(DBType.DB_TYPE_CONFIG_KEY, dbType.getName()); + return dbType; + } + + /** + * 解析driveClassName为DBType + * + * @param driveClassName driveClassName + * @return DBType or default h2 + */ + private static DBType fetchDriveClassName(String driveClassName) { + for (DBType dbType : DBType.ALL_DB_TYPES) { + if (dbType.getDriverClassName().equals(driveClassName)) { + return dbType; + } + } + return DBType.H2; + } + + +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/mybatis/MybatisSQLCommandExecutor.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbCommandExecutor.java similarity index 50% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/mybatis/MybatisSQLCommandExecutor.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbCommandExecutor.java index ec32554d..8b392251 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/mybatis/MybatisSQLCommandExecutor.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbCommandExecutor.java @@ -1,17 +1,23 @@ -package cc.allio.uno.data.orm.executor.mybatis; +package cc.allio.uno.data.orm.executor.db; +import cc.allio.uno.core.StringPool; +import cc.allio.uno.core.api.Adapter; import cc.allio.uno.core.util.ClassUtils; -import cc.allio.uno.core.util.CollectionUtils; import cc.allio.uno.core.util.id.IdGenerator; -import cc.allio.uno.data.orm.SQLAdapter; +import cc.allio.uno.data.orm.dsl.exception.DSLException; import cc.allio.uno.data.orm.executor.*; -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.type.IntegerJavaType; -import com.google.common.collect.Lists; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.type.IntegerJavaType; +import cc.allio.uno.data.orm.executor.handler.BoolResultHandler; +import cc.allio.uno.data.orm.executor.handler.ListResultSetHandler; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import cc.allio.uno.data.orm.executor.options.ExecutorOptionsImpl; import lombok.extern.slf4j.Slf4j; -import org.apache.ibatis.exceptions.PersistenceException; import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.executor.SimpleExecutor; import org.apache.ibatis.mapping.*; import org.apache.ibatis.scripting.LanguageDriver; import org.apache.ibatis.scripting.defaults.RawLanguageDriver; @@ -22,92 +28,109 @@ import org.apache.ibatis.transaction.TransactionFactory; import java.lang.reflect.Field; +import java.net.SocketTimeoutException; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; /** * 基于MybatisSQL执行器 * * @author jiangwei * @date 2023/4/14 13:45 - * @see SQLCommandExecutorFactory + * @see CommandExecutorFactory * @since 1.1.4 */ @Slf4j -public class MybatisSQLCommandExecutor implements SQLCommandExecutor { +public class DbCommandExecutor extends AbstractCommandExecutor implements CommandExecutor { private final Executor executor; private final LanguageDriver languageDriver; - private final UnoMybatisConfiguration configuration; + private final MybatisConfiguration configuration; private final MybatisSQLCommandAdapter sqlCommandAdapter; - private final DruidOperatorMetadata operatorMetadata; - private static final String PACKAGE_NAME = MybatisSQLCommandExecutor.class.getPackage().getName(); + private final OperatorGroup operatorGroup; + private static final String PACKAGE_NAME = DbCommandExecutor.class.getPackage().getName(); - public MybatisSQLCommandExecutor() { - this(new Object[]{new Configuration()}); + public DbCommandExecutor(MybatisConfiguration configuration) { + this(new ExecutorOptionsImpl( + DataSourceHelper.getDbType(configuration.getEnvironment().getDataSource()), + ExecutorKey.DB, + OperatorKey.SQL), configuration); } - public MybatisSQLCommandExecutor(Object[] values) { - Configuration configuration = CollectionUtils.findValueOfType(Lists.newArrayList(values), Configuration.class); + public DbCommandExecutor(ExecutorOptions options, MybatisConfiguration configuration) { + super(options); if (configuration == null) { throw new NullPointerException(String.format("expect %s but not found", Configuration.class.getName())); } - this.configuration = new UnoMybatisConfiguration(configuration); + this.configuration = configuration; Environment environment = configuration.getEnvironment(); TransactionFactory transactionFactory = environment.getTransactionFactory(); Transaction tx = transactionFactory.newTransaction(environment.getDataSource(), TransactionIsolationLevel.READ_COMMITTED, false); - this.executor = configuration.newExecutor(tx); + this.executor = new SimpleExecutor(configuration, tx); this.languageDriver = new RawLanguageDriver(); this.sqlCommandAdapter = new MybatisSQLCommandAdapter(); - this.operatorMetadata = new DruidOperatorMetadata(); + this.operatorGroup = OperatorGroup.getOperatorGroup(OperatorKey.SQL); } @Override - public boolean bool(SQLOperator operator, SQLCommandType sqlCommand, ResultSetHandler resultSetHandler) { - if (sqlCommand == null) { + protected boolean doBool(Operator operator, CommandType commandType, ResultSetHandler resultSetHandler) { + if (commandType == null) { throw new IllegalArgumentException("support correct sql command , but it null"); } - SqlCommandType sqlCommandType = sqlCommandAdapter.get(sqlCommand); + SqlCommandType sqlCommandType = sqlCommandAdapter.adapt(commandType); SqlSource sqlSource; Object parameter = null; - if (operator instanceof SQLPrepareOperator) { - sqlSource = languageDriver.createSqlSource(configuration, ((SQLPrepareOperator) operator).getPrepareSQL(), null); - parameter = ((SQLPrepareOperator) operator).toMapValue(); + String printSQL; + if (operator instanceof PrepareOperator) { + printSQL = ((PrepareOperator) operator).getPrepareDSL(); + sqlSource = languageDriver.createSqlSource(configuration, printSQL, null); + parameter = ((PrepareOperator) operator).toMapValue(); } else { - sqlSource = languageDriver.createSqlSource(configuration, operator.getSQL(), null); + printSQL = operator.getDSL(); + sqlSource = languageDriver.createSqlSource(configuration, printSQL, null); } + ParameterMap parameterMap = getParameterMap(operator); + String cacheId = getCacheId(); MappedStatement.Builder statementBuilder = new MappedStatement - .Builder(configuration, PACKAGE_NAME + IdGenerator.defaultGenerator().getNextIdAsString(), sqlSource, sqlCommandType) - .parameterMap(getParameterMap(operator)); + .Builder(configuration, cacheId, sqlSource, sqlCommandType) + .parameterMap(parameterMap); // 验证连接是否正常,如果异常则重新建立连接 - checkConnection(); + checkAndReset(); try { - if (SQLCommandType.EXIST_TABLE == sqlCommand || SQLCommandType.SELECT == sqlCommand) { + if (CommandType.EXIST_TABLE == commandType || CommandType.SELECT == commandType) { ResultMap resultMap = - new ResultMap.Builder(configuration, IdGenerator.defaultGenerator().getNextIdAsString(), ResultGroup.class, Collections.emptyList()).build(); + new ResultMap.Builder( + configuration, + IdGenerator.defaultGenerator().getNextIdAsString(), + ResultGroup.class, + Collections.emptyList()) + .build(); MappedStatement statement = statementBuilder.resultMaps(Collections.singletonList(resultMap)).build(); List resultGroups = executor.query(statement, parameter, RowBounds.DEFAULT, null); return resultGroups.stream().anyMatch(resultSetHandler::apply); } else { MappedStatement statement = statementBuilder.build(); ResultGroup resultGroup = new ResultGroup(); + int result = executor.update(statement, parameter); resultGroup.addRow( ResultRow.builder() .index(0) - .column(SQLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) + .column(DSLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) .javaType(new IntegerJavaType()) - .value(executor.update(statement, parameter)) + .value(result) .build()); return resultSetHandler.apply(resultGroup); } + } catch (SQLException ex) { // rollback - log.error("SQL: {} executor failed, now rollback", sqlSource, ex); + if (log.isWarnEnabled()) { + log.warn("Operate ['bool'] executor failed, now rollback", ex); + } try { executor.rollback(true); } catch (SQLException ex2) { @@ -124,54 +147,77 @@ public boolean bool(SQLOperator operator, SQLCommandType sqlCommand, ResultSe } @Override - public List queryList(SQLQueryOperator queryOperator, ListResultSetHandler resultSetHandler) { - String querySQL = queryOperator.getPrepareSQL(); + protected List doQueryList(QueryOperator queryOperator, CommandType commandType, ListResultSetHandler resultSetHandler) { + String querySQL = queryOperator.getPrepareDSL(); SqlSource sqlSource = languageDriver.createSqlSource(configuration, querySQL, null); // 构建ResultMap对象 ResultMap resultMap = - new ResultMap.Builder(configuration, IdGenerator.defaultGenerator().getNextIdAsString(), ResultGroup.class, Collections.emptyList()) - .build(); + new ResultMap.Builder( + configuration, + IdGenerator.defaultGenerator().getNextIdAsString(), + ResultGroup.class, + Collections.emptyList()).build(); + ParameterMap parameterMap = getParameterMap(queryOperator); + String cacheId = getCacheId(); MappedStatement statement = - new MappedStatement.Builder(configuration, PACKAGE_NAME + IdGenerator.defaultGenerator().getNextIdAsString(), sqlSource, SqlCommandType.SELECT) + new MappedStatement.Builder(configuration, cacheId, sqlSource, SqlCommandType.SELECT) .resultMaps(Collections.singletonList(resultMap)) - .parameterMap(getParameterMap(queryOperator)) + .parameterMap(parameterMap) .lang(languageDriver) .useCache(false) .resultSetType(ResultSetType.DEFAULT) .build(); // 验证连接是否正常,如果异常则重新建立连接 - checkConnection(); + checkAndReset(); try { List resultGroups = executor.query(statement, queryOperator.toMapValue(), RowBounds.DEFAULT, null); ResultSet resultSet = new ResultSet(); resultSet.setResultGroups(resultGroups); return resultSetHandler.apply(resultSet); } catch (Throwable ex) { - log.error("Execute query SQL: {} failure", querySQL, ex); - throw new PersistenceException(ex); + if (log.isWarnEnabled()) { + log.warn("Execute query failure {}", ex.getMessage()); + } + throw new DSLException(ex); + } + } + + @Override + public boolean check() throws SocketTimeoutException { + try { + Connection connection = executor.getTransaction().getConnection(); + return !connection.isClosed(); + } catch (SQLException ex) { + throw new SocketTimeoutException(ex.getMessage()); } } @Override public ExecutorKey getKey() { - return SQLCommandExecutor.MYBATIS_SQL_COMMAND_EXECUTOR_KEY; + return ExecutorKey.DB; + } + + @Override + public OperatorGroup getOperatorGroup() { + return operatorGroup; } @Override - public OperatorMetadata getOperatorMetadata() { - return operatorMetadata; + public void destroy() { + this.executor.close(true); } /** - * 获取mybatis ParameterMap + * getParameterMap * * @param sqlOperator sqlOperator * @return ParameterMap */ - private ParameterMap getParameterMap(SQLOperator sqlOperator) { - if (sqlOperator instanceof SQLPrepareOperator) { - List prepareValues = ((SQLPrepareOperator) sqlOperator).getPrepareValues(); - List parameterMappings = prepareValues.stream().map(prepareValue -> { + private ParameterMap getParameterMap(Operator sqlOperator) { + if (sqlOperator instanceof PrepareOperator prepareOperator) { + List prepareValues = prepareOperator.getPrepareValues(); + List parameterMappings = prepareValues.stream() + .map(prepareValue -> { Class javaType; try { javaType = prepareValue.getJavaType().getJavaType(); @@ -183,7 +229,7 @@ private ParameterMap getParameterMap(SQLOperator sqlOperator) { .Builder(configuration, prepareValue.getColumn(), javaType) .build(); }) - .collect(Collectors.toList()); + .toList(); return new ParameterMap .Builder(configuration, IdGenerator.defaultGenerator().getNextIdAsString(), null, parameterMappings) .build(); @@ -194,13 +240,13 @@ private ParameterMap getParameterMap(SQLOperator sqlOperator) { /** * 检查当前{@link Executor}的Connection.检查关闭后,重置连接 */ - private void checkConnection() { + private void checkAndReset() { try { - Connection connection = executor.getTransaction().getConnection(); - if (connection.isClosed()) { + boolean check = check(); + if (!check) { resetConnection(); } - } catch (SQLException ex) { + } catch (SocketTimeoutException ex) { // ignore } } @@ -219,30 +265,35 @@ private void resetConnection() { } } - public static class MybatisSQLCommandAdapter implements SQLAdapter { + public static class MybatisSQLCommandAdapter implements Adapter { @Override - public SqlCommandType get(SQLCommandType sqlCommand) { - switch (sqlCommand) { - case UNKNOWN: - return SqlCommandType.UNKNOWN; - case FLUSH: - return SqlCommandType.FLUSH; - case DELETE: - return SqlCommandType.DELETE; - case INSERT: - return SqlCommandType.INSERT; - case SELECT: - return SqlCommandType.SELECT; - case UPDATE: - return SqlCommandType.UPDATE; - } - return null; + public SqlCommandType adapt(CommandType sqlCommand) { + return switch (sqlCommand) { + case UNKNOWN -> SqlCommandType.UNKNOWN; + case FLUSH -> SqlCommandType.FLUSH; + case DELETE -> SqlCommandType.DELETE; + case INSERT -> SqlCommandType.INSERT; + case SELECT -> SqlCommandType.SELECT; + case UPDATE -> SqlCommandType.UPDATE; + default -> null; + }; } @Override - public SQLCommandType reversal(SqlCommandType sqlCommandType) { - return null; + public CommandType reverse(SqlCommandType sqlCommandType) { + return switch (sqlCommandType) { + case SELECT -> CommandType.SELECT; + case INSERT -> CommandType.INSERT; + case FLUSH -> CommandType.FLUSH; + case DELETE -> CommandType.DELETE; + case UPDATE -> CommandType.UPDATE; + case UNKNOWN -> CommandType.UNKNOWN; + }; } } + + private String getCacheId() { + return PACKAGE_NAME + StringPool.SLASH + getOptions().getKey() + StringPool.SLASH + IdGenerator.defaultGenerator().getNextIdAsString(); + } } diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbCommandExecutorLoader.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbCommandExecutorLoader.java new file mode 100644 index 00000000..0f1fbde2 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbCommandExecutorLoader.java @@ -0,0 +1,85 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.executor.*; +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import com.zaxxer.hikari.HikariDataSource; +import org.apache.ibatis.mapping.Environment; +import org.mybatis.spring.transaction.SpringManagedTransactionFactory; +import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; +import org.springframework.boot.jdbc.DataSourceBuilder; + +import javax.sql.DataSource; +import java.time.Duration; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 实例化{@link CommandExecutor} + * + * @author jiangwei + * @date 2024/1/10 18:27 + * @since 1.1.6 + */ +public class DbCommandExecutorLoader implements ExecutorLoader { + + private final MybatisConfiguration configuration; + private final AtomicInteger createCount = new AtomicInteger(0); + + public DbCommandExecutorLoader(MybatisConfiguration configuration) { + this.configuration = configuration; + } + + @Override + public CommandExecutor load(List interceptors) { + DataSource dataSource = configuration.getEnvironment().getDataSource(); + DBType dbType = DataSourceHelper.getDbType(dataSource); + String username = DataSourceHelper.getUsername(dataSource); + String password = DataSourceHelper.getPassword(dataSource); + String address = DataSourceHelper.getAddress(dataSource); + String database = DataSourceHelper.getDatabase(dataSource); + ExecutorOptions executorOptions = ExecutorOptionsBuilder + .create(dbType, "default_" + dbType.getName()) + .executorKey(ExecutorKey.DB) + .operatorKey(OperatorKey.SQL) + .username(username) + .password(password) + .address(address) + .database(database) + .interceptors(interceptors) + .systemDefault(true) + .build(); + return new DbCommandExecutor(executorOptions, configuration); + } + + @Override + public CommandExecutor load(ExecutorOptions executorOptions) { + String jdbcUrl = executorOptions.getDbType().parseTemplate(executorOptions.getAddress(), executorOptions.getDatabase()); + JdbcConnectionDetails connectionDetails = new JdbcConnectionDetailsImpl(executorOptions.getUsername(), executorOptions.getUsername(), jdbcUrl); + HikariDataSource dataSource = + DataSourceBuilder.create(ClassLoader.getSystemClassLoader()) + .type(HikariDataSource.class) + .driverClassName(connectionDetails.getDriverClassName()) + .url(connectionDetails.getJdbcUrl()) + .username(connectionDetails.getUsername()) + .password(connectionDetails.getPassword()) + .build(); + dataSource.setAutoCommit(true); + dataSource.setConnectionTimeout(Duration.ofSeconds(10).toMillis()); + dataSource.setMaximumPoolSize(2); + dataSource.setMaxLifetime(Duration.ofSeconds(30).toMillis()); + MybatisConfiguration newConfiguration = configuration.copy(); + Environment environment = new Environment("DbCommandExecutorLoader" + createCount.getAndIncrement(), new SpringManagedTransactionFactory(), dataSource); + newConfiguration.setEnvironment(environment); + return new DbCommandExecutor(executorOptions, newConfiguration); + } + + @Override + public boolean match(DBType dbType) { + return DBType.DBCategory.RELATIONAL == dbType.getCategory(); + } + +} diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbExecutorAspect.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbExecutorAspect.java new file mode 100644 index 00000000..56dff69d --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbExecutorAspect.java @@ -0,0 +1,15 @@ +package cc.allio.uno.data.orm.executor.db; + +import org.aspectj.lang.annotation.Aspect; + +/** + * Aspect + * + * @author jiangwei + * @date 2024/1/10 18:21 + * @see DbExecutorAware + * @since 1.1.6 + */ +@Aspect +public class DbExecutorAspect { +} diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbExecutorAware.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbExecutorAware.java new file mode 100644 index 00000000..efc47ec2 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbExecutorAware.java @@ -0,0 +1,13 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.data.orm.executor.ExecutorAware; + +/** + * 获取{@link DbCommandExecutor}实例标识接口 + * + * @author jiangwei + * @date 2024/1/10 18:18 + * @since 1.1.6 + */ +public interface DbExecutorAware extends ExecutorAware { +} diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbExecutorProcessor.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbExecutorProcessor.java new file mode 100644 index 00000000..e4048346 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbExecutorProcessor.java @@ -0,0 +1,36 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.core.util.ClassUtils; +import cc.allio.uno.data.orm.executor.CommandExecutorFactory; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import org.aopalliance.intercept.MethodInterceptor; +import org.springframework.aop.aspectj.annotation.AspectJProxyFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.NameMatchMethodPointcut; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +/** + * {@link cc.allio.uno.data.orm.executor.ExecutorAware}实现 + * + * @author jiangwei + * @date 2024/1/10 18:35 + * @since 1.1.6 + */ +public class DbExecutorProcessor implements BeanPostProcessor { + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (!ClassUtils.isAssignable(DbExecutorAware.class, bean.getClass())) { + return bean; + } + AspectJProxyFactory proxyFactory = new AspectJProxyFactory(); + proxyFactory.setTarget(bean); + proxyFactory.addAspect(DbExecutorAspect.class); + NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); + pointcut.setMappedName("getExecutor"); + MethodInterceptor methodInterceptor = invocation -> CommandExecutorFactory.getDSLExecutor(ExecutorKey.DB); + proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut, methodInterceptor)); + return proxyFactory.getProxy(); + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/mybatis/UnoStatementSetHandler.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbStatementSetHandler.java similarity index 86% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/mybatis/UnoStatementSetHandler.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbStatementSetHandler.java index 9a443523..319083b8 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/mybatis/UnoStatementSetHandler.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/DbStatementSetHandler.java @@ -1,8 +1,8 @@ -package cc.allio.uno.data.orm.executor.mybatis; +package cc.allio.uno.data.orm.executor.db; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.type.JavaType; -import cc.allio.uno.data.orm.type.TypeRegistry; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.type.JavaType; +import cc.allio.uno.data.orm.dsl.type.TypeRegistry; import cc.allio.uno.data.orm.executor.ResultGroup; import cc.allio.uno.data.orm.executor.ResultRow; import org.apache.ibatis.executor.Executor; @@ -33,9 +33,9 @@ * @date 2023/4/14 18:00 * @since 1.1.4 */ -public class UnoStatementSetHandler extends DefaultResultSetHandler implements ResultSetHandler { +public class DbStatementSetHandler extends DefaultResultSetHandler implements ResultSetHandler { - public UnoStatementSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql, RowBounds rowBounds) { + public DbStatementSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql, RowBounds rowBounds) { super(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds); } @@ -54,7 +54,8 @@ public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHan ResultRow.ResultRowBuilder resultRowBuilder = ResultRow.builder(); resultRowBuilder.index(i); String columnName = columnNames.get(i); - resultRowBuilder.column(SQLName.of(columnName, SQLName.HUMP_FEATURE)); + // 字段名称自动为驼峰 + resultRowBuilder.column(DSLName.of(columnName, DSLName.HUMP_FEATURE)); JdbcType mybatisJdbcType = rsw.getJdbcType(columnName); JDBCType jdbcType = JDBCType.valueOf(mybatisJdbcType.TYPE_CODE); resultRowBuilder.jdbcType(jdbcType); diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/JdbcConnectionDetailsImpl.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/JdbcConnectionDetailsImpl.java new file mode 100644 index 00000000..0aea4aa7 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/JdbcConnectionDetailsImpl.java @@ -0,0 +1,15 @@ +package cc.allio.uno.data.orm.executor.db; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; + +@AllArgsConstructor +@Getter +public class JdbcConnectionDetailsImpl implements JdbcConnectionDetails { + + private final String username; + private final String password; + private final String jdbcUrl; + +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/mybatis/UnoMybatisConfiguration.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/MybatisConfiguration.java similarity index 93% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/mybatis/UnoMybatisConfiguration.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/MybatisConfiguration.java index ecdec64f..829305be 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/mybatis/UnoMybatisConfiguration.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/MybatisConfiguration.java @@ -1,5 +1,6 @@ -package cc.allio.uno.data.orm.executor.mybatis; +package cc.allio.uno.data.orm.executor.db; +import cc.allio.uno.core.bean.BeanInfoWrapper; import org.apache.ibatis.binding.MapperRegistry; import org.apache.ibatis.builder.CacheRefResolver; import org.apache.ibatis.builder.ResultMapResolver; @@ -17,6 +18,7 @@ import org.apache.ibatis.mapping.*; import org.apache.ibatis.parsing.XNode; import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.InterceptorChain; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.ReflectorFactory; import org.apache.ibatis.reflection.factory.ObjectFactory; @@ -24,6 +26,7 @@ import org.apache.ibatis.scripting.LanguageDriver; import org.apache.ibatis.scripting.LanguageDriverRegistry; import org.apache.ibatis.session.*; +import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory; import org.apache.ibatis.transaction.Transaction; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeAliasRegistry; @@ -34,18 +37,22 @@ /** * 替换一些mybatis{@link ResultSetHandler}的组件 + *

    注意:{@link #environment}如果使用父类进行设置或获取,将会导致使用默认数据源查询时会被替换,相应的代码在{@link DefaultSqlSessionFactory#openSession()}

    * * @author jiangwei * @date 2023/4/14 17:51 * @see #newResultSetHandler(Executor, MappedStatement, RowBounds, ParameterHandler, ResultHandler, BoundSql) * @since 1.1.4 */ -public class UnoMybatisConfiguration extends Configuration { +public class MybatisConfiguration extends Configuration { private final Configuration configuration; + protected Environment environment; - public UnoMybatisConfiguration(Configuration configuration) { + public MybatisConfiguration(Configuration configuration) { this.configuration = configuration; + BeanInfoWrapper beanInfoWrapper = BeanInfoWrapper.of(MybatisConfiguration.class); + beanInfoWrapper.setForce(this, "interceptorChain", new InterceptorChain()); } @Override @@ -200,12 +207,16 @@ public boolean isResourceLoaded(String resource) { @Override public Environment getEnvironment() { - return configuration.getEnvironment(); + if (environment == null) { + return configuration.getEnvironment(); + } else { + return environment; + } } @Override public void setEnvironment(Environment environment) { - configuration.setEnvironment(environment); + this.environment = environment; } @Override @@ -430,7 +441,8 @@ public void setObjectWrapperFactory(ObjectWrapperFactory objectWrapperFactory) { @Override public List getInterceptors() { - return configuration.getInterceptors(); + // 避免走到第三方Interceptor + return Collections.emptyList(); } @Override @@ -473,7 +485,7 @@ public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Obj */ @Override public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) { - ResultSetHandler resultSetHandler = new UnoStatementSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds); + ResultSetHandler resultSetHandler = new DbStatementSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds); resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler); return resultSetHandler; } @@ -665,7 +677,7 @@ public Map getSqlFragments() { @Override public void addInterceptor(Interceptor interceptor) { - configuration.addInterceptor(interceptor); + // 去除mybatis 内置拦截器 } @Override @@ -727,4 +739,12 @@ protected void checkGloballyForDiscriminatedNestedResultMaps(ResultMap rm) { protected void checkLocallyForDiscriminatedNestedResultMaps(ResultMap rm) { super.checkLocallyForDiscriminatedNestedResultMaps(rm); } + + /** + * 新创建一个mybatis configuration实例 + */ + public MybatisConfiguration copy() { + return new MybatisConfiguration(this.configuration); + + } } diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/ColumnDefListResultHandlerDelegate.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/ColumnDefListResultHandlerDelegate.java new file mode 100644 index 00000000..9b84bc60 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/ColumnDefListResultHandlerDelegate.java @@ -0,0 +1,46 @@ +package cc.allio.uno.data.orm.executor.db.handler; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.executor.ResultSet; +import cc.allio.uno.data.orm.executor.db.handler.dialect.H2ColumnDefListResultSetHandler; +import cc.allio.uno.data.orm.executor.db.handler.dialect.MySQLColumnDefListResultHandler; +import cc.allio.uno.data.orm.executor.db.handler.dialect.PostgreSQLColumnDefListResultSetHandler; +import cc.allio.uno.data.orm.executor.handler.ColumnDefListResultSetHandler; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import com.google.common.collect.Maps; + +import java.util.List; +import java.util.Map; + +/** + * 基于db的多类型,构建一个代理类,按照不同的{@link DBType}构建对应的{@link ColumnDefListResultSetHandler} + * + * @author jiangwei + * @date 2024/2/14 22:58 + * @since 1.1.6 + */ +@AutoService(ColumnDefListResultSetHandler.class) +public class ColumnDefListResultHandlerDelegate extends ColumnDefListResultSetHandler { + + private final Map dialectRegistry = Maps.newHashMap(); + + public ColumnDefListResultHandlerDelegate() { + dialectRegistry.put(DBType.H2, new H2ColumnDefListResultSetHandler()); + dialectRegistry.put(DBType.MYSQL, new MySQLColumnDefListResultHandler()); + dialectRegistry.put(DBType.POSTGRESQL, new PostgreSQLColumnDefListResultSetHandler()); + } + + @Override + public List apply(ResultSet resultSet) { + ExecutorOptions executorOptions = obtainExecutorOptions(); + DBType dbType = executorOptions.getDbType(); + ColumnDefListResultSetHandler actual = dialectRegistry.get(dbType); + if (actual != null) { + actual.setExecutorOptions(executorOptions); + return actual.apply(resultSet); + } + return super.apply(resultSet); + } +} diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/dialect/H2ColumnDefListResultSetHandler.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/dialect/H2ColumnDefListResultSetHandler.java new file mode 100644 index 00000000..77aa96af --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/dialect/H2ColumnDefListResultSetHandler.java @@ -0,0 +1,14 @@ +package cc.allio.uno.data.orm.executor.db.handler.dialect; + +import cc.allio.uno.data.orm.dsl.Table; +import cc.allio.uno.data.orm.executor.handler.ColumnDefListResultSetHandler; + +/** + * {@link cc.allio.uno.data.orm.dsl.type.DBType#H2}的{@link cc.allio.uno.data.orm.executor.CommandExecutor#showColumns(Table)}结果集处理器 + * + * @author jiangwei + * @date 2024/2/14 23:19 + * @since 1.1.6 + */ +public class H2ColumnDefListResultSetHandler extends ColumnDefListResultSetHandler { +} diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/dialect/MySQLColumnDefListResultHandler.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/dialect/MySQLColumnDefListResultHandler.java new file mode 100644 index 00000000..0d97f791 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/dialect/MySQLColumnDefListResultHandler.java @@ -0,0 +1,14 @@ +package cc.allio.uno.data.orm.executor.db.handler.dialect; + +import cc.allio.uno.data.orm.dsl.Table; +import cc.allio.uno.data.orm.executor.handler.ColumnDefListResultSetHandler; + +/** + * {@link cc.allio.uno.data.orm.dsl.type.DBType#MYSQL}的{@link cc.allio.uno.data.orm.executor.CommandExecutor#showColumns(Table)}结果集处理器 + * + * @author jiangwei + * @date 2024/2/14 23:18 + * @since 1.1.6 + */ +public class MySQLColumnDefListResultHandler extends ColumnDefListResultSetHandler { +} diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/dialect/PostgreSQLColumnDefListResultSetHandler.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/dialect/PostgreSQLColumnDefListResultSetHandler.java new file mode 100644 index 00000000..19f89fb0 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/orm/executor/db/handler/dialect/PostgreSQLColumnDefListResultSetHandler.java @@ -0,0 +1,48 @@ +package cc.allio.uno.data.orm.executor.db.handler.dialect; + +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.Table; +import cc.allio.uno.data.orm.dsl.ddl.ShowColumnsOperator; +import cc.allio.uno.data.orm.dsl.dialect.TypeTranslator; +import cc.allio.uno.data.orm.dsl.dialect.TypeTranslatorHolder; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DataType; +import cc.allio.uno.data.orm.executor.ResultSet; +import cc.allio.uno.data.orm.executor.handler.ColumnDefListResultSetHandler; +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.Optional; + +/** + * {@link cc.allio.uno.data.orm.dsl.type.DBType#POSTGRESQL}的{@link cc.allio.uno.data.orm.executor.CommandExecutor#showColumns(Table)}结果集处理器 + * + * @author jiangwei + * @date 2024/2/14 23:19 + * @since 1.1.6 + */ +public class PostgreSQLColumnDefListResultSetHandler extends ColumnDefListResultSetHandler { + + /** + * pg 数据类型名称字段 + */ + private static final String UDT_NAME = "UDT_NAME"; + + @Override + public List apply(ResultSet resultSet) { + return Lists.newArrayList(resultSet) + .stream() + .map(r -> { + ColumnDef.ColumnDefBuilder columnDefBuilder = commonFieldBuilder(r); + DBType dbType = obtainExecutorOptions().getDbType(); + TypeTranslator typeTranslator = TypeTranslatorHolder.getTypeTranslator(dbType); + DataType dataType = Optional.ofNullable(typeTranslator.reserve(r.getStringValue(ShowColumnsOperator.DATA_TYPE_FIELD))) + .or(() -> Optional.ofNullable(typeTranslator.reserve(r.getStringValue(UDT_NAME)))) + .map(d -> buildDataType(d, r)) + .orElse(null); + columnDefBuilder.dataType(dataType); + return columnDefBuilder.build(); + }) + .toList(); + } +} diff --git a/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/UnoDataMybatisAutoConfiguration.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/UnoDataMybatisAutoConfiguration.java new file mode 100644 index 00000000..8060f0a1 --- /dev/null +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/UnoDataMybatisAutoConfiguration.java @@ -0,0 +1,24 @@ +package cc.allio.uno.data.query.db; + +import cc.allio.uno.data.query.db.query.interceptor.QueryInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +/** + * UNO-DATA配置 + * + * @author jiangwei + * @date 2022/11/22 15:11 + * @since 1.1.2 + */ +@Configuration(proxyBeanMethods = false) +@EnableAspectJAutoProxy +public class UnoDataMybatisAutoConfiguration { + + @Bean + public QueryInterceptor unoQueryInterceptor() { + return new QueryInterceptor(); + } + +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/mapper/QueryMapper.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/mapper/QueryMapper.java similarity index 68% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/mapper/QueryMapper.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/mapper/QueryMapper.java index c282f8c2..88ea5997 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/mapper/QueryMapper.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/mapper/QueryMapper.java @@ -1,6 +1,6 @@ -package cc.allio.uno.data.query.mybatis.mapper; +package cc.allio.uno.data.query.db.mapper; -import cc.allio.uno.data.query.mybatis.HigherQuery; +import cc.allio.uno.data.query.HigherQuery; import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryContemporaneousForValueTimeQueryMethodInterceptor.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryContemporaneousForValueTimeQueryMethodInterceptor.java similarity index 86% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryContemporaneousForValueTimeQueryMethodInterceptor.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryContemporaneousForValueTimeQueryMethodInterceptor.java index 820bacc8..36d21a13 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryContemporaneousForValueTimeQueryMethodInterceptor.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryContemporaneousForValueTimeQueryMethodInterceptor.java @@ -1,10 +1,10 @@ -package cc.allio.uno.data.query.mybatis.query.interceptor; +package cc.allio.uno.data.query.db.query.interceptor; -import cc.allio.uno.data.query.mybatis.mapper.QueryMapper; -import cc.allio.uno.data.query.mybatis.QueryFilter; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.db.mapper.QueryMapper; import cc.allio.uno.data.query.stream.ContemporaneousStream; import cc.allio.uno.data.query.stream.ContemporaneousValueTimeStream; -import cc.allio.uno.data.query.mybatis.query.stream.QueryMethodInterceptorStream; +import cc.allio.uno.data.query.db.query.stream.QueryMethodInterceptorStream; import cc.allio.uno.core.aop.JoinPointDelegate; import java.lang.reflect.Method; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryContemporaneousQueryMethodInterceptor.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryContemporaneousQueryMethodInterceptor.java similarity index 83% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryContemporaneousQueryMethodInterceptor.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryContemporaneousQueryMethodInterceptor.java index 115fff9b..ee722b51 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryContemporaneousQueryMethodInterceptor.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryContemporaneousQueryMethodInterceptor.java @@ -1,9 +1,9 @@ -package cc.allio.uno.data.query.mybatis.query.interceptor; +package cc.allio.uno.data.query.db.query.interceptor; -import cc.allio.uno.data.query.mybatis.mapper.QueryMapper; -import cc.allio.uno.data.query.mybatis.QueryFilter; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.db.mapper.QueryMapper; import cc.allio.uno.data.query.stream.ContemporaneousStream; -import cc.allio.uno.data.query.mybatis.query.stream.QueryMethodInterceptorStream; +import cc.allio.uno.data.query.db.query.stream.QueryMethodInterceptorStream; import cc.allio.uno.core.aop.JoinPointDelegate; import java.lang.reflect.Method; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryInterceptor.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryInterceptor.java similarity index 93% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryInterceptor.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryInterceptor.java index 6c648bd7..78fa71a9 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryInterceptor.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryInterceptor.java @@ -1,7 +1,7 @@ -package cc.allio.uno.data.query.mybatis.query.interceptor; +package cc.allio.uno.data.query.db.query.interceptor; import cc.allio.uno.core.aop.JoinPointDelegate; -import cc.allio.uno.data.query.mybatis.mapper.QueryMapper; +import cc.allio.uno.data.query.db.mapper.QueryMapper; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -40,7 +40,7 @@ public QueryInterceptor() { /** * 切入点为{@link QueryMapper}下的所有方法 */ - @Pointcut("execution(* cc.allio.uno.data.query.mybatis.mapper.QueryMapper.*(..))") + @Pointcut("execution(* cc.allio.uno.data.query.db.mapper.QueryMapper.*(..))") public void interceptor() { } diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryListForValueTimeQueryMethodInterceptor.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryListForValueTimeQueryMethodInterceptor.java similarity index 85% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryListForValueTimeQueryMethodInterceptor.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryListForValueTimeQueryMethodInterceptor.java index db49d405..fecbd70f 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryListForValueTimeQueryMethodInterceptor.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryListForValueTimeQueryMethodInterceptor.java @@ -1,8 +1,8 @@ -package cc.allio.uno.data.query.mybatis.query.interceptor; +package cc.allio.uno.data.query.db.query.interceptor; -import cc.allio.uno.data.query.mybatis.mapper.QueryMapper; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.query.stream.QueryMethodInterceptorStream; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.db.mapper.QueryMapper; +import cc.allio.uno.data.query.db.query.stream.QueryMethodInterceptorStream; import cc.allio.uno.data.query.stream.ValueTime; import cc.allio.uno.data.query.stream.ValueTimeStream; import cc.allio.uno.core.aop.JoinPointDelegate; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryListQueryMethodInterceptor.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryListQueryMethodInterceptor.java similarity index 82% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryListQueryMethodInterceptor.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryListQueryMethodInterceptor.java index 2dff8adb..d355bd96 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryListQueryMethodInterceptor.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryListQueryMethodInterceptor.java @@ -1,8 +1,8 @@ -package cc.allio.uno.data.query.mybatis.query.interceptor; +package cc.allio.uno.data.query.db.query.interceptor; -import cc.allio.uno.data.query.mybatis.mapper.QueryMapper; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.query.stream.MybatisStream; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.db.mapper.QueryMapper; +import cc.allio.uno.data.query.db.query.stream.MybatisStream; import cc.allio.uno.data.query.stream.StreamBuilder; import cc.allio.uno.core.aop.JoinPointDelegate; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryMethodInterceptor.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryMethodInterceptor.java similarity index 90% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryMethodInterceptor.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryMethodInterceptor.java index f43d5ae1..8de24613 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryMethodInterceptor.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryMethodInterceptor.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.query.mybatis.query.interceptor; +package cc.allio.uno.data.query.db.query.interceptor; import cc.allio.uno.core.aop.JoinPointDelegate; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryMethodInterceptorDelegate.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryMethodInterceptorDelegate.java similarity index 82% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryMethodInterceptorDelegate.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryMethodInterceptorDelegate.java index 5f32d09f..44cfd60f 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryMethodInterceptorDelegate.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryMethodInterceptorDelegate.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.query.mybatis.query.interceptor; +package cc.allio.uno.data.query.db.query.interceptor; /** * 拦截器代理接口 diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryMethodInterceptorFactory.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryMethodInterceptorFactory.java similarity index 97% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryMethodInterceptorFactory.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryMethodInterceptorFactory.java index 2b004963..4d147837 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/interceptor/QueryMethodInterceptorFactory.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/interceptor/QueryMethodInterceptorFactory.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.query.mybatis.query.interceptor; +package cc.allio.uno.data.query.db.query.interceptor; import com.google.common.collect.Maps; import lombok.Data; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/stream/MybatisStream.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/stream/MybatisStream.java similarity index 82% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/stream/MybatisStream.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/stream/MybatisStream.java index 4ed7a1e3..90ea7221 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/stream/MybatisStream.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/stream/MybatisStream.java @@ -1,8 +1,8 @@ -package cc.allio.uno.data.query.mybatis.query.stream; +package cc.allio.uno.data.query.db.query.stream; -import cc.allio.uno.data.query.mybatis.mapper.QueryMapper; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.query.interceptor.QueryMethodInterceptor; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.db.mapper.QueryMapper; +import cc.allio.uno.data.query.db.query.interceptor.QueryMethodInterceptor; import cc.allio.uno.core.aop.JoinPointDelegate; import cc.allio.uno.data.query.stream.CollectionTimeStream; import reactor.core.publisher.Flux; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/stream/QueryMethodInterceptorStream.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/stream/QueryMethodInterceptorStream.java similarity index 79% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/stream/QueryMethodInterceptorStream.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/stream/QueryMethodInterceptorStream.java index 90a29be5..992bb920 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/query/stream/QueryMethodInterceptorStream.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/query/stream/QueryMethodInterceptorStream.java @@ -1,7 +1,7 @@ -package cc.allio.uno.data.query.mybatis.query.stream; +package cc.allio.uno.data.query.db.query.stream; -import cc.allio.uno.data.query.mybatis.QueryFilter; -import cc.allio.uno.data.query.mybatis.query.interceptor.QueryMethodInterceptor; +import cc.allio.uno.data.query.QueryFilter; +import cc.allio.uno.data.query.db.query.interceptor.QueryMethodInterceptor; import cc.allio.uno.core.aop.JoinPointDelegate; import cc.allio.uno.data.query.stream.CollectionTimeStream; import reactor.core.publisher.Flux; diff --git a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/type/DateDimensionTypeHandler.java b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/type/DateDimensionTypeHandler.java similarity index 82% rename from uno-data/src/main/java/cc/allio/uno/data/query/mybatis/type/DateDimensionTypeHandler.java rename to uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/type/DateDimensionTypeHandler.java index d5ee1838..503c471e 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/query/mybatis/type/DateDimensionTypeHandler.java +++ b/uno-data/uno-data-db/src/main/java/cc/allio/uno/data/query/db/type/DateDimensionTypeHandler.java @@ -1,19 +1,22 @@ -package cc.allio.uno.data.query.mybatis.type; +package cc.allio.uno.data.query.db.type; import cc.allio.uno.data.query.param.DateDimension; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.MappedTypes; import java.sql.*; import java.util.Date; /** * {@link DateDimension}类型处理器 + * 注意使用时候需要在Mybatis配置文件中配置typeHandlerPackage = cc/allio/uno/data/query/db/type... * * @author jiangwei * @date 2022/9/30 17:01 * @since 1.1.0 */ +@MappedTypes(Object.class) public class DateDimensionTypeHandler extends BaseTypeHandler { @Override diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/druid-sql.puml b/uno-data/uno-data-db/src/main/resources/uml/druid-sql.puml similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/druid-sql.puml rename to uno-data/uno-data-db/src/main/resources/uml/druid-sql.puml diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/AuditInterceptor.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/AuditInterceptor.java new file mode 100644 index 00000000..94ae18b4 --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/AuditInterceptor.java @@ -0,0 +1,35 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.core.util.id.IdGenerator; +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.dml.InsertOperator; +import cc.allio.uno.data.orm.dsl.dml.UpdateOperator; + +import java.util.Date; + +public class AuditInterceptor implements Interceptor { + + @Override + public void onSaveBefore(CommandExecutor commandExecutor, Operator operator) { + if (operator instanceof InsertOperator insertOperator) { + insertOperator.strictFill("id", () -> IdGenerator.defaultGenerator().getNextId()); + insertOperator.strictFill("create_user", 1L); + insertOperator.strictFill("create_dept", 1L); + insertOperator.strictFill("create_time", new Date()); + insertOperator.strictFill("update_user", 1L); + insertOperator.strictFill("update_time", new Date()); + insertOperator.strictFill("is_deleted", 0); + } + } + + @Override + public void onUpdateBefore(CommandExecutor commandExecutor, Operator operator) { + if (operator instanceof UpdateOperator updateOperator) { + updateOperator.strictFill("update_user", 1L); + updateOperator.strictFill("update_time", new Date()); + updateOperator.strictFill("is_deleted", 0); + } + } +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DataSourceHelperTest.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DataSourceHelperTest.java new file mode 100644 index 00000000..f91a4eb4 --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DataSourceHelperTest.java @@ -0,0 +1,25 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +import javax.sql.DataSource; + +public class DataSourceHelperTest extends BaseTestCase { + DataSource postgreSQLDataSource = DataSourceHelper.createDataSource("", "", "jdbc:postgresql://localhost:5432/test"); + + @Test + void testGetAddressByPostgreSQL() { + + String address = DataSourceHelper.getAddress(postgreSQLDataSource); + + assertEquals("localhost:5432", address); + } + + @Test + void testGetDatabaseByPostgreSQL() { + String database = DataSourceHelper.getDatabase(postgreSQLDataSource); + + assertEquals("test", database); + } +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DbCommandExecutorTest.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DbCommandExecutorTest.java new file mode 100644 index 00000000..978804b0 --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DbCommandExecutorTest.java @@ -0,0 +1,59 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Table; +import cc.allio.uno.test.BaseTestCase; +import cc.allio.uno.test.Inject; +import cc.allio.uno.test.RunTest; +import cc.allio.uno.test.env.annotation.MybatisEnv; +import org.apache.ibatis.session.SqlSessionFactory; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; + +@RunTest +@MybatisEnv +public class DbCommandExecutorTest extends BaseTestCase { + + @Inject + private SqlSessionFactory sqlSessionFactory; + + DbCommandExecutor mybatisCommandExecutor; + + @BeforeEach + void init() { + mybatisCommandExecutor = new DbCommandExecutor(new MybatisConfiguration(sqlSessionFactory.getConfiguration())); + mybatisCommandExecutor.getOptions().addInterceptor(new PrintInterceptor()); + mybatisCommandExecutor.getOptions().addInterceptor(new NothingInterceptor()); + String sql = "CREATE TABLE dual (\n" + + "\tname char(9) PRIMARY KEY NOT NULL UNIQUE\n" + + ")"; + mybatisCommandExecutor.createTable(o -> o.parse(sql)); + } + + @Test + void testConfigurationNotNull() { + assertNotNull(mybatisCommandExecutor); + } + + @Test + void testShowTables() { + List
    tables = mybatisCommandExecutor.showTables(o -> o); + assertEquals(1, tables.size()); + } + + @Test + void testShowColumns() { + List columnDefs = mybatisCommandExecutor.showColumns(o -> o.from(DSLName.of("DUAL", DSLName.PLAIN_FEATURE))); + assertEquals(1, columnDefs.size()); + } + + + @AfterEach + void destroy() { + mybatisCommandExecutor.dropTable(DSLName.of("DUAL", DSLName.PLAIN_FEATURE)); + } +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DbExecutorAwareTest.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DbExecutorAwareTest.java new file mode 100644 index 00000000..be2140f4 --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DbExecutorAwareTest.java @@ -0,0 +1,31 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.core.util.ClassUtils; +import cc.allio.uno.data.orm.config.DbAutoConfiguration; +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.ExecutorInitializerAutoConfiguration; +import cc.allio.uno.test.BaseTestCase; +import cc.allio.uno.test.Inject; +import cc.allio.uno.test.RunTest; +import cc.allio.uno.test.env.annotation.MybatisEnv; +import org.junit.jupiter.api.Test; + +@RunTest(components = {DbAutoConfiguration.class, ExecutorInitializerAutoConfiguration.class, DbExecutorAwareTest.UserRepository.class}) +@MybatisEnv +public class DbExecutorAwareTest extends BaseTestCase { + + @Inject + private UserRepository userRepository; + + @Test + void testBeAbleGetExecutor() { + CommandExecutor executor = userRepository.getExecutor(); + boolean assignable = ClassUtils.isAssignable(DbCommandExecutor.class, executor.getClass()); + assertTrue(assignable); + } + + + static class UserRepository implements DbExecutorAware { + + } +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DbExecutorDynamicCreateTest.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DbExecutorDynamicCreateTest.java new file mode 100644 index 00000000..d9ab9ee7 --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DbExecutorDynamicCreateTest.java @@ -0,0 +1,57 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.test.BaseTestCase; +import cc.allio.uno.test.Inject; +import cc.allio.uno.test.RunTest; +import cc.allio.uno.test.env.annotation.MybatisEnv; +import com.zaxxer.hikari.HikariDataSource; +import org.apache.ibatis.mapping.Environment; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSessionFactory; +import org.junit.jupiter.api.Test; +import org.mybatis.spring.transaction.SpringManagedTransactionFactory; +import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; +import org.springframework.boot.jdbc.DataSourceBuilder; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +@RunTest +@MybatisEnv +public class DbExecutorDynamicCreateTest extends BaseTestCase { + + @Inject + private SqlSessionFactory sqlSessionFactory; + + @Test + void testCreateByH2DataSource() { + JdbcConnectionDetails connectionDetails = new JdbcConnectionDetailsImpl(null, null, "jdbc:h2:mem:test-db;IGNORECASE=TRUE"); + CommandExecutor commandExecutor = getCommandExecutor(connectionDetails); + List> maps = commandExecutor.queryListMap(o -> o.select("1")); + assertNotNull(maps); + } + + private HikariDataSource getHakariDataSource(JdbcConnectionDetails connectionDetails) { + HikariDataSource dataSource = DataSourceBuilder.create(getClass().getClassLoader()) + .type(HikariDataSource.class) + .driverClassName(connectionDetails.getDriverClassName()) + .url(connectionDetails.getJdbcUrl()) + .username(connectionDetails.getUsername()) + .password(connectionDetails.getPassword()) + .build(); + dataSource.setMaximumPoolSize(1); + return dataSource; + } + + private CommandExecutor getCommandExecutor(JdbcConnectionDetails connectionDetails) { + HikariDataSource dataSource = getHakariDataSource(connectionDetails); + Configuration configuration = sqlSessionFactory.getConfiguration(); + MybatisConfiguration mybatisConfiguration = new MybatisConfiguration(configuration); + Environment environment = new Environment("h2", new SpringManagedTransactionFactory(), dataSource); + mybatisConfiguration.setEnvironment(environment); + DbCommandExecutorLoader loader = new DbCommandExecutorLoader(mybatisConfiguration); + return loader.load(Collections.emptyList()); + } +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DynamicDataSourceTest.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DynamicDataSourceTest.java new file mode 100644 index 00000000..74b8bef1 --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/DynamicDataSourceTest.java @@ -0,0 +1,23 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.data.orm.config.DbAutoConfiguration; +import cc.allio.uno.data.orm.executor.ExecutorInitializerAutoConfiguration; +import cc.allio.uno.test.BaseTestCase; +import cc.allio.uno.test.CoreTest; +import cc.allio.uno.test.Parameter; +import cc.allio.uno.test.RunTest; +import cc.allio.uno.test.env.annotation.DynamicDataSourceEnv; +import cc.allio.uno.test.env.annotation.MybatisEnv; +import org.junit.jupiter.api.Test; + +@RunTest(active = "datasource", components = {DbAutoConfiguration.class, ExecutorInitializerAutoConfiguration.class}) +@MybatisEnv +@DynamicDataSourceEnv +public class DynamicDataSourceTest extends BaseTestCase { + + @Test + void testGetDatasource(@Parameter CoreTest coreTest) { + + System.out.println(coreTest); + } +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/ExecutorFactoryBeanTest.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/ExecutorFactoryBeanTest.java new file mode 100644 index 00000000..097b0e16 --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/ExecutorFactoryBeanTest.java @@ -0,0 +1,25 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.core.util.ClassUtils; +import cc.allio.uno.data.orm.config.DbAutoConfiguration; +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.ExecutorInitializerAutoConfiguration; +import cc.allio.uno.test.BaseTestCase; +import cc.allio.uno.test.Inject; +import cc.allio.uno.test.RunTest; +import cc.allio.uno.test.env.annotation.MybatisEnv; +import org.junit.jupiter.api.Test; + +@RunTest(components = {DbAutoConfiguration.class, ExecutorInitializerAutoConfiguration.class}) +@MybatisEnv +public class ExecutorFactoryBeanTest extends BaseTestCase { + + @Inject + private CommandExecutor commandExecutor; + + @Test + void testIsDbCommand() { + boolean assignable = ClassUtils.isAssignable(DbCommandExecutor.class, commandExecutor.getClass()); + assertTrue(assignable); + } +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/LogicInterceptor.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/LogicInterceptor.java new file mode 100644 index 00000000..5fdc776f --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/LogicInterceptor.java @@ -0,0 +1,24 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.dml.UpdateOperator; + +public class LogicInterceptor implements Interceptor { + + @Override + public void onDeleteBefore(CommandExecutor commandExecutor, Operator operator) { + if (operator instanceof UpdateOperator updateOperator) { + updateOperator.strictFill("is_deleted", 1); + } + } + + @Override + public void onQueryBefore(CommandExecutor commandExecutor, Operator operator) { + if (operator instanceof QueryOperator queryOperator) { + queryOperator.eq("is_deleted", 0); + } + } +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/NothingInterceptor.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/NothingInterceptor.java new file mode 100644 index 00000000..5be9de5d --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/NothingInterceptor.java @@ -0,0 +1,6 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; + +public class NothingInterceptor implements Interceptor { +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/PrintInterceptor.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/PrintInterceptor.java new file mode 100644 index 00000000..20c77d23 --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/PrintInterceptor.java @@ -0,0 +1,56 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.CommandType; +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import cc.allio.uno.data.orm.dsl.Operator; +import org.junit.jupiter.api.Order; + +@Order(Integer.MAX_VALUE) +public class PrintInterceptor implements Interceptor { + + @Override + public void onSaveBefore(CommandExecutor commandExecutor, Operator operator) { + System.out.println(String.format("on save before commandExecutor \n %s", operator.getDSL())); + } + + @Override + public void onSaveAfter(CommandExecutor commandExecutor, Operator operator, boolean result) { + System.out.println(String.format("on save after commandExecutor \n %s", operator.getDSL())); + } + + @Override + public void onUpdateBefore(CommandExecutor commandExecutor, Operator operator) { + System.out.println(String.format("on update before commandExecutor \n %s", operator.getDSL())); + } + + @Override + public void onUpdateAfter(CommandExecutor commandExecutor, Operator operator, boolean result) { + System.out.println(String.format("on update after commandExecutor \n %s", operator.getDSL())); + } + + @Override + public void onDeleteBefore(CommandExecutor commandExecutor, Operator operator) { + System.out.println(String.format("on delete before commandExecutor \n %s", operator.getDSL())); + } + + @Override + public void onDeleteAfter(CommandExecutor commandExecutor, Operator operator, boolean result) { + System.out.println(String.format("on delete after commandExecutor \n %s", operator.getDSL())); + } + + @Override + public void onQueryBefore(CommandExecutor commandExecutor, Operator operator) { + System.out.println(String.format("on query before commandExecutor \n %s", operator.getDSL())); + } + + @Override + public void onQueryAfter(CommandExecutor commandExecutor, Operator operator, Object result) { + System.out.println(String.format("on query after commandExecutor \n %s", operator.getDSL())); + } + + @Override + public void onUnknownCommand(CommandExecutor commandExecutor, CommandType commandType, Operator operator) { + System.out.println(String.format("on unknown command command type [%s] \n %s ", operator.getDSL(), commandType)); + } +} diff --git a/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/UserExecutorTest.java b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/UserExecutorTest.java new file mode 100644 index 00000000..8a5ac956 --- /dev/null +++ b/uno-data/uno-data-db/src/test/java/cc/allio/uno/data/orm/executor/db/UserExecutorTest.java @@ -0,0 +1,116 @@ +package cc.allio.uno.data.orm.executor.db; + +import cc.allio.uno.data.orm.dsl.Table; +import cc.allio.uno.data.test.model.User; +import cc.allio.uno.test.BaseTestCase; +import cc.allio.uno.test.Inject; +import cc.allio.uno.test.RunTest; +import cc.allio.uno.test.env.annotation.MybatisEnv; +import com.google.common.collect.Lists; +import org.apache.ibatis.session.SqlSessionFactory; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +@RunTest +@MybatisEnv +public class UserExecutorTest extends BaseTestCase { + + @Inject + private SqlSessionFactory sqlSessionFactory; + + DbCommandExecutor dbCommandExecutor; + + @BeforeEach + void init() { + dbCommandExecutor = new DbCommandExecutor(new MybatisConfiguration(sqlSessionFactory.getConfiguration())); + dbCommandExecutor.getOptions().addInterceptor(new AuditInterceptor()); + dbCommandExecutor.getOptions().addInterceptor(new PrintInterceptor()); + dbCommandExecutor.getOptions().addInterceptor(new LogicInterceptor()); + dbCommandExecutor.createTable(User.class); + } + + @Test + void testBatchInsert() { + ArrayList users = Lists.newArrayList(); + for (int i = 0; i < 2; i++) { + User user = new User(); + user.setName(String.valueOf(i)); + users.add(user); + } + dbCommandExecutor.batchInsertPojos(users); + List users1 = dbCommandExecutor.queryList(User.class); + assertEquals(2, users1.size()); + } + + @Test + void testInsertThenUpdate() { + ArrayList users = Lists.newArrayList(); + for (int i = 0; i < 1; i++) { + User user = new User(); + user.setName(String.valueOf(i)); + users.add(user); + } + + dbCommandExecutor.batchInsertPojos(users); + + User dbUser = dbCommandExecutor.queryOne(User.class); + assertNotNull(dbUser.getName()); + + User user = new User(); + dbCommandExecutor.updatePojo(user); + + dbUser = dbCommandExecutor.queryOne(User.class); + assertNull(dbUser.getName()); + } + + @Test + void testSaveOrUpdate() { + User user = new User(); + user.setName("1"); + + dbCommandExecutor.saveOrUpdate(user); + + user = dbCommandExecutor.queryOne(User.class); + user.setName("2"); + dbCommandExecutor.saveOrUpdate(user); + + + List users = dbCommandExecutor.queryList(User.class); + assertEquals(1, users.size()); + User dbUser = users.get(0); + + assertEquals("2", dbUser.getName()); + } + + @Test + void testDelete() { + User user = new User(); + user.setName("1"); + + dbCommandExecutor.saveOrUpdate(user); + user = dbCommandExecutor.queryOne(User.class); + dbCommandExecutor.delete(user); + + List users = dbCommandExecutor.queryList(User.class); + + assertEquals(0, users.size()); + } + + @Test + void testAlertTables() { + dbCommandExecutor.alertTable(User.class, o -> o.rename("T_USERS_1")); + Table table = dbCommandExecutor.showOneTable("T_USERS_1"); + assertNotNull(table); + + assertEquals("T_USERS_1", table.getName().format()); + } + + @AfterEach + void destroy() { + dbCommandExecutor.dropTable(User.class); + } +} diff --git a/uno-data/src/test/resources/application-db.yaml b/uno-data/uno-data-db/src/test/resources/application-db.yaml similarity index 100% rename from uno-data/src/test/resources/application-db.yaml rename to uno-data/uno-data-db/src/test/resources/application-db.yaml diff --git a/uno-data/uno-data-db/src/test/resources/application.yaml b/uno-data/uno-data-db/src/test/resources/application.yaml new file mode 100644 index 00000000..620ba3b9 --- /dev/null +++ b/uno-data/uno-data-db/src/test/resources/application.yaml @@ -0,0 +1,3 @@ +spring: + profiles: + include: db \ No newline at end of file diff --git a/uno-data/uno-data-db/src/test/resources/logback-test.xml b/uno-data/uno-data-db/src/test/resources/logback-test.xml new file mode 100644 index 00000000..18af173b --- /dev/null +++ b/uno-data/uno-data-db/src/test/resources/logback-test.xml @@ -0,0 +1,16 @@ + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + + + + + diff --git a/uno-data/uno-data-db/src/test/resources/uno-datasource.yaml b/uno-data/uno-data-db/src/test/resources/uno-datasource.yaml new file mode 100644 index 00000000..6cefb7d2 --- /dev/null +++ b/uno-data/uno-data-db/src/test/resources/uno-datasource.yaml @@ -0,0 +1,19 @@ +spring: + datasource: + dynamic: + datasource: + master: + url: jdbc:h2:mem:test-db;IGNORECASE=TRUE + driver-class-name: org.h2.Driver + slave: + url: jdbc:h2:mem:test-db;IGNORECASE=TRUE + driver-class-name: org.h2.Driver + +mybatis-plus: + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + + +logging: + level: + root: debug \ No newline at end of file diff --git a/uno-data/src/test/resources/uno-mybatis.yaml b/uno-data/uno-data-db/src/test/resources/uno-mybatis.yaml similarity index 100% rename from uno-data/src/test/resources/uno-mybatis.yaml rename to uno-data/uno-data-db/src/test/resources/uno-mybatis.yaml diff --git a/uno-data/src/test/resources/uno.yaml b/uno-data/uno-data-db/src/test/resources/uno.yaml similarity index 83% rename from uno-data/src/test/resources/uno.yaml rename to uno-data/uno-data-db/src/test/resources/uno.yaml index 42eb15d8..74ac8983 100644 --- a/uno-data/src/test/resources/uno.yaml +++ b/uno-data/uno-data-db/src/test/resources/uno.yaml @@ -1,7 +1,7 @@ spring: datasource: -# url: jdbc:h2:mem:test-db;IGNORECASE=TRUE -# driver-class-name: org.h2.Driver + url: jdbc:h2:mem:test-db;IGNORECASE=TRUE + driver-class-name: org.h2.Driver # mysql # url: jdbc:mysql://192.168.2.29:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true # username: root @@ -20,11 +20,7 @@ mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl -allio: - uno: - data: - orm: - executor: - type: mybatis - sql: - operator: druid \ No newline at end of file + +logging: + level: + root: debug \ No newline at end of file diff --git a/uno-data/uno-data-elasticsearch/pom.xml b/uno-data/uno-data-elasticsearch/pom.xml new file mode 100644 index 00000000..8255bacd --- /dev/null +++ b/uno-data/uno-data-elasticsearch/pom.xml @@ -0,0 +1,36 @@ + + + + cc.allio + uno-data + 1.1.6-beta.1 + ../pom.xml + + 4.0.0 + jar + uno-data-elasticsearch + + + + cc.allio + uno-data-api + + + co.elastic.clients + elasticsearch-java + provided + + + org.elasticsearch.client + elasticsearch-rest-client + provided + + + cc.allio + uno-data-test + test + + + \ No newline at end of file diff --git a/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/config/ElasticSearchAutoConfiguration.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/config/ElasticSearchAutoConfiguration.java new file mode 100644 index 00000000..12e08213 --- /dev/null +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/config/ElasticSearchAutoConfiguration.java @@ -0,0 +1,33 @@ +package cc.allio.uno.data.orm.config; + +import cc.allio.uno.data.orm.executor.ExecutorInitializerAutoConfiguration; +import cc.allio.uno.data.orm.executor.elasticsearch.EsCommandExecutorLoader; +import cc.allio.uno.data.orm.executor.elasticsearch.EsExecutorProcessor; +import org.elasticsearch.client.RestClientBuilder; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration; +import org.springframework.context.annotation.*; + +@Configuration(proxyBeanMethods = false) +@AutoConfigureBefore(ExecutorInitializerAutoConfiguration.class) +@AutoConfigureAfter(ElasticsearchRestClientAutoConfiguration.class) +@ConditionalOnClass(RestClientBuilder.class) +public class ElasticSearchAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public EsCommandExecutorLoader esCommandExecutorLoader(RestClientBuilder builder) { + return new EsCommandExecutorLoader(builder); + } + + @Bean + @ConditionalOnBean(EsCommandExecutorLoader.class) + public EsExecutorProcessor esExecutorProcessor() { + return new EsExecutorProcessor(); + } + +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchCreateIndexOperator.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchCreateIndexOperator.java similarity index 74% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchCreateIndexOperator.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchCreateIndexOperator.java index 91626795..39fbbe48 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchCreateIndexOperator.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchCreateIndexOperator.java @@ -1,15 +1,17 @@ -package cc.allio.uno.data.orm.sql.ddl.elasticsearch; +package cc.allio.uno.data.orm.dsl.ddl.elasticsearch; +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; import co.elastic.clients.elasticsearch._types.mapping.Property; import co.elastic.clients.elasticsearch._types.mapping.TypeMapping; import co.elastic.clients.elasticsearch.indices.CreateIndexRequest; import co.elastic.clients.elasticsearch.indices.IndexSettings; import co.elastic.clients.json.JsonpUtils; import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.SQLColumnDef; -import cc.allio.uno.data.orm.sql.ddl.SQLCreateTableOperator; +import cc.allio.uno.data.orm.dsl.ddl.CreateTableOperator; /** * 创建索引 @@ -19,18 +21,21 @@ * @see 索引的settings * @since 1.1.4 */ -public class ElasticSearchCreateIndexOperator implements SQLCreateTableOperator { - - private CreateIndexRequest request; - private CreateIndexRequest.Builder builder; +@AutoService(CreateTableOperator.class) +@Operator.Group(OperatorKey.ELASTICSEARCH_LITERAL) +public class ElasticSearchCreateIndexOperator implements CreateTableOperator { private final ElasticSearchPropertyAdapter elasticSearchPropertyAdapter; private final IndexSettings.Builder settingsBuilder; private final TypeMapping.Builder mappingBuilder; + private CreateIndexRequest request; + private CreateIndexRequest.Builder builder; + private Table table; + private DBType dbType; - private static final String ERROR_MSG = "elasticsearch create operator not support that operator"; - + private static final String ERROR_MSG = "elasticsearch registry operator not support that operator"; public ElasticSearchCreateIndexOperator() { + this.dbType = DBType.ELASTIC_SEARCH; this.builder = new CreateIndexRequest.Builder(); this.elasticSearchPropertyAdapter = new ElasticSearchPropertyAdapter(); this.settingsBuilder = new IndexSettings.Builder(); @@ -44,15 +49,15 @@ public ElasticSearchCreateIndexOperator() { } @Override - public String getSQL() { + public String getDSL() { CreateIndexRequest createIndexRequest = getCreateIndexRequest(); String dsl = JsonpUtils.toString(createIndexRequest); return dsl.substring(dsl.indexOf(StringPool.COLON + StringPool.SPACE) + 2); } @Override - public ElasticSearchCreateIndexOperator parse(String sql) { - throw new SQLException(String.format("%s This operation is not supported", this.getClass().getName())); + public ElasticSearchCreateIndexOperator parse(String dsl) { + throw new DSLException(String.format("%s This operation is not supported", this.getClass().getName())); } @Override @@ -61,27 +66,38 @@ public void reset() { this.builder = new CreateIndexRequest.Builder(); } + @Override + public void setDBType(DBType dbType) { + throw Exceptions.unOperate("setDBType"); + } + + @Override + public DBType getDBType() { + return dbType; + } + @Override public ElasticSearchCreateIndexOperator from(Table table) { + this.table = table; builder.index(table.getName().format()); return (ElasticSearchCreateIndexOperator) self(); } @Override - public ElasticSearchCreateIndexOperator column(SQLColumnDef columnDef) { - Property property = elasticSearchPropertyAdapter.get(columnDef.getDataType()); - mappingBuilder.properties(columnDef.getSqlName().format(), property); - return (ElasticSearchCreateIndexOperator) self(); + public Table getTable() { + return table; } @Override - public ElasticSearchCreateIndexOperator schemaName(String schemaName) { - throw new SQLException(ERROR_MSG); + public ElasticSearchCreateIndexOperator column(ColumnDef columnDef) { + Property property = elasticSearchPropertyAdapter.adapt(columnDef.getDataType()); + mappingBuilder.properties(columnDef.getDslName().format(), property); + return (ElasticSearchCreateIndexOperator) self(); } @Override public ElasticSearchCreateIndexOperator comment(String comment) { - throw new SQLException(ERROR_MSG); + throw new DSLException(ERROR_MSG); } // =================== settings =================== diff --git a/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchDropIndexOperator.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchDropIndexOperator.java new file mode 100644 index 00000000..e7be139c --- /dev/null +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchDropIndexOperator.java @@ -0,0 +1,89 @@ +package cc.allio.uno.data.orm.dsl.ddl.elasticsearch; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.exception.DDLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import co.elastic.clients.elasticsearch.indices.DeleteIndexRequest; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.Table; +import cc.allio.uno.data.orm.dsl.ddl.DropTableOperator; + +/** + * 删除索引{@link DeleteIndexRequest} + * + * @author jiangwei + * @date 2023/5/29 18:43 + * @since 1.1.4 + */ +@AutoService(DropTableOperator.class) +@Operator.Group(OperatorKey.ELASTICSEARCH_LITERAL) +public class ElasticSearchDropIndexOperator implements DropTableOperator { + + private DBType dbType; + private DeleteIndexRequest deleteIndexRequest; + private DeleteIndexRequest.Builder builder; + private Table table; + private static final String ERROR_MSG = "elasticsearch drop operator not support that operator"; + + public ElasticSearchDropIndexOperator() { + this.dbType = DBType.ELASTIC_SEARCH; + this.builder = new DeleteIndexRequest.Builder(); + } + + @Override + public String getDSL() { + throw new DSLException(ERROR_MSG); + } + + @Override + public DropTableOperator parse(String dsl) { + return null; + } + + @Override + public void reset() { + deleteIndexRequest = null; + builder = new DeleteIndexRequest.Builder(); + } + + @Override + public void setDBType(DBType dbType) { + throw new DDLException("setDBType"); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public DropTableOperator from(Table table) { + this.table = table; + builder.index(table.getName().format()); + return self(); + } + + @Override + public Table getTable() { + return table; + } + + @Override + public DropTableOperator ifExist(Boolean ifExist) { + throw new DSLException(ERROR_MSG); + } + + /** + * 获取删除index请求 + * + * @return DeleteIndexRequest + */ + public DeleteIndexRequest getDeleteIndexRequest() { + if (deleteIndexRequest == null) { + deleteIndexRequest = builder.build(); + } + return deleteIndexRequest; + } +} diff --git a/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchExistIndexOperator.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchExistIndexOperator.java new file mode 100644 index 00000000..de55f685 --- /dev/null +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchExistIndexOperator.java @@ -0,0 +1,94 @@ +package cc.allio.uno.data.orm.dsl.ddl.elasticsearch; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import co.elastic.clients.elasticsearch.core.SearchRequest; +import cc.allio.uno.data.orm.dsl.ddl.ExistTableOperator; + +import java.util.List; + +/** + * 判断索引是否存在{@link co.elastic.clients.elasticsearch.indices.ExistsRequest} + * + * @author jiangwei + * @date 2023/5/29 18:59 + * @since 1.1.4 + */ +@AutoService(ExistTableOperator.class) +@Operator.Group(OperatorKey.ELASTICSEARCH_LITERAL) +public class ElasticSearchExistIndexOperator implements ExistTableOperator { + private DBType dbType; + SearchRequest.Builder builder; + private SearchRequest searchRequest; + private Table table; + private static final String ERROR_MSG = "elasticsearch drop operator not support that operator"; + + public ElasticSearchExistIndexOperator() { + this.dbType = DBType.ELASTIC_SEARCH; + this.builder = new SearchRequest.Builder(); + } + + @Override + public String getDSL() { + throw new DSLException(ERROR_MSG); + } + + @Override + public ExistTableOperator parse(String dsl) { + return null; + } + + @Override + public void reset() { + this.searchRequest = null; + this.builder = new SearchRequest.Builder(); + } + + @Override + public void setDBType(DBType dbType) { + throw Exceptions.unOperate("setDBType"); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public String getPrepareDSL() { + throw new DSLException(ERROR_MSG); + } + + @Override + public List getPrepareValues() { + throw new DSLException(ERROR_MSG); + } + + @Override + public ExistTableOperator from(Table table) { + this.table = table; + builder.index(table.getName().format()); + return self(); + } + + @Override + public Table getTable() { + return table; + } + + /** + * 获取存在request + * + * @return ExistsRequest + */ + public SearchRequest getSearchRequest() { + if (searchRequest == null) { + searchRequest = builder.build(); + } + return searchRequest; + } + +} diff --git a/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchPropertyAdapter.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchPropertyAdapter.java new file mode 100644 index 00000000..d9c333c9 --- /dev/null +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchPropertyAdapter.java @@ -0,0 +1,71 @@ +package cc.allio.uno.data.orm.dsl.ddl.elasticsearch; + +import cc.allio.uno.data.orm.dsl.type.DataType; +import cc.allio.uno.data.orm.dsl.type.DataTypeAdapter; +import cc.allio.uno.data.orm.dsl.type.DSLType; +import co.elastic.clients.elasticsearch._types.analysis.Analyzer; +import co.elastic.clients.elasticsearch._types.mapping.Property; +import cc.allio.uno.core.util.StringUtils; + +import java.util.Objects; + +import static cc.allio.uno.data.orm.dsl.type.DSLType.DefaultDSLType.*; + +/** + * JDBC数据类型转换为es类型 + * + * @author jiangwei + * @date 2023/7/4 15:25 + * @since 1.1.4 + */ +public class ElasticSearchPropertyAdapter implements DataTypeAdapter { + + private final String analyzer; + + public ElasticSearchPropertyAdapter() { + this(null); + } + + public ElasticSearchPropertyAdapter(String analyzer) { + this.analyzer = analyzer; + } + + @Override + public Property adapt(DataType o) { + DataType dataType = o; + // dataType为null,赋值于VARCHAR + if (dataType == null) { + dataType = DataType.createCharType(DSLType.VARCHAR, 64); + } + // 通用的做分组比较 + DSLType sqlType = dataType.getDslType(); + // 每个数据库类型的做创建 + DSLType sqlTypeConstant = Objects.requireNonNullElse(DSLType.getByJdbcCode(sqlType.getJdbcType()), DSLType.VARCHAR); + return switch (sqlTypeConstant) { + case BIGINT -> Property.of(p -> p.long_(l -> l)); + case SMALLINT, TINYINT, INTEGER -> Property.of(p -> p.integer(i -> i)); + case BIT -> Property.of(p -> p.boolean_(b -> b)); + case DOUBLE, NUMBER, DECIMAL -> Property.of(p -> p.double_(d -> d)); + case FLOAT -> Property.of(p -> p.float_(f -> f)); + case DATE, TIME, TIMESTAMP -> Property.of(p -> p.date(d -> d.locale("zh_CN"))); + case OBJECT -> Property.of(p -> p.object(obj -> obj)); + default -> + Property.of(p -> p.text(t -> t.analyzer(StringUtils.isBlank(analyzer) ? Analyzer.Kind.Standard.jsonValue() : analyzer))); + }; + } + + @Override + public DataType reverse(Property property) { + return switch (property._kind()) { + case Binary, Byte -> DataType.create(DSLType.BIT); + case DateNanos, DateRange, Date -> DataType.create(DSLType.DATE); + case Long -> DataType.create(DSLType.BIGINT); + case Float -> DataType.create(DSLType.FLOAT); + case Double -> DataType.create(DSLType.DOUBLE); + case Integer -> DataType.create(DSLType.INTEGER); + case Short -> DataType.create(DSLType.SMALLINT); + case Object -> DataType.create(DSLType.OBJECT); + default -> DataType.createCharType(DSLType.VARCHAR, 0); + }; + } +} diff --git a/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchShowColumnsOperator.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchShowColumnsOperator.java new file mode 100644 index 00000000..ee36cf26 --- /dev/null +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchShowColumnsOperator.java @@ -0,0 +1,105 @@ +package cc.allio.uno.data.orm.dsl.ddl.elasticsearch; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import co.elastic.clients.elasticsearch.indices.GetMappingRequest; +import cc.allio.uno.data.orm.dsl.ddl.ShowColumnsOperator; +import com.google.common.collect.Lists; + +import java.util.List; + +/** + * es 查询所有映射.{@link GetMappingRequest} + * + * @author jiangwei + * @date 2023/6/11 20:07 + * @since 1.1.4 + */ +@AutoService(ShowColumnsOperator.class) +@Operator.Group(OperatorKey.ELASTICSEARCH_LITERAL) +public class ElasticSearchShowColumnsOperator implements ShowColumnsOperator { + + private DBType dbType; + private GetMappingRequest.Builder builder; + private GetMappingRequest getMappingRequest; + private Table table; + + public ElasticSearchShowColumnsOperator() { + this.dbType = DBType.ELASTIC_SEARCH; + this.builder = new GetMappingRequest.Builder(); + } + + @Override + public String getDSL() { + throw new DSLException(String.format("%s This operation is not supported", this.getClass().getName())); + } + + @Override + public ShowColumnsOperator parse(String dsl) { + throw new DSLException(String.format("%s This operation is not supported", this.getClass().getName())); + } + + @Override + public void reset() { + builder = new GetMappingRequest.Builder(); + getMappingRequest = null; + } + + @Override + public void setDBType(DBType dbType) { + throw Exceptions.unOperate("setDBType"); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public String getPrepareDSL() { + throw new DSLException(String.format("%s This operation is not supported", this.getClass().getName())); + } + + @Override + public List getPrepareValues() { + throw new DSLException(String.format("%s This operation is not supported", this.getClass().getName())); + } + + @Override + public ShowColumnsOperator from(Table table) { + this.table = table; + builder = builder.index(Lists.newArrayList(table.getName().format())); + return self(); + } + + @Override + public Table getTable() { + return table; + } + + @Override + public QueryOperator toQueryOperator() { + throw new DSLException(String.format("%s This operation is not supported", this.getClass().getName())); + } + + /** + * 获取索引映射request + * + * @return GetMappingRequest for instance + */ + public GetMappingRequest getMappingRequest() { + if (getMappingRequest == null) { + getMappingRequest = builder.build(); + } + return getMappingRequest; + } + + @Override + public ShowColumnsOperator database(Database database) { + return null; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchDeleteOperator.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchDeleteOperator.java similarity index 51% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchDeleteOperator.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchDeleteOperator.java index 1e67f79d..4c77f91b 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchDeleteOperator.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchDeleteOperator.java @@ -1,13 +1,15 @@ -package cc.allio.uno.data.orm.sql.dml.elasticsearch; +package cc.allio.uno.data.orm.dsl.dml.elasticsearch; +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; import co.elastic.clients.elasticsearch._types.query_dsl.Query; import co.elastic.clients.elasticsearch.core.DeleteByQueryRequest; import co.elastic.clients.json.JsonpUtils; import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.PrepareValue; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.dml.SQLDeleteOperator; +import cc.allio.uno.data.orm.dsl.dml.DeleteOperator; import java.util.Collections; import java.util.List; @@ -19,25 +21,30 @@ * @date 2023/5/29 13:49 * @since 1.1.4 */ -public class ElasticSearchDeleteOperator extends ElasticSearchGenericWhereOperator implements SQLDeleteOperator { +@AutoService(DeleteOperator.class) +@Operator.Group(OperatorKey.ELASTICSEARCH_LITERAL) +public class ElasticSearchDeleteOperator extends ElasticSearchGenericWhereOperator implements DeleteOperator { + private DBType dbType; private DeleteByQueryRequest deleteRequest; private DeleteByQueryRequest.Builder deleteBuilder; + private Table table; private static final String ERROR_MSG = "elasticsearch delete operator not support that operator"; public ElasticSearchDeleteOperator() { + this.dbType = DBType.ELASTIC_SEARCH; this.deleteBuilder = new DeleteByQueryRequest.Builder(); } @Override - public String getSQL() { + public String getDSL() { DeleteByQueryRequest request = getDeleteRequest(); String dsl = JsonpUtils.toString(request); return dsl.substring(dsl.indexOf(StringPool.COLON + StringPool.SPACE) + 2); } @Override - public SQLDeleteOperator parse(String sql) { + public DeleteOperator parse(String dsl) { return null; } @@ -49,21 +56,37 @@ public void reset() { } @Override - public String getPrepareSQL() { + public void setDBType(DBType dbType) { + throw Exceptions.unOperate("setDBType"); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public String getPrepareDSL() { return null; } @Override public List getPrepareValues() { - throw new SQLException(ERROR_MSG); + throw new DSLException(ERROR_MSG); } @Override - public SQLDeleteOperator from(Table table) { + public DeleteOperator from(Table table) { + this.table = table; deleteBuilder.index(Collections.singletonList(table.getName().format())); return self(); } + @Override + public Table getTable() { + return table; + } + /** * 获取{@link DeleteByQueryRequest}实例 * @@ -76,4 +99,34 @@ public DeleteByQueryRequest getDeleteRequest() { } return deleteRequest; } + + @Override + public DeleteOperator neq(DSLName sqlName, Object value) { + return null; + } + + @Override + public DeleteOperator notIn(DSLName sqlName, Object... values) { + return null; + } + + @Override + public DeleteOperator notLike(DSLName sqlName, Object value) { + return null; + } + + @Override + public DeleteOperator $notLike(DSLName sqlName, Object value) { + return null; + } + + @Override + public DeleteOperator notLike$(DSLName sqlName, Object value) { + return null; + } + + @Override + public DeleteOperator $notLike$(DSLName sqlName, Object value) { + return null; + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchGenericWhereOperator.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchGenericWhereOperator.java similarity index 84% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchGenericWhereOperator.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchGenericWhereOperator.java index 1a3f3593..211358b4 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchGenericWhereOperator.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchGenericWhereOperator.java @@ -1,14 +1,14 @@ -package cc.allio.uno.data.orm.sql.dml.elasticsearch; +package cc.allio.uno.data.orm.dsl.dml.elasticsearch; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLWhereOperator; +import cc.allio.uno.core.api.Self; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.WhereOperator; import co.elastic.clients.elasticsearch._types.FieldValue; import co.elastic.clients.elasticsearch._types.query_dsl.*; import co.elastic.clients.json.JsonData; import cc.allio.uno.core.StringPool; import cc.allio.uno.core.type.Types; import cc.allio.uno.core.util.CollectionUtils; -import cc.allio.uno.data.orm.sql.Operator; import com.google.common.collect.Lists; import java.util.Arrays; @@ -23,7 +23,7 @@ * @date 2023/5/29 13:22 * @since 1.1.4 */ -public abstract class ElasticSearchGenericWhereOperator> implements SQLWhereOperator { +public abstract class ElasticSearchGenericWhereOperator> implements WhereOperator { protected BoolQuery.Builder boolBuilder; @@ -44,81 +44,90 @@ protected ElasticSearchGenericWhereOperator() { } @Override - public T gt(SQLName sqlName, Object value) { + public T gt(DSLName sqlName, Object value) { return logicQuery(RangeQuery.of(rb -> rb.field(sqlName.format()).gt(JsonData.of(value)))._toQuery()); } @Override - public T gte(SQLName sqlName, Object value) { + public T gte(DSLName sqlName, Object value) { return logicQuery(RangeQuery.of(rb -> rb.field(sqlName.format()).gte(JsonData.of(value)))._toQuery()); } @Override - public T lt(SQLName sqlName, Object value) { + public T lt(DSLName sqlName, Object value) { return logicQuery(RangeQuery.of(rb -> rb.field(sqlName.format()).lt(JsonData.of(value)))._toQuery()); } @Override - public T lte(SQLName sqlName, Object value) { + public T lte(DSLName sqlName, Object value) { return logicQuery(RangeQuery.of(rb -> rb.field(sqlName.format()).lte(JsonData.of(value)))._toQuery()); } @Override - public T eq(SQLName sqlName, Object value) { + public T eq(DSLName sqlName, Object value) { FieldValue fieldValue = esValue(value); return logicQuery(MatchQuery.of(tq -> tq.field(sqlName.format()).query(fieldValue))._toQuery()); } @Override - public T notNull(SQLName sqlName) { + public T neq(DSLName sqlName, Object value) { + andNot(); + FieldValue fieldValue = esValue(value); + logicQuery(MatchQuery.of(tq -> tq.field(sqlName.format()).query(fieldValue))._toQuery()); + and(); + return self(); + } + + @Override + public T notNull(DSLName sqlName) { return logicQuery(ExistsQuery.of(eq -> eq.field(sqlName.format()))._toQuery()); } @Override - public T isNull(SQLName sqlName) { + public T isNull(DSLName sqlName) { Query query = ExistsQuery.of(eq -> eq.field(sqlName.format()))._toQuery(); mustNotQuery.add(query); return self(); } @Override - public T in(SQLName sqlName, Object... values) { + public T in(DSLName sqlName, Object... values) { List fieldValues = Arrays.stream(values).map(this::esValue).collect(Collectors.toList()); return logicQuery(TermsQuery.of(tq -> tq.field(sqlName.format()).terms(TermsQueryField.of(tqf -> tqf.value(fieldValues))))._toQuery()); } @Override - public T between(SQLName sqlName, Object withValue, Object endValue) { + public T between(DSLName sqlName, Object withValue, Object endValue) { return logicQuery(RangeQuery.of(rb -> rb.field(sqlName.format()).gte(JsonData.of(withValue)).lte(JsonData.of(endValue)))._toQuery()); } @Override - public T notBetween(SQLName sqlName, Object withValue, Object endValue) { + public T notBetween(DSLName sqlName, Object withValue, Object endValue) { mustNotQuery.add(RangeQuery.of(rb -> rb.field(sqlName.format()).gte(JsonData.of(withValue)).lte(JsonData.of(endValue)))._toQuery()); return self(); } @Override - public T like(SQLName sqlName, Object value) { + public T like(DSLName sqlName, Object value) { // match FieldValue fieldValue = esValue(value); return logicQuery(MatchQuery.of(mq -> mq.field(sqlName.format()).query(fieldValue))._toQuery()); } @Override - public T $like(SQLName sqlName, Object value) { + public T $like(DSLName sqlName, Object value) { // wildcard return logicQuery(WildcardQuery.of(wq -> wq.field(sqlName.format()).value(StringPool.STAR + value.toString()))._toQuery()); } @Override - public T like$(SQLName sqlName, Object value) { + public T like$(DSLName sqlName, Object value) { // wildcard return logicQuery(WildcardQuery.of(wq -> wq.field(sqlName.format()).value(value.toString() + StringPool.STAR))._toQuery()); } @Override - public T $like$(SQLName sqlName, Object value) { + public T $like$(DSLName sqlName, Object value) { // wildcard return logicQuery(WildcardQuery.of(wq -> wq.field(sqlName.format()).value(StringPool.STAR + value.toString() + StringPool.STAR))._toQuery()); } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchInsertOperator.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchInsertOperator.java similarity index 61% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchInsertOperator.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchInsertOperator.java index 13178384..35c23600 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchInsertOperator.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchInsertOperator.java @@ -1,25 +1,25 @@ -package cc.allio.uno.data.orm.sql.dml.elasticsearch; +package cc.allio.uno.data.orm.dsl.dml.elasticsearch; +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; import co.elastic.clients.elasticsearch.core.BulkRequest; import co.elastic.clients.elasticsearch.core.bulk.BulkOperation; import co.elastic.clients.json.JsonpUtils; import cc.allio.uno.core.StringPool; import cc.allio.uno.core.util.id.IdGenerator; -import cc.allio.uno.data.orm.sql.PrepareValue; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.dml.SQLInsertOperator; +import cc.allio.uno.data.orm.dsl.dml.InsertOperator; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Streams; import reactor.util.function.Tuples; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import java.util.function.Supplier; /** * 基于{@link BulkRequest}做数据创建 @@ -29,8 +29,11 @@ * @see BulkOperation * @since 1.1.4 */ -public class ElasticSearchInsertOperator implements SQLInsertOperator { +@AutoService(InsertOperator.class) +@Operator.Group(OperatorKey.ELASTICSEARCH_LITERAL) +public class ElasticSearchInsertOperator implements InsertOperator { + private DBType dbType; private BulkRequest bulkRequest; private BulkRequest.Builder batchBuilder; private final List bkps; @@ -39,19 +42,20 @@ public class ElasticSearchInsertOperator implements SQLInsertOperator { private static final String ERROR_MSG = "elasticsearch insert operator not support that operator"; public ElasticSearchInsertOperator() { + this.dbType = DBType.ELASTIC_SEARCH; this.batchBuilder = new BulkRequest.Builder(); this.bkps = Lists.newArrayList(); } @Override - public String getSQL() { + public String getDSL() { BulkRequest request = getBulkRequest(); String dsl = JsonpUtils.toString(request); return dsl.substring(dsl.indexOf(StringPool.COLON + StringPool.SPACE) + 2); } @Override - public SQLInsertOperator parse(String sql) { + public InsertOperator parse(String dsl) { return null; } @@ -64,30 +68,45 @@ public void reset() { } @Override - public String getPrepareSQL() { + public void setDBType(DBType dbType) { + throw Exceptions.unOperate("setDBType"); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public String getPrepareDSL() { return null; } @Override public List getPrepareValues() { - throw new SQLException(ERROR_MSG); + throw new DSLException(ERROR_MSG); } @Override - public SQLInsertOperator from(Table table) { + public InsertOperator from(Table table) { this.table = table; return self(); } @Override - public SQLInsertOperator inserts(Map values) { - return batchInserts(values.keySet(), Collections.singleton(values.values())); + public Table getTable() { + return table; + } + + @Override + public InsertOperator inserts(Map values) { + return batchInserts(values.keySet().stream().toList(), List.of((values.values().stream().toList()))); } @Override - public SQLInsertOperator batchInserts(Collection columns, Collection> values) { + public InsertOperator batchInserts(List columns, List> values) { if (table == null) { - throw new SQLException("ensure invoke #from() given index"); + throw new DSLException("ensure invoke #xxxx() given index"); } List thisOp = values.stream() .map(v -> @@ -105,11 +124,36 @@ public SQLInsertOperator batchInserts(Collection columns, Collection BulkOperation.of(bp -> bp.create(c -> c.id(IdGenerator.defaultGenerator().getNextIdAsString()).index(table.getName().format()).document(v)))) - .collect(Collectors.toList()); + .toList(); bkps.addAll(thisOp); return self(); } + @Override + public InsertOperator strictFill(String f, Object v) { + return null; + } + + @Override + public InsertOperator strictFill(String f, Supplier v) { + return null; + } + + @Override + public InsertOperator columns(Collection columns) { + return null; + } + + @Override + public InsertOperator values(List values) { + return null; + } + + @Override + public boolean isBatched() { + return false; + } + /** * 获取批量创建数据{@link BulkRequest} * diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchQueryOperator.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchQueryOperator.java similarity index 60% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchQueryOperator.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchQueryOperator.java index 192120bf..3aabb57d 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchQueryOperator.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchQueryOperator.java @@ -1,8 +1,13 @@ -package cc.allio.uno.data.orm.sql.dml.elasticsearch; - -import cc.allio.uno.data.orm.dialect.func.Func; -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.word.Distinct; +package cc.allio.uno.data.orm.dsl.dml.elasticsearch; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.data.orm.dsl.Func; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.word.Distinct; import co.elastic.clients.elasticsearch._types.SortOptions; import co.elastic.clients.elasticsearch._types.SortOrder; import co.elastic.clients.elasticsearch._types.aggregations.Aggregation; @@ -11,8 +16,7 @@ import co.elastic.clients.json.JsonpUtils; import cc.allio.uno.core.StringPool; import cc.allio.uno.core.util.CollectionUtils; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.local.OrderCondition; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; import java.util.Collection; import java.util.Collections; @@ -25,22 +29,27 @@ * @date 2023/5/28 15:34 * @since 1.1.4 */ -public class ElasticSearchQueryOperator extends ElasticSearchGenericWhereOperator implements SQLQueryOperator { +@AutoService(QueryOperator.class) +@Operator.Group(OperatorKey.ELASTICSEARCH_LITERAL) +public class ElasticSearchQueryOperator extends ElasticSearchGenericWhereOperator implements QueryOperator { + private DBType dbType; private SearchRequest searchRequest; private SearchRequest.Builder searchBuilder; + private Table table; private static final String ERROR_MSG = "elasticsearch query operator not support that operator"; public ElasticSearchQueryOperator() { super(); - searchBuilder = new SearchRequest.Builder(); + this.dbType = DBType.ELASTIC_SEARCH; + this.searchBuilder = new SearchRequest.Builder(); // 默认查询所有数据 - searchBuilder.size(Integer.MAX_VALUE); + this.searchBuilder.size(Integer.MAX_VALUE); } @Override - public String getSQL() { + public String getDSL() { SearchRequest request = getSearchRequest(); if (request != null && request.query() != null) { String dsl = JsonpUtils.toString(request.query()); @@ -50,7 +59,7 @@ public String getSQL() { } @Override - public SQLQueryOperator parse(String dsl) { + public QueryOperator parse(String dsl) { return null; } @@ -62,34 +71,50 @@ public void reset() { } @Override - public String getPrepareSQL() { - throw new SQLException(ERROR_MSG); + public void setDBType(DBType dbType) { + throw Exceptions.unOperate("setDBType"); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public String getPrepareDSL() { + throw new DSLException(ERROR_MSG); } @Override public List getPrepareValues() { - throw new SQLException(ERROR_MSG); + throw new DSLException(ERROR_MSG); } @Override - public SQLQueryOperator from(Table table) { + public QueryOperator from(Table table) { + this.table = table; searchBuilder = searchBuilder.index(table.getName().format()); return self(); } @Override - public SQLQueryOperator select(SQLName sqlName) { + public Table getTable() { + return table; + } + + @Override + public QueryOperator select(DSLName sqlName) { return this.selects(Collections.singleton(sqlName)); } @Override - public SQLQueryOperator select(SQLName sqlName, String alias) { + public QueryOperator select(DSLName sqlName, String alias) { return this.selects(Collections.singleton(sqlName)); } @Override - public SQLQueryOperator selects(Collection sqlNames) { - for (SQLName sqlName : sqlNames) { + public QueryOperator selects(Collection sqlNames) { + for (DSLName sqlName : sqlNames) { FieldAndFormat ff = FieldAndFormat.of(f -> f.field(sqlName.format())); searchBuilder = searchBuilder.fields(ff); } @@ -97,19 +122,19 @@ public SQLQueryOperator selects(Collection sqlNames) { } @Override - public SQLQueryOperator distinct() { - throw new SQLException(ERROR_MSG); + public QueryOperator distinct() { + throw new DSLException(ERROR_MSG); } @Override - public SQLQueryOperator distinctOn(SQLName sqlName, String alias) { + public QueryOperator distinctOn(DSLName sqlName, String alias) { Aggregation aggregation = Aggregation.of(a -> a.cardinality(v -> v.field(sqlName.format()))); searchBuilder.aggregations(alias, aggregation); - throw new SQLException(ERROR_MSG); + throw new DSLException(ERROR_MSG); } @Override - public SQLQueryOperator aggregate(Func syntax, SQLName sqlName, String alias, Distinct distinct) { + public QueryOperator aggregate(Func syntax, DSLName sqlName, String alias, Distinct distinct) { Aggregation aggregation = Aggregation.of(a -> { switch (syntax) { case COUNT_FUNCTION: @@ -135,17 +160,17 @@ public SQLQueryOperator aggregate(Func syntax, SQLName sqlName, String alias, Di } @Override - public SQLQueryOperator from(SQLQueryOperator fromTable, String alias) { - throw new SQLException(ERROR_MSG); + public QueryOperator from(QueryOperator fromTable, String alias) { + throw new DSLException(ERROR_MSG); } @Override - public SQLQueryOperator join(Table left, JoinType joinType, Table right, SQLBinaryCondition condition) { - throw new SQLException(ERROR_MSG); + public QueryOperator join(Table left, JoinType joinType, Table right, BinaryCondition condition) { + throw new DSLException(ERROR_MSG); } @Override - public SQLQueryOperator orderBy(SQLName sqlName, OrderCondition orderCondition) { + public QueryOperator orderBy(DSLName sqlName, OrderCondition orderCondition) { SortOrder sortOrder; switch (orderCondition) { case ASC: @@ -161,15 +186,15 @@ public SQLQueryOperator orderBy(SQLName sqlName, OrderCondition orderCondition) } @Override - public SQLQueryOperator limit(Long limit, Long offset) { + public QueryOperator limit(Long limit, Long offset) { searchBuilder.from(Math.toIntExact(limit)); searchBuilder.size(Math.toIntExact(offset)); return self(); } @Override - public SQLQueryOperator groupByOnes(Collection fieldNames) { - throw new SQLException(ERROR_MSG); + public QueryOperator groupByOnes(Collection fieldNames) { + throw new DSLException(ERROR_MSG); } /** @@ -197,4 +222,34 @@ private void addDefaultQuery() { matchAll(); } } + + @Override + public QueryOperator neq(DSLName sqlName, Object value) { + return null; + } + + @Override + public QueryOperator notIn(DSLName sqlName, Object... values) { + return null; + } + + @Override + public QueryOperator notLike(DSLName sqlName, Object value) { + return null; + } + + @Override + public QueryOperator $notLike(DSLName sqlName, Object value) { + return null; + } + + @Override + public QueryOperator notLike$(DSLName sqlName, Object value) { + return null; + } + + @Override + public QueryOperator $notLike$(DSLName sqlName, Object value) { + return null; + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchUpdateOperator.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchUpdateOperator.java similarity index 55% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchUpdateOperator.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchUpdateOperator.java index 844842ce..449212cb 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchUpdateOperator.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchUpdateOperator.java @@ -1,19 +1,21 @@ -package cc.allio.uno.data.orm.sql.dml.elasticsearch; +package cc.allio.uno.data.orm.dsl.dml.elasticsearch; +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; import co.elastic.clients.elasticsearch._types.query_dsl.Query; import co.elastic.clients.elasticsearch.core.UpdateByQueryRequest; import co.elastic.clients.json.JsonData; import co.elastic.clients.json.JsonpUtils; import cc.allio.uno.core.StringPool; -import cc.allio.uno.data.orm.sql.PrepareValue; -import cc.allio.uno.data.orm.sql.SQLException; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.Table; -import cc.allio.uno.data.orm.sql.dml.SQLUpdateOperator; +import cc.allio.uno.data.orm.dsl.dml.UpdateOperator; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -23,54 +25,74 @@ * @date 2023/5/29 13:03 * @since 1.1.4 */ -public class ElasticSearchUpdateOperator extends ElasticSearchGenericWhereOperator implements SQLUpdateOperator { +@AutoService(UpdateOperator.class) +@Operator.Group(OperatorKey.ELASTICSEARCH_LITERAL) +public class ElasticSearchUpdateOperator extends ElasticSearchGenericWhereOperator implements UpdateOperator { + private DBType dbType; private UpdateByQueryRequest updateRequest; private UpdateByQueryRequest.Builder updateBuilder; + private Table table; private static final String ERROR_MSG = "elasticsearch update operator not support that operator"; public ElasticSearchUpdateOperator() { super(); + this.dbType = DBType.ELASTIC_SEARCH; this.updateBuilder = new UpdateByQueryRequest.Builder(); } @Override - public String getSQL() { + public String getDSL() { UpdateByQueryRequest request = getUpdateRequest(); String dsl = JsonpUtils.toString(request); return dsl.substring(dsl.indexOf(StringPool.COLON + StringPool.SPACE) + 2); } @Override - public SQLUpdateOperator parse(String sql) { + public UpdateOperator parse(String dsl) { return null; } @Override public void reset() { super.reset(); - updateRequest = null; - updateBuilder = new UpdateByQueryRequest.Builder(); + this.updateBuilder = new UpdateByQueryRequest.Builder(); } @Override - public String getPrepareSQL() { + public void setDBType(DBType dbType) { + throw Exceptions.unOperate("setDBType"); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public String getPrepareDSL() { return null; } @Override public List getPrepareValues() { - throw new SQLException(ERROR_MSG); + throw new DSLException(ERROR_MSG); } @Override - public SQLUpdateOperator from(Table table) { + public UpdateOperator from(Table table) { + this.table = table; this.updateBuilder = updateBuilder.index(Collections.singletonList(table.getName().format())); return self(); } @Override - public SQLUpdateOperator updates(Map values) { + public Table getTable() { + return table; + } + + @Override + public UpdateOperator updates(Map values) { // source String source = values.keySet().stream().map(o -> "ctx._source['" + o.format() + "'] = params['" + o.format() + "']").collect(Collectors.joining(StringPool.SEMICOLON)); // params @@ -79,6 +101,11 @@ public SQLUpdateOperator updates(Map values) { return self(); } + @Override + public UpdateOperator strictFill(String f, Supplier v) { + return null; + } + /** * 获取更新request * @@ -92,4 +119,29 @@ public UpdateByQueryRequest getUpdateRequest() { } return updateRequest; } + + @Override + public UpdateOperator notIn(DSLName sqlName, Object... values) { + return null; + } + + @Override + public UpdateOperator notLike(DSLName sqlName, Object value) { + return null; + } + + @Override + public UpdateOperator $notLike(DSLName sqlName, Object value) { + return null; + } + + @Override + public UpdateOperator notLike$(DSLName sqlName, Object value) { + return null; + } + + @Override + public UpdateOperator $notLike$(DSLName sqlName, Object value) { + return null; + } } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/AggrResultSet.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/AggrResultSet.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/AggrResultSet.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/AggrResultSet.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsSQLCommandExecutor.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCommandExecutor.java similarity index 58% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsSQLCommandExecutor.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCommandExecutor.java index 265f7bc2..2cda49fd 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsSQLCommandExecutor.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCommandExecutor.java @@ -1,15 +1,21 @@ package cc.allio.uno.data.orm.executor.elasticsearch; +import cc.allio.uno.data.orm.dsl.exception.DSLException; import cc.allio.uno.data.orm.executor.*; -import cc.allio.uno.data.orm.sql.*; -import cc.allio.uno.data.orm.sql.ddl.SQLShowColumnsOperator; -import cc.allio.uno.data.orm.sql.ddl.elasticsearch.ElasticSearchPropertyAdapter; -import cc.allio.uno.data.orm.sql.ddl.elasticsearch.ElasticSearchShowColumnsOperator; -import cc.allio.uno.data.orm.sql.dml.SQLQueryOperator; -import cc.allio.uno.data.orm.sql.dml.elasticsearch.ElasticSearchQueryOperator; -import cc.allio.uno.data.orm.type.DataType; -import cc.allio.uno.data.orm.type.JavaType; -import cc.allio.uno.data.orm.type.TypeRegistry; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.ddl.ShowColumnsOperator; +import cc.allio.uno.data.orm.dsl.ddl.elasticsearch.ElasticSearchPropertyAdapter; +import cc.allio.uno.data.orm.dsl.ddl.elasticsearch.ElasticSearchShowColumnsOperator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.dml.elasticsearch.ElasticSearchQueryOperator; +import cc.allio.uno.data.orm.dsl.type.DataType; +import cc.allio.uno.data.orm.dsl.type.JavaType; +import cc.allio.uno.data.orm.dsl.type.TypeRegistry; +import cc.allio.uno.data.orm.executor.handler.ColumnDefListResultSetHandler; +import cc.allio.uno.data.orm.executor.handler.ListResultSetHandler; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.aggregations.Aggregate; import co.elastic.clients.elasticsearch._types.mapping.Property; @@ -28,19 +34,18 @@ import co.elastic.clients.json.jackson.JacksonJsonpMapper; import co.elastic.clients.transport.rest_client.RestClientTransport; import cc.allio.uno.core.StringPool; -import cc.allio.uno.core.util.CollectionUtils; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import java.io.IOException; +import java.net.SocketTimeoutException; import java.sql.JDBCType; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; /** * 基于es的SQL执行器 @@ -50,93 +55,43 @@ * @since 1.1.4 */ @Slf4j -public class EsSQLCommandExecutor implements SQLCommandExecutor { +public class EsCommandExecutor extends AbstractCommandExecutor implements CommandExecutor { private final ElasticsearchClient elasticsearchClient; private final ElasticsearchIndicesClient indicesClient; - private final ElasticSearchOperatorMetadata elasticSearchOperatorMetadata; + private final OperatorGroup operatorGroup; + private final RestClient restClient; - public EsSQLCommandExecutor(Object[] values) { - RestClientBuilder restClientBuilder = CollectionUtils.findValueOfType(Lists.newArrayList(values), RestClientBuilder.class); - if (restClientBuilder == null) { - throw new NullPointerException(String.format("expect %s but not found", RestClientBuilder.class.getName())); - } - RestClient restClient = restClientBuilder.build(); + public EsCommandExecutor(ExecutorOptions options, RestClientBuilder restClientBuilder) { + super(options); + this.restClient = restClientBuilder.build(); JsonpMapper mapper = new JacksonJsonpMapper(); RestClientTransport transport = new RestClientTransport(restClient, mapper); this.indicesClient = new ElasticsearchIndicesClient(transport); this.elasticsearchClient = new ElasticsearchClient(transport); - this.elasticSearchOperatorMetadata = new ElasticSearchOperatorMetadata(); + this.operatorGroup = OperatorGroup.getOperatorGroup(OperatorKey.ELASTICSEARCH); } @Override - public boolean bool(SQLOperator operator, SQLCommandType sqlCommandType, ResultSetHandler resultSetHandler) { + protected boolean doBool(Operator operator, CommandType commandType, ResultSetHandler resultSetHandler) { try { - switch (sqlCommandType) { - case CREATE_TABLE: - return new EsCreateTableCommandExecutor(indicesClient).exec(operator, resultSetHandler); - case DELETE_TABLE: - return new EsDeleteTableCommandExecutor(indicesClient).exec(operator, resultSetHandler); - case EXIST_TABLE: - return new EsExistTableCommandExecutor(elasticsearchClient).exec(operator, resultSetHandler); - case INSERT: - return new EsInsertCommandExecutor(elasticsearchClient).exec(operator, resultSetHandler); - case UPDATE: - return new EsUpdateCommandExecutor(elasticsearchClient).exec(operator, resultSetHandler); - case DELETE: - return new EsDeleteCommandExecutor(elasticsearchClient).exec(operator, resultSetHandler); - default: - return false; - } + return switch (commandType) { + case CREATE_TABLE -> new EsCreateTableCommandExecutor(indicesClient).exec(operator, resultSetHandler); + case DELETE_TABLE -> new EsDeleteTableCommandExecutor(indicesClient).exec(operator, resultSetHandler); + case EXIST_TABLE -> + new EsExistTableCommandExecutor(elasticsearchClient).exec(operator, resultSetHandler); + case INSERT -> new EsInsertCommandExecutor(elasticsearchClient).exec(operator, resultSetHandler); + case UPDATE -> new EsUpdateCommandExecutor(elasticsearchClient).exec(operator, resultSetHandler); + case DELETE -> new EsDeleteCommandExecutor(elasticsearchClient).exec(operator, resultSetHandler); + default -> false; + }; } catch (Throwable ex) { - throw new SQLException(String.format("exec operator %s has err", operator.getClass().getName()), ex); + throw new DSLException(String.format("exec operator %s has err", operator.getClass().getName()), ex); } } @Override - public List showColumns(SQLShowColumnsOperator sqlShowColumnsOperator) { - if (!ElasticSearchShowColumnsOperator.class.isAssignableFrom(sqlShowColumnsOperator.getClass())) { - throw new IllegalArgumentException(String.format("the show index operator not ElasticSearchShowColumnsOperator, this is %s", sqlShowColumnsOperator.getClass().getName())); - } - GetMappingRequest mappingRequest = ((ElasticSearchShowColumnsOperator) sqlShowColumnsOperator).getMappingRequest(); - try { - GetMappingResponse res = indicesClient.getMapping(mappingRequest); - // key 为索引名称 value 为该索引下mapping的记录 - // 在下面解析时按照只能查询一个来做处理(有且仅有一个) - Map result = res.result(); - ElasticSearchPropertyAdapter propertyAdapter = new ElasticSearchPropertyAdapter(); - List resultGroups = result.values() - .stream() - .flatMap(record -> { - TypeMapping mappings = record.mappings(); - Map properties = mappings.properties(); - return properties.entrySet() - .stream() - .map(field -> { - ResultGroup resultGroup = new ResultGroup(); - ResultRow.ResultRowBuilder builder = ResultRow.builder(); - builder.column(SQLName.of(SQLColumnDefListResultSetHandler.ROW_FIELD_NAME)); - Property fieldProperty = field.getValue(); - DataType dataType = propertyAdapter.reversal(fieldProperty); - builder.jdbcType(JDBCType.valueOf(dataType.getSqlType().getJdbcType())); - String fieldKey = field.getKey(); - builder.value(fieldKey); - resultGroup.addRow(builder.build()); - return resultGroup; - }); - }) - .collect(Collectors.toList()); - ResultSet resultSet = new ResultSet(); - resultSet.setResultGroups(resultGroups); - return new SQLColumnDefListResultSetHandler().apply(resultSet); - } catch (IOException ex) { - log.error("show columns has err", ex); - return Collections.emptyList(); - } - } - - @Override - public List queryList(SQLQueryOperator queryOperator, ListResultSetHandler resultSetHandler) { + protected List doQueryList(QueryOperator queryOperator, CommandType commandType, ListResultSetHandler resultSetHandler) { ElasticSearchQueryOperator elasticSearchQueryOperator = null; if (ElasticSearchQueryOperator.class.isAssignableFrom(queryOperator.getClass())) { elasticSearchQueryOperator = ((ElasticSearchQueryOperator) queryOperator); @@ -151,16 +106,64 @@ public List queryList(SQLQueryOperator queryOperator, ListResultSetHandle SearchRequest searchRequest = elasticSearchQueryOperator.getSearchRequest(); response = elasticsearchClient.search(searchRequest, Map.class); } catch (Throwable ex) { - throw new SQLException(String.format("elasticsearch exec dsl: %s has error", queryOperator.getSQL()), ex); + throw new DSLException(String.format("elasticsearch exec dsl: %s has error", queryOperator.getDSL()), ex); } if (response == null) { - throw new SQLException(String.format("elasticsearch request has err the msg is: %s", "")); + throw new DSLException(String.format("elasticsearch request has err the msg is: %s", "")); } EsResultSet resultSet = explainSearchRes(response); return resultSetHandler.apply(resultSet); } else { - throw new SQLException("queryOperator argument not SearchRequest instance"); + throw new DSLException("queryOperator argument not SearchRequest instance"); + } + } + + @Override + public List showColumns(ShowColumnsOperator sqlShowColumnsOperator) { + if (!ElasticSearchShowColumnsOperator.class.isAssignableFrom(sqlShowColumnsOperator.getClass())) { + throw new IllegalArgumentException(String.format("the show index operator not ElasticSearchShowColumnsOperator, this is %s", sqlShowColumnsOperator.getClass().getName())); } + GetMappingRequest mappingRequest = ((ElasticSearchShowColumnsOperator) sqlShowColumnsOperator).getMappingRequest(); + try { + GetMappingResponse res = indicesClient.getMapping(mappingRequest); + // key 为索引名称 value 为该索引下mapping的记录 + // 在下面解析时按照只能查询一个来做处理(有且仅有一个) + Map result = res.result(); + ElasticSearchPropertyAdapter propertyAdapter = new ElasticSearchPropertyAdapter(); + List resultGroups = + result.values() + .stream() + .flatMap(record -> { + TypeMapping mappings = record.mappings(); + Map properties = mappings.properties(); + return properties.entrySet() + .stream() + .map(field -> { + ResultGroup resultGroup = new ResultGroup(); + ResultRow.ResultRowBuilder builder = ResultRow.builder(); +// builder.column(DSLName.of(ColumnDefListResultSetHandler.ROW_FIELD_NAME)); + Property fieldProperty = field.getValue(); + DataType dataType = propertyAdapter.reverse(fieldProperty); + builder.jdbcType(JDBCType.valueOf(dataType.getDslType().getJdbcType())); + String fieldKey = field.getKey(); + builder.value(fieldKey); + resultGroup.addRow(builder.build()); + return resultGroup; + }); + }) + .toList(); + ResultSet resultSet = new ResultSet(); + resultSet.setResultGroups(resultGroups); + return new ColumnDefListResultSetHandler().apply(resultSet); + } catch (IOException ex) { + log.error("Show columns has err", ex); + return Collections.emptyList(); + } + } + + @Override + public boolean check() throws SocketTimeoutException { + return restClient.isRunning(); } /** @@ -188,8 +191,6 @@ private EsResultSet explainSearchRes(SearchResponse response) { // 设置文档基础信息 resultGroup.setId(hit.id()); resultGroup.setIndex(hit.index()); - // TODO 确定es返回字段的类型 -// resultGroup.setType(Optional.ofNullable(hit).orElse(StringPool.EMPTY)); resultGroup.setScore(Optional.ofNullable(hit.score()).orElse(0D)); // 设置分片信息 resultGroup.setNodeId(hit.node()); @@ -200,7 +201,7 @@ private EsResultSet explainSearchRes(SearchResponse response) { for (Map.Entry df : source.entrySet()) { String columnName = df.getKey(); Object value = df.getValue(); - builder.column(SQLName.of(columnName, SQLName.HUMP_FEATURE)); + builder.column(DSLName.of(columnName, DSLName.HUMP_FEATURE)); JavaType javaType = TypeRegistry.getInstance().guessJavaType(value); builder.javaType(javaType); builder.value(value); @@ -216,11 +217,20 @@ private EsResultSet explainSearchRes(SearchResponse response) { @Override public ExecutorKey getKey() { - return MYBATIS_SQL_COMMAND_EXECUTOR_KEY; + return ExecutorKey.ELASTICSEARCH; } @Override - public OperatorMetadata getOperatorMetadata() { - return elasticSearchOperatorMetadata; + public OperatorGroup getOperatorGroup() { + return operatorGroup; + } + + @Override + public void destroy() { + try { + restClient.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } } } diff --git a/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCommandExecutorLoader.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCommandExecutorLoader.java new file mode 100644 index 00000000..0190361b --- /dev/null +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCommandExecutorLoader.java @@ -0,0 +1,39 @@ +package cc.allio.uno.data.orm.executor.elasticsearch; + +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.executor.CommandExecutor; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import cc.allio.uno.data.orm.executor.ExecutorLoader; +import cc.allio.uno.data.orm.executor.options.ExecutorOptions; +import cc.allio.uno.data.orm.executor.options.ExecutorOptionsImpl; +import cc.allio.uno.data.orm.executor.interceptor.Interceptor; +import org.elasticsearch.client.RestClientBuilder; + +import java.util.List; + +public class EsCommandExecutorLoader implements ExecutorLoader { + + private final RestClientBuilder restClientBuilder; + + public EsCommandExecutorLoader(RestClientBuilder restClientBuilder) { + this.restClientBuilder = restClientBuilder; + } + + @Override + public CommandExecutor load(List interceptors) { + ExecutorOptions executorOptions = new ExecutorOptionsImpl(DBType.ELASTIC_SEARCH, ExecutorKey.ELASTICSEARCH, OperatorKey.ELASTICSEARCH); + executorOptions.addInterceptors(interceptors); + return load(executorOptions); + } + + @Override + public CommandExecutor load(ExecutorOptions executorOptions) { + return new EsCommandExecutor(executorOptions, restClientBuilder); + } + + @Override + public boolean match(DBType dbType) { + return DBType.ELASTIC_SEARCH == dbType; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCreateTableCommandExecutor.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCreateTableCommandExecutor.java similarity index 64% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCreateTableCommandExecutor.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCreateTableCommandExecutor.java index 20afaf38..2956f7bc 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCreateTableCommandExecutor.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsCreateTableCommandExecutor.java @@ -1,21 +1,23 @@ package cc.allio.uno.data.orm.executor.elasticsearch; import cc.allio.uno.data.orm.executor.*; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.ddl.elasticsearch.ElasticSearchCreateIndexOperator; -import cc.allio.uno.data.orm.type.IntegerJavaType; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.ddl.elasticsearch.ElasticSearchCreateIndexOperator; +import cc.allio.uno.data.orm.dsl.type.IntegerJavaType; +import cc.allio.uno.data.orm.executor.handler.BoolResultHandler; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; import co.elastic.clients.elasticsearch.indices.CreateIndexResponse; import co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient; /** - * {@link SQLCommandType#CREATE_TABLE} + * {@link CommandType#CREATE_TABLE} * * @author jiangwei * @date 2023/5/29 21:56 * @since 1.1.4 */ -public class EsCreateTableCommandExecutor implements SQLCommandTypeExecutor { +public class EsCreateTableCommandExecutor implements CommandTypeExecutor { private final ElasticsearchIndicesClient indicesClient; @@ -24,9 +26,9 @@ public EsCreateTableCommandExecutor(ElasticsearchIndicesClient indicesClient) { } @Override - public Boolean exec(SQLOperator operator, ResultSetHandler resultSetHandler) throws Throwable { + public Boolean exec(Operator operator, ResultSetHandler resultSetHandler) throws Throwable { if (!ElasticSearchCreateIndexOperator.class.isAssignableFrom(operator.getClass())) { - throw new IllegalArgumentException(String.format("the create index operator not ElasticSearchCreateIndexOperator, this is %s", operator.getClass().getName())); + throw new IllegalArgumentException(String.format("the registry index operator not ElasticSearchCreateIndexOperator, this is %s", operator.getClass().getName())); } ElasticSearchCreateIndexOperator indexOperator = ((ElasticSearchCreateIndexOperator) operator); CreateIndexResponse createIndexResponse = indicesClient.create(indexOperator.getCreateIndexRequest()); @@ -34,7 +36,7 @@ public Boolean exec(SQLOperator operator, ResultSetHandler resultSet resultGroup.addRow( ResultRow.builder() .index(0) - .column(SQLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) + .column(DSLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) .javaType(new IntegerJavaType()) .value(createIndexResponse.acknowledged()) .build()); diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteCommandExecutor.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteCommandExecutor.java similarity index 64% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteCommandExecutor.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteCommandExecutor.java index 532b735b..130484e2 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteCommandExecutor.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteCommandExecutor.java @@ -1,22 +1,24 @@ package cc.allio.uno.data.orm.executor.elasticsearch; import cc.allio.uno.data.orm.executor.*; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.dml.elasticsearch.ElasticSearchDeleteOperator; -import cc.allio.uno.data.orm.type.IntegerJavaType; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.dml.elasticsearch.ElasticSearchDeleteOperator; +import cc.allio.uno.data.orm.dsl.type.IntegerJavaType; +import cc.allio.uno.data.orm.executor.handler.BoolResultHandler; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.core.DeleteByQueryRequest; import co.elastic.clients.elasticsearch.core.DeleteByQueryResponse; /** - * {@link SQLCommandType#DELETE} + * {@link CommandType#DELETE} * * @author jiangwei * @date 2023/7/4 15:59 * @since 1.1.4 */ -public class EsDeleteCommandExecutor implements SQLCommandTypeExecutor { +public class EsDeleteCommandExecutor implements CommandTypeExecutor { private final ElasticsearchClient elasticsearchClient; @@ -25,9 +27,9 @@ public EsDeleteCommandExecutor(ElasticsearchClient elasticsearchClient) { } @Override - public Boolean exec(SQLOperator operator, ResultSetHandler resultSetHandler) throws Throwable { + public Boolean exec(Operator operator, ResultSetHandler resultSetHandler) throws Throwable { if (!ElasticSearchDeleteOperator.class.isAssignableFrom(operator.getClass())) { - throw new IllegalArgumentException(String.format("the create index operator not ElasticSearchDeleteOperator, this is %s", operator.getClass().getName())); + throw new IllegalArgumentException(String.format("the registry index operator not ElasticSearchDeleteOperator, this is %s", operator.getClass().getName())); } DeleteByQueryRequest deleteRequest = ((ElasticSearchDeleteOperator) operator).getDeleteRequest(); DeleteByQueryResponse res = elasticsearchClient.deleteByQuery(deleteRequest); @@ -35,7 +37,7 @@ public Boolean exec(SQLOperator operator, ResultSetHandler resultSet resultGroup.addRow( ResultRow.builder() .index(0) - .column(SQLName.of(BoolResultHandler.GUESS_COUNT)) + .column(DSLName.of(BoolResultHandler.GUESS_COUNT)) .javaType(new IntegerJavaType()) .value(res.deleted()) .build()); diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteTableCommandExecutor.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteTableCommandExecutor.java similarity index 63% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteTableCommandExecutor.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteTableCommandExecutor.java index ffb73d7b..ae8b3eab 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteTableCommandExecutor.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsDeleteTableCommandExecutor.java @@ -1,21 +1,23 @@ package cc.allio.uno.data.orm.executor.elasticsearch; import cc.allio.uno.data.orm.executor.*; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.ddl.elasticsearch.ElasticSearchDropIndexOperator; -import cc.allio.uno.data.orm.type.IntegerJavaType; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.ddl.elasticsearch.ElasticSearchDropIndexOperator; +import cc.allio.uno.data.orm.dsl.type.IntegerJavaType; +import cc.allio.uno.data.orm.executor.handler.BoolResultHandler; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse; import co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient; /** - * {@link SQLCommandType#DELETE_TABLE} + * {@link CommandType#DELETE_TABLE} * * @author jiangwei * @date 2023/5/30 08:53 * @since 1.1.4 */ -public class EsDeleteTableCommandExecutor implements SQLCommandTypeExecutor { +public class EsDeleteTableCommandExecutor implements CommandTypeExecutor { private final ElasticsearchIndicesClient indicesClient; @@ -24,9 +26,9 @@ public EsDeleteTableCommandExecutor(ElasticsearchIndicesClient indicesClient) { } @Override - public Boolean exec(SQLOperator operator, ResultSetHandler resultSetHandler) throws Throwable { + public Boolean exec(Operator operator, ResultSetHandler resultSetHandler) throws Throwable { if (!ElasticSearchDropIndexOperator.class.isAssignableFrom(operator.getClass())) { - throw new IllegalArgumentException(String.format("the create index operator not ElasticSearchExistIndexOperator, this is %s", operator.getClass().getName())); + throw new IllegalArgumentException(String.format("the registry index operator not ElasticSearchExistIndexOperator, this is %s", operator.getClass().getName())); } ElasticSearchDropIndexOperator dropIndexOperator = (ElasticSearchDropIndexOperator) operator; DeleteIndexResponse res = indicesClient.delete(dropIndexOperator.getDeleteIndexRequest()); @@ -34,7 +36,7 @@ public Boolean exec(SQLOperator operator, ResultSetHandler resultSet resultGroup.addRow( ResultRow.builder() .index(0) - .column(SQLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) + .column(DSLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) .javaType(new IntegerJavaType()) .value(res.acknowledged()) .build()); diff --git a/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExecutorAspect.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExecutorAspect.java new file mode 100644 index 00000000..45023f42 --- /dev/null +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExecutorAspect.java @@ -0,0 +1,14 @@ +package cc.allio.uno.data.orm.executor.elasticsearch; + +import org.aspectj.lang.annotation.Aspect; + +/** + * Aspect + * + * @author jiangwei + * @date 2024/1/10 22:24 + * @since 1.1.6 + */ +@Aspect +public class EsExecutorAspect { +} diff --git a/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExecutorAware.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExecutorAware.java new file mode 100644 index 00000000..655695bd --- /dev/null +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExecutorAware.java @@ -0,0 +1,13 @@ +package cc.allio.uno.data.orm.executor.elasticsearch; + +import cc.allio.uno.data.orm.executor.ExecutorAware; + +/** + * 获取{@link EsCommandExecutor}实例标识接口 + * + * @author jiangwei + * @date 2024/1/10 18:18 + * @since 1.1.6 + */ +public interface EsExecutorAware extends ExecutorAware { +} diff --git a/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExecutorProcessor.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExecutorProcessor.java new file mode 100644 index 00000000..78011b23 --- /dev/null +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExecutorProcessor.java @@ -0,0 +1,35 @@ +package cc.allio.uno.data.orm.executor.elasticsearch; + +import cc.allio.uno.core.util.ClassUtils; +import cc.allio.uno.data.orm.executor.CommandExecutorFactory; +import cc.allio.uno.data.orm.executor.options.ExecutorKey; +import org.aopalliance.intercept.MethodInterceptor; +import org.springframework.aop.aspectj.annotation.AspectJProxyFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.NameMatchMethodPointcut; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +/** + * {@link cc.allio.uno.data.orm.executor.ExecutorAware}的ES实现 + * + * @author jiangwei + * @date 2024/1/10 22:26 + * @since 1.1.6 + */ +public class EsExecutorProcessor implements BeanPostProcessor { + + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (ClassUtils.isAssignable(EsExecutorAware.class, bean.getClass())) { + AspectJProxyFactory proxyFactory = new AspectJProxyFactory(); + proxyFactory.setTarget(bean); + proxyFactory.addAspect(EsExecutorAspect.class); + NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); + pointcut.setMappedName("getExecutor"); + MethodInterceptor methodInterceptor = invocation -> CommandExecutorFactory.getDSLExecutor(ExecutorKey.ELASTICSEARCH); + proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut, methodInterceptor)); + return proxyFactory.getProxy(); + } + return bean; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExistTableCommandExecutor.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExistTableCommandExecutor.java similarity index 67% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExistTableCommandExecutor.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExistTableCommandExecutor.java index 8888371d..01f130df 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExistTableCommandExecutor.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsExistTableCommandExecutor.java @@ -1,21 +1,23 @@ package cc.allio.uno.data.orm.executor.elasticsearch; import cc.allio.uno.data.orm.executor.*; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.ddl.elasticsearch.ElasticSearchExistIndexOperator; -import cc.allio.uno.data.orm.type.IntegerJavaType; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.ddl.elasticsearch.ElasticSearchExistIndexOperator; +import cc.allio.uno.data.orm.dsl.type.IntegerJavaType; +import cc.allio.uno.data.orm.executor.handler.BoolResultHandler; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.ElasticsearchException; /** - * {@link SQLCommandType#EXIST_TABLE} + * {@link CommandType#EXIST_TABLE} * * @author jiangwei * @date 2023/5/30 08:54 * @since 1.1.4 */ -public class EsExistTableCommandExecutor implements SQLCommandTypeExecutor { +public class EsExistTableCommandExecutor implements CommandTypeExecutor { private final ElasticsearchClient elasticsearchClient; @@ -24,9 +26,9 @@ public EsExistTableCommandExecutor(ElasticsearchClient elasticsearchClient) { } @Override - public Boolean exec(SQLOperator operator, ResultSetHandler resultSetHandler) throws Throwable { + public Boolean exec(Operator operator, ResultSetHandler resultSetHandler) throws Throwable { if (!ElasticSearchExistIndexOperator.class.isAssignableFrom(operator.getClass())) { - throw new IllegalArgumentException(String.format("the create index operator not ElasticSearchExistIndexOperator, this is %s", operator.getClass().getName())); + throw new IllegalArgumentException(String.format("the registry index operator not ElasticSearchExistIndexOperator, this is %s", operator.getClass().getName())); } ElasticSearchExistIndexOperator existIndexOperator = (ElasticSearchExistIndexOperator) operator; boolean isExist = true; @@ -40,7 +42,7 @@ public Boolean exec(SQLOperator operator, ResultSetHandler resultSet resultGroup.addRow( ResultRow.builder() .index(0) - .column(SQLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) + .column(DSLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) .javaType(new IntegerJavaType()) .value(isExist) .build()); diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsInsertCommandExecutor.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsInsertCommandExecutor.java similarity index 64% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsInsertCommandExecutor.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsInsertCommandExecutor.java index 6f4911ef..28a7dbe2 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsInsertCommandExecutor.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsInsertCommandExecutor.java @@ -1,22 +1,24 @@ package cc.allio.uno.data.orm.executor.elasticsearch; import cc.allio.uno.data.orm.executor.*; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.dml.elasticsearch.ElasticSearchInsertOperator; -import cc.allio.uno.data.orm.type.IntegerJavaType; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.dml.elasticsearch.ElasticSearchInsertOperator; +import cc.allio.uno.data.orm.dsl.type.IntegerJavaType; +import cc.allio.uno.data.orm.executor.handler.BoolResultHandler; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.core.BulkRequest; import co.elastic.clients.elasticsearch.core.BulkResponse; /** - * {@link SQLCommandType#INSERT} + * {@link CommandType#INSERT} * * @author jiangwei * @date 2023/5/30 08:58 * @since 1.1.4 */ -public class EsInsertCommandExecutor implements SQLCommandTypeExecutor { +public class EsInsertCommandExecutor implements CommandTypeExecutor { private final ElasticsearchClient elasticsearchClient; @@ -25,9 +27,9 @@ public EsInsertCommandExecutor(ElasticsearchClient elasticsearchClient) { } @Override - public Boolean exec(SQLOperator operator, ResultSetHandler resultSetHandler) throws Throwable { + public Boolean exec(Operator operator, ResultSetHandler resultSetHandler) throws Throwable { if (!ElasticSearchInsertOperator.class.isAssignableFrom(operator.getClass())) { - throw new IllegalArgumentException(String.format("the create index operator not ElasticSearchCreateIndexOperator, this is %s", operator.getClass().getName())); + throw new IllegalArgumentException(String.format("the registry index operator not ElasticSearchCreateIndexOperator, this is %s", operator.getClass().getName())); } ElasticSearchInsertOperator insertOperator = (ElasticSearchInsertOperator) operator; BulkRequest bulkRequest = insertOperator.getBulkRequest(); @@ -36,7 +38,7 @@ public Boolean exec(SQLOperator operator, ResultSetHandler resultSet resultGroup.addRow( ResultRow.builder() .index(0) - .column(SQLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) + .column(DSLName.of(BoolResultHandler.GUESS_UPDATE_OR_UPDATE)) .javaType(new IntegerJavaType()) .value(res.errors()) .build()); diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsResultGroup.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsResultGroup.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsResultGroup.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsResultGroup.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsResultSet.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsResultSet.java similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsResultSet.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsResultSet.java diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsUpdateCommandExecutor.java b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsUpdateCommandExecutor.java similarity index 64% rename from uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsUpdateCommandExecutor.java rename to uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsUpdateCommandExecutor.java index 768b72f2..effde811 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsUpdateCommandExecutor.java +++ b/uno-data/uno-data-elasticsearch/src/main/java/cc/allio/uno/data/orm/executor/elasticsearch/EsUpdateCommandExecutor.java @@ -1,21 +1,23 @@ package cc.allio.uno.data.orm.executor.elasticsearch; import cc.allio.uno.data.orm.executor.*; -import cc.allio.uno.data.orm.sql.SQLName; -import cc.allio.uno.data.orm.sql.SQLOperator; -import cc.allio.uno.data.orm.sql.dml.elasticsearch.ElasticSearchUpdateOperator; -import cc.allio.uno.data.orm.type.IntegerJavaType; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.dml.elasticsearch.ElasticSearchUpdateOperator; +import cc.allio.uno.data.orm.dsl.type.IntegerJavaType; +import cc.allio.uno.data.orm.executor.handler.BoolResultHandler; +import cc.allio.uno.data.orm.executor.handler.ResultSetHandler; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.core.UpdateByQueryResponse; /** - * {@link SQLCommandType#UPDATE} + * {@link CommandType#UPDATE} * * @author jiangwei * @date 2023/6/11 20:22 * @since 1.1.4 */ -public class EsUpdateCommandExecutor implements SQLCommandTypeExecutor { +public class EsUpdateCommandExecutor implements CommandTypeExecutor { private final ElasticsearchClient elasticsearchClient; @@ -24,9 +26,9 @@ public EsUpdateCommandExecutor(ElasticsearchClient elasticsearchClient) { } @Override - public Boolean exec(SQLOperator operator, ResultSetHandler resultSetHandler) throws Throwable { + public Boolean exec(Operator operator, ResultSetHandler resultSetHandler) throws Throwable { if (!ElasticSearchUpdateOperator.class.isAssignableFrom(operator.getClass())) { - throw new IllegalArgumentException(String.format("the create index operator not ElasticSearchUpdateOperator, this is %s", operator.getClass().getName())); + throw new IllegalArgumentException(String.format("the registry index operator not ElasticSearchUpdateOperator, this is %s", operator.getClass().getName())); } ElasticSearchUpdateOperator updateOperator = (ElasticSearchUpdateOperator) operator; UpdateByQueryResponse res = elasticsearchClient.updateByQuery(updateOperator.getUpdateRequest()); @@ -35,7 +37,7 @@ public Boolean exec(SQLOperator operator, ResultSetHandler resultSet resultGroup.addRow( ResultRow.builder() .index(0) - .column(SQLName.of(BoolResultHandler.GUESS_COUNT)) + .column(DSLName.of(BoolResultHandler.GUESS_COUNT)) .javaType(new IntegerJavaType()) .value(updated) .build()); diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/es-sql.puml b/uno-data/uno-data-elasticsearch/src/main/resources/uml/es-sql.puml similarity index 100% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/es-sql.puml rename to uno-data/uno-data-elasticsearch/src/main/resources/uml/es-sql.puml diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchShowColumnsOperatorTest.java b/uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchShowColumnsOperatorTest.java similarity index 86% rename from uno-data/src/test/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchShowColumnsOperatorTest.java rename to uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchShowColumnsOperatorTest.java index 02b5769f..1b80ec52 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/ddl/elasticsearch/ElasticSearchShowColumnsOperatorTest.java +++ b/uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/ddl/elasticsearch/ElasticSearchShowColumnsOperatorTest.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql.ddl.elasticsearch; +package cc.allio.uno.data.orm.dsl.ddl.elasticsearch; import cc.allio.uno.test.BaseTestCase; import org.junit.jupiter.api.Test; diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchInsertOperatorTest.java b/uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchInsertOperatorTest.java similarity index 67% rename from uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchInsertOperatorTest.java rename to uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchInsertOperatorTest.java index 298fdd8f..6396a676 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchInsertOperatorTest.java +++ b/uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchInsertOperatorTest.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql.dml.elasticsearch; +package cc.allio.uno.data.orm.dsl.dml.elasticsearch; import cc.allio.uno.test.BaseTestCase; import org.junit.jupiter.api.Test; @@ -9,7 +9,7 @@ public class ElasticSearchInsertOperatorTest extends BaseTestCase { @Test void testSingeInsert() { - String sql = operator.from("test").insert("t1", "t2").getSQL(); - assertEquals("[{\"create\":{\"_id\":\"1112832259796238336\",\"_index\":\"test\"}}]", sql); + String sql = operator.from("test").insert("t1", "t2").getDSL(); + assertEquals("[{\"registry\":{\"_id\":\"1112832259796238336\",\"_index\":\"test\"}}]", sql); } } diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchUpdateOperatorTest.java b/uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchUpdateOperatorTest.java similarity index 93% rename from uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchUpdateOperatorTest.java rename to uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchUpdateOperatorTest.java index c33ea398..5816c295 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticSearchUpdateOperatorTest.java +++ b/uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticSearchUpdateOperatorTest.java @@ -1,7 +1,7 @@ -package cc.allio.uno.data.orm.sql.dml.elasticsearch; +package cc.allio.uno.data.orm.dsl.dml.elasticsearch; import cc.allio.uno.core.util.JsonUtils; -import cc.allio.uno.data.orm.Bank; +import cc.allio.uno.data.test.model.Bank; import cc.allio.uno.test.BaseTestCase; import org.junit.jupiter.api.Test; @@ -25,7 +25,7 @@ void testUpdateForEQ() { " \"state\" : \"OK\"\n" + " }", Bank.class); bank.setAge(33); - String sql = updateOperator.from("bank").eq(Bank::getFirstname, "firstname").updatePojo(bank).getSQL(); + String sql = updateOperator.from("bank").eq(Bank::getFirstname, "firstname").updatePojo(bank).getDSL(); assertEquals("{\"query\":{\"bool\":{\"must\":[{\"match\":{\"firstname\":{\"query\":\"firstname\"}}}]}},\"script\":{\"params\":{\"firstname\":\"Mcgee\",\"address\":\"826 Fillmore Place\",\"gender\":\"M\",\"balance\":18612,\"city\":\"Tooleville\",\"employer\":\"Reversus\",\"state\":\"OK\",\"accountNumber\":0,\"email\":\"mcgeemooney@reversus.com\",\"age\":33,\"lastname\":\"Mooney\"},\"source\":\"ctx._source['city'] = params['city'];ctx._source['accountNumber'] = params['accountNumber'];ctx._source['lastname'] = params['lastname'];ctx._source['state'] = params['state'];ctx._source['firstname'] = params['firstname'];ctx._source['address'] = params['address'];ctx._source['balance'] = params['balance'];ctx._source['employer'] = params['employer'];ctx._source['gender'] = params['gender'];ctx._source['age'] = params['age'];ctx._source['email'] = params['email']\"}}", sql); } } diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticsearchQueryOperatorTest.java b/uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticsearchQueryOperatorTest.java similarity index 91% rename from uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticsearchQueryOperatorTest.java rename to uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticsearchQueryOperatorTest.java index fb061070..6cd9c0b6 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/sql/dml/elasticsearch/ElasticsearchQueryOperatorTest.java +++ b/uno-data/uno-data-elasticsearch/src/test/java/cc/allio/uno/data/orm/dsl/dml/elasticsearch/ElasticsearchQueryOperatorTest.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm.sql.dml.elasticsearch; +package cc.allio.uno.data.orm.dsl.dml.elasticsearch; import cc.allio.uno.test.BaseTestCase; import org.junit.jupiter.api.BeforeEach; @@ -15,31 +15,31 @@ public void setup() { @Test void testEQ() { - String sql = queryOperator.eq("test", "1").from("bank").getSQL(); + String sql = queryOperator.eq("test", "1").from("bank").getDSL(); assertEquals("{\"bool\":{\"must\":[{\"term\":{\"test\":{\"value\":\"1\"}}}]}}", sql); } @Test void testMatch() { - String sql = queryOperator.like("test", "1").from("bank").getSQL(); + String sql = queryOperator.like("test", "1").from("bank").getDSL(); assertEquals("{\"bool\":{\"must\":[{\"match\":{\"test\":{\"query\":\"1\"}}}]}}", sql); } @Test void testGt() { - String sql = queryOperator.gt("test", "1").from("bank").getSQL(); + String sql = queryOperator.gt("test", "1").from("bank").getDSL(); assertEquals("{\"bool\":{\"must\":[{\"range\":{\"test\":{\"gt\":\"1\"}}}]}}", sql); } @Test void testLike$() { - String sql = queryOperator.like$("test", "1").from("bank").getSQL(); + String sql = queryOperator.like$("test", "1").from("bank").getDSL(); assertEquals("{\"bool\":{\"must\":[{\"wildcard\":{\"test\":{\"value\":\"1*\"}}}]}}", sql); } @Test void testAndOrAndNot() { - String sql = queryOperator.like$("test", "1").from("bank").or().eq("t1", "2").getSQL(); + String sql = queryOperator.like$("test", "1").from("bank").or().eq("t1", "2").getDSL(); assertEquals("{\"bool\":{\"must\":[{\"wildcard\":{\"test\":{\"value\":\"1*\"}}}],\"should\":[{\"term\":{\"t1\":{\"value\":\"2\"}}}]}}", sql); } } diff --git a/uno-data/uno-data-influxdb/pom.xml b/uno-data/uno-data-influxdb/pom.xml new file mode 100644 index 00000000..2b6e7886 --- /dev/null +++ b/uno-data/uno-data-influxdb/pom.xml @@ -0,0 +1,26 @@ + + + + cc.allio + uno-data + 1.1.6-beta.1 + ../pom.xml + + 4.0.0 + jar + uno-data-influxdb + + + + cc.allio + uno-data-api + + + com.influxdb + influxdb-client-java + provided + + + \ No newline at end of file diff --git a/uno-data/uno-data-mongodb/pom.xml b/uno-data/uno-data-mongodb/pom.xml new file mode 100644 index 00000000..e223f213 --- /dev/null +++ b/uno-data/uno-data-mongodb/pom.xml @@ -0,0 +1,22 @@ + + + + cc.allio + uno-data + 1.1.6-beta.1 + ../pom.xml + + jar + 4.0.0 + uno-data-mongodb + + + + cc.allio + uno-data-api + + + + \ No newline at end of file diff --git a/uno-data/uno-data-neo4j/pom.xml b/uno-data/uno-data-neo4j/pom.xml new file mode 100644 index 00000000..6d08db94 --- /dev/null +++ b/uno-data/uno-data-neo4j/pom.xml @@ -0,0 +1,21 @@ + + + + cc.allio + uno-data + 1.1.6-beta.1 + ../pom.xml + + jar + 4.0.0 + uno-data-neo4j + + + + cc.allio + uno-data-api + + + \ No newline at end of file diff --git a/uno-data/uno-data-redis/pom.xml b/uno-data/uno-data-redis/pom.xml new file mode 100644 index 00000000..c4432d4c --- /dev/null +++ b/uno-data/uno-data-redis/pom.xml @@ -0,0 +1,21 @@ + + + + cc.allio + uno-data + 1.1.6-beta.1 + ../pom.xml + + jar + 4.0.0 + uno-data-redis + + + + cc.allio + uno-data-api + + + \ No newline at end of file diff --git a/uno-data/uno-data-sql/pom.xml b/uno-data/uno-data-sql/pom.xml new file mode 100644 index 00000000..d1f57695 --- /dev/null +++ b/uno-data/uno-data-sql/pom.xml @@ -0,0 +1,33 @@ + + + + cc.allio + uno-data + 1.1.6-beta.1 + ../pom.xml + + + 4.0.0 + jar + uno-data-sql + + + + cc.allio + uno-data-api + + + + com.alibaba + druid + + + cc.allio + uno-data-test + test + + + + \ No newline at end of file diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/LogicMode.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/LogicMode.java new file mode 100644 index 00000000..a9aa96bf --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/LogicMode.java @@ -0,0 +1,106 @@ +package cc.allio.uno.data.orm.dsl; + +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.expr.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.TreeSet; + +public enum LogicMode { + AND, OR; + + public SQLExpr appendWhere(SQLObject sqlObject, SQLExpr where, SQLExpr condition, DbType dbType) { + if (this == AND) { + return andWhere(sqlObject, where, condition, dbType); + } else if (this == OR) { + return orWhere(sqlObject, where, condition, dbType); + } + return where; + } + + private SQLExpr andWhere(SQLObject sqlObject, SQLExpr where, SQLExpr condition, DbType dbType) { + if (condition == null) { + return where; + } + if (where == null) { + condition.setParent(sqlObject); + where = condition; + return where; + } + + List items = SQLBinaryOpExpr.split(where, SQLBinaryOperator.BooleanAnd); + for (SQLExpr item : items) { + if (condition.equals(item)) { + return where; + } + + if (condition instanceof SQLInListExpr inListExpr) { + if (item instanceof SQLBinaryOpExpr binaryOpItem) { + SQLExpr left = binaryOpItem.getLeft(); + SQLExpr right = binaryOpItem.getRight(); + if (inListExpr.getExpr().equals(left) + && binaryOpItem.getOperator() == SQLBinaryOperator.Equality + && !(right instanceof SQLNullExpr) + ) { + if (inListExpr.getTargetList().contains(right)) { + return where; + } + + SQLUtils.replaceInParent(item, new SQLBooleanExpr(false)); + return where; + } + } else { + if (item instanceof SQLInListExpr inListItem && (inListExpr.getExpr().equals(inListItem.getExpr()))) { + TreeSet set = new TreeSet<>(inListItem.getTargetList()); + List andList = new ArrayList(); + for (SQLExpr exprItem : inListExpr.getTargetList()) { + if (set.contains(exprItem)) { + andList.add(exprItem.clone()); + } + } + + if (andList.isEmpty()) { + SQLUtils.replaceInParent(item, new SQLBooleanExpr(false)); + return where; + } + + inListItem.getTargetList().clear(); + for (SQLExpr val : andList) { + inListItem.addTarget(val); + } + return where; + + } + } + } + } + where = SQLBinaryOpExpr.and(where, condition); + where.setParent(sqlObject); + return where; + } + + private SQLExpr orWhere(SQLObject sqlObject, SQLExpr where, SQLExpr condition, DbType dbType) { + if (condition == null) { + return where; + } + + if (where == null) { + condition.setParent(sqlObject); + where = condition; + } else if (SQLBinaryOpExpr.isOr(where) || SQLBinaryOpExpr.isOr(condition)) { + SQLBinaryOpExprGroup group = new SQLBinaryOpExprGroup(SQLBinaryOperator.BooleanOr, dbType); + group.add(where); + group.add(condition); + group.setParent(sqlObject); + where = group; + } else { + where = SQLBinaryOpExpr.or(where, condition); + where.setParent(sqlObject); + } + return where; + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/SQLSupport.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/SQLSupport.java new file mode 100644 index 00000000..18158586 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/SQLSupport.java @@ -0,0 +1,436 @@ +package cc.allio.uno.data.orm.dsl; + +import cc.allio.uno.core.StringPool; +import cc.allio.uno.core.api.Self; +import cc.allio.uno.core.function.ConsumerAction; +import cc.allio.uno.core.function.SupplierAction; +import cc.allio.uno.core.function.TernaryConsumer; +import cc.allio.uno.core.function.VoidConsumer; +import cc.allio.uno.core.type.Types; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DSLType; +import cc.allio.uno.data.orm.dsl.type.DataType; +import cc.allio.uno.data.orm.dsl.type.DruidDbTypeAdapter; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.expr.*; +import com.google.common.collect.Lists; +import reactor.util.function.Tuple2; +import reactor.util.function.Tuples; + +import java.util.Collections; +import java.util.List; +import java.util.TimeZone; + +/** + * druid sql 相关工具类 + * + * @author jiangwei + * @date 2024/1/4 17:06 + * @since 1.1.6 + */ +public class SQLSupport implements Self { + + private static final List CURRENT_SUPPORT_DB = List.of(DbType.mysql, DbType.postgresql, DbType.db2, DbType.h2); + private static final Object EMPTY = new Object(); + + private static final List BINARY_VALUABLE_OPERATOR = Lists.newArrayList(); + + private static final SQLVariantRefExpr PLACEHOLDER = new SQLVariantRefExpr(StringPool.QUESTION_MARK); + + static { + BINARY_VALUABLE_OPERATOR.add(SQLBinaryOperator.Like); + BINARY_VALUABLE_OPERATOR.add(SQLBinaryOperator.NotLike); + BINARY_VALUABLE_OPERATOR.add(SQLBinaryOperator.Equality); + BINARY_VALUABLE_OPERATOR.add(SQLBinaryOperator.GreaterThan); + BINARY_VALUABLE_OPERATOR.add(SQLBinaryOperator.LessThan); + BINARY_VALUABLE_OPERATOR.add(SQLBinaryOperator.GreaterThanOrEqual); + BINARY_VALUABLE_OPERATOR.add(SQLBinaryOperator.LessThanOrEqual); + } + + private final Operator druidOperator; + private Throwable ex; + private final List internalActions; + private Object obj; + + private VoidConsumer exAction; + + public SQLSupport(Operator druidOperator) { + this.druidOperator = druidOperator; + this.internalActions = Lists.newArrayList(); + } + + /** + * 基于{@link Operator}实体创建帮助类 + * + * @param druidOperator druidOperator + * @return DruidSQLSupport + */ + public static SQLSupport on(Operator druidOperator) { + return new SQLSupport(druidOperator); + } + + /** + * 目前支持的DB + */ + public static boolean isSupportDb(DbType dbType) { + return CURRENT_SUPPORT_DB.contains(dbType); + } + + /** + * 是否支持db + * + * @param dbType dbtype + * @return DruidSQLSupport + */ + public SQLSupport onDb(DbType dbType) { + this.internalActions.add(() -> { + boolean supportDb = isSupportDb(dbType); + if (!supportDb) { + this.ex = new DSLException(String.format("Operator %s nonsupport db type for %s", this.druidOperator.getClass().getName(), dbType)); + } + }); + return self(); + } + + public SQLSupport then(SupplierAction supplier) { + this.internalActions.add(() -> this.obj = supplier.get()); + return self(); + } + + public SQLSupport then(VoidConsumer action) { + this.internalActions.add(() -> action.accept(EMPTY)); + return self(); + } + + /** + * 当support 发生异常时回掉获取异常信息 + * + * @param action action + * @return DruidSQLSupport + */ + public SQLSupport onException(ConsumerAction action) { + this.exAction = () -> action.accept(ex); + return self(); + } + + /** + * 翻译{@link DBType}为druid的{@link DbType}类型 + * + * @param systemDb systemDb + * @return druid db + */ + public static DbType translateDb(DBType systemDb) { + return DruidDbTypeAdapter.getInstance().adapt(systemDb); + } + + /** + * 反译druid{@link DbType}为{@link DBType} + * + * @param druidDb druidDb + * @return DBType + */ + public static DBType reversalDb(DbType druidDb) { + return DruidDbTypeAdapter.getInstance().reverse(druidDb); + } + + /** + * 未支持,调用该action将会抛出异常 + * + * @param operateName operateName + * @return DruidSQLSupport + */ + public SQLSupport onNonsupport(String operateName) { + this.internalActions.add(() -> this.ex = nonsupportOperate(this.druidOperator, operateName)); + return self(); + } + + /** + * 未支持操作 + * + * @throws DSLException 构建信息并抛出该异常 + */ + public static DSLException nonsupportOperate(Operator druidOperator, String operateName) { + String message = String.format("Operator %s nonsupport %s operate", druidOperator.getClass().getName(), operateName); + return new DSLException(message); + } + + /** + * 启动 + * + * @return 由使用者提供 + * @throws DSLException 当action执行过程中发生异常则进行包装成{@link DSLException}返回 + */ + public T execute() { + for (VoidConsumer action : internalActions) { + if (ex != null) { + exAction.accept(ex); + return (T) new DSLException(ex); + } + try { + action.accept(EMPTY); + } catch (Throwable ex) { + this.ex = ex; + } + } + if (ex != null) { + return (T) new DSLException(ex); + } + return (T) obj; + } + + /** + * 判断{@link SQLExpr}是否是{@link com.alibaba.druid.sql.ast.SQLName},如果是则返回,否则返回null + * + * @param expr expr + * @return + */ + public static String getExprColumn(SQLExpr expr) { + if (isNameExpr(expr)) { + return ((SQLName) expr).getSimpleName(); + } + return expr.toString(); + } + + /** + * 判断{@link SQLExpr}是否是{@link SQLValuableExpr},如果是则返回,否则返回null + * + * @param expr expr + * @return + */ + public static Object getExprValue(SQLExpr expr) { + if (isValuableExpr(expr)) { + return ((SQLValuableExpr) expr).getValue(); + } + return null; + } + + /** + * 判断{@link SQLExpr}是否是{@link SQLBinaryOpExpr} + * + * @param expr + * @return + */ + public static boolean isBinaryExpr(SQLExpr expr) { + return SQLBinaryOpExpr.class.isAssignableFrom(expr.getClass()); + } + + /** + * 判断给定的expr是否是{@link com.alibaba.druid.sql.ast.expr.SQLBetweenExpr} + * + * @param expr expr + * @return + */ + public static boolean isBetweenExpr(SQLExpr expr) { + return SQLBetweenExpr.class.isAssignableFrom(expr.getClass()); + } + + /** + * 判断给定的expr是否是{@link com.alibaba.druid.sql.ast.expr.SQLInListExpr} + * + * @param expr expr + * @return + */ + public static boolean isInExpr(SQLExpr expr) { + return SQLInListExpr.class.isAssignableFrom(expr.getClass()); + } + + /** + * 判断给定的expr是否是{@link SQLExpr} + * + * @param expr expr + * @return + */ + public static boolean isNullExpr(SQLExpr expr) { + return SQLNullExpr.class.isAssignableFrom(expr.getClass()); + } + + /** + * 判断给定expr是否是{@link SQLName} + * + * @param expr expr + * @return + */ + public static boolean isNameExpr(SQLExpr expr) { + return SQLName.class.isAssignableFrom(expr.getClass()); + } + + /** + * 判断给定expr是否是{@link SQLValuableExpr} + * + * @param expr expr + * @return + */ + public static boolean isValuableExpr(SQLExpr expr) { + return SQLValuableExpr.class.isAssignableFrom(expr.getClass()); + } + + /** + * 判断给定的{@link SQLBinaryOperator}是否是值操作 + * + * @param binaryOperator binaryOperator + * @return + */ + public static boolean isBinaryValuableOperator(SQLBinaryOperator binaryOperator) { + return BINARY_VALUABLE_OPERATOR.contains(binaryOperator); + } + + /** + * 遍历{@link SQLBinaryOpExpr},存在如下情况进行回调: + *
      + *
    • 判断是否是值类型{@link #isBinaryValuableOperator(SQLBinaryOperator)},如果是则它的left结点是column expr,right结点是value expr
    • + *
    • 如果是{@link #isBetweenExpr(SQLExpr)}类型,则调用{@link #betweenTrigger(SQLBetweenExpr, LogicMode, TernaryConsumer)}转换并触发
    • + *
    • 如果是{@link #isInExpr(SQLExpr)}类型,则调用{@link #inTrigger(SQLInListExpr, LogicMode, TernaryConsumer)}转换并触发
    • + *
    • 如果是{@link #isNullExpr(SQLExpr)}类型,可以得到它是is null等语句
    • + *
    + * + * @param binaryOpExpr binaryOpExpr + * @param trigger 当满足上述条件时,进行回调,接受三个参数,一个是包装后的expr实例(增加{@link #PLACEHOLDER}的占位符),一个是LogicMode,另外一个是预处理的参数值类型 + */ + public static void binaryExprTraversal(SQLBinaryOpExpr binaryOpExpr, TernaryConsumer>> trigger) { + SQLExpr left = binaryOpExpr.getLeft(); + SQLExpr right = binaryOpExpr.getRight(); + if (isBinaryExpr(left)) { + binaryExprTraversal((SQLBinaryOpExpr) left, trigger); + } + if (isBinaryExpr(right)) { + binaryExprTraversal((SQLBinaryOpExpr) right, trigger); + } + SQLBinaryOperator operator = binaryOpExpr.getOperator(); + LogicMode mode = toMode(operator); + if (isBinaryValuableOperator(operator)) { + // 值类型 + String exprColumn = getExprColumn(left); + Object exprValue = getExprValue(right); + trigger.accept( + new SQLBinaryOpExpr(left, operator, PLACEHOLDER), + mode, + List.of(Tuples.of(exprColumn, exprValue))); + } else { + if (isBetweenExpr(left)) { + betweenTrigger((SQLBetweenExpr) left, mode, trigger); + } + if (isBetweenExpr(right)) { + betweenTrigger((SQLBetweenExpr) right, mode, trigger); + } + if (isInExpr(left)) { + inTrigger((SQLInListExpr) left, mode, trigger); + } + if (isInExpr(right)) { + inTrigger((SQLInListExpr) right, mode, trigger); + } + if (isNullExpr(right)) { + trigger.accept(new SQLBinaryOpExpr(left, operator, right), mode, Collections.emptyList()); + } + } + } + + /** + * between转换触发 + * + * @param betweenExpr betweenExpr + * @param trigger trigger + */ + private static void betweenTrigger(SQLBetweenExpr betweenExpr, LogicMode mode, TernaryConsumer>> trigger) { + SQLExpr testExpr = betweenExpr.getTestExpr(); + String exprColumn = getExprColumn(testExpr); + SQLExpr beginExpr = betweenExpr.getBeginExpr(); + Object beginValue = getExprValue(beginExpr); + Tuple2 begin = Tuples.of(exprColumn, beginValue); + SQLExpr endExpr = betweenExpr.getEndExpr(); + Object exprValue = getExprValue(endExpr); + Tuple2 end = Tuples.of(exprColumn, exprValue); + SQLBetweenExpr newBetweenExpr = new SQLBetweenExpr(testExpr, PLACEHOLDER, PLACEHOLDER); + newBetweenExpr.setNot(betweenExpr.isNot()); + trigger.accept( + newBetweenExpr, + mode, + List.of(begin, end)); + } + + /** + * in转换触发 + * + * @param inExpr inExpr + * @param trigger trigger + */ + private static void inTrigger(SQLInListExpr inExpr, LogicMode mode, TernaryConsumer>> trigger) { + SQLExpr expr = inExpr.getExpr(); + String exprColumn = getExprColumn(expr); + List targetList = inExpr.getTargetList(); + SQLInListExpr newInExpr = new SQLInListExpr(); + newInExpr.setExpr(expr); + newInExpr.setNot(inExpr.isNot()); + List> consumeResource = + targetList.stream() + .map(target -> { + newInExpr.addTarget(PLACEHOLDER); + Object exprValue = getExprValue(target); + return Tuples.of(exprColumn, exprValue); + }) + .toList(); + trigger.accept(newInExpr, mode, consumeResource); + } + + private static LogicMode toMode(SQLBinaryOperator operator) { + if (operator == SQLBinaryOperator.BooleanAnd) { + return LogicMode.AND; + } else if (operator == SQLBinaryOperator.BooleanOr) { + return LogicMode.OR; + } + return LogicMode.AND; + } + + /** + * 基于数据类型和值,生成{@code SQLValuableExpr}实例。遍历Java已有数据类型 + * + * @param dataType dataType + * @param value value + * @return SQLValuableExpr + */ + public static SQLValuableExpr newSQLValue(DataType dataType, Object value) { + DSLType sqlType = dataType.getDslType(); + if (DSLType.CHAR.equals(sqlType) + || DSLType.VARCHAR.equals(sqlType) + || DSLType.LONGNVARCHAR.equals(sqlType) + || DSLType.LONGVARCHAR.equals(sqlType) + || DSLType.LONGVARBINARY.equals(sqlType) + || DSLType.VARBINARY.equals(sqlType) + || DSLType.NVARCHAR.equals(sqlType)) { + return new SQLCharExpr(Types.parseString(value)); + } + if (DSLType.DATE.equals(sqlType)) { + return new SQLDateExpr(Types.parseDate(value)); + } + if (DSLType.TIME.equals(sqlType)) { + return new SQLTimeExpr(Types.parseDate(value), TimeZone.getDefault()); + } + if (DSLType.TIMESTAMP.equals(sqlType)) { + return new SQLTimestampExpr(Types.parseDate(value)); + } + if (DSLType.DECIMAL.equals(sqlType) || DSLType.NUMBER.equals(sqlType)) { + return new SQLDecimalExpr(Types.parseBigDecimal(value)); + } + if (DSLType.INTEGER.equals(sqlType)) { + return new SQLIntegerExpr(Types.getInteger(value)); + } + if (DSLType.TINYINT.equals(sqlType)) { + return new SQLTinyIntExpr(Types.parseByte(value)); + } + if (DSLType.SMALLINT.equals(sqlType)) { + return new SQLSmallIntExpr(Types.parseShort(value)); + } + if (DSLType.BIGINT.equals(sqlType)) { + return new SQLBigIntExpr(Types.parseLong(value)); + } + if (DSLType.FLOAT.equals(sqlType)) { + return new SQLFloatExpr(Types.parseFloat(value)); + } + if (DSLType.DOUBLE.equals(sqlType)) { + return new SQLDoubleExpr(Types.parseDouble(value)); + } + return new SQLNullExpr(); + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/UnoSQLExprTableSource.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/UnoSQLExprTableSource.java new file mode 100644 index 00000000..7ab6e2fe --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/UnoSQLExprTableSource.java @@ -0,0 +1,30 @@ +package cc.allio.uno.data.orm.dsl; + +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; + +/** + * 基于{@link SQLExprTableSource},拓展当设置schema,判断数据库类型决定是否设置 + * + * @author jiangwei + * @date 2024/1/5 16:15 + * @since 1.1.6 + */ +public class UnoSQLExprTableSource extends SQLExprTableSource { + + private final DbType dbType; + + public UnoSQLExprTableSource(DbType dbType) { + this.dbType = dbType; + } + + @Override + public void setSchema(String schema) { + if (dbType == null) { + super.setSchema(schema); + } + if (!(dbType == DbType.mysql || dbType == DbType.mariadb)) { + super.setSchema(schema); + } + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/DDLSQLSupport.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/DDLSQLSupport.java new file mode 100644 index 00000000..10e76641 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/DDLSQLSupport.java @@ -0,0 +1,85 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DataType; +import cc.allio.uno.data.orm.dsl.type.DruidDataTypeAdapter; +import cc.allio.uno.data.orm.dsl.type.DruidDbTypeAdapter; +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.expr.SQLValuableExpr; +import com.alibaba.druid.sql.ast.statement.*; + +/** + * 与DDL SQL相关的操作 + * + * @author jiangwei + * @date 2024/2/8 13:46 + * @since 1.1.6 + */ +public class DDLSQLSupport extends SQLSupport { + + public DDLSQLSupport(Operator druidOperator) { + super(druidOperator); + } + + /** + * 基于{@link Table}创建{@link SQLExprTableSource}实例 + * + * @param table table + * @return SQLExprTableSource + */ + public static SQLExprTableSource createTableSource(Table table, DBType dbType) { + var druidType = DruidDbTypeAdapter.getInstance().adapt(dbType); + SQLExprTableSource tableSource = new UnoSQLExprTableSource(druidType); + tableSource.setExpr(table.getName().getName()); + tableSource.setSchema(table.getSchema()); + tableSource.setCatalog(table.getCatalog()); + return tableSource; + } + + /** + * 基于{@link ColumnDef}创建{@link SQLColumnDefinition}实例 + * + * @param columnDef columnDef + * @param dbType dbType + * @return SQLColumnDefinition + */ + public static SQLColumnDefinition createColumnDefinition(ColumnDef columnDef, DBType dbType) { + var druidType = DruidDbTypeAdapter.getInstance().adapt(dbType); + SQLColumnDefinition sqlColumnDefinition = new SQLColumnDefinition(); + sqlColumnDefinition.setComment(columnDef.getComment()); + sqlColumnDefinition.setName(columnDef.getDslName().format()); + sqlColumnDefinition.setDbType(druidType); + DataType dataType = columnDef.getDataType(); + SQLDataType druidDataType = DruidDataTypeAdapter.getInstance(dbType).adapt(dataType); + if (druidType != null) { + druidDataType.setDbType(druidType); + sqlColumnDefinition.setDataType(druidDataType); + } + if (columnDef.isPk()) { + SQLColumnPrimaryKey sqlPrimaryKey = new SQLColumnPrimaryKey(); + sqlColumnDefinition.addConstraint(sqlPrimaryKey); + } + if (columnDef.isFk()) { + SQLColumnReference sqlColumnReference = new SQLColumnReference(); + sqlColumnDefinition.addConstraint(sqlColumnReference); + } + if (columnDef.isNull()) { + SQLNullConstraint sqlNullConstraint = new SQLNullConstraint(); + sqlColumnDefinition.addConstraint(sqlNullConstraint); + } + if (columnDef.isNonNull()) { + SQLNotNullConstraint sqlNotNullConstraint = new SQLNotNullConstraint(); + sqlColumnDefinition.addConstraint(sqlNotNullConstraint); + } + if (columnDef.isUnique()) { + SQLColumnUniqueKey sqlColumnUniqueKey = new SQLColumnUniqueKey(); + sqlColumnDefinition.addConstraint(sqlColumnUniqueKey); + } + if (columnDef.getDefaultValue() != null) { + SQLValuableExpr defaultValueExpr = SQLSupport.newSQLValue(dataType, columnDef.getDefaultValue()); + sqlColumnDefinition.setDefaultExpr(defaultValueExpr); + } + return sqlColumnDefinition; + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLAlterTableOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLAlterTableOperator.java new file mode 100644 index 00000000..2ccf30e7 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLAlterTableOperator.java @@ -0,0 +1,157 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.exception.DDLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DruidDataTypeAdapter; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLValuableExpr; +import com.alibaba.druid.sql.ast.statement.*; +import cc.allio.uno.data.orm.dsl.ddl.AlterTableOperator; + +import java.util.Collection; + +/** + * druid for modify xxxx structure + * + * @author jiangwei + * @date 2023/6/8 19:55 + * @since 1.1.4 + */ +@AutoService(AlterTableOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLAlterTableOperator implements AlterTableOperator { + + private SQLAlterTableStatement alterTableStatement; + private DBType dbType; + private DbType druidDbType; + private Table from; + + public SQLAlterTableOperator() { + this(DBType.getSystemDbType()); + } + + public SQLAlterTableOperator(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.alterTableStatement = new SQLAlterTableStatement(druidDbType); + } + + /** + * {@link com.alibaba.druid.sql.visitor.SQLASTOutputVisitor#visit(SQLAlterTableAlterColumn)} + */ + @Override + public String getDSL() { + if (from == null) { + throw new DDLException("alter table rename requirement 'from table', you can through #from invoke support 'from table'"); + } + String sql = SQLUtils.toSQLString(alterTableStatement); + if (DBType.POSTGRESQL == dbType) { + // 特殊处理,去除SQLASTOutputVisitor#visit(SQLAlterTableAlterColumn)的DATA TYPE,替换为TYPE + return sql.replace("SET DATA TYPE", "TYPE"); + } + return sql; + } + + @Override + public AlterTableOperator parse(String dsl) { + this.alterTableStatement = (SQLAlterTableStatement) SQLUtils.parseSingleStatement(dsl, druidDbType); + return self(); + } + + @Override + public void reset() { + this.alterTableStatement = new SQLAlterTableStatement(druidDbType); + this.from = null; + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.alterTableStatement.setDbType(this.druidDbType); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public AlterTableOperator alertColumns(Collection columnDefs) { + for (ColumnDef columnDef : columnDefs) { + SQLColumnDefinition columnDefinition = new SQLColumnDefinition(); + columnDefinition.setComment(columnDef.getComment()); + columnDefinition.setName(columnDef.getDslName().format()); + columnDefinition.setDbType(druidDbType); + if (columnDef.getDataType() != null) { + SQLAlterTableAlterColumn alterTableAlterColumn = new SQLAlterTableAlterColumn(); + SQLDataType druidDataType = DruidDataTypeAdapter.getInstance(dbType).adapt(columnDef.getDataType()); + alterTableAlterColumn.setDataType(druidDataType); + alterTableAlterColumn.setColumn(columnDefinition); + this.alterTableStatement.addItem(alterTableAlterColumn); + } + if (columnDef.isNonNull()) { + SQLAlterTableAlterColumn alterTableAlterColumn = new SQLAlterTableAlterColumn(); + alterTableAlterColumn.setSetNotNull(true); + alterTableAlterColumn.setColumn(columnDefinition); + this.alterTableStatement.addItem(alterTableAlterColumn); + } + if (columnDef.getDefaultValue() != null && columnDef.getDataType() != null) { + SQLValuableExpr defaultValueExpr = SQLSupport.newSQLValue(columnDef.getDataType(), columnDef.getDefaultValue()); + SQLAlterTableAlterColumn alterTableAlterColumn = new SQLAlterTableAlterColumn(); + alterTableAlterColumn.setSetDefault(defaultValueExpr); + alterTableAlterColumn.setColumn(columnDefinition); + this.alterTableStatement.addItem(alterTableAlterColumn); + } + } + return self(); + } + + @Override + public AlterTableOperator addColumns(Collection columnDefs) { + for (ColumnDef columnDef : columnDefs) { + SQLAlterTableAddColumn alterTableAddColumn = new SQLAlterTableAddColumn(); + alterTableAddColumn.toString(); + SQLColumnDefinition columnDefinition = DDLSQLSupport.createColumnDefinition(columnDef, dbType); + alterTableAddColumn.addColumn(columnDefinition); + this.alterTableStatement.addItem(alterTableAddColumn); + } + return self(); + } + + @Override + public AlterTableOperator deleteColumns(Collection columns) { + SQLAlterTableDropColumnItem dropColumnItem = new SQLAlterTableDropColumnItem(); + for (DSLName column : columns) { + dropColumnItem.addColumn(new SQLIdentifierExpr(column.format())); + } + this.alterTableStatement.addItem(dropColumnItem); + return self(); + } + + @Override + public AlterTableOperator rename(Table to) { + SQLAlterTableRename alterTableRename = new SQLAlterTableRename(); + alterTableRename.setTo(new SQLIdentifierExpr(to.getName().format())); + this.alterTableStatement.addItem(alterTableRename); + return self(); + } + + @Override + public AlterTableOperator from(Table table) { + this.from = table; + SQLExprTableSource tableSource = DDLSQLSupport.createTableSource(table, dbType); + this.alterTableStatement.setTableSource(tableSource); + return self(); + } + + @Override + public Table getTable() { + return from; + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLCreateTableOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLCreateTableOperator.java new file mode 100644 index 00000000..c3005d6a --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLCreateTableOperator.java @@ -0,0 +1,105 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DruidDbTypeAdapter; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.statement.*; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateTableStatement; +import cc.allio.uno.data.orm.dsl.ddl.CreateTableOperator; + +/** + * 基于Druid registry operator + * + * @author jiangwei + * @date 2023/4/12 19:45 + * @since 1.1.4 + */ +@AutoService(CreateTableOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLCreateTableOperator implements CreateTableOperator { + + private DBType dbType; + private DbType druidType; + private Table table; + private SQLCreateTableStatement createTableStatement; + + public SQLCreateTableOperator() { + this(DBType.getSystemDbType()); + } + + public SQLCreateTableOperator(DBType dbType) { + this.dbType = dbType; + this.druidType = SQLSupport.translateDb(dbType); + this.createTableStatement = + switch (druidType) { + case DbType.mysql -> new MySqlCreateTableStatement(); + case DbType.oracle -> new OracleCreateTableStatement(); + default -> new SQLCreateTableStatement(); + }; + } + + @Override + public String getDSL() { + return SQLUtils.toSQLString(createTableStatement); + } + + @Override + public CreateTableOperator parse(String dsl) { + this.createTableStatement = (SQLCreateTableStatement) SQLUtils.parseSingleStatement(dsl, druidType); + return self(); + } + + @Override + public void reset() { + // eachReset + this.createTableStatement = new SQLCreateTableStatement(druidType); + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidType = DruidDbTypeAdapter.getInstance().adapt(dbType); + this.createTableStatement.setDbType(this.druidType); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public CreateTableOperator from(String table) { + return from(Table.of(table)); + } + + @Override + public CreateTableOperator from(Table table) { + this.table = table; + SQLExprTableSource tableSource = DDLSQLSupport.createTableSource(table, dbType); + createTableStatement.setTableSource(tableSource); + return self(); + } + + @Override + public Table getTable() { + return table; + } + + @Override + public CreateTableOperator column(ColumnDef columnDef) { + SQLColumnDefinition columnDefinition = DDLSQLSupport.createColumnDefinition(columnDef, dbType); + createTableStatement.addColumn(columnDefinition); + return self(); + } + + @Override + public CreateTableOperator comment(String comment) { + createTableStatement.setComment(new SQLIdentifierExpr(comment)); + return self(); + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLDropTableOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLDropTableOperator.java new file mode 100644 index 00000000..b30727f5 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLDropTableOperator.java @@ -0,0 +1,89 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import cc.allio.uno.data.orm.dsl.ddl.DropTableOperator; + +/** + * DruidSQLDropTableOperator + * + * @author jiangwei + * @date 2023/4/16 13:02 + * @since 1.1.4 + */ +@AutoService(DropTableOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLDropTableOperator implements DropTableOperator { + + private DBType dbType; + private DbType druidDbType; + private Table table; + private SQLDropTableStatement dropTableStatement; + + public SQLDropTableOperator() { + this(DBType.getSystemDbType()); + } + + public SQLDropTableOperator(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.dropTableStatement = new SQLDropTableStatement(); + this.dropTableStatement.setDbType(druidDbType); + } + + @Override + public String getDSL() { + return SQLUtils.toSQLString(dropTableStatement); + } + + @Override + public DropTableOperator parse(String dsl) { + return null; + } + + @Override + public void reset() { + // eachReset + this.dropTableStatement = new SQLDropTableStatement(); + this.dropTableStatement.setDbType(druidDbType); + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.dropTableStatement.setDbType(this.druidDbType); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public DropTableOperator from(Table table) { + SQLExprTableSource tableSource = new UnoSQLExprTableSource(druidDbType); + tableSource.setExpr(table.getName().getName()); + tableSource.setSchema(table.getSchema()); + tableSource.setCatalog(table.getCatalog()); + this.table = table; + dropTableStatement.addTableSource(tableSource); + return self(); + } + + @Override + public Table getTable() { + return table; + } + + @Override + public DropTableOperator ifExist(Boolean ifExist) { + dropTableStatement.setIfExists(ifExist); + return self(); + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLExistTableOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLExistTableOperator.java new file mode 100644 index 00000000..3a9395a6 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLExistTableOperator.java @@ -0,0 +1,102 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.alibaba.druid.DbType; +import cc.allio.uno.data.orm.dsl.ddl.ExistTableOperator; + +import java.util.List; + +/** + * druid + * + * @author jiangwei + * @date 2023/4/17 09:47 + * @since 1.1.4 + */ +@AutoService(ExistTableOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLExistTableOperator extends PrepareOperatorImpl implements ExistTableOperator { + + private DBType dbType; + private DbType druidDbType; + private Table table; + private final QueryOperator queryOperator; + + public SQLExistTableOperator() { + this(DBType.getSystemDbType()); + } + + public SQLExistTableOperator(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.queryOperator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL, dbType); + } + + @Override + public String getDSL() { + return queryOperator.getDSL(); + } + + @Override + public ExistTableOperator parse(String dsl) { + throw SQLSupport.on(this).onNonsupport("parse").execute(); + } + + @Override + public String getPrepareDSL() { + return queryOperator.getPrepareDSL(); + } + + @Override + public ExistTableOperator from(Table table) { + Object obj = SQLSupport.on(this) + .onDb(druidDbType) + .then(() -> + queryOperator.count() + .from("INFORMATION_SCHEMA.TABLES") + .$like$("TABLE_NAME", table.getName().format())) + .execute(); + if (obj instanceof DSLException ex) { + throw ex; + } + this.table = table; + return self(); + } + + @Override + public Table getTable() { + return table; + } + + @Override + protected void addPrepareValue(String column, Object value) { + throw SQLSupport.on(this).onNonsupport("addPrepareValue").execute(); + } + + @Override + public List getPrepareValues() { + return queryOperator.getPrepareValues(); + } + + @Override + public void reset() { + super.reset(); + queryOperator.reset(); + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.queryOperator.setDBType(dbType); + } + + @Override + public DBType getDBType() { + return dbType; + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowColumnsOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowColumnsOperator.java new file mode 100644 index 00000000..60b2515e --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowColumnsOperator.java @@ -0,0 +1,150 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.alibaba.druid.DbType; +import cc.allio.uno.data.orm.dsl.ddl.ShowColumnsOperator; + +import java.util.List; + +/** + * 表结构 + * + * @author jiangwei + * @date 2023/6/8 19:20 + * @since 1.1.4 + */ +@AutoService(ShowColumnsOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLShowColumnsOperator extends PrepareOperatorImpl implements ShowColumnsOperator { + + private DBType dbType; + private DbType druidDbType; + private Table table; + private Database database; + private final QueryOperator queryOperator; + + public SQLShowColumnsOperator() { + this(DBType.getSystemDbType()); + } + + public SQLShowColumnsOperator(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.queryOperator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL, dbType); + } + + @Override + public String getDSL() { + return SQLSupport.on(this) + .onDb(druidDbType) + .then(queryOperator::getDSL) + .execute(); + } + + @Override + public ShowColumnsOperator parse(String dsl) { + throw SQLSupport.on(this).onNonsupport("parse").execute(); + } + + @Override + public String getPrepareDSL() { + throw SQLSupport.on(this).onNonsupport("getPrepareDSL").execute(); + } + + @Override + public List getPrepareValues() { + throw SQLSupport.on(this).onNonsupport("getPrepareValues").execute(); + } + + @Override + public void reset() { + super.reset(); + queryOperator.reset(); + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.queryOperator.setDBType(dbType); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public ShowColumnsOperator from(Table table) { + Object result = SQLSupport.on(this) + .onDb(druidDbType) + .then(queryOperator::reset) + .then(() -> { + queryOperator.selectAll() + .select(DSLName.of(TABLE_CATALOG_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(TABLE_SCHEMA_FILED, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(TABLE_NAME_FILED, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(COLUMN_NAME_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(ORDINAL_POSITION_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(COLUMN_DEFAULT_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(IS_NULLABLE_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(DATA_TYPE_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(CHARACTER_MAXIMUM_LENGTH_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(CHARACTER_OCTET_LENGTH_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(NUMERIC_PRECISION_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(NUMERIC_SCALE_FIELD, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(DATETIME_PRECISION_FIELD, DSLName.PLAIN_FEATURE)); + switch (druidDbType) { + case DbType.mysql -> { + Table systemTable = Table.of(DSLName.of("INFORMATION_SCHEMA.COLUMNS", DSLName.PLAIN_FEATURE)).setSchema(null); + queryOperator.from(systemTable) + .eq(DSLName.of(TABLE_NAME_FILED, DSLName.PLAIN_FEATURE), table.getName().format()); + if (database != null) { + queryOperator.eq(DSLName.of(TABLE_SCHEMA_FILED, DSLName.PLAIN_FEATURE), database.getName()); + } + } + case DbType.h2, DbType.postgresql -> { + Table systemTable = Table.of(DSLName.of("INFORMATION_SCHEMA.COLUMNS", DSLName.PLAIN_FEATURE)).setSchema(null); + queryOperator + .from(systemTable) + .eq(DSLName.of("TABLE_NAME", DSLName.PLAIN_FEATURE), table.getName().format()); + } + case DbType.db2 -> { + Table systemTable = Table.of(DSLName.of("SYSCAT.COLUMNS", DSLName.PLAIN_FEATURE)).setSchema(null); + queryOperator + .from(systemTable) + .eq(DSLName.of("TABNAME", DSLName.PLAIN_FEATURE), table.getName().format()); + } + } + }) + .execute(); + if (result instanceof DSLException err) { + throw err; + } + this.table = table; + return self(); + } + + @Override + public Table getTable() { + return table; + } + + @Override + public QueryOperator toQueryOperator() { + return SQLSupport.on(this) + .onDb(druidDbType) + .then(() -> queryOperator) + .execute(); + } + + @Override + public ShowColumnsOperator database(Database database) { + this.database = database; + return self(); + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowTablesOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowTablesOperator.java new file mode 100644 index 00000000..5e8fe1fd --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowTablesOperator.java @@ -0,0 +1,140 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.util.CollectionUtils; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.ddl.ShowTablesOperator; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.alibaba.druid.DbType; +import com.google.common.collect.Lists; + +import java.util.List; + +@AutoService(ShowTablesOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLShowTablesOperator extends PrepareOperatorImpl implements ShowTablesOperator { + + private DBType dbType; + private DbType druidDbType; + private String schema; + private Database database; + private List
    tables; + private QueryOperator queryOperator; + + public SQLShowTablesOperator() { + this(DBType.getSystemDbType()); + } + + public SQLShowTablesOperator(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.queryOperator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL, dbType); + this.schema = "PUBLIC"; + this.tables = Lists.newArrayList(); + } + + @Override + public String getDSL() { + trigger(); + return queryOperator.getDSL(); + } + + @Override + public ShowTablesOperator parse(String dsl) { + this.queryOperator = queryOperator.parse(dsl); + return self(); + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.queryOperator.setDBType(this.dbType); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public String getPrepareDSL() { + throw SQLSupport.nonsupportOperate(this, "getPrepareDSL"); + } + + @Override + public QueryOperator toQueryOperator() { + trigger(); + return queryOperator; + } + + @Override + public ShowTablesOperator database(Database database) { + this.database = database; + return self(); + } + + @Override + public ShowTablesOperator schema(String schema) { + this.schema = schema; + return self(); + } + + private void trigger() { + Table formTable = Table.of(DSLName.of("INFORMATION_SCHEMA.TABLES", DSLName.PLAIN_FEATURE)).setSchema(null); + Object result = SQLSupport.on(this) + .onDb(druidDbType) + .then(() -> { + switch (druidDbType) { + case DbType.mysql -> + queryOperator.select(DSLName.of(ShowTablesOperator.TABLE_CATALOG_FILED, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(ShowTablesOperator.TABLE_SCHEMA_FILED, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(ShowTablesOperator.TABLE_NAME_FILED, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(ShowTablesOperator.TABLE_TYPE_FILED, DSLName.PLAIN_FEATURE)) + .from(formTable) + .eq(DSLName.of(ShowTablesOperator.TABLE_SCHEMA_FILED, DSLName.PLAIN_FEATURE), database.getName().format()) + .and() + .eq(DSLName.of(ShowTablesOperator.TABLE_TYPE_FILED, DSLName.PLAIN_FEATURE), "BASE TABLE"); + case DbType.h2, DbType.postgresql -> { + queryOperator.select(DSLName.of(ShowTablesOperator.TABLE_CATALOG_FILED, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(ShowTablesOperator.TABLE_SCHEMA_FILED, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(ShowTablesOperator.TABLE_NAME_FILED, DSLName.PLAIN_FEATURE)) + .select(DSLName.of(ShowTablesOperator.TABLE_TYPE_FILED, DSLName.PLAIN_FEATURE)) + .from(formTable) + .eq(DSLName.of(ShowTablesOperator.TABLE_TYPE_FILED, DSLName.PLAIN_FEATURE), "BASE TABLE"); + if (DbType.h2 == druidDbType) { + queryOperator.eq(DSLName.of(ShowTablesOperator.TABLE_SCHEMA_FILED, DSLName.PLAIN_FEATURE), schema); + } else if (DbType.postgresql == druidDbType) { + queryOperator.eq(DSLName.of(ShowTablesOperator.TABLE_SCHEMA_FILED, DSLName.PLAIN_FEATURE), schema.toLowerCase()); + } + } + } + if (CollectionUtils.isNotEmpty(tables)) { + if (tables.size() == 1) { + queryOperator.eq(DSLName.of(ShowTablesOperator.TABLE_NAME_FILED, DSLName.PLAIN_FEATURE), tables.get(0).getName().format()); + } else { + List tableNames = tables.stream().map(Table::getName).map(DSLName::format).toList(); + queryOperator.in(DSLName.of(ShowTablesOperator.TABLE_NAME_FILED, DSLName.PLAIN_FEATURE), tableNames); + } + } + }) + .execute(); + if (result instanceof DSLException err) { + throw err; + } + } + + @Override + public ShowTablesOperator from(Table table) { + this.tables.add(table); + return self(); + } + + @Override + public Table getTable() { + throw SQLSupport.nonsupportOperate(this, "getTable"); + } + +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/H2TypeTranslator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/H2TypeTranslator.java new file mode 100644 index 00000000..d94fb0e6 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/H2TypeTranslator.java @@ -0,0 +1,32 @@ +package cc.allio.uno.data.orm.dsl.dialect; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.dialect.type.H2SQLTypeDelegate; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DSLType; + +/** + * h2 + * + * @author jiangwei + * @date 2024/1/8 19:50 + * @since 1.1.6 + */ +@AutoService(TypeTranslator.class) +public class H2TypeTranslator implements TypeTranslator { + + @Override + public DSLType translate(DSLType dslType) { + return new H2SQLTypeDelegate(dslType); + } + + @Override + public DSLType translate(DSLType dslType, Integer precision, Integer scale) { + return new H2SQLTypeDelegate(dslType, precision, scale); + } + + @Override + public DBType getDBType() { + return DBType.H2; + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/MySQLTypeTranslator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/MySQLTypeTranslator.java new file mode 100644 index 00000000..9d86e3ce --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/MySQLTypeTranslator.java @@ -0,0 +1,25 @@ +package cc.allio.uno.data.orm.dsl.dialect; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.dialect.type.MySQLTypeDelegate; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DSLType; + +@AutoService(TypeTranslator.class) +public class MySQLTypeTranslator implements TypeTranslator { + + @Override + public DSLType translate(DSLType dslType) { + return new MySQLTypeDelegate(dslType); + } + + @Override + public DSLType translate(DSLType dslType, Integer precision, Integer scale) { + return new MySQLTypeDelegate(dslType, precision, scale); + } + + @Override + public DBType getDBType() { + return DBType.MYSQL; + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/PostgreSQLTypeTranslator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/PostgreSQLTypeTranslator.java new file mode 100644 index 00000000..d13e5f3d --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/PostgreSQLTypeTranslator.java @@ -0,0 +1,38 @@ +package cc.allio.uno.data.orm.dsl.dialect; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.dialect.type.PostgreSQLTypeDelegate; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DSLType; + +@AutoService(TypeTranslator.class) +public class PostgreSQLTypeTranslator implements TypeTranslator { + + @Override + public DSLType translate(DSLType dslType) { + return new PostgreSQLTypeDelegate(dslType); + } + + @Override + public DSLType translate(DSLType dslType, Integer precision, Integer scale) { + return new PostgreSQLTypeDelegate(dslType, precision, scale); + } + + @Override + public DSLType reserve(String dslTypeName) { + DSLType dslType = TypeTranslator.super.reserve(dslTypeName); + if (dslType == null) { + for (PostgreSQLTypeDelegate.PostgreSQLLinkType type : PostgreSQLTypeDelegate.PostgreSQLLinkType.values()) { + if (type.getName().equalsIgnoreCase(dslTypeName)) { + return DSLType.create(type, null, null); + } + } + } + return dslType; + } + + @Override + public DBType getDBType() { + return DBType.POSTGRESQL; + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/DSLTypeDelegate.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/DSLTypeDelegate.java new file mode 100644 index 00000000..6d265dea --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/DSLTypeDelegate.java @@ -0,0 +1,66 @@ +package cc.allio.uno.data.orm.dsl.dialect.type; + +import cc.allio.uno.data.orm.dsl.type.DSLType; + +import java.util.List; + +/** + * 内置DSLType基类,实现通用的方法 + * + * @author jiangwei + * @date 2024/2/1 19:56 + * @since 1.1.6 + */ +public abstract class DSLTypeDelegate implements DSLType { + + protected final DSLType sqlType; + + protected DSLTypeDelegate(DSLType sqlType) { + this(sqlType, null, null); + } + + protected DSLTypeDelegate(DSLType sqlType, Integer precision, Integer scale) { + DSLType dslType = null; + for (DSLLinkType linkType : getDSLLinkValues()) { + List parent = linkType.getParent(); + if (parent.stream().anyMatch(p -> p.getName().equals(sqlType.getName()))) { + dslType = linkType; + // 优先取link的定义 + precision = dslType.getPrecision(); + scale = dslType.getScale(); + break; + } + } + if (dslType == null) { + dslType = sqlType; + } + this.sqlType = DSLType.create(dslType, precision, scale); + } + + @Override + public String getName() { + return sqlType.getName(); + } + + @Override + public int getJdbcType() { + return sqlType.getJdbcType(); + } + + @Override + public Integer getPrecision() { + return sqlType.getPrecision(); + } + + @Override + public Integer getScale() { + return sqlType.getScale(); + } + + /** + * 子类实现,获取{@link cc.allio.uno.data.orm.dsl.type.DSLType.DSLLinkType}数组,得到某个{@link cc.allio.uno.data.orm.dsl.type.DSLType.DefaultDSLType}关联到不同数据实例的数据类型 + * + * @return values + */ + protected abstract DSLLinkType[] getDSLLinkValues(); +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/H2SQLTypeDelegate.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/H2SQLTypeDelegate.java new file mode 100644 index 00000000..aaf829e5 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/H2SQLTypeDelegate.java @@ -0,0 +1,48 @@ +package cc.allio.uno.data.orm.dsl.dialect.type; + +import cc.allio.uno.data.orm.dsl.type.DSLType; +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.sql.Types; +import java.util.List; + +/** + * h2数据库字段类型二次转换 + * + * @author jiangwei + * @date 2024/1/8 19:42 + * @since 1.1.6 + */ +public class H2SQLTypeDelegate extends DSLTypeDelegate { + + public H2SQLTypeDelegate(DSLType sqlType) { + super(sqlType); + } + + public H2SQLTypeDelegate(DSLType sqlType, Integer precision, Integer scale) { + super(sqlType, precision, scale); + } + + @Override + protected DSLLinkType[] getDSLLinkValues() { + return H2LinkType.values(); + } + + @Getter + @AllArgsConstructor + public enum H2LinkType implements DSLLinkType { + H2_BIGINT("bigint", Types.BIGINT, null, null, Lists.newArrayList(DSLType.BIGINT)), + H2_INT("int", Types.INTEGER, null, null, Lists.newArrayList(DSLType.INTEGER)), + H2_SMALLINT("smallint", Types.SMALLINT, null, null, Lists.newArrayList(DSLType.SMALLINT)), + H2_TINYINT("tinyint", Types.SMALLINT, null, null, Lists.newArrayList(DSLType.TINYINT)), + NUMERIC("numeric", Types.DOUBLE, 12, 2, Lists.newArrayList(DSLType.DOUBLE, DSLType.NUMBER)); + + private final String name; + private final int jdbcType; + private final Integer precision; + private final Integer scale; + private final List parent; + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/MySQLTypeDelegate.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/MySQLTypeDelegate.java new file mode 100644 index 00000000..c7b772ba --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/MySQLTypeDelegate.java @@ -0,0 +1,43 @@ +package cc.allio.uno.data.orm.dsl.dialect.type; + +import cc.allio.uno.data.orm.dsl.type.DSLType; + +/** + * 对mysql库字段进行处理 + * + * @author jiangwei + * @date 2023/4/18 11:15 + * @since 1.1.4 + */ +public class MySQLTypeDelegate implements DSLType { + + private final DSLType sqlType; + + public MySQLTypeDelegate(DSLType sqlType) { + this(sqlType, null, null); + } + + public MySQLTypeDelegate(DSLType sqlType, Integer precision, Integer scale) { + this.sqlType = DSLType.create(sqlType, precision, scale); + } + + @Override + public String getName() { + return sqlType.getName(); + } + + @Override + public int getJdbcType() { + return sqlType.getJdbcType(); + } + + @Override + public Integer getPrecision() { + return sqlType.getPrecision(); + } + + @Override + public Integer getScale() { + return sqlType.getScale(); + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/PostgreSQLTypeDelegate.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/PostgreSQLTypeDelegate.java new file mode 100644 index 00000000..c5cbbb03 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dialect/type/PostgreSQLTypeDelegate.java @@ -0,0 +1,48 @@ +package cc.allio.uno.data.orm.dsl.dialect.type; + +import cc.allio.uno.data.orm.dsl.type.DSLType; +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.sql.Types; +import java.util.List; + +/** + * 对pg库的字段类型进行处理 + * + * @author jiangwei + * @date 2023/4/18 11:14 + * @since 1.1.4 + */ +public class PostgreSQLTypeDelegate extends DSLTypeDelegate { + + public PostgreSQLTypeDelegate(DSLType sqlType) { + super(sqlType); + } + + public PostgreSQLTypeDelegate(DSLType sqlType, Integer precision, Integer scale) { + super(sqlType, precision, scale); + } + + @Override + protected DSLLinkType[] getDSLLinkValues() { + return PostgreSQLLinkType.values(); + } + + @Getter + @AllArgsConstructor + public enum PostgreSQLLinkType implements DSLLinkType { + INT8("int8", Types.BIGINT, null, null, Lists.newArrayList(DSLType.BIGINT)), + FLOAT("float8", Types.FLOAT, 12, 2, Lists.newArrayList(DSLType.FLOAT)), + NUMERIC("numeric", Types.DOUBLE, 12, 2, Lists.newArrayList(DSLType.DOUBLE, DSLType.NUMBER)), + INT4("int4", Types.INTEGER, null, null, Lists.newArrayList(DSLType.INTEGER)), + INT2("int2", Types.INTEGER, null, null, Lists.newArrayList(DSLType.SMALLINT)); + + private final String name; + private final int jdbcType; + private final Integer precision; + private final Integer scale; + private final List parent; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidJoinTypeAdapter.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/DruidJoinTypeAdapter.java similarity index 68% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidJoinTypeAdapter.java rename to uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/DruidJoinTypeAdapter.java index 0efa285d..faf99885 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidJoinTypeAdapter.java +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/DruidJoinTypeAdapter.java @@ -1,8 +1,8 @@ -package cc.allio.uno.data.orm.sql.dml.druid; +package cc.allio.uno.data.orm.dsl.dml.sql; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; -import cc.allio.uno.data.orm.sql.JoinType; -import cc.allio.uno.data.orm.sql.JoinTypeAdapter; +import cc.allio.uno.data.orm.dsl.JoinType; +import cc.allio.uno.data.orm.dsl.JoinTypeAdapter; /** * DruidJoinTypeAdapter @@ -11,11 +11,15 @@ * @date 2023/4/13 13:25 * @since 1.1.4 */ -public class DruidJoinTypeAdapter implements JoinTypeAdapter { +public final class DruidJoinTypeAdapter implements JoinTypeAdapter { private static final DruidJoinTypeAdapter INSTANCE = new DruidJoinTypeAdapter(); + public static DruidJoinTypeAdapter getInstance() { + return INSTANCE; + } + @Override - public SQLJoinTableSource.JoinType get(JoinType o) { + public SQLJoinTableSource.JoinType adapt(JoinType o) { for (SQLJoinTableSource.JoinType joinType : SQLJoinTableSource.JoinType.values()) { if (joinType.name.equals(o.name)) { return joinType; @@ -25,7 +29,7 @@ public SQLJoinTableSource.JoinType get(JoinType o) { } @Override - public JoinType reversal(SQLJoinTableSource.JoinType joinType) { + public JoinType reverse(SQLJoinTableSource.JoinType joinType) { for (JoinType value : JoinType.values()) { if (value.name.equals(joinType.name)) { return value; @@ -33,9 +37,4 @@ public JoinType reversal(SQLJoinTableSource.JoinType joinType) { } return null; } - - public static DruidJoinTypeAdapter getInstance() { - return INSTANCE; - } - } diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidTokenOperatorAdapter.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/DruidTokenOperatorAdapter.java similarity index 70% rename from uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidTokenOperatorAdapter.java rename to uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/DruidTokenOperatorAdapter.java index 64e1d7cb..1e457ade 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/sql/dml/druid/DruidTokenOperatorAdapter.java +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/DruidTokenOperatorAdapter.java @@ -1,8 +1,8 @@ -package cc.allio.uno.data.orm.sql.dml.druid; +package cc.allio.uno.data.orm.dsl.dml.sql; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; -import cc.allio.uno.data.orm.sql.TokenOperator; -import cc.allio.uno.data.orm.sql.TokenOperatorAdapter; +import cc.allio.uno.data.orm.dsl.TokenOperator; +import cc.allio.uno.data.orm.dsl.TokenOperatorAdapter; /** * BinaryOperator @@ -14,8 +14,12 @@ public class DruidTokenOperatorAdapter implements TokenOperatorAdapter { private static final DruidTokenOperatorAdapter INSTANCE = new DruidTokenOperatorAdapter(); + public static DruidTokenOperatorAdapter getInstance() { + return INSTANCE; + } + @Override - public SQLBinaryOperator get(TokenOperator o) { + public SQLBinaryOperator adapt(TokenOperator o) { for (SQLBinaryOperator operator : SQLBinaryOperator.values()) { if (operator.getName().equals(o.getName())) { return operator; @@ -25,16 +29,12 @@ public SQLBinaryOperator get(TokenOperator o) { } @Override - public TokenOperator reversal(SQLBinaryOperator sqlBinaryOperator) { + public TokenOperator reverse(SQLBinaryOperator binaryOperator) { for (TokenOperator value : TokenOperator.values()) { - if (value.getName().equals(sqlBinaryOperator.name)) { + if (value.getName().equals(binaryOperator.name)) { return value; } } return null; } - - public static DruidTokenOperatorAdapter getInstance() { - return INSTANCE; - } } diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLDeleteOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLDeleteOperator.java new file mode 100644 index 00000000..5ae9995b --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLDeleteOperator.java @@ -0,0 +1,129 @@ +package cc.allio.uno.data.orm.dsl.dml.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.expr.*; +import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import cc.allio.uno.data.orm.dsl.dml.DeleteOperator; +import reactor.util.function.Tuple2; + +import java.util.function.Consumer; + +/** + * DruidSQLDeleteQueryOperator + * + * @author jiangwei + * @date 2023/4/16 18:43 + * @since 1.1.4 + */ +@AutoService(DeleteOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLDeleteOperator extends SQLWhereOperatorImpl implements DeleteOperator { + + private DBType dbType; + private DbType druidDbType; + private Table table; + private SQLDeleteStatement deleteStatement; + + public SQLDeleteOperator() { + this(DBType.getSystemDbType()); + } + + public SQLDeleteOperator(DBType dbType) { + super(); + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.deleteStatement = new SQLDeleteStatement(); + deleteStatement.setDbType(druidDbType); + } + + @Override + public String getDSL() { + return ParameterizedOutputVisitorUtils.restore( + getPrepareDSL(), + druidDbType, + getPrepareValues().stream().map(PrepareValue::getValue).toList()); + + } + + @Override + public DeleteOperator parse(String dsl) { + this.deleteStatement = (SQLDeleteStatement) SQLUtils.parseSingleStatement(dsl, druidDbType); + SQLExpr where = this.deleteStatement.getWhere(); + if (SQLSupport.isBinaryExpr(where)) { + this.deleteStatement.setWhere(null); + SQLSupport.binaryExprTraversal( + (SQLBinaryOpExpr) where, + (newExpr, mode, prepareValues) -> { + switchMode(mode); + appendAndSetWhere(newExpr); + for (Tuple2 prepareValue : prepareValues) { + addPrepareValue(prepareValue.getT1(), prepareValue.getT2()); + } + }); + } + return self(); + } + + @Override + public void reset() { + super.reset(); + this.deleteStatement = new SQLDeleteStatement(); + deleteStatement.setDbType(druidDbType); + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.deleteStatement.setDbType(this.druidDbType); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public String getPrepareDSL() { + return SQLUtils.toSQLString(deleteStatement); + } + + @Override + public DeleteOperator from(Table table) { + SQLExprTableSource tableSource = new UnoSQLExprTableSource(druidDbType); + tableSource.setExpr(new SQLIdentifierExpr(table.getName().format())); + tableSource.setCatalog(table.getCatalog()); + tableSource.setSchema(table.getSchema()); + this.table = table; + deleteStatement.setTableSource(tableSource); + return self(); + } + + @Override + public Table getTable() { + return table; + } + + @Override + protected DbType getDruidType() { + return druidDbType; + } + + @Override + protected SQLObject getSQLObject() { + return deleteStatement; + } + + @Override + protected Consumer getSetWhere() { + return where -> deleteStatement.setWhere(where); + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLInsertOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLInsertOperator.java new file mode 100644 index 00000000..52ce978c --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLInsertOperator.java @@ -0,0 +1,222 @@ +package cc.allio.uno.data.orm.dsl.dml.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.bean.ValueWrapper; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import cc.allio.uno.core.StringPool; +import cc.allio.uno.data.orm.dsl.dml.InsertOperator; + +import java.util.*; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * Druid INSERT + * + * @author jiangwei + * @date 2023/4/13 16:25 + * @since 1.1.4 + */ +@AutoService(InsertOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLInsertOperator extends PrepareOperatorImpl implements InsertOperator { + + private DBType dbType; + private DbType druidDbType; + private SQLInsertStatement insertStatement; + // 暂存于已经添加过的column + private final ArrayList columns; + private Table table; + + public SQLInsertOperator() { + this(DBType.getSystemDbType()); + } + + public SQLInsertOperator(DBType dbType) { + super(); + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.insertStatement = new SQLInsertStatement(); + this.insertStatement.setDbType(druidDbType); + this.columns = new ArrayList<>(); + } + + @Override + public String getDSL() { + return ParameterizedOutputVisitorUtils.restore( + getPrepareDSL(), + druidDbType, + getPrepareValues().stream().map(PrepareValue::getValue).collect(Collectors.toList())); + } + + @Override + public InsertOperator parse(String dsl) { + this.insertStatement = (SQLInsertStatement) SQLUtils.parseSingleStatement(dsl, druidDbType); + List columns = insertStatement.getColumns(); + List valuesList = insertStatement.getValuesList(); + for (SQLInsertStatement.ValuesClause valuesClause : valuesList) { + List values = valuesClause.getValues(); + for (int i = 0; i < values.size(); i++) { + String column; + try { + SQLExpr exprColumn = columns.get(i); + column = SQLSupport.getExprColumn(exprColumn); + } catch (Throwable ex) { + throw new DSLException( + String.format("Append values not equals columns. now columns is %s, values is %s", columns, valuesClause.getValues())); + } + this.columns.add(column); + SQLExpr valueExpr = values.get(i); + Object value = SQLSupport.getExprValue(valueExpr); + addPrepareValue(column, value); + } + } + return self(); + } + + @Override + public void reset() { + super.reset(); + this.insertStatement = new SQLInsertStatement(); + insertStatement.setDbType(druidDbType); + columns.clear(); + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.insertStatement.setDbType(this.druidDbType); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public InsertOperator from(Table table) { + SQLExprTableSource tableSource = new UnoSQLExprTableSource(druidDbType); + tableSource.setExpr(new SQLIdentifierExpr(table.getName().format())); + tableSource.setCatalog(table.getCatalog()); + tableSource.setSchema(table.getSchema()); + insertStatement.setTableSource(tableSource); + this.table = table; + return self(); + } + + @Override + public Table getTable() { + return table; + } + + + @Override + public InsertOperator strictFill(String f, Supplier v) { + return strictFill(f, v, true); + } + + @Override + public InsertOperator columns(Collection columns) { + List valuesList = insertStatement.getValuesList(); + if (valuesList.isEmpty()) { + for (DSLName column : columns) { + addColumn(column.format()); + } + } else { + for (DSLName diffColumn : columns) { + strictFill(diffColumn.format(), () -> null, false); + } + } + return self(); + } + + @Override + public InsertOperator values(List values) { + SQLInsertStatement.ValuesClause valuesClause = new SQLInsertStatement.ValuesClause(); + for (int i = 0; i < columns.size(); i++) { + String column = columns.get(i); + Object value; + try { + value = values.get(i); + } catch (IndexOutOfBoundsException ex) { + // values缺失部分 null进行填充 + value = null; + } + if (ValueWrapper.EMPTY_VALUE.equals(value)) { + value = null; + } + valuesClause.addValue(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); + addPrepareValue(column, value); + } + insertStatement.addValueCause(valuesClause); + return self(); + } + + @Override + public boolean isBatched() { + return insertStatement.getValuesList().size() > 1; + } + + /** + * 数据填充API,按照column是否存在与否,批量填充或者批量覆盖数据,可以根据参数existAssign来确认存在是否覆盖数据 + * + * @param f column + * @param supplier 值提供者 + * @param existAssign existAssign + * @return SQLInsertOperator + */ + private InsertOperator strictFill(String f, Supplier supplier, boolean existAssign) { + // 1.在batch里面 + // 2.如果相同column值覆盖 + int index = columns.indexOf(f); + List valuesList = insertStatement.getValuesList(); + Object v = supplier == null ? null : supplier.get(); + if (index < 0) { + addColumn(f); + index = columns.size() - 1; + for (int i = 0; i < valuesList.size(); i++) { + SQLInsertStatement.ValuesClause valuesClause = valuesList.get(i); + valuesClause.addValue(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); + // 相同字段在值数组中对应位置计算,即字段index + VALUES从句的索引号 * 字段长度 + int prepareIndex = index + i * columns.size(); + backward(prepareIndex, 1); + setPrepareValue(prepareIndex, f, v); + incrementPrepareIndex(); + } + } else if (existAssign) { + for (int i = 0; i < insertStatement.getValuesList().size(); i++) { + int prepareIndex = index + i * columns.size(); + setPrepareValue(prepareIndex, f, v); + } + } + return self(); + } + + /** + * 添加column到缓存与{@link SQLInsertStatement},如果已经存在则不进行添加。 + * + * @param column column + */ + private void addColumn(String column) { + if (!columns.contains(column)) { + columns.add(column); + insertStatement.addColumn(new SQLIdentifierExpr(column)); + } + } + + @Override + public String getPrepareDSL() { + return SQLUtils.toSQLString(insertStatement); + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLQueryOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLQueryOperator.java new file mode 100644 index 00000000..851945a1 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLQueryOperator.java @@ -0,0 +1,352 @@ +package cc.allio.uno.data.orm.dsl.dml.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.util.ClassUtils; +import cc.allio.uno.core.util.StringUtils; +import cc.allio.uno.data.orm.dsl.Func; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.word.Distinct; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.*; +import com.alibaba.druid.sql.ast.expr.*; +import com.alibaba.druid.sql.ast.statement.*; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import cc.allio.uno.core.StringPool; +import cc.allio.uno.core.util.CollectionUtils; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import com.google.common.collect.Lists; +import org.apache.commons.lang3.reflect.FieldUtils; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; + +/** + * Druid Query Operator + * + * @author jiangwei + * @date 2023/4/12 23:08 + * @since 1.1.4 + */ +@AutoService(QueryOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLQueryOperator extends SQLWhereOperatorImpl implements QueryOperator { + + private DBType dbType; + private DbType druidDbType; + private final DruidTokenOperatorAdapter tokenOperatorAdapter; + + private SQLSelectQueryBlock selectQuery; + private SQLTableSource tableSource; + private Table table; + + // order by + private SQLOrderBy orderBy; + // group by + private SQLSelectGroupByClause groupBy; + // limit by + private SQLLimit sqlLimit; + + // select columns缓存 + private final List columns = Lists.newArrayList(); + + public SQLQueryOperator() { + this(DBType.getSystemDbType()); + } + + public SQLQueryOperator(DBType dbType) { + super(); + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.tokenOperatorAdapter = new DruidTokenOperatorAdapter(); + this.selectQuery = new SQLSelectQueryBlock(); + selectQuery.setDbType(druidDbType); + } + + @Override + public String getDSL() { + List values = getPrepareValues().stream().map(PrepareValue::getValue).toList(); + if (CollectionUtils.isEmpty(values)) { + return getPrepareDSL(); + } + return ParameterizedOutputVisitorUtils.restore( + getPrepareDSL(), + druidDbType, + getPrepareValues().stream().map(PrepareValue::getValue).toList()); + } + + @Override + public QueryOperator parse(String dsl) { + SQLStatement sqlStatement = SQLUtils.parseSingleStatement(dsl, druidDbType); + Field selectField = FieldUtils.getField(sqlStatement.getClass(), "select", true); + if (selectField == null) { + throw new DSLException("not found select statement field"); + } + ClassUtils.setAccessible(selectField); + try { + SQLSelect sqlSelect = (SQLSelect) selectField.get(sqlStatement); + SQLSelectQueryBlock queryBlock = sqlSelect.getQueryBlock(); + this.selectQuery = queryBlock; + this.tableSource = queryBlock.getFrom(); + List selectList = queryBlock.getSelectList(); + for (SQLSelectItem selectItem : selectList) { + SQLExpr expr = selectItem.getExpr(); + String exprColumn = SQLSupport.getExprColumn(expr); + addColumns(exprColumn, null, false); + } + } catch (Throwable ex) { + throw new DSLException(ex); + } + return self(); + } + + @Override + public void reset() { + super.reset(); + this.selectQuery = new SQLSelectQueryBlock(); + selectQuery.setDbType(druidDbType); + this.tableSource = null; + this.orderBy = null; + this.groupBy = null; + this.sqlLimit = null; + this.columns.clear(); + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.selectQuery.setDbType(this.druidDbType); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public QueryOperator select(DSLName sqlName) { + addColumns(sqlName.format(), null, true); + return self(); + } + + @Override + public QueryOperator select(DSLName sqlName, String alias) { + addColumns(sqlName.format(), alias, true); + return self(); + } + + @Override + public QueryOperator selects(Collection sqlNames) { + for (DSLName sqlName : sqlNames) { + addColumns(sqlName.format(), null, true); + } + return self(); + } + + @Override + public QueryOperator distinct() { + SQLSelectItem sqlSelectItem = new SQLSelectItem(new SQLAggregateExpr("", SQLAggregateOption.DISTINCT)); + selectQuery.addSelectItem(sqlSelectItem); + return self(); + } + + @Override + public QueryOperator distinctOn(DSLName sqlName, String alias) { + SQLSelectItem sqlSelectItem = new SQLSelectItem(new SQLAggregateExpr(sqlName.format(), SQLAggregateOption.DISTINCT)); + selectQuery.addSelectItem(sqlSelectItem); + return self(); + } + + @Override + public QueryOperator aggregate(Func syntax, DSLName sqlName, String alias, Distinct distinct) { + SQLSelectItem sqlSelectItem = new SQLSelectItem(); + SQLAggregateExpr sqlAggregateExpr = new SQLAggregateExpr(syntax.getName()); + if (distinct != null) { + sqlAggregateExpr.setOption(SQLAggregateOption.DISTINCT); + } + sqlAggregateExpr.addArgument(new SQLIdentifierExpr(sqlName.format())); + sqlSelectItem.setExpr(sqlAggregateExpr); + selectQuery.addSelectItem(sqlSelectItem); + return self(); + } + + @Override + public QueryOperator from(Table table) { + SQLExprTableSource tableSource = new UnoSQLExprTableSource(druidDbType); + tableSource.setExpr(new SQLIdentifierExpr(table.getName().format())); + tableSource.setCatalog(table.getCatalog()); + tableSource.setSchema(table.getSchema()); + this.table = table; + this.tableSource = tableSource; + return self(); + } + + @Override + public Table getTable() { + return table; + } + + @Override + public QueryOperator from(QueryOperator fromTable, String alias) { + String fromSQL = fromTable.getDSL(); + SQLStatement sqlStatement = SQLUtils.parseSingleStatement(fromSQL, druidDbType, true); + SQLSubqueryTableSource from = new SQLSubqueryTableSource((SQLSelect) sqlStatement); + from.setAlias(alias); + this.tableSource = from; + return self(); + } + + @Override + public QueryOperator join(Table left, JoinType joinType, Table right, BinaryCondition condition) { + // 构建连接关系 + SQLExprTableSource rightSource = new UnoSQLExprTableSource(druidDbType); + rightSource.setExpr(new SQLIdentifierExpr(right.getName().format())); + rightSource.setCatalog(right.getCatalog()); + rightSource.setSchema(right.getSchema()); + SQLBinaryOperator operator = tokenOperatorAdapter.adapt(condition.getSyntax()); + SQLBinaryOpExpr opExpr = new SQLBinaryOpExpr(new SQLIdentifierExpr(condition.getLeft()), operator, new SQLIdentifierExpr(condition.getRight())); + // 判断是否已经包含连接关系,如果则组建复合关系 + if (tableSource instanceof SQLJoinTableSource) { + SQLJoinTableSource combineTableSource = new SQLJoinTableSource(); + tableSource.setAlias(left.getAlias()); + combineTableSource.setLeft(tableSource); + combineTableSource.setRight(rightSource); + combineTableSource.setJoinType(DruidJoinTypeAdapter.getInstance().adapt(joinType)); + combineTableSource.setCondition(opExpr); + this.tableSource = combineTableSource; + } else { + SQLJoinTableSource joinTableSource = new SQLJoinTableSource(); + SQLExprTableSource leftSource = new SQLExprTableSource(new SQLIdentifierExpr(left.getName().format()), left.getAlias()); + joinTableSource.setRight(rightSource); + joinTableSource.setJoinType(DruidJoinTypeAdapter.getInstance().adapt(joinType)); + joinTableSource.setCondition(opExpr); + joinTableSource.setLeft(leftSource); + this.tableSource = joinTableSource; + } + return self(); + } + + @Override + public QueryOperator orderBy(DSLName sqlName, OrderCondition orderCondition) { + SQLOrderingSpecification druidOrder; + if (orderCondition == OrderCondition.ASC) { + druidOrder = SQLOrderingSpecification.ASC; + } else { + druidOrder = SQLOrderingSpecification.DESC; + } + getOrderBy().addItem(new SQLIdentifierExpr(sqlName.format()), druidOrder); + return self(); + } + + @Override + public QueryOperator limit(Long limit, Long offset) { + getLimit().setRowCount(Math.toIntExact(limit)); + getLimit().setOffset(Math.toIntExact(offset)); + return self(); + } + + @Override + public QueryOperator groupByOnes(Collection fieldNames) { + fieldNames.stream() + .map(sqlName -> new SQLIdentifierExpr(sqlName.format())) + .forEach(getGroupBy()::addItem); + return self(); + } + + /** + * 获取 order by子句 + * + * @return orderBy + */ + private SQLOrderBy getOrderBy() { + if (orderBy == null) { + orderBy = new SQLOrderBy(); + } + return orderBy; + } + + /** + * 获取 group by 实例 + * + * @return groupBy + */ + private SQLSelectGroupByClause getGroupBy() { + if (groupBy == null) { + groupBy = new SQLSelectGroupByClause(); + } + return groupBy; + } + + /** + * 获取limit子句 + * + * @return limit + */ + private SQLLimit getLimit() { + if (sqlLimit == null) { + sqlLimit = new SQLLimit(); + } + return sqlLimit; + } + + @Override + public String getPrepareDSL() { + if (orderBy != null) { + selectQuery.setOrderBy(orderBy); + } + if (groupBy != null) { + selectQuery.setGroupBy(groupBy); + } + if (sqlLimit != null) { + selectQuery.setLimit(sqlLimit); + } + selectQuery.setFrom(tableSource); + return SQLUtils.toSQLString(selectQuery, druidDbType); + } + + @Override + protected DbType getDruidType() { + return druidDbType; + } + + @Override + protected SQLObject getSQLObject() { + return selectQuery; + } + + @Override + protected Consumer getSetWhere() { + return where -> selectQuery.setWhere(where); + } + + /** + * 添加column + * + * @param column column + * @param alias 别名 + * @param appendedDruid 是否追加至druid中 + */ + private void addColumns(String column, String alias, boolean appendedDruid) { + if (columns.contains(column)) { + return; + } + columns.add(column); + if (appendedDruid) { + SQLSelectItem sqlSelectItem; + if (StringPool.ASTERISK.equals(column)) { + sqlSelectItem = new SQLSelectItem(new SQLAllColumnExpr()); + } else if (StringUtils.isNotBlank(alias)) { + sqlSelectItem = new SQLSelectItem(new SQLIdentifierExpr(column), alias); + } else { + sqlSelectItem = new SQLSelectItem(new SQLIdentifierExpr(column)); + } + selectQuery.addSelectItem(sqlSelectItem); + } + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLUpdateOperator.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLUpdateOperator.java new file mode 100644 index 00000000..36d325dc --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLUpdateOperator.java @@ -0,0 +1,229 @@ +package cc.allio.uno.data.orm.dsl.dml.sql; + +import cc.allio.uno.auto.service.AutoService; +import cc.allio.uno.core.util.CollectionUtils; +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.exception.DSLException; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.expr.*; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; +import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import cc.allio.uno.core.StringPool; +import cc.allio.uno.data.orm.dsl.dml.UpdateOperator; +import org.apache.commons.lang3.ArrayUtils; +import reactor.util.function.Tuple2; + +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * DruidSQLUpdateOperator + * + * @author jiangwei + * @date 2023/4/16 18:18 + * @since 1.1.4 + */ +@AutoService(UpdateOperator.class) +@Operator.Group(OperatorKey.SQL_LITERAL) +public class SQLUpdateOperator extends SQLWhereOperatorImpl implements UpdateOperator { + + private DBType dbType; + private DbType druidDbType; + private Table table; + private SQLUpdateStatement updateStatement; + + /** + * 记录update where开始的索引 + */ + private int wherePrepareIndex; + + /** + * where条件值的大小 + */ + private int whereSize; + + public SQLUpdateOperator() { + this(DBType.getSystemDbType()); + } + + public SQLUpdateOperator(DBType dbType) { + super(); + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.updateStatement = new SQLUpdateStatement(); + updateStatement.setDbType(druidDbType); + } + + @Override + public String getDSL() { + return ParameterizedOutputVisitorUtils.restore( + getPrepareDSL(), + druidDbType, + getPrepareValues().stream().map(PrepareValue::getValue).toList()); + } + + @Override + public UpdateOperator parse(String dsl) { + this.updateStatement = (SQLUpdateStatement) SQLUtils.parseSingleStatement(dsl, druidDbType); + // 重构建update使之成为prepare dsl + List items = this.updateStatement.getItems(); + if (CollectionUtils.isNotEmpty(items)) { + List newItems = items.stream() + .map(item -> { + String columnName = SQLSupport.getExprColumn(item.getColumn()); + Object value = SQLSupport.getExprValue(item.getValue()); + addPrepareValue(columnName, value); + SQLUpdateSetItem updateSetItem = new SQLUpdateSetItem(); + updateSetItem.setColumn(item.getColumn()); + updateSetItem.setValue(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); + return updateSetItem; + }) + .toList(); + items.clear(); + items.addAll(newItems); + } + SQLExpr where = this.updateStatement.getWhere(); + if (SQLSupport.isBinaryExpr(where)) { + this.updateStatement.setWhere(null); + SQLSupport.binaryExprTraversal( + (SQLBinaryOpExpr) where, + (newExpr, mode, prepareValues) -> { + switchMode(mode); + appendAndSetWhere(newExpr); + for (Tuple2 prepareValue : prepareValues) { + addPrepareValue(prepareValue.getT1(), prepareValue.getT2()); + } + }); + } + return self(); + } + + @Override + public void reset() { + super.reset(); + this.updateStatement = new SQLUpdateStatement(); + updateStatement.setDbType(druidDbType); + this.whereSize = 0; + this.wherePrepareIndex = 0; + } + + @Override + public void setDBType(DBType dbType) { + this.dbType = dbType; + this.druidDbType = SQLSupport.translateDb(dbType); + this.updateStatement.setDbType(this.druidDbType); + } + + @Override + public DBType getDBType() { + return dbType; + } + + @Override + public UpdateOperator from(Table table) { + SQLExprTableSource tableSource = new UnoSQLExprTableSource(druidDbType); + tableSource.setExpr(new SQLIdentifierExpr(table.getName().format())); + tableSource.setCatalog(table.getCatalog()); + tableSource.setSchema(table.getSchema()); + this.table = table; + updateStatement.setFrom(tableSource); + updateStatement.setTableSource(tableSource); + return self(); + } + + @Override + public Table getTable() { + return table; + } + + @Override + protected DbType getDruidType() { + return druidDbType; + } + + @Override + protected SQLObject getSQLObject() { + return updateStatement; + } + + @Override + protected Consumer getSetWhere() { + return where -> updateStatement.setWhere(where); + } + + @Override + public UpdateOperator updates(Map values) { + if (CollectionUtils.isEmpty(values)) { + throw new DSLException("update needs not empty values"); + } + for (Map.Entry columnValue : values.entrySet()) { + String column = columnValue.getKey().format(); + Object value = columnValue.getValue(); + SQLUpdateSetItem updateSetItem = new SQLUpdateSetItem(); + updateSetItem.setColumn(new SQLIdentifierExpr(column)); + updateSetItem.setValue(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); + updateStatement.addItem(updateSetItem); + addPrepareValue(columnValue.getKey().getName(), value, false); + } + return self(); + } + + @Override + public UpdateOperator strictFill(String f, Supplier v) { + // set语句 + List columns = + updateStatement.getItems() + .stream() + .map(SQLUpdateSetItem::getColumn) + .map(SQLSupport::getExprColumn) + .toList(); + Object value = v == null ? null : v.get(); + int index = columns.indexOf(f); + if (index < 0) { + update(f, value); + } else { + setPrepareValue(index, f, value); + } + return self(); + } + + @Override + public String getPrepareDSL() { + return SQLUtils.toSQLString(updateStatement); + } + + /** + * 在where查询中,这部分是没有问题。如果在update,导致update xx where column = ?的占位符的值排序到前面,导致数据插入问题 + */ + @Override + protected void addPrepareValue(String column, Object value) { + addPrepareValue(column, value, true); + } + + /** + * 如果遇到非where条件,则把where数据进行挪动,让非where数据记录到where之前 + */ + private void addPrepareValue(String column, Object value, boolean isWhere) { + if (isWhere) { + super.addPrepareValue(column, value); + whereSize++; + } else { + ensureExplicitCapacity(prepareValues.length + 1); + PrepareValue[] updateReplace = ArrayUtils.subarray(prepareValues, wherePrepareIndex, wherePrepareIndex + whereSize); + prepareValues[wherePrepareIndex] = PrepareValue.of(prepareIndex++, column, getRealityValue(value)); + // update数据进行替换 + for (int i = 0; i < updateReplace.length; i++) { + prepareValues[wherePrepareIndex + i + 1] = updateReplace[i]; + } + wherePrepareIndex++; + } + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLWhereOperatorImpl.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLWhereOperatorImpl.java new file mode 100644 index 00000000..061df934 --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLWhereOperatorImpl.java @@ -0,0 +1,341 @@ +package cc.allio.uno.data.orm.dsl.dml.sql; + +import cc.allio.uno.core.StringPool; +import cc.allio.uno.core.type.Types; +import cc.allio.uno.core.util.Values; +import cc.allio.uno.data.orm.dsl.*; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.ast.expr.*; + +import java.util.Collection; +import java.util.function.Consumer; + +/** + * where操作集合归类 + * + * @author jiangwei + * @date 2024/1/5 20:28 + * @since 1.1.6 + */ +public abstract class SQLWhereOperatorImpl & PrepareOperator> + extends PrepareOperatorImpl + implements WhereOperator { + + private SQLExpr where = null; + private LogicMode mode = LogicMode.AND; + + protected SQLWhereOperatorImpl() { + super(); + } + + @Override + public T gt(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.GreaterThan, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), value); + return self(); + } + + @Override + public T gte(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.GreaterThanOrEqual, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), value); + return self(); + } + + @Override + public T lt(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.LessThan, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), value); + return self(); + } + + @Override + public T lte(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.LessThanOrEqual, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), value); + return self(); + } + + @Override + public T eq(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.Equality, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), value); + return self(); + } + + @Override + public T neq(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.NotEqual, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), value); + return self(); + } + + @Override + public T notNull(DSLName sqlName) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), SQLBinaryOperator.IsNot, + new SQLNullExpr(), + getDruidType()); + appendAndSetWhere(expr); + return self(); + } + + @Override + public T isNull(DSLName sqlName) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.Is, + new SQLNullExpr(), + getDruidType()); + appendAndSetWhere(expr); + return self(); + } + + @Override + public T in(DSLName sqlName, V... values) { + SQLInListExpr sqlInListExpr = new SQLInListExpr(new SQLIdentifierExpr(sqlName.format())); + Collection vs = Values.collectionExpand(values); + for (V v : vs) { + sqlInListExpr.addTarget(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); + addPrepareValue(sqlName.getName(), v); + } + appendAndSetWhere(sqlInListExpr); + return self(); + } + + @Override + public T notIn(DSLName sqlName, V... values) { + SQLInListExpr sqlInListExpr = new SQLInListExpr(new SQLIdentifierExpr(sqlName.format())); + sqlInListExpr.setNot(true); + Collection vs = Values.collectionExpand(values); + for (V v : vs) { + sqlInListExpr.addTarget(new SQLVariantRefExpr(StringPool.QUESTION_MARK)); + addPrepareValue(sqlName.getName(), v); + } + appendAndSetWhere(sqlInListExpr); + return self(); + } + + @Override + public T between(DSLName sqlName, Object withValue, Object endValue) { + SQLBetweenExpr sqlBetweenExpr = + new SQLBetweenExpr( + new SQLIdentifierExpr(sqlName.format()), + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + new SQLVariantRefExpr(StringPool.QUESTION_MARK)); + addPrepareValue(sqlName.getName(), withValue); + addPrepareValue(sqlName.getName(), endValue); + appendAndSetWhere(sqlBetweenExpr); + return self(); + } + + @Override + public T notBetween(DSLName sqlName, Object withValue, Object endValue) { + SQLBetweenExpr sqlBetweenExpr = + new SQLBetweenExpr( + new SQLIdentifierExpr(sqlName.format()), + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + new SQLVariantRefExpr(StringPool.QUESTION_MARK)); + sqlBetweenExpr.setNot(true); + addPrepareValue(sqlName.getName(), withValue); + addPrepareValue(sqlName.getName(), endValue); + appendAndSetWhere(sqlBetweenExpr); + return self(); + } + + @Override + public T like(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.Like, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), value); + return self(); + } + + @Override + public T $like(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.Like, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus.name + Types.toString(value)); + return self(); + } + + @Override + public T like$(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.Like, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), Types.toString(value) + SQLBinaryOperator.Modulus.name); + return self(); + } + + @Override + public T $like$(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.Like, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus.name + Types.toString(value) + SQLBinaryOperator.Modulus.name); + return self(); + } + + @Override + public T notLike(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.NotLike, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), value); + return self(); + } + + @Override + public T $notLike(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.NotLike, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus.name + Types.toString(value)); + return self(); + } + + @Override + public T notLike$(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.NotLike, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), Types.toString(value) + SQLBinaryOperator.Modulus.name); + return self(); + } + + @Override + public T $notLike$(DSLName sqlName, Object value) { + SQLBinaryOpExpr expr = + new SQLBinaryOpExpr( + new SQLIdentifierExpr(sqlName.format()), + SQLBinaryOperator.NotLike, + new SQLVariantRefExpr(StringPool.QUESTION_MARK), + getDruidType()); + appendAndSetWhere(expr); + addPrepareValue(sqlName.getName(), SQLBinaryOperator.Modulus.name + Types.toString(value) + SQLBinaryOperator.Modulus.name); + return self(); + } + + @Override + public T or() { + switchMode(LogicMode.OR); + return self(); + } + + @Override + public T and() { + switchMode(LogicMode.AND); + return self(); + } + + /** + * 拼接where and setValue + * + * @param expr expr + */ + protected void appendAndSetWhere(SQLExpr expr) { + this.where = mode.appendWhere(getSQLObject(), this.where, expr, getDruidType()); + Consumer setWhere = getSetWhere(); + setWhere.accept(where); + } + + protected void switchMode(LogicMode mode) { + this.mode = mode; + } + + /** + * 获取{@link DbType}实例 + * + * @return 非null + */ + protected abstract DbType getDruidType(); + + /** + * 获取SQL DSL实例 + * + * @return 非null + */ + protected abstract SQLObject getSQLObject(); + + /** + * 设置where + * + * @return 非null + */ + protected abstract Consumer getSetWhere(); + + @Override + public void reset() { + super.reset(); + this.where = null; + this.mode = LogicMode.AND; + } +} diff --git a/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/type/DruidDataTypeAdapter.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/type/DruidDataTypeAdapter.java new file mode 100644 index 00000000..76f5219c --- /dev/null +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/type/DruidDataTypeAdapter.java @@ -0,0 +1,83 @@ +package cc.allio.uno.data.orm.dsl.type; + +import cc.allio.uno.data.orm.dsl.dialect.TypeTranslator; +import cc.allio.uno.data.orm.dsl.dialect.TypeTranslatorHolder; +import com.alibaba.druid.sql.ast.SQLDataType; +import com.alibaba.druid.sql.ast.SQLDataTypeImpl; +import com.alibaba.druid.sql.ast.expr.*; + +import java.util.Objects; + +import static cc.allio.uno.data.orm.dsl.type.DSLType.DefaultDSLType.*; + +/** + * druid的类型转换器 + * + * @author jiangwei + * @date 2023/4/12 20:06 + * @since 1.1.4 + */ +public class DruidDataTypeAdapter implements DataTypeAdapter { + + private final DBType dbType; + + private DruidDataTypeAdapter(DBType dbType) { + this.dbType = dbType; + } + + public static DruidDataTypeAdapter getInstance(DBType dbType) { + return new DruidDataTypeAdapter(dbType); + } + + @Override + public SQLDataType adapt(DataType o) { + DataType dataType = o; + // dataType为null,赋值于VARCHAR + if (dataType == null) { + dataType = DataType.createCharType(DefaultDSLType.VARCHAR, 64); + } + // 通用的做分组比较 + DSLType sqlType = dataType.getDslType(); + // 每个数据库类型的做创建 + DSLType sqlTypeConstant = Objects.requireNonNullElse(DSLType.getByJdbcCode(sqlType.getJdbcType()), DSLType.VARCHAR); + TypeTranslator typeTranslator = TypeTranslatorHolder.getTypeTranslator(dbType); + DSLType dbSQLType = typeTranslator.translate(sqlType, dataType.getPrecision(), dataType.getScale()); + // scale 随着 precision值进行赋予,precision没值时,scale没值 + Integer precision = dbSQLType.getPrecision(); + Integer scale = dbSQLType.getScale(); + switch (sqlTypeConstant) { + case DefaultDSLType.BIGINT, DefaultDSLType.SMALLINT, DefaultDSLType.TINYINT, DefaultDSLType.BIT, DefaultDSLType.INTEGER, DefaultDSLType.DOUBLE, DefaultDSLType.NUMBER, DefaultDSLType.FLOAT: + if (precision == null) { + return new SQLDataTypeImpl(dbSQLType.getName()); + } else if (scale == null) { + return new SQLDataTypeImpl(dbSQLType.getName(), precision); + } else { + return new SQLDataTypeImpl(dbSQLType.getName(), precision, scale); + } + case DefaultDSLType.DECIMAL: + SQLDataTypeImpl decimalDataType = new SQLDataTypeImpl(dbSQLType.getName()); + if (precision != null) { + decimalDataType.addArgument(new SQLIntegerExpr(dataType.getPrecision())); + } + if (scale != null) { + decimalDataType.addArgument(new SQLIntegerExpr(dataType.getPrecision())); + } + return decimalDataType; + case DefaultDSLType.DATE, DefaultDSLType.TIME, DefaultDSLType.TIMESTAMP: + SQLDataTypeImpl dateDataType = new SQLDataTypeImpl(dbSQLType.getName()); + if (precision != null) { + dateDataType.addArgument(new SQLIntegerExpr(precision)); + } + return dateDataType; + default: + SQLDataTypeImpl charDataType = new SQLDataTypeImpl(dbSQLType.getName()); + charDataType.addArgument(new SQLIntegerExpr(dataType.getPrecision())); + return charDataType; + } + } + + @Override + public DataType reverse(SQLDataType sqlDataType) { + return null; + } +} diff --git a/uno-data/src/main/java/cc/allio/uno/data/orm/type/druid/DruidDbTypeAdapter.java b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/type/DruidDbTypeAdapter.java similarity index 58% rename from uno-data/src/main/java/cc/allio/uno/data/orm/type/druid/DruidDbTypeAdapter.java rename to uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/type/DruidDbTypeAdapter.java index c814489a..8b4b6396 100644 --- a/uno-data/src/main/java/cc/allio/uno/data/orm/type/druid/DruidDbTypeAdapter.java +++ b/uno-data/uno-data-sql/src/main/java/cc/allio/uno/data/orm/dsl/type/DruidDbTypeAdapter.java @@ -1,8 +1,6 @@ -package cc.allio.uno.data.orm.type.druid; +package cc.allio.uno.data.orm.dsl.type; import com.alibaba.druid.DbType; -import cc.allio.uno.data.orm.type.DBType; -import cc.allio.uno.data.orm.type.DBTypeAdapter; /** * DruidDbTypeBridge @@ -15,8 +13,12 @@ public class DruidDbTypeAdapter implements DBTypeAdapter { private static final DruidDbTypeAdapter INSTANCE = new DruidDbTypeAdapter(); + public static DruidDbTypeAdapter getInstance() { + return INSTANCE; + } + @Override - public DbType get(DBType o) { + public DbType adapt(DBType o) { DBType dbType = o; if (DBType.MYSQL.equals(dbType)) { return DbType.mysql; @@ -29,27 +31,17 @@ public DbType get(DBType o) { } else if (DBType.H2.equals(dbType)) { return DbType.h2; } - return null; + return DbType.h2; } @Override - public DBType reversal(DbType dbType) { - switch (dbType) { - case mysql: - return DBType.MYSQL; - case oracle: - return DBType.ORACLE; - case postgresql: - return DBType.POSTGRESQL; - case sqlserver: - return DBType.SQLSERVER; - case h2: - return DBType.H2; - } - return null; - } - - public static DruidDbTypeAdapter getInstance() { - return INSTANCE; + public DBType reverse(DbType dbType) { + return switch (dbType) { + case DbType.mysql -> DBType.MYSQL; + case DbType.oracle -> DBType.ORACLE; + case DbType.postgresql -> DBType.POSTGRESQL; + case DbType.sqlserver -> DBType.SQLSERVER; + default -> DBType.H2; + }; } } diff --git a/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLAlterTableOperatorTest.java b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLAlterTableOperatorTest.java new file mode 100644 index 00000000..8dbe280c --- /dev/null +++ b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLAlterTableOperatorTest.java @@ -0,0 +1,74 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.data.orm.dsl.OperatorGroup; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.ddl.AlterTableOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.test.model.Operators; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static cc.allio.uno.data.test.model.DataSets.*; + +public class SQLAlterTableOperatorTest extends BaseTestCase { + + Operators.OperatorFeature feature; + + @BeforeEach + void init() { + AlterTableOperator alterTableOperator = OperatorGroup.getOperator(AlterTableOperator.class, OperatorKey.SQL); + feature = Operators.feature(alterTableOperator); + } + + @Test + void testRename() { + // test mysql + + // test pg + feature.dbType(DBType.POSTGRESQL) + .thenReset() + .trigger(alterTableOperator -> { + String dsl = alterTableOperator.from(DUAL).rename("dual1").getDSL(); + assertEquals("ALTER TABLE PUBLIC.dual\n" + + "\tRENAME TO dual1", dsl); + }); + } + + @Test + void testAddColumns() { + feature.dbType(DBType.POSTGRESQL) + .thenReset() + .trigger(alterTableOperator -> { + String dsl = alterTableOperator.from(DUAL).addColumns(ID, CREATE_BY).getDSL(); + assertEquals("ALTER TABLE PUBLIC.dual\n" + + "\tADD COLUMN id int8 PRIMARY KEY NOT NULL,\n" + + "\tADD COLUMN create_by int8", dsl); + }); + + } + + @Test + void testDropColumns() { + feature.dbType(DBType.POSTGRESQL) + .thenReset() + .trigger(alterTableOperator -> { + String dsl = alterTableOperator.from(DUAL).deleteColumns(ID.getDslName(), CREATE_BY.getDslName()).getDSL(); + assertEquals("ALTER TABLE PUBLIC.dual\n" + + "\tDROP COLUMN id, create_by", dsl); + }); + + } + + @Test + void testAlterColumns() { + feature.dbType(DBType.POSTGRESQL) + .thenReset() + .trigger(alterTableOperator -> { + String dsl = alterTableOperator.from(DUAL).alertColumns(ID, CREATE_BY).getDSL(); + assertEquals("ALTER TABLE PUBLIC.dual\n" + + "\tALTER COLUMN id int8 PRIMARY KEY NOT NULL,\n" + + "\tALTER COLUMN create_by int8", dsl); + }); + } +} diff --git a/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLCreateOperatorTest.java b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLCreateOperatorTest.java new file mode 100644 index 00000000..ef693f7f --- /dev/null +++ b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLCreateOperatorTest.java @@ -0,0 +1,96 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.OperatorGroup; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.ddl.CreateTableOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.orm.dsl.type.DSLType; +import cc.allio.uno.data.orm.dsl.type.DataType; +import cc.allio.uno.data.test.model.User; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class SQLCreateOperatorTest extends BaseTestCase { + + @Test + void testCreateTable() { + CreateTableOperator createTableOperator = OperatorGroup.getOperator(CreateTableOperator.class, OperatorKey.SQL); + String sql = createTableOperator.from("dual") + .column( + ColumnDef.builder() + .dslName(DSLName.of("name")) + .dataType(DataType.createCharType(DSLType.CHAR, 9)) + .isPk(true) + .isNonNull(true) + .isUnique(true) + .build()) + .getDSL(); + assertEquals("CREATE TABLE PUBLIC.dual (\n" + + "\tname char(9) PRIMARY KEY NOT NULL UNIQUE\n" + + ")", sql); + } + + @Test + void testParseCreateTableSQL() { + CreateTableOperator createTableOperator = OperatorGroup.getOperator(CreateTableOperator.class, OperatorKey.SQL); + String sql = "CREATE TABLE dual (\n" + + "\tname char(9) PRIMARY KEY NOT NULL UNIQUE\n" + + ")"; + String literal = createTableOperator.parse(sql).getDSL(); + assertEquals(sql, literal); + } + + // =================== pg =================== + + @Test + void testPgCreateComplexTypeTable() { + CreateTableOperator createTableOperator = OperatorGroup.getOperator(CreateTableOperator.class, OperatorKey.SQL, DBType.POSTGRESQL); + createTableOperator.from("dual"); + ColumnDef d1 = ColumnDef.builder() + .dslName(DSLName.of("d1")) + .dataType(DataType.create(DSLType.BIGINT)) + .build(); + + ColumnDef d2 = ColumnDef.builder() + .dslName(DSLName.of("d2")) + .dataType(DataType.create(DSLType.TIMESTAMP)) + .build(); + ColumnDef d3 = ColumnDef.builder() + .dslName(DSLName.of("d3")) + .dataType(DataType.createCharType(DSLType.VARCHAR, 66)) + .build(); + + ColumnDef d4 = ColumnDef.builder() + .dslName(DSLName.of("d4")) + .dataType(DataType.create(DSLType.SMALLINT)) + .build(); + createTableOperator.columns(d1, d2, d3, d4); + String dsl = createTableOperator.getDSL(); + assertEquals("CREATE TABLE PUBLIC.dual (\n" + + "\td1 int8,\n" + + "\td2 timestamp,\n" + + "\td3 varchar(66),\n" + + "\td4 int2\n" + + ")", dsl); + } + + @Test + void testPgParsePojoCreateTableSQL() { + CreateTableOperator createTableOperator = OperatorGroup.getOperator(CreateTableOperator.class, OperatorKey.SQL, DBType.POSTGRESQL); + String sql = createTableOperator.fromPojo(User.class).getDSL(); + assertEquals("CREATE TABLE t_users (\n" + + "\tid int8 PRIMARY KEY,\n" + + "\tcreate_user int8,\n" + + "\tcreate_dept int8,\n" + + "\tcreate_time timestamp,\n" + + "\tupdate_user int8,\n" + + "\tupdate_time timestamp,\n" + + "\tis_deleted int4,\n" + + "\tname varchar(64) NULL,\n" + + "\trole_id int8 NULL\n" + + ")", sql); + } + +} diff --git a/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowColumnsOperatorTest.java b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowColumnsOperatorTest.java new file mode 100644 index 00000000..13a6cb41 --- /dev/null +++ b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowColumnsOperatorTest.java @@ -0,0 +1,22 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.data.orm.dsl.OperatorGroup; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.ddl.ShowColumnsOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class SQLShowColumnsOperatorTest extends BaseTestCase { + + @Test + void testMySQLShoWColumns() { + ShowColumnsOperator showColumnsOperator = OperatorGroup.getOperator(ShowColumnsOperator.class, OperatorKey.SQL, DBType.MYSQL); + String dsl = showColumnsOperator.from("dual").getDSL(); + assertEquals("SELECT *, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME\n" + + "\t, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH\n" + + "\t, CHARACTER_OCTET_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, DATETIME_PRECISION\n" + + "FROM INFORMATION_SCHEMA.COLUMNS\n" + + "WHERE TABLE_NAME = 'dual'", dsl); + } +} diff --git a/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowTablesOperatorTest.java b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowTablesOperatorTest.java new file mode 100644 index 00000000..b572cde6 --- /dev/null +++ b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/ddl/sql/SQLShowTablesOperatorTest.java @@ -0,0 +1,64 @@ +package cc.allio.uno.data.orm.dsl.ddl.sql; + +import cc.allio.uno.data.orm.dsl.OperatorGroup; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.ddl.ShowTablesOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class SQLShowTablesOperatorTest extends BaseTestCase { + + @Test + void testSQLLByH2() { + ShowTablesOperator operator = OperatorGroup.getOperator(ShowTablesOperator.class, OperatorKey.SQL); + String sql = operator.getDSL(); + assertEquals("SELECT TABLE_CATALOG AS CATALOG, TABLE_SCHEMA AS SCHEMA, TABLE_NAME AS NAME, TABLE_TYPE AS TYPE\n" + + "FROM INFORMATION_SCHEMA.TABLES\n" + + "WHERE TABLE_SCHEMA = 'PUBLIC'\n" + + "\tAND TABLE_TYPE = 'BASE TABLE'", sql); + } + + @Test + void testSQLLByMySQL() { + ShowTablesOperator operator = OperatorGroup.getOperator(ShowTablesOperator.class, OperatorKey.SQL, DBType.MYSQL); + String sql = operator.database("da").getDSL(); + assertEquals("SELECT TABLE_CATALOG AS CATALOG, TABLE_SCHEMA AS SCHEMA, TABLE_NAME AS NAME, TABLE_TYPE AS TYPE\n" + + "FROM INFORMATION_SCHEMA.TABLES\n" + + "WHERE TABLE_SCHEMA = 'da'\n" + + "\tAND TABLE_TYPE = 'BASE TABLE'", sql); + } + + + @Test + void testSQLLByPostgreSQL() { + ShowTablesOperator operator = OperatorGroup.getOperator(ShowTablesOperator.class, OperatorKey.SQL, DBType.POSTGRESQL); + String sql = operator.getDSL(); + assertEquals("SELECT TABLE_CATALOG AS CATALOG, TABLE_SCHEMA AS SCHEMA, TABLE_NAME AS NAME, TABLE_TYPE AS TYPE\n" + + "FROM INFORMATION_SCHEMA.TABLES\n" + + "WHERE TABLE_SCHEMA = 'PUBLIC'\n" + + "\tAND TABLE_TYPE = 'BASE TABLE'", sql); + } + + @Test + void testDualShowTable() { + ShowTablesOperator operator = OperatorGroup.getOperator(ShowTablesOperator.class, OperatorKey.SQL, DBType.POSTGRESQL); + String sql = operator.from("dual").getDSL(); + assertEquals("SELECT TABLE_CATALOG AS CATALOG, TABLE_SCHEMA AS SCHEMA, TABLE_NAME AS NAME, TABLE_TYPE AS TYPE\n" + + "FROM INFORMATION_SCHEMA.TABLES\n" + + "WHERE TABLE_SCHEMA = 'PUBLIC'\n" + + "\tAND TABLE_TYPE = 'BASE TABLE'\n" + + "\tAND TABLE_NAME = 'dual'", sql); + } + + @Test + void testCompositeShowTable() { + ShowTablesOperator operator = OperatorGroup.getOperator(ShowTablesOperator.class, OperatorKey.SQL, DBType.POSTGRESQL); + String sql = operator.from("dualA").from("dualB").database("da").schema("db").getDSL(); + assertEquals("SELECT TABLE_CATALOG AS CATALOG, TABLE_SCHEMA AS SCHEMA, TABLE_NAME AS NAME, TABLE_TYPE AS TYPE\n" + + "FROM INFORMATION_SCHEMA.TABLES\n" + + "WHERE TABLE_SCHEMA = 'db'\n" + + "\tAND TABLE_TYPE = 'BASE TABLE'\n" + + "\tAND TABLE_NAME IN ('dual_a', 'dual_b')", sql); + } +} diff --git a/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLDeleteOperatorTest.java b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLDeleteOperatorTest.java new file mode 100644 index 00000000..24558c21 --- /dev/null +++ b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLDeleteOperatorTest.java @@ -0,0 +1,53 @@ +package cc.allio.uno.data.orm.dsl.dml.sql; + +import cc.allio.uno.data.orm.dsl.OperatorGroup; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.dml.DeleteOperator; +import cc.allio.uno.data.test.model.Operators; +import cc.allio.uno.data.test.model.User; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class SQLDeleteOperatorTest extends BaseTestCase { + + @Test + void testSimplePojoInsert() { + DeleteOperator deleteOperator = OperatorGroup.getOperator(DeleteOperator.class, OperatorKey.SQL); + String sql = deleteOperator.from(User.class).from(User.class).getDSL(); + assertEquals("DELETE FROM PUBLIC.t_users", sql); + } + + @Test + void testComplexCondition() { + DeleteOperator deleteOperator = OperatorGroup.getOperator(DeleteOperator.class, OperatorKey.SQL); + String sql = deleteOperator.from("dual") + .eq("a", "a") + .or() + .in("b", "b1", "b2") + .and() + .between("c", "c1", "c2") + .isNull("e") + .getDSL(); + assertEquals("DELETE FROM PUBLIC.dual\n" + + "WHERE (a = 'a'\n" + + "\t\tOR b IN ('b1', 'b2'))\n" + + "\tAND c BETWEEN 'c1' AND 'c2'\n" + + "\tAND e IS NULL", sql); + } + + @Test + void testParseSQL() { + DeleteOperator deleteOperator = OperatorGroup.getOperator(DeleteOperator.class, OperatorKey.SQL); + Operators.thenRest(() -> { + String sql = "DELETE FROM PUBLIC.dual\n" + + "WHERE (a = 'a'\n" + + "\t\tOR b IN ('b1', 'b2'))\n" + + "\tAND c BETWEEN 'c1' AND 'c2'\n" + + "\tAND e IS NULL"; + String reversal = deleteOperator.parse(sql).getDSL(); + assertEquals(sql, reversal); + return deleteOperator; + }); + } +} + diff --git a/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLInsertOperatorTest.java b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLInsertOperatorTest.java new file mode 100644 index 00000000..0f686cfe --- /dev/null +++ b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLInsertOperatorTest.java @@ -0,0 +1,138 @@ +package cc.allio.uno.data.orm.dsl.dml.sql; + +import cc.allio.uno.data.orm.dsl.OperatorGroup; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.dml.InsertOperator; +import cc.allio.uno.data.test.model.Operators; +import cc.allio.uno.test.BaseTestCase; +import com.google.common.collect.Lists; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.junit.jupiter.api.Test; + +public class SQLInsertOperatorTest extends BaseTestCase { + + @Test + void testInsert() { + InsertOperator insertOperator = OperatorGroup.getOperator(InsertOperator.class, OperatorKey.SQL); + String sql = insertOperator.from("test") + .insert("x", "2") + .getDSL(); + assertEquals("INSERT INTO PUBLIC.test (x)\n" + + "VALUES ('2')", sql); + insertOperator.reset(); + sql = insertOperator. + from(User.class) + .batchInsertPojos(Lists.newArrayList(new User("21", 2), new User("xc", 2))) + .getDSL(); + assertEquals("INSERT INTO PUBLIC.t_user (name, age)\n" + + "VALUES ('21', 2), ('xc', 2)", sql); + } + + @Test + void testNotEqualityInsertColumn() { + InsertOperator insertOperator = OperatorGroup.getOperator(InsertOperator.class, OperatorKey.SQL); + String sql = insertOperator.from("dual") + .insert("a1", null, "a2", "2") + .insert("a1", null) + .getDSL(); + assertEquals("INSERT INTO PUBLIC.dual (a1, a2)\n" + + "VALUES (NULL, '2'), (NULL, NULL)", sql); + } + + @Test + void testNullValueInsert() { + InsertOperator insertOperator = OperatorGroup.getOperator(InsertOperator.class, OperatorKey.SQL); + + Operators.thenRest(() -> { + String sql = insertOperator.from("dual") + .insert("x", null) + .getDSL(); + assertEquals("INSERT INTO PUBLIC.dual (x)\n" + + "VALUES (NULL)", sql); + return insertOperator; + }); + + Operators.thenRest(() -> { + // test multi Null values + String sql = insertOperator.from("dual") + .insert("a", null, "b", null) + .getDSL(); + assertEquals("INSERT INTO PUBLIC.dual (a, b)\n" + + "VALUES (NULL, NULL)", sql); + return insertOperator; + }); + } + + @Test + void testStrictSingleValueClause() { + InsertOperator insertOperator = OperatorGroup.getOperator(InsertOperator.class, OperatorKey.SQL); + new Operators(insertOperator) + .then(() -> { + // column不存在 + String sql = insertOperator.from("dual") + .insert("a", null) + .strictFill("b", null) + .getDSL(); + + assertEquals("INSERT INTO PUBLIC.dual (a, b)\n" + + "VALUES (NULL, NULL)", sql); + }) + .then(() -> { + // column存在 + String sql = insertOperator.from("dual") + .insert("a", "a1", "b", null) + .strictFill("a", null) + .getDSL(); + assertEquals("INSERT INTO PUBLIC.dual (a, b)\n" + + "VALUES (NULL, NULL)", sql); + }) + .eachReset(); + } + + @Test + void testStrictMultiValueClause() { + InsertOperator insertOperator = OperatorGroup.getOperator(InsertOperator.class, OperatorKey.SQL); + new Operators(insertOperator) + .then(() -> { + // column不存在 + String sql = insertOperator.from("dual") + .insert("a1", null, "a2", "2") + .insert("a1", null, "a2", "2") + .strictFill("a3", "3") + .getDSL(); + assertEquals("INSERT INTO PUBLIC.dual (a1, a2, a3)\n" + + "VALUES (NULL, '2', '3'), (NULL, '2', '3')", sql); + }) + .then(() -> { + // column存在 + String sql = insertOperator.from("dual") + .insert("a1", null, "a2", "2") + .insert("a1", null, "a2", "2") + .strictFill("a1", "1") + .getDSL(); + assertEquals("INSERT INTO PUBLIC.dual (a1, a2)\n" + + "VALUES ('1', '2'), ('1', '2')", sql); + }) + .eachReset(); + } + + @Test + void testParse() { + InsertOperator insertOperator = OperatorGroup.getOperator(InsertOperator.class, OperatorKey.SQL); + String oriSQL = "INSERT INTO PUBLIC.t_user (name, age)\n" + + "VALUES ('21', 2), ('xc', 2)"; + insertOperator.parse(oriSQL); + String sql = insertOperator.getDSL(); + assertEquals(oriSQL, sql); + } + + @Data + @Table(name = "t_user") + @AllArgsConstructor + public static class User { + private String name; + private int age; + } +} diff --git a/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLQueryOperatorTest.java b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLQueryOperatorTest.java new file mode 100644 index 00000000..ede5c8ed --- /dev/null +++ b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLQueryOperatorTest.java @@ -0,0 +1,238 @@ +package cc.allio.uno.data.orm.dsl.dml.sql; + +import cc.allio.uno.data.orm.dsl.*; +import cc.allio.uno.data.orm.dsl.dml.QueryOperator; +import cc.allio.uno.data.orm.dsl.type.DBType; +import cc.allio.uno.data.test.model.Operators; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class SQLQueryOperatorTest extends BaseTestCase { + + @Test + void testSelect() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.selectAll().getDSL(); + assertEquals("SELECT *", sql); + } + + @Test + void testFunc() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.select("z") + .min("z") + .getDSL(); + assertEquals("SELECT z, MIN(z)", sql); + } + + @Test + void testSimpleWhere() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.select("z").from("dual").like("x", "zxc").getDSL(); + assertEquals("SELECT z\n" + + "FROM PUBLIC.dual\n" + + "WHERE x LIKE 'zxc'", sql); + } + + @Test + void testMultiWhere() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.select("z").from("dual").like("a", "a").eq("b", "b").getDSL(); + assertEquals("SELECT z\n" + + "FROM PUBLIC.dual\n" + + "WHERE a LIKE 'a'\n" + + "\tAND b = 'b'", sql); + } + + @Test + void testLogicPredicateOr() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.select("z").from("dual").or().eq("a", "a").eq("b", "b").getDSL(); + assertEquals("SELECT z\n" + + "FROM PUBLIC.dual\n" + + "WHERE a = 'a'\n" + + "\tOR b = 'b'", sql); + } + + @Test + void testMultiLogicPredicate() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.select("z").from("dual").or().eq("a", "a").eq("b", "b").and().eq("d", "d").getDSL(); + assertEquals("SELECT z\n" + + "FROM PUBLIC.dual\n" + + "WHERE (a = 'a'\n" + + "\t\tOR b = 'b')\n" + + "\tAND d = 'd'", sql); + } + + @Test + void testSubTable() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.leftJoin(Table.of("dual1"), Table.of("dual2"), BinaryCondition.of("dual1.cc", "dual2.aa", TokenOperator.EQUALITY)) + .leftJoinThen("dual", "dual3", BinaryCondition.of("dual.xx", "dual3.xx", TokenOperator.EQUALITY)) + .getDSL(); + assertEquals("SELECT \n" + + "FROM (dual1\n" + + "\tLEFT JOIN PUBLIC.dual2 ON dual1.cc = dual2.aa) AS dual\n" + + "\tLEFT JOIN PUBLIC.dual3 ON dual.xx = dual3.xx", sql); + } + + @Test + void testOrder() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.select("a") + .from("dual") + .orderBy("a", OrderCondition.DESC) + .getDSL(); + assertEquals("SELECT a\n" + + "FROM PUBLIC.dual\n" + + "ORDER BY a DESC", sql); + } + + @Test + void testGroup() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.select("z") + .from("dual") + .groupByOne("z") + .getDSL(); + assertEquals("SELECT z\n" + + "FROM PUBLIC.dual\n" + + "GROUP BY z", sql); + } + + @Test + void testLimit() { + Operators.thenRest(() -> { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.select("z") + .from("dual") + .page(1L, 10L) + .getDSL(); + assertEquals("SELECT z\n" + + "FROM PUBLIC.dual\n" + + "LIMIT 0, 10", sql); + return operator; + }); + + // test pg + Operators.thenRest(() -> { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL, DBType.POSTGRESQL); + String sql = operator.select("z") + .from("dual") + .page(1L, 10L) + .getDSL(); + assertEquals("SELECT z\n" + + "FROM PUBLIC.dual\n" + + "LIMIT 10 OFFSET 0", sql); + return operator; + }); + } + + @Test + void testIn() { + Operators.thenRest(() -> { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + String sql = operator.select("z") + .from("dual") + .in("t1", "2", "2") + .getDSL(); + assertEquals("SELECT z\n" + + "FROM PUBLIC.dual\n" + + "WHERE t1 IN ('2', '2')", sql); + return operator; + }); + + } + + @Test + void testParse() { + QueryOperator operator = OperatorGroup.getOperator(QueryOperator.class, OperatorKey.SQL); + Operators.thenRest(() -> { + String s1 = "SELECT *\n" + + "FROM dual"; + String s1p = operator.parse(s1).getDSL(); + assertEquals(s1, s1p); + return operator; + }); + + Operators.thenRest(() -> { + String s2 = "SELECT z\n" + + "FROM PUBLIC.dual\n" + + "WHERE x LIKE 'zxc'"; + String s2p = operator.parse(s2).getDSL(); + assertEquals(s2, s2p); + return operator; + }); + + Operators.thenRest(() -> { + String s3 = "SELECT z\n" + + "FROM PUBLIC.dual\n" + + "WHERE a LIKE 'a'\n" + + "\tAND b = 'b'"; + String s3p = operator.parse(s3).getDSL(); + assertEquals(s3, s3p); + return operator; + }); + + Operators.thenRest(() -> { + String s4 = "SELECT z\n" + + "FROM PUBLIC.dual\n" + + "WHERE a = 'a'\n" + + "\tOR b = 'b'"; + String s4p = operator.parse(s4).getDSL(); + assertEquals(s4, s4p); + return operator; + }); + + Operators.thenRest(() -> { + String s5 = "SELECT z\n" + + "FROM PUBLIC.dual\n" + + "WHERE (a = 'a'\n" + + "\t\tOR b = 'b')\n" + + "\tAND d = 'd'"; + String s5p = operator.parse(s5).getDSL(); + assertEquals(s5, s5p); + return operator; + }); + + // druid failed +// Operators.thenRest(() -> { +// String s6 = "SELECT \n" + +// "FROM (dual1\n" + +// "\tLEFT JOIN PUBLIC.dual2 ON dual1.cc = dual2.aa) AS dual\n" + +// "\tLEFT JOIN PUBLIC.dual3 ON dual.xx = dual3.xx"; +// String s6p = operator.parse(s6).getDSL(); +// assertEquals(s6, s6p); +// return operator; +// }); + + Operators.thenRest(() -> { + String s7 = "SELECT a\n" + + "FROM PUBLIC.dual\n" + + "ORDER BY a DESC"; + String s7p = operator.parse(s7).getDSL(); + assertEquals(s7, s7p); + return operator; + }); + + Operators.thenRest(() -> { + String s8 = "SELECT z\n" + + "FROM PUBLIC.dual\n" + + "GROUP BY z"; + String s8p = operator.parse(s8).getDSL(); + assertEquals(s8, s8p); + return operator; + }); + + Operators.thenRest(() -> { + String s9 = "SELECT z\n" + + "FROM PUBLIC.dual\n" + + "LIMIT 10, 0"; + String s9p = operator.parse(s9).getDSL(); + assertEquals(s9, s9p); + return operator; + }); + } + +} diff --git a/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLUpdateOperatorTest.java b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLUpdateOperatorTest.java new file mode 100644 index 00000000..337a7287 --- /dev/null +++ b/uno-data/uno-data-sql/src/test/java/cc/allio/uno/data/orm/dsl/dml/sql/SQLUpdateOperatorTest.java @@ -0,0 +1,158 @@ +package cc.allio.uno.data.orm.dsl.dml.sql; + +import cc.allio.uno.data.orm.dsl.OperatorGroup; +import cc.allio.uno.data.orm.dsl.OperatorKey; +import cc.allio.uno.data.orm.dsl.dml.UpdateOperator; +import cc.allio.uno.data.test.model.Operators; +import cc.allio.uno.data.test.model.User; +import cc.allio.uno.test.BaseTestCase; +import org.junit.jupiter.api.Test; + +public class SQLUpdateOperatorTest extends BaseTestCase { + + @Test + void testSimplePojoInsert() { + UpdateOperator updateOperator = OperatorGroup.getOperator(UpdateOperator.class, OperatorKey.SQL); + User user = new User(); + user.setName("a"); + String sql = updateOperator.from(User.class).updatePojo(user).getDSL(); + assertEquals("UPDATE t_users\n" + + "SET create_user = NULL, create_dept = NULL, create_time = NULL, update_user = NULL, update_time = NULL, is_deleted = NULL, name = 'a', role_id = NULL", sql); + } + + @Test + void testUpdateWherePrepareValue() { + UpdateOperator updateOperator = OperatorGroup.getOperator(UpdateOperator.class, OperatorKey.SQL); + updateOperator.eq("eq1", "eq1"); + updateOperator.update("t11", "t11"); + + // 交替 + updateOperator.eq("eq2", "eq2"); + updateOperator.update("t12", "t12"); + + // 循环10次 update + for (int i = 0; i < 10; i++) { + updateOperator.update("t12", "t12"); + } + + // 循环5次 eq + for (int i = 0; i < 5; i++) { + updateOperator.eq("eq2", "eq2"); + } + + // 循环10次 update + for (int i = 0; i < 10; i++) { + updateOperator.update("t12", "t12"); + } + + System.out.println(updateOperator.getPrepareValues()); + } + + @Test + void testSimpleUpdate() { + UpdateOperator updateOperator = OperatorGroup.getOperator(UpdateOperator.class, OperatorKey.SQL); + User user = new User(); + user.setName("test"); + String sql = updateOperator.from(User.class).updatePojo(user).getDSL(); + assertEquals("UPDATE t_users\n" + + "SET create_user = NULL, create_dept = NULL, create_time = NULL, update_user = NULL, update_time = NULL, is_deleted = NULL, name = 'test', role_id = NULL", sql); + } + + @Test + void testWhereUpdate() { + UpdateOperator updateOperator = OperatorGroup.getOperator(UpdateOperator.class, OperatorKey.SQL); + String sql = updateOperator.from("dual").update("a", "a").eq("a", "a").getDSL(); + assertEquals("UPDATE PUBLIC.dual\n" + + "SET a = 'a'\n" + + "WHERE a = 'a'", sql); + } + + @Test + void testComplexWhereUpdate() { + UpdateOperator updateOperator = OperatorGroup.getOperator(UpdateOperator.class, OperatorKey.SQL); + String sql = updateOperator.from("dual").update("a", "a") + .eq("a", "a") + .eq("b", "b") + .between("c", "c1", "c2") + .in("d", "d1", "d2") + .isNull("e") + .getDSL(); + assertEquals("UPDATE PUBLIC.dual\n" + + "SET a = 'a'\n" + + "WHERE a = 'a'\n" + + "\tAND b = 'b'\n" + + "\tAND c BETWEEN 'c1' AND 'c2'\n" + + "\tAND d IN ('d1', 'd2')\n" + + "\tAND e IS NULL", sql); + } + + @Test + void testStrictFill() { + UpdateOperator updateOperator = OperatorGroup.getOperator(UpdateOperator.class, OperatorKey.SQL); + + new Operators(updateOperator) + .then(() -> { + String sql = updateOperator.from("dual") + .update("a", null) + .strictFill("a", "a") + .eq("d", "1") + .getDSL(); + assertEquals("UPDATE PUBLIC.dual\n" + + "SET a = 'a'\n" + + "WHERE d = '1'", sql); + }) + .then(() -> { + String sql = updateOperator.from("dual") + .update("a", null) + .update("b", "b") + .strictFill("a", "a") + .strictFill("b", "3") + .strictFill("c", "3") + .eq("d", "1") + .isNull("e") + .getDSL(); + assertEquals("UPDATE PUBLIC.dual\n" + + "SET a = 'a', b = '3', c = '3'\n" + + "WHERE d = '1'\n" + + "\tAND e IS NULL", sql); + }) + .eachReset(); + } + + @Test + void testParse() { + UpdateOperator updateOperator = OperatorGroup.getOperator(UpdateOperator.class, OperatorKey.SQL); + Operators.thenRest(() -> { + String sql = "UPDATE PUBLIC.dual\n" + + "SET a = 'a'\n" + + "WHERE a = 'a'\n" + + "\tAND b = 'b'"; + String reverse = updateOperator.parse(sql).getDSL(); + assertEquals(sql, reverse); + return updateOperator; + }); + + Operators.thenRest(() -> { + String sql = "UPDATE PUBLIC.dual\n" + + "SET a = 'a'\n" + + "WHERE a = 'a'\n" + + "\tAND b = 'b'\n" + + "\tAND c BETWEEN 'c1' AND 'c2'\n" + + "\tAND d IN ('d1', 'd2')\n" + + "\tAND e IS NULL"; + String reverse = updateOperator.parse(sql).getDSL(); + assertEquals(sql, reverse); + return updateOperator; + }); + } + + @Test + void testStrictModelUpdate() { + UpdateOperator updateOperator = OperatorGroup.getOperator(UpdateOperator.class, OperatorKey.SQL); + User user = new User(); + user.setId(1L); + String sql = updateOperator.updatePojo(user).getDSL(); + assertEquals("UPDATE t_users\n" + + "SET create_user = NULL, create_dept = NULL, create_time = NULL, update_user = NULL, update_time = NULL, is_deleted = NULL, name = NULL, role_id = NULL", sql); + } +} diff --git a/uno-data/uno-data-test/pom.xml b/uno-data/uno-data-test/pom.xml new file mode 100644 index 00000000..a2fe6b64 --- /dev/null +++ b/uno-data/uno-data-test/pom.xml @@ -0,0 +1,21 @@ + + + + cc.allio + uno-data + 1.1.6-beta.1 + ../pom.xml + + jar + 4.0.0 + uno-data-test + + + + cc.allio + uno-data-api + + + \ No newline at end of file diff --git a/uno-data/src/test/java/cc/allio/uno/data/orm/Bank.java b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Bank.java similarity index 90% rename from uno-data/src/test/java/cc/allio/uno/data/orm/Bank.java rename to uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Bank.java index 9d8e8299..2cf6b49f 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/orm/Bank.java +++ b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Bank.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.orm; +package cc.allio.uno.data.test.model; import lombok.Data; diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/BaseEntity.java b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/BaseEntity.java similarity index 82% rename from uno-data/src/test/java/cc/allio/uno/data/model/BaseEntity.java rename to uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/BaseEntity.java index 7a2ca0d6..2b113c6c 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/model/BaseEntity.java +++ b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/BaseEntity.java @@ -10,23 +10,20 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its - * contributors may be used to endorse or promote products derived from + * contributors may be used to endorse or promote products derived xxxx * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ -package cc.allio.uno.data.model; +package cc.allio.uno.data.test.model; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableLogic; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import jakarta.persistence.Id; import lombok.Data; import java.io.Serializable; import java.util.Date; - /** * 基础实体类 * @@ -34,11 +31,12 @@ */ @Data public class BaseEntity implements Serializable { + /** * 主键id */ @JsonSerialize(using = ToStringSerializer.class) - @TableId(value = "id", type = IdType.ASSIGN_ID) + @Id private Long id; /** @@ -69,15 +67,8 @@ public class BaseEntity implements Serializable { */ private Date updateTime; - /** - * 状态[1:正常] - */ - // @ApiModelProperty(value = "业务状态") - // private Integer status; - /** * 状态[0:未删除,1:删除] */ - @TableLogic private Integer isDeleted; } diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/Car.java b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Car.java similarity index 84% rename from uno-data/src/test/java/cc/allio/uno/data/model/Car.java rename to uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Car.java index 02e7cd42..e230e5a1 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/model/Car.java +++ b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Car.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.model; +package cc.allio.uno.data.test.model; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -10,7 +10,7 @@ @Setter @ToString @RequiredArgsConstructor -@Entity(name = "car") +@Entity(name = "t_car") public class Car { @Id diff --git a/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/DataSets.java b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/DataSets.java new file mode 100644 index 00000000..6de8e4a8 --- /dev/null +++ b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/DataSets.java @@ -0,0 +1,68 @@ +package cc.allio.uno.data.test.model; + +import cc.allio.uno.data.orm.dsl.ColumnDef; +import cc.allio.uno.data.orm.dsl.DSLName; +import cc.allio.uno.data.orm.dsl.Table; +import cc.allio.uno.data.orm.dsl.type.DSLType; +import cc.allio.uno.data.orm.dsl.type.DataType; +import com.google.common.collect.Lists; + +import java.util.List; + +/** + * 常用的数据集 + * + * @author jiangwei + * @date 2024/2/8 14:10 + * @since 1.1.6 + */ +public final class DataSets { + + public static final Table DUAL = Table.of("dual"); + + public static final ColumnDef ID = + ColumnDef.builder() + .dslName(DSLName.of("id")) + .isPk(true) + .isNonNull(true) + .dataType(DataType.createNumberType(DSLType.BIGINT, 64)) + .build(); + public static final ColumnDef CREATE_BY = + cc.allio.uno.data.orm.dsl.ColumnDef.builder() + .dslName(DSLName.of("create_by")) + .defaultValue(0) + .dataType(DataType.createNumberType(DSLType.BIGINT, 64)) + .build(); + public static final ColumnDef CREATE_TIME = + cc.allio.uno.data.orm.dsl.ColumnDef.builder() + .dslName(DSLName.of("create_time")) + .dataType(DataType.create(DSLType.TIMESTAMP)) + .build(); + public static final ColumnDef UPDATE_BY = + ColumnDef.builder() + .dslName(DSLName.of("update_by")) + .dataType(DataType.createNumberType(DSLType.BIGINT, 64)) + .build(); + public static final ColumnDef UPDATE_TIME = + ColumnDef.builder() + .dslName(DSLName.of("update_time")) + .dataType(DataType.create(DSLType.TIMESTAMP)) + .build(); + public static final ColumnDef VERSION = + ColumnDef.builder() + .dslName(DSLName.of("version")) + .dataType(DataType.create(DSLType.INTEGER)) + .build(); + public static final ColumnDef IS_DELETED = + ColumnDef.builder() + .dslName(DSLName.of("create_time")) + .dataType(DataType.create(DSLType.SMALLINT)) + .build(); + public static final ColumnDef TENANT_ID = + ColumnDef.builder() + .dslName(DSLName.of("create_time")) + .dataType(DataType.createCharType(DSLType.VARCHAR, 32)) + .build(); + + public static final List COLUMN_DEFS = Lists.newArrayList(ID, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, VERSION, IS_DELETED, TENANT_ID); +} diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/Dept.java b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Dept.java similarity index 88% rename from uno-data/src/test/java/cc/allio/uno/data/model/Dept.java rename to uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Dept.java index 6a8ef8ac..7f7d689b 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/model/Dept.java +++ b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Dept.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.model; +package cc.allio.uno.data.test.model; import jakarta.persistence.ElementCollection; import jakarta.persistence.Entity; @@ -15,7 +15,7 @@ @Setter @ToString @RequiredArgsConstructor -@Entity(name = "dept") +@Entity(name = "t_dept") public class Dept { @Id diff --git a/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Operators.java b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Operators.java new file mode 100644 index 00000000..54fb4097 --- /dev/null +++ b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Operators.java @@ -0,0 +1,100 @@ +package cc.allio.uno.data.test.model; + +import cc.allio.uno.core.api.Self; +import cc.allio.uno.data.orm.dsl.Operator; +import cc.allio.uno.data.orm.dsl.type.DBType; +import com.google.common.collect.Lists; +import lombok.NonNull; + +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public final class Operators { + + private Operator operator = null; + private final List triggers = Lists.newArrayList(); + + public Operators(Operator operator) { + this.operator = operator; + } + + public static > OperatorFeature feature(T operator) { + return new OperatorFeature<>(operator); + } + + public static void eachReset(@NonNull Operator operator) { + operator.reset(); + } + + public static void thenRest(Supplier> supplier) { + Operator sqlOperator = supplier.get(); + if (sqlOperator != null) { + sqlOperator.reset(); + } + } + + public Operators then(Trigger trigger) { + triggers.add(trigger); + return this; + } + + + public void eachReset() { + trigger(() -> { + if (operator != null) { + operator.reset(); + } + }); + } + + private void trigger(Trigger parent) { + for (Trigger trigger : triggers) { + trigger.doAccept(); + parent.doAccept(); + } + } + + public static class OperatorFeature> implements Self> { + + private final T operator; + private final List preTriggers; + private final List postTriggers; + + public OperatorFeature(T operator) { + this.operator = operator; + this.preTriggers = Lists.newArrayList(); + this.postTriggers = Lists.newArrayList(); + } + + public OperatorFeature dbType(DBType dbType) { + this.preTriggers.add(() -> operator.setDBType(dbType)); + return self(); + } + + public OperatorFeature thenReset() { + this.postTriggers.add(operator::reset); + return self(); + } + + public void trigger(Consumer acceptor) { + for (Trigger preTrigger : preTriggers) { + preTrigger.doAccept(); + } + acceptor.accept(operator); + for (Trigger postTrigger : postTriggers) { + postTrigger.doAccept(); + } + } + } + + public interface Trigger extends Consumer { + + @Override + default void accept(Object o) { + this.doAccept(); + } + + void doAccept(); + } +} diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/Role.java b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Role.java similarity index 78% rename from uno-data/src/test/java/cc/allio/uno/data/model/Role.java rename to uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Role.java index 80ce63ec..34213199 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/model/Role.java +++ b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/Role.java @@ -1,4 +1,4 @@ -package cc.allio.uno.data.model; +package cc.allio.uno.data.test.model; import jakarta.persistence.*; import lombok.*; @@ -8,9 +8,8 @@ @Setter @ToString @RequiredArgsConstructor -@Entity(name = "roles") +@Entity(name = "t_roles") @Table -@org.springframework.data.relational.core.mapping.Table("roles") public class Role implements Persistable { @Id diff --git a/uno-data/src/test/java/cc/allio/uno/data/model/User.java b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/User.java similarity index 74% rename from uno-data/src/test/java/cc/allio/uno/data/model/User.java rename to uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/User.java index f9b1acc2..653e5afb 100644 --- a/uno-data/src/test/java/cc/allio/uno/data/model/User.java +++ b/uno-data/uno-data-test/src/main/java/cc/allio/uno/data/test/model/User.java @@ -1,15 +1,15 @@ -package cc.allio.uno.data.model; +package cc.allio.uno.data.test.model; -import cc.allio.uno.data.orm.jpa.model.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.*; @Getter @Setter @ToString @RequiredArgsConstructor -@Entity(name = "users") +@Table(name = "t_users") public class User extends BaseEntity { @Column(name = "name", length = 64) diff --git a/uno-demo/pom.xml b/uno-demo/pom.xml index 2b86dbf0..4b5e5357 100644 --- a/uno-demo/pom.xml +++ b/uno-demo/pom.xml @@ -5,20 +5,14 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-demo pom - uno-liquibase-demo uno-websocket-demo - - 8 - 8 - - \ No newline at end of file diff --git a/uno-demo/uno-liquibase-demo/pom.xml b/uno-demo/uno-liquibase-demo/pom.xml deleted file mode 100644 index 982269e0..00000000 --- a/uno-demo/uno-liquibase-demo/pom.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - uno-demo - cc.allio - 1.1.5.RELEASE - - 4.0.0 - - uno-liquibase-demo - - - 8 - 8 - - - - - cc.allio - uno-starter-liquibase - - - org.postgresql - postgresql - - - mysql - mysql-connector-java - - - com.alibaba - druid - - - com.alibaba - druid-spring-boot-starter - - - org.springframework.boot - spring-boot-starter-jdbc - - - - \ No newline at end of file diff --git a/uno-demo/uno-liquibase-demo/src/main/java/cc/allio/uno/demo/liquibase/DemoLiquibaseApplication.java b/uno-demo/uno-liquibase-demo/src/main/java/cc/allio/uno/demo/liquibase/DemoLiquibaseApplication.java deleted file mode 100644 index 9745acdf..00000000 --- a/uno-demo/uno-liquibase-demo/src/main/java/cc/allio/uno/demo/liquibase/DemoLiquibaseApplication.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.allio.uno.demo.liquibase; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class DemoLiquibaseApplication { - - public static void main(String[] args) { - SpringApplication.run(DemoLiquibaseApplication.class, args); - } -} diff --git a/uno-demo/uno-liquibase-demo/src/main/java/cc/allio/uno/demo/liquibase/task/PersonChangeTask.java b/uno-demo/uno-liquibase-demo/src/main/java/cc/allio/uno/demo/liquibase/task/PersonChangeTask.java deleted file mode 100644 index fff084a5..00000000 --- a/uno-demo/uno-liquibase-demo/src/main/java/cc/allio/uno/demo/liquibase/task/PersonChangeTask.java +++ /dev/null @@ -1,35 +0,0 @@ -package cc.allio.uno.demo.liquibase.task; - -import liquibase.change.custom.CustomTaskChange; -import liquibase.database.Database; -import liquibase.exception.CustomChangeException; -import liquibase.exception.SetupException; -import liquibase.exception.ValidationErrors; -import liquibase.resource.ResourceAccessor; - -public class PersonChangeTask implements CustomTaskChange { - @Override - public void execute(Database database) throws CustomChangeException { - // 执行sql - } - - @Override - public String getConfirmationMessage() { - return null; - } - - @Override - public void setUp() throws SetupException { - - } - - @Override - public void setFileOpener(ResourceAccessor resourceAccessor) { - - } - - @Override - public ValidationErrors validate(Database database) { - return null; - } -} diff --git a/uno-demo/uno-liquibase-demo/src/main/resources/application.yaml b/uno-demo/uno-liquibase-demo/src/main/resources/application.yaml deleted file mode 100644 index 42893513..00000000 --- a/uno-demo/uno-liquibase-demo/src/main/resources/application.yaml +++ /dev/null @@ -1,8 +0,0 @@ -spring: - datasource: - url: jdbc:mysql://192.168.2.29:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8 - username: root - password: 123456 - liquibase: - enabled: false - change-log: classpath:demo-migration.yaml diff --git a/uno-demo/uno-liquibase-demo/src/main/resources/db/migrations/postgres/sql/V1__Person.sql b/uno-demo/uno-liquibase-demo/src/main/resources/db/migrations/postgres/sql/V1__Person.sql deleted file mode 100644 index a97e36e1..00000000 --- a/uno-demo/uno-liquibase-demo/src/main/resources/db/migrations/postgres/sql/V1__Person.sql +++ /dev/null @@ -1,6 +0,0 @@ -DROP TABLE IF EXISTS "person"; -CREATE TABLE "person" -( - "id" int4, - "name" varchar(255) -); \ No newline at end of file diff --git a/uno-demo/uno-liquibase-demo/src/main/resources/db/migrations/postgres/sql/V1__Person_Data.sql b/uno-demo/uno-liquibase-demo/src/main/resources/db/migrations/postgres/sql/V1__Person_Data.sql deleted file mode 100644 index d13048d4..00000000 --- a/uno-demo/uno-liquibase-demo/src/main/resources/db/migrations/postgres/sql/V1__Person_Data.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO person(id, name) -values (1, 'name') \ No newline at end of file diff --git a/uno-demo/uno-liquibase-demo/src/main/resources/demo-migration.yaml b/uno-demo/uno-liquibase-demo/src/main/resources/demo-migration.yaml deleted file mode 100644 index 198a424d..00000000 --- a/uno-demo/uno-liquibase-demo/src/main/resources/demo-migration.yaml +++ /dev/null @@ -1,23 +0,0 @@ -databaseChangeLog: - # 一次数据库版本变化都是一个变更集 - - changeSet: - # 命名规则:框架(系统名)-服务-版本号-功能(或者目的) - id: uno-demo-V1-Person - author: jiangwei - comment: 创建Person表 - runInTransaction: true - changes: - # 创建表结构 - - sqlFile: - path: classpath:db/migrations/postgres/sql/V1__Person.sql - encoding: utf8 - # 创建表数据 - - sqlFile: - path: classpath:db/migrations/postgres/sql/V1__Person_Data.sql - encoding: utf8 - - changeSet: - id: uno-demo-V1-Person-task - author: jiangwei - changes: - # 创建自定义数据变更类 - - customChange: { "class": "cc.allio.uno.demo.liquibase.task.PersonChangeTask" } diff --git a/uno-demo/uno-websocket-demo/pom.xml b/uno-demo/uno-websocket-demo/pom.xml index f6d779c1..70538b0d 100644 --- a/uno-demo/uno-websocket-demo/pom.xml +++ b/uno-demo/uno-websocket-demo/pom.xml @@ -5,7 +5,7 @@ uno-demo cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 @@ -13,12 +13,6 @@ websocket使用示例 - - 8 - 8 - UTF-8 - - cc.allio diff --git a/uno-gis/pom.xml b/uno-gis/pom.xml index d0e5b34d..72290344 100644 --- a/uno-gis/pom.xml +++ b/uno-gis/pom.xml @@ -5,18 +5,12 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-gis - - 8 - 8 - UTF-8 - - cc.allio diff --git a/uno-gis/src/main/java/cc/allio/uno/gis/config/UnoGisMybatisAutoConfiguration.java b/uno-gis/src/main/java/cc/allio/uno/gis/config/UnoGisMybatisAutoConfiguration.java deleted file mode 100644 index e518f68d..00000000 --- a/uno-gis/src/main/java/cc/allio/uno/gis/config/UnoGisMybatisAutoConfiguration.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.allio.uno.gis.config; - -import cc.allio.uno.gis.mybatis.type.*; -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties; -import com.baomidou.mybatisplus.core.MybatisConfiguration; -import lombok.AllArgsConstructor; -import org.apache.ibatis.type.TypeHandlerRegistry; -import org.locationtech.jts.geom.*; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration(proxyBeanMethods = false) -@AllArgsConstructor -@EnableConfigurationProperties(UnoGisProperties.class) -@AutoConfigureAfter(MybatisPlusAutoConfiguration.class) -public class UnoGisMybatisAutoConfiguration implements InitializingBean { - private final MybatisPlusProperties mybatisPlusProperties; - private final UnoGisProperties gisProperties; - - @Override - public void afterPropertiesSet() throws Exception { - // 注册Mybatis空间数据Type-Handler - MybatisConfiguration configuration = mybatisPlusProperties.getConfiguration(); - TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); - typeHandlerRegistry.register(LinearRing.class, new LinearRingTypeHandler(gisProperties)); - typeHandlerRegistry.register(LineString.class, new LineStringTypeHandler(gisProperties)); - typeHandlerRegistry.register(MultiLineString.class, new MultiLineStringTypeHandler(gisProperties)); - typeHandlerRegistry.register(MultiPoint.class, new MultiPointTypeHandler(gisProperties)); - typeHandlerRegistry.register(MultiPolygon.class, new MultiPolygonTypeHandler(gisProperties)); - typeHandlerRegistry.register(Point.class, new PointTypeHandler(gisProperties)); - typeHandlerRegistry.register(Polygon.class, new PolygonTypeHandler(gisProperties)); - } -} diff --git a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonId.java b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonId.java index 696a0225..0bfbdbe4 100644 --- a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonId.java +++ b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonId.java @@ -14,7 +14,7 @@ /** * Indicates the id of the generated Feature. *

    This annotation is complementary to a {@link GeoJsonType#type()} of {@link FeatureType#FEATURE} - * and can be present 0...1 times. No id field is set if missing. + * and can be present 0...1 times. No id field is setValue if missing. *

    Getter annotation example with type {@link UUID}: *

      *    @GeoJsonId
    diff --git a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonProperties.java b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonProperties.java
    index 18555b25..3e8f7381 100644
    --- a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonProperties.java
    +++ b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonProperties.java
    @@ -15,7 +15,7 @@
      * 

    This annotation can be present 0...1 times. The properties object can be any JSON * object. The getter or field name is not relevant. * The annotations {@link GeoJsonProperties} and {@link GeoJsonProperty} are mutual exclusive. - *

    The properties field will be set to JSON null if no property available. + *

    The properties field will be setValue to JSON null if no property available. *

    Getter annotation example with a {@link java.util.Map}: *

      *    @GeoJsonProperties
    diff --git a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonProperty.java b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonProperty.java
    index c62d2a09..3a217826 100644
    --- a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonProperty.java
    +++ b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonProperty.java
    @@ -16,7 +16,7 @@
      * getter or field and can be overwritten by {@link GeoJsonProperty#name()}. The attribute values
      * can be any JSON object.
      * 

    This annotation is mutually exclusive with {@link GeoJsonProperties}. - *

    The properties field will be set to JSON null if no property is available. + *

    The properties field will be setValue to JSON null if no property is available. *

    Getter annotations example with the {@link String}: *

      *    @GeoJsonProperty
    @@ -42,7 +42,7 @@
     
     	/**
     	 * Returns the name of the property attribute. Allows to overwrite the default behaviour.
    -	 * 

    If not set, the field name or getter name (without "get", lower case) wil be used. + *

    If not setValue, the field name or getter name (without "getValue", lower case) wil be used. * * @return the optional name of the property */ diff --git a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonType.java b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonType.java index bebcbdab..f8806f5c 100644 --- a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonType.java +++ b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/annotation/GeoJsonType.java @@ -16,7 +16,7 @@ /** * Enables the annotated type to be serialized as a GeoJson Object by the {@link GeoJsonSerializer}. - *

    Please note that the {@link GeoJsonSerializer} needs to be set with the {@link JsonSerialize} annotation. + *

    Please note that the {@link GeoJsonSerializer} needs to be setValue with the {@link JsonSerialize} annotation. *

    Depending on the type, further annotations on fields or getters are complementary. *

    {@link FeatureType#FEATURE} *

      diff --git a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/document/FeatureDocumentFactory.java b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/document/FeatureDocumentFactory.java index c30665c3..a6d599fe 100644 --- a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/document/FeatureDocumentFactory.java +++ b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/document/FeatureDocumentFactory.java @@ -113,7 +113,7 @@ private FeatureDocument featureFrom(Object object) throws DocumentFactoryExcepti /** * Returns the values of all annotated field or methods as a {@link Map}. * The key of the map is the name of the field or method as default. When the annotation's attribute - * {@link GeoJsonProperty#name()} is set, this name will be used as key. + * {@link GeoJsonProperty#name()} is setValue, this name will be used as key. * * @param object the object to retrieve the values from * @param annotateds the fields or methods diff --git a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/serializer/GeoJsonSerializer.java b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/serializer/GeoJsonSerializer.java index cef0a01d..c85396a2 100644 --- a/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/serializer/GeoJsonSerializer.java +++ b/uno-gis/src/main/java/cc/allio/uno/gis/jackson/geojson/serializer/GeoJsonSerializer.java @@ -52,7 +52,7 @@ public void serialize(Object object, JsonGenerator gen, SerializerProvider provi throw new IllegalArgumentException("Annotation @GeoJson is not present."); } - // get document factory from annotation + // getValue document factory from annotation Class factory = geoJsonTypeAnnotation.factory(); DocumentFactory documentFactory; try { @@ -61,7 +61,7 @@ public void serialize(Object object, JsonGenerator gen, SerializerProvider provi throw new IllegalStateException("Factory instantiation failed for " + factory, e); } - // call document factory to get a document representation of the annotations + // call document factory to getValue a document representation of the annotations Document document; try { document = documentFactory.from(object); diff --git a/uno-gis/src/main/java/cc/allio/uno/gis/mybatis/type/AbstractGeometryTypeHandler.java b/uno-gis/src/main/java/cc/allio/uno/gis/mybatis/type/AbstractGeometryTypeHandler.java index 2e0663a6..00578637 100644 --- a/uno-gis/src/main/java/cc/allio/uno/gis/mybatis/type/AbstractGeometryTypeHandler.java +++ b/uno-gis/src/main/java/cc/allio/uno/gis/mybatis/type/AbstractGeometryTypeHandler.java @@ -15,6 +15,12 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; + +/** + * 注意使用时候需要在Mybatis配置文件中配置typeHandlerPackage = cc/allio/uno/gis/mybatis/type... + * + * @see org.mybatis.spring.boot.autoconfigure.MybatisProperties#typeHandlersPackage + */ @Slf4j public abstract class AbstractGeometryTypeHandler extends BaseTypeHandler { @@ -76,7 +82,7 @@ private T getResult(String string) throws SQLException { } } - private T getRealResult(String s){ + private T getRealResult(String s) { boolean right = false; T result = null; for (SRID srid : SRID.values()) { diff --git a/uno-gis/src/test/java/cc/allio/uno/gis/GisUtilTest.java b/uno-gis/src/test/java/cc/allio/uno/gis/GisUtilTest.java index 16d96dcd..b136f36c 100644 --- a/uno-gis/src/test/java/cc/allio/uno/gis/GisUtilTest.java +++ b/uno-gis/src/test/java/cc/allio/uno/gis/GisUtilTest.java @@ -1,8 +1,6 @@ package cc.allio.uno.gis; -import cc.allio.uno.core.util.ResourceUtil; -import cc.allio.uno.gis.GisUtil; -import cc.allio.uno.gis.SRID; +import cc.allio.uno.core.util.ResourceUtils; import cc.allio.uno.test.BaseTestCase; import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.Point; @@ -14,7 +12,7 @@ public class GisUtilTest extends BaseTestCase { @Test void testElevation() throws FileNotFoundException { - File file = ResourceUtil.getFile("classpath:高平市.tif"); + File file = ResourceUtils.getFile("classpath:高平市.tif"); String path = file.getAbsoluteFile().getPath(); GisUtil.elevation(GisUtil.createPoint(2, 2), path); diff --git a/uno-gis/src/test/java/cc/allio/uno/gis/type/VillageTest.java b/uno-gis/src/test/java/cc/allio/uno/gis/type/VillageTest.java index 1024211f..4422473e 100644 --- a/uno-gis/src/test/java/cc/allio/uno/gis/type/VillageTest.java +++ b/uno-gis/src/test/java/cc/allio/uno/gis/type/VillageTest.java @@ -3,17 +3,18 @@ import cc.allio.uno.test.CoreTest; import cc.allio.uno.test.Inject; import cc.allio.uno.test.RunTest; -import cc.allio.uno.gis.config.UnoGisMybatisAutoConfiguration; import cc.allio.uno.gis.type.entity.Village; import cc.allio.uno.gis.type.mapper.VillageMapper; import cc.allio.uno.test.env.annotation.MybatisPlusEnv; +import cc.allio.uno.test.env.annotation.properties.MybatisProperties; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import org.junit.jupiter.api.Test; import java.util.List; -@RunTest(components = UnoGisMybatisAutoConfiguration.class) +@RunTest @MybatisPlusEnv(basePackages = "cc.allio.uno.gis.type.mapper.**") +@MybatisProperties(typeHandlersPackage = "cc/allio/uno/gis/mybatis/type") public class VillageTest extends CoreTest { @Inject diff --git a/uno-plugins/pom.xml b/uno-plugins/pom.xml index f9a3d670..a057ad08 100644 --- a/uno-plugins/pom.xml +++ b/uno-plugins/pom.xml @@ -5,7 +5,7 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 diff --git a/uno-plugins/uno-plugins-manager/pom.xml b/uno-plugins/uno-plugins-manager/pom.xml index 31424bc0..6f365783 100644 --- a/uno-plugins/uno-plugins-manager/pom.xml +++ b/uno-plugins/uno-plugins-manager/pom.xml @@ -5,16 +5,11 @@ uno-plugins cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 ../pom.xml 4.0.0 uno-plugins-manager - - 8 - 8 - - \ No newline at end of file diff --git a/uno-plugins/uno-plugins-platform/pom.xml b/uno-plugins/uno-plugins-platform/pom.xml index 07314348..4a81bb02 100644 --- a/uno-plugins/uno-plugins-platform/pom.xml +++ b/uno-plugins/uno-plugins-platform/pom.xml @@ -5,16 +5,11 @@ uno-plugins cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 ../pom.xml 4.0.0 uno-plugins-platform - - 8 - 8 - - \ No newline at end of file diff --git a/uno-rule/pom.xml b/uno-rule/pom.xml index 4cd27ebb..ffbc2f78 100644 --- a/uno-rule/pom.xml +++ b/uno-rule/pom.xml @@ -6,18 +6,12 @@ cc.allio uno - 1.1.5.RELEASE + 1.1.6-beta.1 uno-rule 构建简易API,提供规则引擎的计算服务 - - 8 - 8 - UTF-8 - - org.drools diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/RuleEngineFactory.java b/uno-rule/src/main/java/cc/allio/uno/rule/RuleEngineFactory.java index fcd85cf0..e1768ff3 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/RuleEngineFactory.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/RuleEngineFactory.java @@ -35,12 +35,12 @@ public class RuleEngineFactory { public static synchronized T get() { String ruleEngineKey = Envs.getProperty(RULE_ENGINE_KEY); if (StringUtils.isEmpty(ruleEngineKey)) { - Envs.setProperty(RULE_ENGINE_KEY, DROOLS_KEY.getKey()); - ruleEngineKey = DROOLS_KEY.getKey(); + Envs.setProperty(RULE_ENGINE_KEY, DROOLS_KEY.key()); + ruleEngineKey = DROOLS_KEY.key(); } - if (DROOLS_KEY.getKey().equals(ruleEngineKey)) { + if (DROOLS_KEY.key().equals(ruleEngineKey)) { return get(DROOLS_KEY); - } else if (EASY_RULES_KEY.getKey().equals(ruleEngineKey)) { + } else if (EASY_RULES_KEY.key().equals(ruleEngineKey)) { return get(EASY_RULES_KEY); } // 默认为drools diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/DefaultRuleResult.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/DefaultRuleResult.java index 1d2e8150..87f5ae62 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/DefaultRuleResult.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/DefaultRuleResult.java @@ -103,7 +103,7 @@ public Set get(long timeout, TimeUnit timeUnit) throws RuleResultTim } try { resultLock.lock(); - // add default for notify get() result + // add default for notify getValue() result SignalListener signalListener = new SignalListener(this); addLister(signalListener); while (!isSingle.get()) { diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/EventBusRuleEngine.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/EventBusRuleEngine.java index 62a2f805..ed9d357b 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/EventBusRuleEngine.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/EventBusRuleEngine.java @@ -40,7 +40,7 @@ public synchronized RuleResult fire(Rule rule, Fact fact, Duration timer) { fact, context, timer); - // set context value + // setValue context value context.putCurrentRule(rule); context.putCurrentFact(fact); context.putResultRule(ruleResult); diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/Fact.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/Fact.java index bf0189a7..ed5e0107 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/Fact.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/Fact.java @@ -58,7 +58,7 @@ static Fact from(Rule rule) { */ static Fact from(Rule rule, Object pojo) { ObjectWrapper wrapper = new ObjectWrapper(pojo); - return from(rule, wrapper.findAllValuesForce()); + return from(rule, wrapper.findMapValuesForce()); } /** diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/Rule.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/Rule.java index 2fd14ad7..a67c604b 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/Rule.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/Rule.java @@ -43,7 +43,7 @@ public interface Rule extends Serializable { /** * 获取当前规则所包含属性项的字面表达式,形如: - *

      >get('a') < xx

      + *

      >getValue('a') < xx

      * * @return 字面量 */ diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/RuleAttr.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/RuleAttr.java index ce818989..c3923260 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/RuleAttr.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/RuleAttr.java @@ -15,7 +15,7 @@ */ public interface RuleAttr extends Serializable { - String EXPRESS_TEMPLATE = "get(#{key}) #{op} #{value}"; + String EXPRESS_TEMPLATE = "getValue(#{key}) #{op} #{value}"; String SIMPLE_EXPRESS_TEMPLATE = "#{key} #{op} #{value}"; ExpressionTemplate TEMPLATE = ExpressionTemplate.createTemplate(Tokenizer.HASH_BRACE, false); @@ -71,7 +71,7 @@ public interface RuleAttr extends Serializable { /** * 获取rule index 构建的表达式。 * - * @return 如 get(a) > xxx + * @return 如 getValue(a) > xxx */ String getExpr(); diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/AttrElement.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/AttrElement.java index 4d82edf4..406f8d45 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/AttrElement.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/AttrElement.java @@ -1,6 +1,5 @@ package cc.allio.uno.rule.api.vistor; -import cc.allio.uno.core.datastructure.tree.Element; import cc.allio.uno.core.exception.Exceptions; import cc.allio.uno.core.util.id.IdGenerator; import cc.allio.uno.rule.api.RuleAttr; @@ -19,12 +18,12 @@ * @date 2023/4/26 11:53 * @since 1.1.4 */ -public class AttrElement extends LiteralTraversalElement implements LiteralElement { +public class AttrElement extends LogicGroup { private final Serializable id; @Getter - private GroupElement parent; + private LogicGroup parent; @Getter private final RuleAttr ruleAttr; @@ -35,7 +34,8 @@ public class AttrElement extends LiteralTraversalElement implements LiteralEleme @Getter private int depth; - public AttrElement(GroupElement parent, RuleAttr ruleAttr) { + public AttrElement(LogicGroup parent, RuleAttr ruleAttr) { + super(null, null); this.parent = parent; this.ruleAttr = ruleAttr; if (parent != null) { @@ -49,28 +49,53 @@ public Serializable getId() { return id; } - @Override - public void setParent(T parent) { - this.parent = (GroupElement) parent; - } - @Override public boolean isLeaf() { return true; } @Override - public List getChildren() { + public List getChildren() { return Collections.emptyList(); } @Override - public void addChildren(T element) { + public boolean addElement(LogicGroup element) { + throw Exceptions.eee("AttrElement is leaf element, cannot addElement", UnsupportedOperationException.class); + } + + @Override + public boolean addElements(List elements) { + throw Exceptions.eee("AttrElement is leaf element, cannot addElements", UnsupportedOperationException.class); + } + + @Override + public boolean removeElement(LogicGroup element) { + throw Exceptions.eee("AttrElement is leaf element, cannot LogicGroup", UnsupportedOperationException.class); + } + + @Override + public List getGroupElement() { + throw Exceptions.eee("AttrElement is leaf element, cannot getGroupElement", UnsupportedOperationException.class); + } + + @Override + public List getAttrElement() { + throw Exceptions.eee("AttrElement is leaf element, cannot getAttrElement", UnsupportedOperationException.class); + } + + @Override + public void clearAttrElement() { + throw Exceptions.eee("AttrElement is leaf element, cannot clearAttrElement", UnsupportedOperationException.class); + } + + @Override + public void addChildren(LogicGroup element) { Exceptions.eee("AttrElement is leaf element, cannot addChildren", UnsupportedOperationException.class); } @Override - public void setChildren(List children) { + public void setChildren(List children) { Exceptions.eee("AttrElement is leaf element, cannot setChildren", UnsupportedOperationException.class); } diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/DefaultCompilationRule.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/DefaultCompilationRule.java index 0a2dcdd9..451d12d7 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/DefaultCompilationRule.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/DefaultCompilationRule.java @@ -44,7 +44,7 @@ public GroupElement treeifyBin(List ruleItems) { } else if (p.getLogic() == LogicPredicate.OR) { if (item.getLogic() == LogicPredicate.AND) { // 放入 and group 中 - List attrElement = p.getAttrElement(); + List attrElement = p.getAttrElement(); p.clearAttrElement(); // 规则项重组为and节点 LogicGroup n = new LogicGroup(p, LogicPredicate.AND); diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/GroupElement.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/GroupElement.java index 86fa9ccf..a42554e5 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/GroupElement.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/GroupElement.java @@ -9,7 +9,7 @@ * @date 2023/4/26 12:04 * @since 1.1.4 */ -public interface GroupElement extends LiteralElement { +public interface GroupElement> extends LiteralElement { /** * 添加子节点元素 diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LiteralElement.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LiteralElement.java index 6c402128..f069055b 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LiteralElement.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LiteralElement.java @@ -9,7 +9,7 @@ * @date 2023/11/9 11:07 * @since 1.1.5 */ -public interface LiteralElement extends Element { +public interface LiteralElement> extends Element { /** * 平展开当前规则group 节点规则表达式。 diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LiteralTraversalElement.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LiteralTraversalElement.java deleted file mode 100644 index 348bb545..00000000 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LiteralTraversalElement.java +++ /dev/null @@ -1,6 +0,0 @@ -package cc.allio.uno.rule.api.vistor; - -import cc.allio.uno.core.datastructure.tree.TraversalElement; - -public abstract class LiteralTraversalElement extends TraversalElement implements LiteralElement { -} diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LogicGroup.java b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LogicGroup.java index ed4f9944..f8603d18 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LogicGroup.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/api/vistor/LogicGroup.java @@ -2,6 +2,7 @@ import cc.allio.uno.core.StringPool; import cc.allio.uno.core.datastructure.tree.Element; +import cc.allio.uno.core.datastructure.tree.TraversalElement; import cc.allio.uno.core.util.CollectionUtils; import cc.allio.uno.core.util.id.IdGenerator; import cc.allio.uno.rule.api.LogicPredicate; @@ -19,7 +20,11 @@ * @date 2023/4/26 11:53 * @since 1.1.4 */ -public class LogicGroup extends LiteralTraversalElement implements GroupElement { +public class LogicGroup extends TraversalElement implements GroupElement { + + @Getter + @Setter + private Serializable parentId; @Getter private final Serializable id; @@ -28,14 +33,14 @@ public class LogicGroup extends LiteralTraversalElement implements GroupElement< private final LogicPredicate logic; @Getter - private GroupElement parent; - private List children; + private LogicGroup parent; + private final List children; @Setter @Getter private int depth; - public LogicGroup(GroupElement parent, LogicPredicate logic) { + public LogicGroup(LogicGroup parent, LogicPredicate logic) { this.parent = parent; this.logic = logic; this.children = Lists.newArrayList(); @@ -46,8 +51,8 @@ public LogicGroup(GroupElement parent, LogicPredicate l } @Override - public void setParent(T parent) { - this.parent = (GroupElement) parent; + public void setParent(LogicGroup parent) { + this.parent = parent; } @Override @@ -56,17 +61,18 @@ public boolean isLeaf() { } @Override - public List getChildren() { - return (List) children; + public List getChildren() { + return null; } @Override - public void addChildren(T element) { - addElement((LiteralTraversalElement) element); + public void addChildren(LogicGroup element) { + addElement(element); } + @Override - public void setChildren(List children) { + public void setChildren(List children) { clearChildren(); this.children.addAll(children); } @@ -77,51 +83,49 @@ public void clearChildren() { } @Override - public boolean addElement(LiteralTraversalElement element) { + public boolean addElement(LogicGroup element) { return children.add(element); } @Override - public boolean addElements(List elements) { + public boolean addElements(List elements) { return children.addAll(elements); } @Override - public boolean removeElement(LiteralTraversalElement element) { + public boolean removeElement(LogicGroup element) { return children.remove(element); } @Override - public List getGroupElement() { + public List getGroupElement() { return children.stream() - .filter(e -> GroupElement.class.isAssignableFrom(e.getClass())) - .map(LiteralTraversalElement.class::cast) + .filter(e -> !e.isLeaf()) .toList(); } @Override - public List getAttrElement() { + public List getAttrElement() { return children.stream() - .filter(e -> AttrElement.class.isAssignableFrom(e.getClass())) - .map(LiteralTraversalElement.class::cast) + .filter(LogicGroup::isLeaf) .toList(); } @Override public void clearAttrElement() { - children.removeIf(AttrElement.class::isInstance); + children.removeIf(LogicGroup::isLeaf); } @Override public String getLiteral() { if (isRoot() && CollectionUtils.isNotEmpty(children)) { // root 节点第一个元素一定时OR - LogicGroup element = (LogicGroup) children.get(0); + LogicGroup element = children.get(0); return element.getLiteral(); } StringBuilder literalExpr = new StringBuilder(); for (int i = 0; i < children.size(); i++) { - LiteralTraversalElement children = (LiteralTraversalElement) this.children.get(i); + LogicGroup children = this.children.get(i); String literal = children.getLiteral(); // 构建 a = xxx && xxx 或者 a = xx && (b = xx) literalExpr.append(literal).append(StringPool.SPACE); diff --git a/uno-rule/src/main/java/cc/allio/uno/rule/drools/DroolsPatternDescr.java b/uno-rule/src/main/java/cc/allio/uno/rule/drools/DroolsPatternDescr.java index 92840db9..14c611a9 100644 --- a/uno-rule/src/main/java/cc/allio/uno/rule/drools/DroolsPatternDescr.java +++ b/uno-rule/src/main/java/cc/allio/uno/rule/drools/DroolsPatternDescr.java @@ -179,7 +179,7 @@ public int getLeftParentCharacter() { } /** - * @param leftParentCharacter the leftParentCharacter to set + * @param leftParentCharacter the leftParentCharacter to setValue */ public void setLeftParentCharacter(final int leftParentCharacter) { this.leftParentCharacter = leftParentCharacter; @@ -193,7 +193,7 @@ public int getRightParentCharacter() { } /** - * @param rightParentCharacter the rightParentCharacter to set + * @param rightParentCharacter the rightParentCharacter to setValue */ public void setRightParentCharacter(final int rightParentCharacter) { this.rightParentCharacter = rightParentCharacter; @@ -224,7 +224,7 @@ public List getBehaviors() { } /** - * @param behaviors the behaviors to set + * @param behaviors the behaviors to setValue */ public void setBehaviors(List behaviors) { this.behaviors = behaviors; @@ -245,7 +245,7 @@ public boolean isUnification() { } /** - * @param unification the unification to set + * @param unification the unification to setValue */ public void setUnification(boolean unification) { this.unification = unification; diff --git a/uno-rule/src/test/java/cc/allio/uno/rule/drools/DroolsRuleEngineTest.java b/uno-rule/src/test/java/cc/allio/uno/rule/drools/DroolsRuleEngineTest.java index 24994a3e..779c5e9f 100644 --- a/uno-rule/src/test/java/cc/allio/uno/rule/drools/DroolsRuleEngineTest.java +++ b/uno-rule/src/test/java/cc/allio/uno/rule/drools/DroolsRuleEngineTest.java @@ -254,9 +254,9 @@ void testMultiTrigger() { Flux.merge(fireA.getOnReactive(), fireC.getOnReactive()) .subscribe(); -// Set matchIndices = fireD.get(); +// Set matchIndices = fireD.getValue(); // System.out.println(matchIndices); -// Set matchIndices1 = fireC.get(); +// Set matchIndices1 = fireC.getValue(); } } diff --git a/uno-starters/pom.xml b/uno-starters/pom.xml index 94a6a270..b07e313c 100644 --- a/uno-starters/pom.xml +++ b/uno-starters/pom.xml @@ -5,18 +5,13 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-starters pom - - 8 - 8 - - uno-starter-core uno-starter-kafka diff --git a/uno-starters/uno-starter-core/pom.xml b/uno-starters/uno-starter-core/pom.xml index 7a597f96..261b4bd7 100644 --- a/uno-starters/uno-starter-core/pom.xml +++ b/uno-starters/uno-starter-core/pom.xml @@ -5,7 +5,7 @@ uno-starters cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 diff --git a/uno-starters/uno-starter-core/src/main/java/cc/allio/uno/starter/core/UnoCoreAutoConfiguration.java b/uno-starters/uno-starter-core/src/main/java/cc/allio/uno/starter/core/UnoCoreAutoConfiguration.java index b8d374ec..bf66c3b1 100644 --- a/uno-starters/uno-starter-core/src/main/java/cc/allio/uno/starter/core/UnoCoreAutoConfiguration.java +++ b/uno-starters/uno-starter-core/src/main/java/cc/allio/uno/starter/core/UnoCoreAutoConfiguration.java @@ -4,7 +4,7 @@ import cc.allio.uno.core.env.Envs; import cc.allio.uno.core.env.SpringEnv; import cc.allio.uno.core.env.SystemEnv; -import cc.allio.uno.core.util.CoreBeanUtil; +import cc.allio.uno.core.util.BeanUtils; import org.springframework.beans.BeansException; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.context.ApplicationContext; @@ -26,16 +26,16 @@ public class UnoCoreAutoConfiguration implements ApplicationContextAware { @Bean("unoBeanUtil") - public CoreBeanUtil coreBeanUtil() { - return new CoreBeanUtil(); + public BeanUtils coreBeanUtil() { + return new BeanUtils(); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { ConfigurableEnvironment environment = (ConfigurableEnvironment) applicationContext.getEnvironment(); Env currentEnv = Envs.getCurrentEnv(); - if (currentEnv instanceof SystemEnv) { - Envs.reset(new SpringEnv((SystemEnv) currentEnv, environment)); + if (currentEnv instanceof SystemEnv systemEnv) { + Envs.reset(new SpringEnv(systemEnv, environment)); } } } diff --git a/uno-starters/uno-starter-kafka/pom.xml b/uno-starters/uno-starter-kafka/pom.xml index 7c637b56..0f3dcd6f 100644 --- a/uno-starters/uno-starter-kafka/pom.xml +++ b/uno-starters/uno-starter-kafka/pom.xml @@ -5,17 +5,12 @@ uno-starters cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-starter-kafka - - 8 - 8 - - cc.allio diff --git a/uno-starters/uno-starter-redis/pom.xml b/uno-starters/uno-starter-redis/pom.xml index c694ad87..c38c1cff 100644 --- a/uno-starters/uno-starter-redis/pom.xml +++ b/uno-starters/uno-starter-redis/pom.xml @@ -5,7 +5,7 @@ uno-starters cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 @@ -13,12 +13,6 @@ jar 封装reactive-redis - - 8 - 8 - UTF-8 - - org.springframework.boot diff --git a/uno-starters/uno-starter-sequential/pom.xml b/uno-starters/uno-starter-sequential/pom.xml index 037a29f8..e1747368 100644 --- a/uno-starters/uno-starter-sequential/pom.xml +++ b/uno-starters/uno-starter-sequential/pom.xml @@ -5,18 +5,12 @@ uno-starters cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-starter-sequential - - 8 - 8 - UTF-8 - - cc.allio diff --git a/uno-starters/uno-starter-websocket/pom.xml b/uno-starters/uno-starter-websocket/pom.xml index 48438cf8..e88b2494 100644 --- a/uno-starters/uno-starter-websocket/pom.xml +++ b/uno-starters/uno-starter-websocket/pom.xml @@ -5,18 +5,12 @@ uno-starters cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-starter-websocket - - 8 - 8 - UTF-8 - - org.springframework.boot diff --git a/uno-test/pom.xml b/uno-test/pom.xml index 5cca3065..86cdfe3b 100644 --- a/uno-test/pom.xml +++ b/uno-test/pom.xml @@ -5,17 +5,12 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-test - - 8 - 8 - - @@ -63,6 +58,11 @@ mybatis-plus-boot-starter provided + + com.baomidou + dynamic-datasource-spring-boot-starter + provided + org.springframework.boot spring-boot-starter-data-jpa @@ -72,7 +72,6 @@ cc.allio uno-core - provided diff --git a/uno-test/src/main/java/cc/allio/uno/test/BaseSpringTest.java b/uno-test/src/main/java/cc/allio/uno/test/BaseSpringTest.java index 99fd53fa..b1736231 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/BaseSpringTest.java +++ b/uno-test/src/main/java/cc/allio/uno/test/BaseSpringTest.java @@ -1,5 +1,6 @@ package cc.allio.uno.test; +import cc.allio.uno.core.env.Env; import cc.allio.uno.core.env.Envs; import cc.allio.uno.core.env.SpringEnv; import cc.allio.uno.core.env.SystemEnv; @@ -54,7 +55,7 @@ public abstract class BaseSpringTest extends BaseTestCase { @Override protected void onInit() throws Throwable { // 实例化 context - this.context = createApplication(); + this.context = createApplicationContext(); // ---------- 资源初始化 ---------- // 从当前项目路径上下文添加配置文件 @@ -70,7 +71,10 @@ protected void onInit() throws Throwable { // 构建spring环境 ConfigurableEnvironment environment = context.getEnvironment(); - Envs.reset(new SpringEnv((SystemEnv) Envs.getCurrentEnv(), environment)); + Env env = Envs.getCurrentEnv(); + if (env instanceof SystemEnv systemEnv) { + Envs.reset(new SpringEnv(systemEnv, environment)); + } context.refresh(); // 完成后的回调 @@ -82,7 +86,7 @@ protected void onInit() throws Throwable { * * @return ApplicationContext实例 */ - protected GenericApplicationContext createApplication() { + protected GenericApplicationContext createApplicationContext() { return new AnnotationConfigApplicationContext(); } diff --git a/uno-test/src/main/java/cc/allio/uno/test/CoreTest.java b/uno-test/src/main/java/cc/allio/uno/test/CoreTest.java index d98cbb5b..d01ae27d 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/CoreTest.java +++ b/uno-test/src/main/java/cc/allio/uno/test/CoreTest.java @@ -39,11 +39,7 @@ public CoreTest() { } public CoreTest(Class testClass) { - if (testClass == null) { - this.testClass = getClass(); - } else { - this.testClass = testClass; - } + this.testClass = Objects.requireNonNullElseGet(testClass, this::getClass); } // ----------------- lifecycle ----------------- @@ -99,7 +95,7 @@ public RunTestAttributes getRunTestAttributes() { return new RunTestAttributes(getTestClass()); } - // ----------------- get/set ----------------- + // ----------------- getValue/setValue ----------------- public void setEnv(EnvironmentFacade env) { this.env = env; @@ -115,7 +111,7 @@ public EnvironmentFacade getEnv() { } /** - * set CoreRunner + * setValue CoreRunner * * @param coreRunner coreRunner */ @@ -124,7 +120,7 @@ public void setCoreRunner(CoreRunner coreRunner) { } /** - * get coreRunner + * getValue coreRunner * * @return coreRunner */ diff --git a/uno-test/src/main/java/cc/allio/uno/test/ExecutableCoreTest.java b/uno-test/src/main/java/cc/allio/uno/test/ExecutableCoreTest.java index 96fd7e36..b30b3b51 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/ExecutableCoreTest.java +++ b/uno-test/src/main/java/cc/allio/uno/test/ExecutableCoreTest.java @@ -3,9 +3,6 @@ import cc.allio.uno.test.env.Visitor; import cc.allio.uno.test.runner.CoreRunner; import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.context.support.GenericApplicationContext; import java.util.Set; @@ -27,22 +24,8 @@ public ExecutableCoreTest(Class testClass, TestContext testContext) { this.testContext = testContext; } - @Override - protected GenericApplicationContext createApplication() { - return getTestContext().get(TestContext.WEB_SERVER) - .map(web -> { - if ("servlet".equals(web)) { - return new AnnotationConfigServletWebServerApplicationContext(); - } else if ("reactive".equals(web)) { - return new AnnotationConfigReactiveWebServerApplicationContext(); - } - return super.createApplication(); - }) - .orElseGet(super::createApplication); - } - /** - * set CoreRunner + * setValue CoreRunner * * @param coreRunner coreRunner * @see RunTestAttributes#getCoreRunner() @@ -53,7 +36,7 @@ public void setCoreRunner(CoreRunner coreRunner) { } /** - * get coreRunner + * getValue coreRunner * * @return coreRunner */ diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/DynamicDataSourceEnvironment.java b/uno-test/src/main/java/cc/allio/uno/test/env/DynamicDataSourceEnvironment.java new file mode 100644 index 00000000..9f64c468 --- /dev/null +++ b/uno-test/src/main/java/cc/allio/uno/test/env/DynamicDataSourceEnvironment.java @@ -0,0 +1,24 @@ +package cc.allio.uno.test.env; + +import cc.allio.uno.test.CoreTest; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DruidDynamicDataSourceConfiguration; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration; +import jakarta.annotation.Priority; + +import java.lang.annotation.Annotation; + +@Priority(Integer.MIN_VALUE + 1) +public class DynamicDataSourceEnvironment extends VisitorEnvironment { + @Override + public Class[] getPropertiesAnnotation() { + return new Class[0]; + } + + @Override + protected void onSupport(CoreTest coreTest) throws Throwable { + coreTest.registerAutoConfiguration( + DynamicDataSourceAutoConfiguration.class, + DynamicDataSourceAutoConfiguration.class, + DruidDynamicDataSourceConfiguration.class); + } +} diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/DynamicConfigure.java b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/DynamicConfigure.java index af153d16..662caeb9 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/DynamicConfigure.java +++ b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/DynamicConfigure.java @@ -31,7 +31,7 @@ public BeanDefinition extract(CoreTest coreTest, MergedAnnotation an try { URL resource = ClassLoader.getSystemResource("./"); if (resource == null) { - throw new NullPointerException("the class can't get '/' resource"); + throw new NullPointerException("the class can't getValue '/' resource"); } String currentClassPath = resource.getPath(); // 动态生成一个配置类 diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/DynamicDataSourceEnv.java b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/DynamicDataSourceEnv.java new file mode 100644 index 00000000..2ee54988 --- /dev/null +++ b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/DynamicDataSourceEnv.java @@ -0,0 +1,13 @@ +package cc.allio.uno.test.env.annotation; + +import cc.allio.uno.test.env.DynamicDataSourceEnvironment; + +import java.lang.annotation.*; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@AnnoConfigure +@Env({DynamicDataSourceEnvironment.class}) +public @interface DynamicDataSourceEnv { +} diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisConfigure.java b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisConfigure.java index 51512105..9acc6a9f 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisConfigure.java +++ b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisConfigure.java @@ -24,7 +24,8 @@ protected AnnotationDescription[] buildAnnoDesc(CoreTest coreTest, MergedAnnotat String[] basePackages = annotation.getStringArray("basePackages"); // values and basePackages mutual alias for if (values.length == 0 && basePackages.length == 0) { - basePackages = new String[]{coreTestPackageName}; + // if not specified basePackages, use test package path and addition .mapper + basePackages = new String[]{coreTestPackageName.concat(".mapper")}; } annoBuilder = annoBuilder.defineArray("value", values) .defineArray("basePackages", basePackages) diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisEnv.java b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisEnv.java index 012aee89..c059930b 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisEnv.java +++ b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisEnv.java @@ -124,7 +124,7 @@ * Default is {@code false}. *

      * - * @return set {@code true} to enable lazy initialization + * @return setValue {@code true} to enable lazy initialization * @since 2.0.2 */ String lazyInitialization() default ""; diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisPlusEnv.java b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisPlusEnv.java index 283a5b34..2c691a7c 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisPlusEnv.java +++ b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/MybatisPlusEnv.java @@ -119,7 +119,7 @@ * Default is {@code false}. *

      * - * @return set {@code true} to enable lazy initialization + * @return setValue {@code true} to enable lazy initialization * @since 2.0.2 */ String lazyInitialization() default ""; diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/DataSourceProperties.java b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/DataSourceProperties.java index cd696aff..3b1613f4 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/DataSourceProperties.java +++ b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/DataSourceProperties.java @@ -49,7 +49,7 @@ /** * JNDI location of the datasource. Class, url, username and password are ignored when - * set. + * setValue. */ String jndiName() default ""; diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/LoadBalancerRetryProperties.java b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/LoadBalancerRetryProperties.java index a44bb367..d1713120 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/LoadBalancerRetryProperties.java +++ b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/LoadBalancerRetryProperties.java @@ -59,19 +59,19 @@ boolean enable() default false; /** - * Used to set {@link RetryBackoffSpec#minBackoff}. + * Used to setValue {@link RetryBackoffSpec#minBackoff}. */ @PropertiesType(Duration.class) long minBackoff() default 5; /** - * Used to set {@link RetryBackoffSpec#maxBackoff}. + * Used to setValue {@link RetryBackoffSpec#maxBackoff}. */ @PropertiesType(Duration.class) long maxBackoff() default Long.MAX_VALUE; /** - * Used to set {@link RetryBackoffSpec#jitter}. + * Used to setValue {@link RetryBackoffSpec#jitter}. */ double jitter() default 0.5d; } diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/MybatisProperties.java b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/MybatisProperties.java index 4de18822..3185eb0c 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/MybatisProperties.java +++ b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/MybatisProperties.java @@ -63,12 +63,6 @@ */ Class defaultScriptingLanguageDriver() default XMLLanguageDriver.class; - /** - * A Configuration object for customize default settings. If {@link #configLocation} is specified, this property is - * not used. - */ - Configuration configuration(); - /** * {@link org.apache.ibatis.session.Configuration}注解描述 * diff --git a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/RedisProperties.java b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/RedisProperties.java index c448ab8e..76c70638 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/RedisProperties.java +++ b/uno-test/src/main/java/cc/allio/uno/test/env/annotation/properties/RedisProperties.java @@ -65,7 +65,7 @@ long timeout() default 30000L; /** - * Client name to be set on connections with CLIENT SETNAME. + * Client name to be setValue on connections with CLIENT SETNAME. */ String clientName() default ""; diff --git a/uno-test/src/main/java/cc/allio/uno/test/runner/AnnoMetadataRunner.java b/uno-test/src/main/java/cc/allio/uno/test/runner/AnnoMetadataRunner.java index 41ab8e96..3e9b578b 100644 --- a/uno-test/src/main/java/cc/allio/uno/test/runner/AnnoMetadataRunner.java +++ b/uno-test/src/main/java/cc/allio/uno/test/runner/AnnoMetadataRunner.java @@ -1,14 +1,12 @@ package cc.allio.uno.test.runner; import cc.allio.uno.core.util.ClassUtils; -import cc.allio.uno.core.util.ObjectUtils; import cc.allio.uno.test.env.Environment; import cc.allio.uno.test.env.annotation.AnnoConfigure; import cc.allio.uno.test.env.annotation.Env; import cc.allio.uno.test.env.annotation.EnvConfigure; import cc.allio.uno.test.env.annotation.Extractor; import cc.allio.uno.test.CoreTest; -import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.support.GenericApplicationContext; @@ -18,8 +16,6 @@ import java.lang.annotation.Annotation; import java.util.List; -import java.util.Set; -import java.util.stream.Stream; /** * 基于注解信息,构建环境配置信息。 @@ -37,9 +33,6 @@ @Slf4j public class AnnoMetadataRunner implements RegisterRunner { - private final Set> parsedEnvCaches = Sets.newConcurrentHashSet(); - private final Set> envConfigureCaches = Sets.newConcurrentHashSet(); - @Override public void onRegister(CoreTest coreTest) throws Throwable { MergedAnnotations mergedAnnotations = coreTest.getAllAnnotations(); @@ -70,25 +63,21 @@ public void onRegister(CoreTest coreTest) throws Throwable { * * @param env Environment */ - public void resolveEnv(CoreTest coreTest, Env env) throws Throwable { + public void resolveEnv(CoreTest coreTest, Env env) { Class[] envClasses = env.value(); - // 能够被允许的环境 - Class[] allowEnv = Stream.of(envClasses).filter(c -> !parsedEnvCaches.contains(c)).toArray(Class[]::new); - if (ObjectUtils.isNotEmpty(allowEnv)) { - ClassUtils.Instantiation instantiation = - ClassUtils.instantiationBuilder().addMultiForInstanceClasses(allowEnv).setExcludeNull(true).build(); - instantiation.addFeature(new ClassUtils.DeDuplicationFeature<>()); - instantiation.addFeature(new ClassUtils.SortFeature<>()); - List environments = instantiation.create(); - for (Environment environment : environments) { - Class envClass = environment.getClass(); - try { - environment.support(coreTest); - // 构建的环境添加于缓存之中 - parsedEnvCaches.add(envClass); - } catch (Throwable ex) { - log.error("support environment {} happened error", environment.getClass().getName(), ex); - } + ClassUtils.Instantiation instantiation = + ClassUtils.instantiationBuilder() + .addMultiForInstanceClasses(envClasses) + .setExcludeNull(true) + .build(); + instantiation.addFeature(new ClassUtils.DeDuplicationFeature<>()); + instantiation.addFeature(new ClassUtils.SortFeature<>()); + List environments = instantiation.create(); + for (Environment environment : environments) { + try { + environment.support(coreTest); + } catch (Throwable ex) { + log.error("support environment {} happened error", environment.getClass().getName(), ex); } } } @@ -102,16 +91,13 @@ public void resolveEnv(CoreTest coreTest, Env env) throws Throwable { */ private void extractEnv(MergedAnnotation anno, Extractor extractor, CoreTest coreTest) { Class extractorClazz = extractor.value(); - if (!envConfigureCaches.contains(extractorClazz)) { - EnvConfigure configureExtractor = ClassUtils.newInstanceIfErrorDefault(extractorClazz, null, null); - if (configureExtractor != null) { - // 动态生成bean 配置类 - BeanDefinition beanDefinition = configureExtractor.extract(coreTest, anno); - GenericApplicationContext context = coreTest.getContext(); - if (beanDefinition != null && context != null) { - context.registerBeanDefinition(anno.getType().getName(), beanDefinition); - } - envConfigureCaches.add(extractorClazz); + EnvConfigure configureExtractor = ClassUtils.newInstanceIfErrorDefault(extractorClazz, null, null); + if (configureExtractor != null) { + // 动态生成bean 配置类 + BeanDefinition beanDefinition = configureExtractor.extract(coreTest, anno); + GenericApplicationContext context = coreTest.getContext(); + if (beanDefinition != null && context != null) { + context.registerBeanDefinition(anno.getType().getName(), beanDefinition); } } } diff --git a/uno-web/pom.xml b/uno-web/pom.xml index 27b01ca7..8120f3dc 100644 --- a/uno-web/pom.xml +++ b/uno-web/pom.xml @@ -5,20 +5,14 @@ uno cc.allio - 1.1.5.RELEASE + 1.1.6-beta.1 4.0.0 uno-web - 1.1.5.RELEASE + 1.1.6-beta.1 基于spring-webmvc、spring-webflux - - 8 - 8 - UTF-8 - - cc.allio