├── .gitignore ├── LICENSE ├── README.md ├── build.gradle.kts ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src ├── main └── kotlin │ └── cn │ └── enaium │ └── jimmer │ └── gradle │ ├── JimmerPlugin.kt │ ├── SettingPlugin.kt │ ├── extension │ ├── Association.kt │ ├── Client.kt │ ├── Driver.kt │ ├── Dto.kt │ ├── Entry.kt │ ├── Generator.kt │ ├── Immutable.kt │ ├── InputDtoModifier.kt │ ├── JDBC.kt │ ├── JimmerExtension.kt │ ├── Language.kt │ ├── Poet.kt │ ├── SettingExtension.kt │ ├── Source.kt │ ├── Table.kt │ └── Target.kt │ ├── model │ ├── Column.kt │ ├── ForeignKey.kt │ ├── PrimaryKey.kt │ ├── Table.kt │ └── UniqueKey.kt │ ├── service │ ├── EntityGenerateService.kt │ └── impl │ │ ├── JavaEntityGenerateService.kt │ │ └── KotlinEntityGenerateService.kt │ ├── task │ ├── AllProjectDependencies.kt │ ├── GenerateEntityTask.kt │ └── GenerateLspDependenciesTask.kt │ └── utility │ ├── const.kt │ ├── dependency.kt │ ├── extension.kt │ ├── jdbc.kt │ ├── mapping.kt │ ├── plugin.kt │ ├── string.kt │ ├── task.kt │ └── utility.kt └── test ├── kotlin └── cn │ └── enaium │ └── jimmer │ └── gradle │ ├── integration │ ├── AbstractGeneratorEntityTest.kt │ ├── AptArgumentTest.kt │ ├── DDLGeneratorTest.kt │ ├── H2GeneratorTest.kt │ ├── KspArgumentTest.kt │ ├── MariaDBGeneratorTest.kt │ └── PostgresSQLGeneratorTest.kt │ └── util │ └── ProjectTest.kt └── resources ├── generated └── entity │ ├── java │ ├── Answer.java │ ├── BaseEntity.java │ ├── Comment.java │ ├── People.java │ ├── Post.java │ ├── Profile.java │ ├── Question.java │ └── Topic.java │ └── kotlin │ ├── Answer.kt │ ├── BaseEntity.kt │ ├── Comment.kt │ ├── People.kt │ ├── Post.kt │ ├── Profile.kt │ ├── Question.kt │ └── Topic.kt ├── mariadb.sql ├── postgres.sql └── projects ├── aptArgument ├── build.gradle.kts └── settings.gradle.kts ├── generateDDL ├── build.gradle.kts ├── settings.gradle.kts └── src │ └── main │ └── resources │ └── schema.sql ├── generateEntity ├── build.gradle.kts └── settings.gradle.kts └── kspArgument ├── build.gradle.kts └── settings.gradle.kts /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea 9 | *.iws 10 | *.iml 11 | *.ipr 12 | out/ 13 | !**/src/main/**/out/ 14 | !**/src/test/**/out/ 15 | 16 | ### Eclipse ### 17 | .apt_generated 18 | .classpath 19 | .factorypath 20 | .project 21 | .settings 22 | .springBeans 23 | .sts4-cache 24 | bin/ 25 | !**/src/main/**/bin/ 26 | !**/src/test/**/bin/ 27 | 28 | ### NetBeans ### 29 | /nbproject/private/ 30 | /nbbuild/ 31 | /dist/ 32 | /nbdist/ 33 | /.nb-gradle/ 34 | 35 | ### VS Code ### 36 | .vscode/ 37 | 38 | ### Mac OS ### 39 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jimmer-gradle 2 | 3 | ![GitHub top language](https://img.shields.io/github/languages/top/enaium/jimmer-gradle?style=flat-square&logo=kotlin) 4 | ![Gradle Plugin Portal Version](https://img.shields.io/gradle-plugin-portal/v/cn.enaium.jimmer.gradle?style=flat-square&logo=gradle) 5 | 6 | ## Feature 7 | 8 | - Generate code for table, column and association from database or ddl. 9 | - Incremental compile for dto language (apt/ksp). 10 | - Add implementation (spring-boot-start/sql/sql-kotlin) for dependencies. 11 | - Add annotationProcessor/ksp for dependencies. 12 | - Easy to add arguments for annotationProcessor/ksp. 13 | - Can use jimmer's catalog in the project. 14 | - Let jimmer generate code when opening the project for the first time. 15 | 16 | ## Usage(Recommended Method 2) 17 | 18 | Warning: You cannot use the method 1 and method 2 at the same time. 19 | 20 | ### Gradle Project Plugin(Method 1) 21 | 22 | In the `build.gradle.kts` file, you can use the following code to apply the plugin. 23 | 24 | ```kotlin 25 | plugins { 26 | id("cn.enaium.jimmer.gradle") version "latest.release" 27 | } 28 | ``` 29 | 30 | If you also used kotlin, you need to declare the ksp plugin before the jimmer plugin. 31 | 32 | ```kotlin 33 | plugins { 34 | kotlin("jvm") version "2.0.21" 35 | id("com.google.devtools.ksp") version "2.0.21+" 36 | id("cn.enaium.jimmer.gradle") version "latest.release" 37 | } 38 | ``` 39 | 40 | ### Gradle Settings Plugin(Method 2) 41 | 42 | In the `settings.gradle.kts` file, you can use the following code to apply the plugin. 43 | 44 | ```kotlin 45 | plugins { 46 | id("cn.enaium.jimmer.gradle.setting") version "latest.release" 47 | } 48 | ``` 49 | 50 | If you want to modify the extension of the gradle project plugin, then you can use the gradle project plugin. 51 | 52 | ```kotlin 53 | plugins { 54 | alias(jimmers.plugins.jimmer) 55 | } 56 | ``` 57 | 58 | If you also used kotlin, you need to declare the ksp plugin before the jimmer plugin. 59 | 60 | ```kotlin 61 | plugins { 62 | kotlin("jvm") version "2.0.21" 63 | alias(jimmers.plugins.ksp) version "2.0.21+" 64 | alias(jimmers.plugins.jimmer) 65 | } 66 | ``` 67 | 68 | then you need to add the ksp dependency in the `build.gradle.kts` file. 69 | 70 | ```kotlin 71 | dependencies { 72 | ksp(jimmers.ksp) 73 | } 74 | ``` 75 | 76 | ## Jimmer's Version(Both Gradle Project Plugin and Gradle Settings Plugin) 77 | 78 | Warning: The version of the extension is not supported for `ksp` when 79 | issue [#1789](https://github.com/google/ksp/issues/1789) isn't fixed, but you can use the latest version or use the 80 | gradle setting 81 | plugin. 82 | 83 | In the `build.gradle.kts` file if you use the gradle project plugin, or in the `settings.gradle.kts` file if you use the 84 | gradle settings plugin, you can use the following code to set the version of jimmer. 85 | 86 | ```kotlin 87 | jimmer { 88 | version.set("latest.release")//default latest 89 | } 90 | ``` 91 | 92 | ## Generate Entity(Only Gradle Project Plugin) 93 | 94 | ![Static Badge](https://img.shields.io/badge/-Kotlin-gray?style=flat-square&logo=kotlin&logoColor=white) 95 | ![Static Badge](https://img.shields.io/badge/-Java-gray?style=flat-square&logo=openjdk&logoColor=white) 96 | 97 | ![Static Badge](https://img.shields.io/badge/-PostgreSQL-gray?style=flat-square&logo=postgresql&logoColor=white) 98 | ![Static Badge](https://img.shields.io/badge/-MariaDB-gray?style=flat-square&logo=mariadb&logoColor=white) 99 | ![Static Badge](https://img.shields.io/badge/-MySQL-gray?style=flat-square&logo=mysql&logoColor=white) 100 | 101 | ### From Database 102 | 103 | ```kotlin 104 | import cn.enaium.jimmer.gradle.extension.Association 105 | import cn.enaium.jimmer.gradle.extension.Driver 106 | 107 | plugins { 108 | //... 109 | id("cn.enaium.jimmer.gradle") version "" 110 | } 111 | 112 | dependencies { 113 | //... 114 | runtimeOnly("org.postgresql:postgresql:42.6.0")//require jdbc driver 115 | } 116 | 117 | jimmer { 118 | generator { 119 | target { 120 | srcDir.set("src/main/kotlin") 121 | packageName.set("cn.enaium") 122 | } 123 | jdbc { 124 | driver.set(Driver.POSTGRESQL)//Driver.POSTGRESQL,Driver.MARIADB,Driver.MYSQL, no default 125 | url.set("jdbc:postgresql://localhost:5432/postgres") 126 | username.set("postgres") 127 | password.set("postgres") 128 | // catalog.set("postgres") 129 | // schemaPattern.set("public") 130 | // tableNamePattern.set("t_%") 131 | } 132 | table { 133 | idView.set(true) 134 | comment.set(true) 135 | primaryKey.set("id")//default id 136 | association.set(Association.REAL)//Association.REAL,Association.FAKE,Association.NO, default Association.REAL 137 | typeMappings.set( 138 | mapOf( 139 | "float8" to "kotlin.Float", 140 | ) 141 | ) 142 | } 143 | } 144 | } 145 | ``` 146 | 147 | ### From DDL 148 | 149 | ```kotlin 150 | jimmer { 151 | generator { 152 | target { 153 | srcDir.set("src/main/kotlin") 154 | packageName.set("cn.enaium") 155 | } 156 | jdbc { 157 | ddl.set(file("src/main/resources/schema.sql")) 158 | } 159 | } 160 | } 161 | ``` 162 | 163 | ### Association(Only Gradle Project Plugin) 164 | 165 | You must add the suffix '_id'(`primaryKey.set("id")`) to the column name if the column is a fake foreign key, otherwise 166 | the column cannot be recognized as a foreign key. 167 | 168 | If you want to use the fake foreign key, you need to set the `association.set(Association.FAKE)`, otherwise the default 169 | is `association.set(Association.REAL)`, of course you can also set `association.set(Association.NO)` to disable the 170 | association. 171 | 172 | **Warning: You can't use the fake association if you included the real association in the database.** 173 | 174 | ```kotlin 175 | jimmer { 176 | generator { 177 | table { 178 | primaryKey.set("id") 179 | association.set(Association.REAL) 180 | } 181 | } 182 | } 183 | ``` 184 | 185 | ### typeMappings(Only Gradle Project Plugin) 186 | 187 | [default](src/main/kotlin/cn/enaium/jimmer/gradle/utility/mapping.kt) 188 | 189 | You can customize the type mapping, the default is as follows: 190 | 191 | ```kotlin 192 | jimmer { 193 | generator { 194 | table { 195 | typeMappings.set( 196 | mapOf( 197 | "float8" to "kotlin.Float",//Java: "java.lang.Float" 198 | ) 199 | ) 200 | } 201 | } 202 | } 203 | ``` 204 | 205 | ## Dto Incremental Compile 206 | 207 | Open the dto file and press `Ctrl + F9` to compile the dto file. 208 | 209 | ## implementation for dependencies 210 | 211 | ### spring-boot-start 212 | 213 | ```kotlin 214 | plugins { 215 | id("org.springframework.boot")//require 216 | } 217 | ``` 218 | 219 | It will automatically add or use the catalog of jimmer if you use the gradle settings plugin. 220 | 221 | ```kotlin 222 | dependencies { 223 | implementation(jimmers.springBootStart) 224 | } 225 | ``` 226 | 227 | ### sql-kotlin 228 | 229 | It will automatically add or use the catalog of jimmer if you use the gradle settings plugin. 230 | 231 | ```kotlin 232 | dependencies { 233 | implementation(jimmers.sqlKotlin) 234 | } 235 | ``` 236 | 237 | ### sql 238 | 239 | It will automatically add or use the catalog of jimmer if you use the gradle settings plugin. 240 | 241 | ```kotlin 242 | dependencies { 243 | implementation(jimmers.sql) 244 | } 245 | ``` 246 | 247 | ## annotationProcessor/ksp for dependencies 248 | 249 | ### ksp 250 | 251 | It will automatically add or use the catalog of jimmer if you use the gradle settings plugin. 252 | 253 | ```kotlin 254 | plugins { 255 | kotlin("jvm") version "2.0.21" 256 | id("com.google.devtools.ksp") version "2.0.21+" //require and must declare before jimmer gradle plugin 257 | } 258 | ``` 259 | 260 | ```kotlin 261 | plugins { 262 | kotlin("jvm") version "2.0.21" 263 | alias(jimmers.plugins.ksp) version "2.0.21+" 264 | } 265 | ``` 266 | 267 | ```kotlin 268 | dependencies { 269 | ksp(jimmers.ksp) 270 | } 271 | ``` 272 | 273 | ### annotationProcessor 274 | 275 | It will automatically add or use the catalog of jimmer if you use the gradle settings plugin. 276 | 277 | ```kotlin 278 | dependencies { 279 | annotationProcessor(jimmers.apt) 280 | } 281 | ``` 282 | 283 | ## annotationProcessor/ksp arguments(Only Gradle Project Plugin) 284 | 285 | ```kotlin 286 | jimmer { 287 | entry { 288 | objects.set("Drafts")//equal to -Ajimmer.entry.objects=Drafts 289 | } 290 | } 291 | ``` 292 | 293 | ## Gradle Project Plugin Extension 294 | 295 | | extension | type | default | description | 296 | |-------------------------------------|------------------------------------------------------|------------------|--------------------------------------------------------------| 297 | | `version` | `String` | `latest.release` | Jimmer version. | 298 | | `keepIsPrefix` | `Boolean` | `false` | Keep 'is' prefix in getter method. | 299 | | `generator` | `cn.enaium.jimmer.gradle.extension.Generator` | | Entity generator. | 300 | | `generator.target` | `cn.enaium.jimmer.gradle.extension.Target` | | Entity generator target. | 301 | | `generator.target.srcDir` | `String` | | Entity generator target src dir. | 302 | | `generator.target.packageName` | `String` | | Entity generator target package. | 303 | | `generator.jdbc` | `cn.enaium.jimmer.gradle.extension.Jdbc` | | For database connection. | 304 | | `generator.jdbc.driver` | `cn.enaium.jimmer.gradle.extension.Driver` | | Database driver. | 305 | | `generator.jdbc.url` | `String` | | Database url. | 306 | | `generator.jdbc.username` | `String` | | Database username. | 307 | | `generator.jdbc.password` | `String` | | Database password. | 308 | | `generator.jdbc.ddl` | `File` | | DDL sql file. | 309 | | `generator.jdbc.catalog` | `String` | | Database catalog. | 310 | | `generator.jdbc.schemaPattern` | `String` | | Database schema pattern. | 311 | | `generator.jdbc.tableNamePattern` | `String` | | Database table name pattern. | 312 | | `generator.table` | `cn.enaium.jimmer.gradle.extension.Table` | | Table rule. | 313 | | `generator.table.name` | `Boolean` | `false` | Add table annotation. | 314 | | `generator.table.column` | `Boolean` | `false` | Add column annotation. | 315 | | `generator.table.primaryKey` | `String` | `id` | Table primary key name. | 316 | | `generator.table.asociation` | `cn.enaium.jimmer.gradle.extension.Association` | `REAL` | Table association rule. | 317 | | `generator.table.typeMappings` | `Map` | | Column type mapping. | 318 | | `generator.table.comment` | `Boolean` | `false` | Generate table comment. | 319 | | `generator.table.idView` | `Boolean` | `false` | Generate id view annotation. | 320 | | `generator.table.joinTable` | `Boolean` | `false` | Generate join table annotation. | 321 | | `generator.table.idGeneratorType` | `String` | | Generate generated value annotation that has generator type. | 322 | | `generator.poet` | `cn.enaium.jimmer.gradle.extension.Poet` | | Poet rule. | 323 | | `generator.poet.indent` | `String` | Four spaces | Poet indent. | 324 | | `client.checkedExceptions` | `Boolean` | | | 325 | | `client.ignoreJdkWarning` | `Boolean` | | Java only. | 326 | | `dto.dirs` | `List` | | | 327 | | `dto.testDirs` | `List` | | | 328 | | `dto.mutable` | `Boolean` | | Kotlin only. | 329 | | `dto.defaultNullableInputModifier` | `cn.enaium.jimmer.gradle.extension.InputDtoModifier` | | | 330 | | `dto.hibernateValidatorEnhancement` | `Boolean` | | Java only. | 331 | | `entry` | `cn.enaium.jimmer.gradle.extension.Entry` | | Java only. | 332 | | `entry.objects` | `String` | | Generate `objects` class name, java only. | 333 | | `entry.tables` | `String` | | Generate `tables` class name, java only. | 334 | | `entry.tableExes` | `String` | | Generate `tableExes` class name, java only. | 335 | | `entry.fetchers` | `String` | | Generate `fetchers` class name, java only. | 336 | | `immutable.isModuleRequired` | `Boolean` | | Kotlin only. | 337 | | `source.includes` | `List` | | Java only. | 338 | | `source.excludes` | `List` | | Java only. | 339 | 340 | ## Gradle Settings Plugin Extension 341 | 342 | | extension | type | default | description | 343 | |-----------|----------|------------------|-----------------| 344 | | `version` | `String` | `latest.release` | Jimmer version. | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.kotlin.jvm) 3 | alias(libs.plugins.gradle.publish) 4 | `java-gradle-plugin` 5 | `maven-publish` 6 | } 7 | 8 | group = "cn.enaium" 9 | version = "${properties["version"]}" 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation(libs.kotlinpoet) 17 | implementation(libs.javapoet) 18 | implementation(libs.jetbrainsAnnotations) 19 | implementation(libs.jimmer) 20 | implementation(libs.jackson) 21 | implementation(libs.jackson.kotlin) 22 | implementation(libs.h2) 23 | testImplementation(libs.testcontainers.postgresql) 24 | testImplementation(libs.testcontainers.mariadb) 25 | testImplementation(libs.testcontainers.mysql) 26 | testImplementation(libs.postgresql) 27 | testImplementation(libs.mariadb) 28 | testImplementation(libs.mysql) 29 | testImplementation(libs.kotlin.test) 30 | } 31 | 32 | tasks.test { 33 | useJUnitPlatform() 34 | jvmArgs("-D${rootProject.name}=${project.version}") 35 | dependsOn(tasks.publishToMavenLocal) 36 | } 37 | 38 | gradlePlugin { 39 | website.set("https://github.com/Enaium/jimmer-gradle/") 40 | vcsUrl.set("https://github.com/Enaium/jimmer-gradle/") 41 | plugins { 42 | create("jimmer") { 43 | id = "cn.enaium.jimmer.gradle" 44 | implementationClass = "cn.enaium.jimmer.gradle.JimmerPlugin" 45 | displayName = "jimmer-gradle" 46 | description = "A gradle plugin for jimmer" 47 | tags.set(listOf("orm", "jimmer", "generator")) 48 | } 49 | create("setting") { 50 | id = "cn.enaium.jimmer.gradle.setting" 51 | implementationClass = "cn.enaium.jimmer.gradle.SettingPlugin" 52 | displayName = "setting" 53 | description = "A gradle plugin for jimmer" 54 | tags.set(listOf("orm", "jimmer", "generator")) 55 | } 56 | } 57 | } 58 | 59 | 60 | publishing { 61 | publications { 62 | create("maven") { 63 | groupId = project.group.toString() 64 | artifactId = project.name 65 | version = project.version.toString() 66 | 67 | from(components["java"]) 68 | } 69 | } 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | version=0.0.29 -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | kotlin = "2.1.0" 3 | publishing = "1.2.1" 4 | kotlinpoet = "2.0.0" 5 | javapoet = "1.13.0" 6 | testcontainers = "1.19.7" 7 | postgresql = "42.7.3" 8 | mariadb = "3.3.3" 9 | mysql = "8.3.0" 10 | jimmer = "0.9.45" 11 | jetbrainsAnnotations = "24.1.0" 12 | jackson = "2.18.2" 13 | h2 = "2.3.232" 14 | 15 | [libraries] 16 | kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } 17 | javapoet = { module = "com.squareup:javapoet", version.ref = "javapoet" } 18 | jetbrainsAnnotations = { module = "org.jetbrains:annotations", version.ref = "jetbrainsAnnotations" } 19 | jimmer = { module = "org.babyfish.jimmer:jimmer-core", version.ref = "jimmer" } 20 | jackson = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "jackson" } 21 | jackson-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } 22 | testcontainers-postgresql = { module = "org.testcontainers:postgresql", version.ref = "testcontainers" } 23 | testcontainers-mariadb = { module = "org.testcontainers:mariadb", version.ref = "testcontainers" } 24 | testcontainers-mysql = { module = "org.testcontainers:mysql", version.ref = "testcontainers" } 25 | postgresql = { module = "org.postgresql:postgresql", version.ref = "postgresql" } 26 | mariadb = { module = "org.mariadb.jdbc:mariadb-java-client", version.ref = "mariadb" } 27 | mysql = { module = "com.mysql:mysql-connector-j", version.ref = "mysql" } 28 | kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } 29 | h2 = { module = "com.h2database:h2", version.ref = "h2" } 30 | 31 | [plugins] 32 | kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } 33 | gradle-publish = { id = "com.gradle.plugin-publish", version.ref = "publishing" } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enaium/jimmer-gradle/b90c16adacebb4370ecd244141abbe89b2c26272/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Feb 21 13:43:28 CST 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "jimmer-gradle" 2 | 3 | -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/JimmerPlugin.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle 18 | 19 | import cn.enaium.jimmer.gradle.extension.JimmerExtension 20 | import cn.enaium.jimmer.gradle.extension.Language 21 | import cn.enaium.jimmer.gradle.task.AllProjectDependencies 22 | import cn.enaium.jimmer.gradle.task.GenerateEntityTask 23 | import cn.enaium.jimmer.gradle.task.GenerateLspDependenciesTask 24 | import cn.enaium.jimmer.gradle.utility.* 25 | import org.gradle.api.Plugin 26 | import org.gradle.api.Project 27 | import org.gradle.api.Task 28 | import org.gradle.api.internal.tasks.JvmConstants 29 | 30 | /** 31 | * @author Enaium 32 | */ 33 | class JimmerPlugin : Plugin { 34 | override fun apply(project: Project) { 35 | val extension = project.extensions.create("jimmer", JimmerExtension::class.java) 36 | 37 | if (!extension.language.isPresent) { 38 | if (project.plugins.hasJava) { 39 | extension.language.set(Language.JAVA) 40 | } 41 | 42 | if (project.plugins.hasKotlin) { 43 | extension.language.set(Language.KOTLIN) 44 | } 45 | } 46 | 47 | project.afterEvaluate { afterProject -> 48 | val generateEntity = afterProject.tasks.register("generateEntity", GenerateEntityTask::class.java) 49 | val generateLspDependencies = 50 | afterProject.tasks.register("generateLspDependencies", GenerateLspDependenciesTask::class.java) 51 | val allProjectDependencies = 52 | afterProject.tasks.register("allProjectDependencies", AllProjectDependencies::class.java) 53 | 54 | if (extension.language.get() == Language.JAVA) { 55 | afterProject.tasks.compileJava { compile -> 56 | 57 | fun add(key: String, value: String) { 58 | compile.options.compilerArgs.add("-A$key=$value") 59 | } 60 | 61 | extension.keepIsPrefix.takeIf { it.isPresent }?.let { 62 | add(KEEP_IS_PREFIX, it.get().toString()) 63 | } 64 | 65 | extension.source.includes.takeIf { it.isPresent && it.get().isNotEmpty() }?.let { 66 | add(SOURCE_INCLUDES, it.get().joinToString(",")) 67 | } 68 | 69 | extension.source.excludes.takeIf { it.isPresent && it.get().isNotEmpty() }?.let { 70 | add(SOURCE_EXCLUDES, it.get().joinToString(",")) 71 | } 72 | 73 | extension.dto.dirs.takeIf { it.isPresent && it.get().isNotEmpty() }?.let { 74 | add(DTO_DIRS, it.get().joinToString(",")) 75 | } 76 | 77 | extension.dto.testDirs.takeIf { it.isPresent && it.get().isNotEmpty() }?.let { 78 | add(DTO_TEST_DIRS, it.get().joinToString(",")) 79 | } 80 | 81 | extension.dto.defaultNullableInputModifier.takeIf { it.isPresent }?.let { 82 | add(DTO_DEFAULT_NULLABLE_INPUT_MODIFIER, it.get().name.lowercase()) 83 | } 84 | 85 | extension.dto.hibernateValidatorEnhancement.takeIf { it.isPresent }?.let { 86 | add(DTO_HIBERNATE_VALIDATOR_ENHANCEMENT, it.get().toString()) 87 | } 88 | 89 | extension.client.checkedException.takeIf { it.isPresent }?.let { 90 | add(CLIENT_CHECKED_EXCEPTION, it.get().toString()) 91 | } 92 | 93 | extension.client.ignoreJdkWarning.takeIf { it.isPresent }?.let { 94 | add(CLIENT_IGNORE_JDK_WARNING, it.get().toString()) 95 | } 96 | 97 | extension.entry.objects.takeIf { it.isPresent }?.let { 98 | add(ENTRY_OBJECTS, it.get()) 99 | } 100 | 101 | extension.entry.tables.takeIf { it.isPresent }?.let { 102 | add(ENTRY_TABLES, it.get()) 103 | } 104 | 105 | extension.entry.tableExes.takeIf { it.isPresent }?.let { 106 | add(ENTRY_TABLE_EXES, it.get()) 107 | } 108 | 109 | extension.entry.fetchers.takeIf { it.isPresent }?.let { 110 | add(ENTRY_FETCHERS, it.get()) 111 | } 112 | } 113 | } else if (afterProject.plugins.hasKsp && extension.language.get() == Language.KOTLIN) { 114 | fun add(key: String, value: String) { 115 | kspArg(afterProject.extensions.getByName("ksp"), key, value) 116 | } 117 | 118 | extension.dto.dirs.takeIf { it.isPresent && it.get().isNotEmpty() }?.let { 119 | add(DTO_DIRS, it.get().joinToString(",")) 120 | } 121 | 122 | extension.dto.testDirs.takeIf { it.isPresent && it.get().isNotEmpty() }?.let { 123 | add(DTO_TEST_DIRS, it.get().joinToString(",")) 124 | } 125 | 126 | extension.dto.mutable.takeIf { it.isPresent }?.let { 127 | add(DTO_MUTABLE, it.get().toString()) 128 | } 129 | 130 | extension.dto.defaultNullableInputModifier.takeIf { it.isPresent }?.let { 131 | add(DTO_DEFAULT_NULLABLE_INPUT_MODIFIER, it.get().name.lowercase()) 132 | } 133 | 134 | extension.client.checkedException.takeIf { it.isPresent }?.let { 135 | add(CLIENT_CHECKED_EXCEPTION, it.get().toString()) 136 | } 137 | 138 | extension.immutable.isModuleRequired.takeIf { it.isPresent }?.let { 139 | add(IMMUTABLE_IS_MODULE_REQUIRED, it.get().toString()) 140 | } 141 | } 142 | 143 | if (afterProject.tasks.hasCompileJava && extension.language.get() == Language.JAVA) { 144 | afterProject.rootProject.tasks.also { 145 | if (it.hasPre) { 146 | it.getByName(PRE_TASK_NAME).dependsOn(afterProject.tasks.getByName("compileJava")) 147 | } 148 | } 149 | afterProject.tasks.compileJava { compile -> 150 | compile.options.compilerArgs.firstOrNull { 151 | it.startsWith("-A$DTO_DIRS=") 152 | }?.let { 153 | val dirs = it.split("=")[1] 154 | for (path in dirs.trim().split("\\*[,:;]\\s*".toRegex())) { 155 | var p = path 156 | if (p.isEmpty() || p == "/") { 157 | continue 158 | } 159 | if (p.startsWith("/")) { 160 | p = p.substring(1) 161 | } 162 | if (path.endsWith("/")) { 163 | p = p.substring(0, path.length - 1) 164 | } 165 | if (p.isNotEmpty()) { 166 | compile.inputs.dir(p) 167 | } 168 | } 169 | } ?: let { 170 | val dir = afterProject.layout.projectDirectory.dir("src").file("main/dto/") 171 | if (dir.asFile.exists()) { 172 | compile.inputs.dir(dir) 173 | } 174 | } 175 | } 176 | } 177 | 178 | if (afterProject.tasks.hasCompileKotlin && afterProject.tasks.hasKsp && extension.language.get() == Language.KOTLIN) { 179 | afterProject.rootProject.tasks.also { 180 | if (it.hasPre) { 181 | it.getByName(PRE_TASK_NAME).dependsOn(afterProject.tasks.getByName(KSP_TASK_NAME)) 182 | } 183 | } 184 | } 185 | 186 | fun addInputs(task: Task) { 187 | if (!afterProject.plugins.hasKsp) { 188 | return 189 | } 190 | kspArguments(afterProject.extensions.getByName("ksp"))[DTO_DIRS]?.let { dirs -> 191 | dirs.split("\\s*[,:;]\\s*".toRegex()).mapNotNull { 192 | when { 193 | it == "" || it == "/" -> null 194 | it.startsWith("/") -> it.substring(1) 195 | it.endsWith("/") -> it.substring(0, it.length - 1) 196 | else -> it.takeIf { it.isNotEmpty() } 197 | } 198 | }.toSet().forEach { 199 | task.inputs.dir(it) 200 | } 201 | } ?: let { 202 | val dir = afterProject.layout.projectDirectory.dir("src").file("main/dto/") 203 | if (dir.asFile.exists()) { 204 | task.inputs.dir(dir) 205 | } 206 | } 207 | } 208 | 209 | if (afterProject.tasks.hasCompileKotlin) { 210 | afterProject.tasks.compileKotlin { compileKotlin -> 211 | addInputs(compileKotlin) 212 | } 213 | } 214 | 215 | if (afterProject.tasks.hasCompileDebugKotlin) { 216 | afterProject.tasks.compileDebugKotlin { compileDebugKotlin -> 217 | addInputs(compileDebugKotlin) 218 | } 219 | } 220 | 221 | if (afterProject.tasks.hasKsp) { 222 | afterProject.tasks.kspKotlin { kspKotlin -> 223 | addInputs(kspKotlin) 224 | } 225 | } 226 | 227 | if (afterProject.tasks.hasDebugKsp) { 228 | afterProject.tasks.kspDebugKotlin { kspDebugKotlin -> 229 | addInputs(kspDebugKotlin) 230 | } 231 | } 232 | 233 | // Add spring-boot-starter,sql,sql-kotlin 234 | if (afterProject.plugins.hasSpringBoot && !afterProject.hasDependency(JIMMER_SPRINGBOOT_NAME)) { 235 | afterProject.dependencies.implementation( 236 | "$JIMMER_GROUP:$JIMMER_SPRINGBOOT_NAME:${extension.version.get()}" 237 | ) 238 | } else if (extension.language.get() == Language.JAVA && !afterProject.hasDependency(JIMMER_SQL_NAME)) { 239 | afterProject.dependencies.implementation( 240 | "$JIMMER_GROUP:$JIMMER_SQL_NAME:${extension.version.get()}" 241 | ) 242 | } else if (extension.language.get() == Language.KOTLIN 243 | && !afterProject.hasDependency(JIMMER_SQL_KOTLIN_NAME) 244 | ) { 245 | afterProject.dependencies.implementation( 246 | "$JIMMER_GROUP:$JIMMER_SQL_KOTLIN_NAME:${extension.version.get()}" 247 | ) 248 | } 249 | 250 | if (extension.language.get() == Language.JAVA 251 | && !afterProject.hasDependency(JIMMER_APT_NAME, JvmConstants.ANNOTATION_PROCESSOR_CONFIGURATION_NAME) 252 | ) { 253 | afterProject.dependencies.annotationProcessor( 254 | "$JIMMER_GROUP:$JIMMER_APT_NAME:${extension.version.get()}" 255 | ) 256 | } 257 | } 258 | 259 | if (project.plugins.hasKsp && extension.language.get() == Language.KOTLIN 260 | && hasClass("com.google.devtools.ksp.gradle.KspExtension") 261 | ) { 262 | project.dependencies.ksp( 263 | "$JIMMER_GROUP:$JIMMER_KSP_NAME:${extension.version.get()}" 264 | ) 265 | } 266 | } 267 | 268 | private fun kspArg(any: Any, key: String, value: String) { 269 | any.javaClass.methods.firstOrNull { 270 | it.name == "arg" && it.parameterTypes.size == 2 271 | }?.invoke(any, key, value) 272 | } 273 | 274 | private fun kspArguments(any: Any): MutableMap { 275 | @Suppress("UNCHECKED_CAST") 276 | return any.javaClass.methods.firstOrNull { 277 | it.name == "getArguments" 278 | }?.invoke(any) as MutableMap 279 | } 280 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/SettingPlugin.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle 18 | 19 | import cn.enaium.jimmer.gradle.extension.SettingExtension 20 | import cn.enaium.jimmer.gradle.utility.lib 21 | import org.gradle.api.Plugin 22 | import org.gradle.api.initialization.Settings 23 | 24 | /** 25 | * @author Enaium 26 | */ 27 | class SettingPlugin : Plugin { 28 | override fun apply(target: Settings) { 29 | val extension = target.extensions.create("jimmer", SettingExtension::class.java) 30 | 31 | target.dependencyResolutionManagement.versionCatalogs.apply { 32 | register("jimmers") { 33 | it.plugin("jimmer", "cn.enaium.jimmer.gradle").version { 34 | // Nothing 35 | } 36 | it.plugin("ksp", "com.google.devtools.ksp").version { 37 | // Nothing 38 | } 39 | it.lib("apt", "apt").version(extension.version.get()) 40 | it.lib("bom", "bom").version(extension.version.get()) 41 | it.lib("client", "client").version(extension.version.get()) 42 | it.lib("coreKotlin", "core-kotlin").version(extension.version.get()) 43 | it.lib("core", "core").version(extension.version.get()) 44 | it.lib("dtoCompiler", "dto-compiler").version(extension.version.get()) 45 | it.lib("ksp", "ksp").version(extension.version.get()) 46 | it.lib("mapstructApt", "mapstruct-apt").version(extension.version.get()) 47 | it.lib("springBootStarter", "spring-boot-starter").version(extension.version.get()) 48 | it.lib("sqlKotlin", "sql-kotlin").version(extension.version.get()) 49 | it.lib("sql", "sql").version(extension.version.get()) 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Association.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | enum class Association { 23 | NO, 24 | REAL, 25 | FAKE 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Client.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.Property 21 | import javax.inject.Inject 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | open class Client @Inject constructor(objects: ObjectFactory) { 27 | val checkedException: Property = objects.property(Boolean::class.java) 28 | val ignoreJdkWarning: Property = objects.property(Boolean::class.java) 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Driver.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | enum class Driver(val className: String, val module: String) { 23 | POSTGRESQL("org.postgresql.Driver", "postgresql"), 24 | MARIADB("org.mariadb.jdbc.Driver", "mariadb"), 25 | MYSQL("com.mysql.cj.jdbc.Driver", "mysql"), 26 | SQLITE("org.sqlite.JDBC", "sqlite"), 27 | H2("org.h2.Driver", "h2"), 28 | HYPERSONIC("org.hsqldb.jdbc.JDBCDriver", "hsqldb"), 29 | ORACLE("oracle.jdbc.driver.OracleDriver", "ojdbc"), 30 | DB2("com.ibm.db2.jcc.DB2Driver", "jcc"), 31 | SQLSERVER("com.microsoft.sqlserver.jdbc.SQLServerDriver", "mssql-jdbc"), 32 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Dto.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.ListProperty 21 | import org.gradle.api.provider.Property 22 | import javax.inject.Inject 23 | 24 | /** 25 | * @author Enaium 26 | */ 27 | open class Dto @Inject constructor(objects: ObjectFactory) { 28 | val dirs: ListProperty = objects.listProperty(String::class.java) 29 | val testDirs: ListProperty = objects.listProperty(String::class.java) 30 | val mutable: Property = objects.property(Boolean::class.java) 31 | val defaultNullableInputModifier: Property = objects.property(InputDtoModifier::class.java) 32 | val hibernateValidatorEnhancement: Property = objects.property(Boolean::class.java) 33 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Entry.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.Property 21 | import javax.inject.Inject 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | open class Entry @Inject constructor(objects: ObjectFactory) { 27 | val objects: Property = objects.property(String::class.java) 28 | val tables: Property = objects.property(String::class.java) 29 | val tableExes: Property = objects.property(String::class.java) 30 | val fetchers: Property = objects.property(String::class.java) 31 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Generator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import javax.inject.Inject 21 | 22 | /** 23 | * @author Enaium 24 | */ 25 | open class Generator @Inject constructor(objects: ObjectFactory) { 26 | val target: Target = objects.newInstance(Target::class.java) 27 | val jdbc: JDBC = objects.newInstance(JDBC::class.java) 28 | val table: Table = objects.newInstance(Table::class.java) 29 | val poet: Poet = objects.newInstance(Poet::class.java) 30 | 31 | 32 | fun target(action: Target.() -> Unit) { 33 | action.invoke(target) 34 | } 35 | 36 | fun jdbc(action: JDBC.() -> Unit) { 37 | action.invoke(jdbc) 38 | } 39 | 40 | fun table(action: Table.() -> Unit) { 41 | action.invoke(table) 42 | } 43 | 44 | fun poet(action: Poet.() -> Unit) { 45 | action.invoke(poet) 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Immutable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.Property 21 | import javax.inject.Inject 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | open class Immutable @Inject constructor(objects: ObjectFactory) { 27 | val isModuleRequired: Property = objects.property(Boolean::class.java) 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/InputDtoModifier.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | enum class InputDtoModifier { 23 | FIXED, 24 | STATIC, 25 | DYNAMIC, 26 | FUZZY 27 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/JDBC.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.Property 21 | import java.io.File 22 | import javax.inject.Inject 23 | 24 | /** 25 | * @author Enaium 26 | */ 27 | open class JDBC @Inject constructor(objects: ObjectFactory) { 28 | val driver: Property = objects.property(Driver::class.java) 29 | val url: Property = objects.property(String::class.java) 30 | val username: Property = objects.property(String::class.java) 31 | val password: Property = objects.property(String::class.java) 32 | val ddl: Property = objects.property(File::class.java) 33 | val catalog: Property = objects.property(String::class.java) 34 | val schemaPattern: Property = objects.property(String::class.java) 35 | val tableNamePattern: Property = objects.property(String::class.java) 36 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/JimmerExtension.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.Property 21 | import javax.inject.Inject 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | open class JimmerExtension @Inject constructor(objects: ObjectFactory) { 27 | val generator: Generator = objects.newInstance(Generator::class.java) 28 | val client: Client = objects.newInstance(Client::class.java) 29 | val dto: Dto = objects.newInstance(Dto::class.java) 30 | val entry: Entry = objects.newInstance(Entry::class.java) 31 | val source: Source = objects.newInstance(Source::class.java) 32 | val immutable: Immutable = objects.newInstance(Immutable::class.java) 33 | val language: Property = objects.property(Language::class.java) 34 | val version: Property = objects.property(String::class.java).convention("latest.release") 35 | val keepIsPrefix: Property = objects.property(Boolean::class.java) 36 | 37 | fun generator(action: Generator.() -> Unit) { 38 | action.invoke(generator) 39 | } 40 | 41 | fun client(action: Client.() -> Unit) { 42 | action.invoke(client) 43 | } 44 | 45 | fun dto(action: Dto.() -> Unit) { 46 | action.invoke(dto) 47 | } 48 | 49 | fun entry(action: Entry.() -> Unit) { 50 | action.invoke(entry) 51 | } 52 | 53 | fun source(action: Source.() -> Unit) { 54 | action.invoke(source) 55 | } 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Language.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | enum class Language { 23 | KOTLIN, 24 | JAVA 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Poet.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.Property 21 | import javax.inject.Inject 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | open class Poet @Inject constructor(objects: ObjectFactory) { 27 | val indent: Property = objects.property(String::class.java).convention(" ") 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/SettingExtension.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.Property 21 | import javax.inject.Inject 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | open class SettingExtension @Inject constructor(objects: ObjectFactory) { 27 | val version: Property = objects.property(String::class.java).convention("latest.release") 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Source.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.ListProperty 21 | import javax.inject.Inject 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | open class Source @Inject constructor(objects: ObjectFactory) { 27 | val includes: ListProperty = objects.listProperty(String::class.java) 28 | val excludes: ListProperty = objects.listProperty(String::class.java) 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Table.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.MapProperty 21 | import org.gradle.api.provider.Property 22 | import javax.inject.Inject 23 | 24 | /** 25 | * @author Enaium 26 | */ 27 | open class Table @Inject constructor(objects: ObjectFactory) { 28 | val name: Property = objects.property(Boolean::class.java).convention(false) 29 | val column: Property = objects.property(Boolean::class.java).convention(false) 30 | val primaryKey: Property = objects.property(String::class.java).convention("id") 31 | val association: Property = objects.property(Association::class.java).convention(Association.REAL) 32 | val typeMappings: MapProperty = objects.mapProperty(String::class.java, String::class.java) 33 | val comment: Property = objects.property(Boolean::class.java).convention(false) 34 | val idView: Property = objects.property(Boolean::class.java).convention(false) 35 | val joinTable: Property = objects.property(Boolean::class.java).convention(false) 36 | val idGeneratorType: Property = objects.property(String::class.java) 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/extension/Target.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.extension 18 | 19 | import org.gradle.api.model.ObjectFactory 20 | import org.gradle.api.provider.Property 21 | import javax.inject.Inject 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | open class Target @Inject constructor(objects: ObjectFactory) { 27 | val srcDir: Property = objects.property(String::class.java) 28 | val packageName: Property = objects.property(String::class.java) 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/model/Column.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.model 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | data class Column( 23 | val name: String, 24 | val tableName: String, 25 | val type: String, 26 | val remark: String?, 27 | val defaultValue: String?, 28 | val nullable: Boolean, 29 | ) { 30 | override fun equals(other: Any?): Boolean { 31 | if (this === other) return true 32 | if (javaClass != other?.javaClass) return false 33 | 34 | other as Column 35 | 36 | return name == other.name 37 | } 38 | 39 | override fun hashCode(): Int { 40 | return name.hashCode() 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/model/ForeignKey.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.model 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | data class ForeignKey( 23 | val name: String, 24 | val tableName: String, 25 | val column: Column, 26 | val reference: Column, 27 | val real: Boolean = true 28 | ) { 29 | override fun equals(other: Any?): Boolean { 30 | if (this === other) return true 31 | if (javaClass != other?.javaClass) return false 32 | 33 | other as ForeignKey 34 | 35 | return name == other.name 36 | } 37 | 38 | override fun hashCode(): Int { 39 | return name.hashCode() 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/model/PrimaryKey.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.model 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | data class PrimaryKey( 23 | val name: String, 24 | val tableName: String, 25 | val column: Column 26 | ) { 27 | override fun equals(other: Any?): Boolean { 28 | if (this === other) return true 29 | if (javaClass != other?.javaClass) return false 30 | 31 | other as PrimaryKey 32 | 33 | return name == other.name 34 | } 35 | 36 | override fun hashCode(): Int { 37 | return name.hashCode() 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/model/Table.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.model 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | data class Table( 23 | val name: String, 24 | val columns: Set, 25 | val primaryKeys: Set, 26 | val foreignKeys: MutableSet, 27 | val uniqueKeys: Set 28 | ) { 29 | override fun equals(other: Any?): Boolean { 30 | if (this === other) return true 31 | if (javaClass != other?.javaClass) return false 32 | 33 | other as Table 34 | 35 | return name == other.name 36 | } 37 | 38 | override fun hashCode(): Int { 39 | return name.hashCode() 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/model/UniqueKey.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.model 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | data class UniqueKey( 23 | val name: String, 24 | val tableName: String, 25 | val columns: List, 26 | ) { 27 | override fun equals(other: Any?): Boolean { 28 | if (this === other) return true 29 | if (javaClass != other?.javaClass) return false 30 | 31 | other as UniqueKey 32 | 33 | return name == other.name 34 | } 35 | 36 | override fun hashCode(): Int { 37 | return name.hashCode() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/service/EntityGenerateService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.service 18 | 19 | import cn.enaium.jimmer.gradle.extension.Generator 20 | import cn.enaium.jimmer.gradle.model.Column 21 | import cn.enaium.jimmer.gradle.model.Table 22 | import java.io.File 23 | import java.sql.Connection 24 | import java.sql.DriverManager 25 | 26 | /** 27 | * @author Enaium 28 | */ 29 | interface EntityGenerateService { 30 | 31 | fun generate(projectDir: File, generator: Generator) 32 | 33 | fun getConnection(generator: Generator): Connection { 34 | return generator.jdbc.ddl.orNull?.let { ddl -> 35 | DriverManager.getConnection( 36 | "jdbc:h2:mem:test;DATABASE_TO_LOWER=true;INIT=RUNSCRIPT FROM '${ 37 | ddl.absolutePath.replace( 38 | "\\", 39 | "/" 40 | ) 41 | }'" 42 | ) 43 | } ?: let { 44 | DriverManager.getConnection( 45 | generator.jdbc.url.get(), 46 | generator.jdbc.username.get(), 47 | generator.jdbc.password.get() 48 | ) 49 | } 50 | } 51 | 52 | fun getCommonColumns(tables: Set): Set { 53 | return tables.asSequence().flatMap { it.columns }.groupBy { it.name } 54 | .filter { it -> it.value.size == tables.count { it.primaryKeys.isNotEmpty() } }.map { it.value.first() } 55 | .toSet() 56 | } 57 | } 58 | 59 | internal const val BASE_ENTITY = "BaseEntity" -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/service/impl/JavaEntityGenerateService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.service.impl 18 | 19 | import cn.enaium.jimmer.gradle.extension.Association 20 | import cn.enaium.jimmer.gradle.extension.Generator 21 | import cn.enaium.jimmer.gradle.model.Column 22 | import cn.enaium.jimmer.gradle.model.ForeignKey 23 | import cn.enaium.jimmer.gradle.service.BASE_ENTITY 24 | import cn.enaium.jimmer.gradle.service.EntityGenerateService 25 | import cn.enaium.jimmer.gradle.utility.* 26 | import com.squareup.javapoet.* 27 | import org.babyfish.jimmer.sql.* 28 | import org.jetbrains.annotations.Nullable 29 | import java.io.File 30 | import java.util.* 31 | import javax.lang.model.element.Modifier 32 | 33 | /** 34 | * @author Enaium 35 | */ 36 | class JavaEntityGenerateService : EntityGenerateService { 37 | /** 38 | * Generate entity 39 | * @param generator Generator 40 | * @return relative path and content 41 | */ 42 | override fun generate(projectDir: File, generator: Generator) { 43 | val idSuffix = "_${generator.table.primaryKey.get()}" 44 | 45 | val connect = getConnection(generator) 46 | val metaData = connect.metaData 47 | 48 | val tables = metaData.getTables( 49 | catalog = generator.jdbc.catalog.orNull, 50 | schemaPattern = generator.jdbc.schemaPattern.orNull, 51 | tableNamePattern = generator.jdbc.tableNamePattern.orNull 52 | ) 53 | 54 | val commonColumns = getCommonColumns(tables) 55 | 56 | val type2Builder = mutableMapOf() 57 | 58 | val packageName = generator.target.packageName.get() 59 | 60 | // Generate base entity 61 | if (commonColumns.isNotEmpty()) { 62 | TypeSpec.interfaceBuilder(ClassName.get(packageName, BASE_ENTITY)).let { 63 | it.addModifiers(Modifier.PUBLIC) 64 | it.addMethods(commonColumns.map { column -> 65 | val returns = MethodSpec.methodBuilder(column.name.snakeToCamelCase(firstCharUppercase = false)) 66 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 67 | .returns(getTypeName(javaTypeMappings, column)) 68 | if (column.name == generator.table.primaryKey.get()) { 69 | returns.addAnnotation(Id::class.java) 70 | generator.table.idGeneratorType.orNull?.also { idGeneratorType -> 71 | returns.addAnnotation( 72 | AnnotationSpec.builder(GeneratedValue::class.java) 73 | .addMember("generatorType", "\$T.class", className(idGeneratorType)) 74 | .build() 75 | ) 76 | } 77 | } 78 | returns.build() 79 | }) 80 | it.addAnnotation(MappedSuperclass::class.java) 81 | }.let { 82 | type2Builder[BASE_ENTITY] = it 83 | } 84 | } 85 | 86 | // Add fake association 87 | if (generator.table.association.get() == Association.FAKE) { 88 | tables.forEach { table -> 89 | table.columns.filter { commonColumns.contains(it).not() }.forEach { column -> 90 | if (column.name.endsWith(idSuffix)) { 91 | val foreignKey = ForeignKey( 92 | "${table.name}_${column.name}_id_fkey", 93 | table.name, 94 | column, 95 | tables.first { 96 | it.name == column.name.substring( 97 | 0, 98 | column.name.length - idSuffix.length 99 | ) 100 | }.columns.first { it.name == generator.table.primaryKey.get() }, 101 | real = false 102 | ) 103 | 104 | if (table.foreignKeys.contains(foreignKey).not()) { 105 | table.foreignKeys.add(foreignKey) 106 | } 107 | } 108 | } 109 | } 110 | } 111 | 112 | // Generate entity 113 | tables.forEach { table -> 114 | // Skip table without primary key 115 | if (table.primaryKeys.isEmpty()) { 116 | return@forEach 117 | } 118 | 119 | val typeName = table.name.snakeToCamelCase() 120 | TypeSpec.interfaceBuilder(ClassName.get(packageName, typeName)).let { type -> 121 | if (commonColumns.isNotEmpty()) type.addSuperinterface(ClassName.get(packageName, BASE_ENTITY)) 122 | // Add table columns 123 | type.addMethods( 124 | table.columns 125 | .filter { 126 | // Exclude common columns 127 | commonColumns.contains(it).not() 128 | }.filter { 129 | // Exclude id column 130 | if (generator.table.idView.get().not()) it.name.endsWith( 131 | idSuffix, 132 | true 133 | ).not() else true 134 | } 135 | .map { column -> 136 | val methodBuilder = 137 | MethodSpec.methodBuilder(column.name.snakeToCamelCase(firstCharUppercase = false)) 138 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 139 | 140 | methodBuilder.returns(getTypeName(javaTypeMappings, column)) 141 | 142 | if (generator.table.column.get()) { 143 | methodBuilder.addAnnotation( 144 | AnnotationSpec.builder(org.babyfish.jimmer.sql.Column::class.java) 145 | .addMember("name", "\$S", column.name) 146 | .build() 147 | ) 148 | } 149 | 150 | if (generator.table.comment.get()) { 151 | column.remark?.let { 152 | methodBuilder.addJavadoc(it) 153 | } 154 | } 155 | 156 | if (column.name.endsWith(idSuffix, true)) { 157 | methodBuilder.addAnnotation(IdView::class.java) 158 | } 159 | 160 | if (column.nullable) { 161 | methodBuilder.addAnnotation(Nullable::class.java) 162 | } 163 | 164 | methodBuilder.build() 165 | } 166 | ) 167 | 168 | // Add table associations 169 | if (generator.table.association.get() != Association.NO) { 170 | type.addMethods(table.foreignKeys.map { foreignKey -> 171 | val referenceTypeName = foreignKey.reference.tableName.snakeToCamelCase() 172 | 173 | val unique = table.uniqueKeys.filter { it.columns.size == 1 }.map { it.columns.first() } 174 | .contains(foreignKey.column) 175 | 176 | // owning side 177 | val own = MethodSpec.methodBuilder(referenceTypeName.firstCharLowercase()) 178 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 179 | .returns(ClassName.get(packageName, referenceTypeName)) 180 | .addAnnotation( 181 | AnnotationSpec.builder( 182 | if (unique) OneToOne::class.java else ManyToOne::class.java 183 | ).build(), 184 | ) 185 | 186 | if (foreignKey.column.nullable) { 187 | own.addAnnotation(Nullable::class.java) 188 | } 189 | 190 | // inverse side 191 | type2Builder[referenceTypeName]?.addMethod( 192 | MethodSpec.methodBuilder( 193 | typeName.firstCharLowercase().let { 194 | if (unique) { 195 | it 196 | } else { 197 | it.toPlural() 198 | } 199 | } 200 | ).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 201 | .returns( 202 | if (unique) { 203 | ClassName.get(packageName, typeName) 204 | } else { 205 | ParameterizedTypeName.get( 206 | ClassName.get("java.util", "List"), 207 | ClassName.get(packageName, typeName) 208 | ) 209 | } 210 | ).addAnnotation( 211 | AnnotationSpec.builder( 212 | if (unique) OneToOne::class.java else OneToMany::class.java 213 | ).addMember("mappedBy", "\$S", referenceTypeName.firstCharLowercase()) 214 | .build() 215 | ).let { 216 | if (unique) it.addAnnotation(Nullable::class.java) else it 217 | }.build() 218 | ) 219 | 220 | own.build() 221 | }) 222 | } 223 | type.addAnnotation(Entity::class.java) 224 | type.addModifiers(Modifier.PUBLIC) 225 | if (generator.table.name.get()) { 226 | type.addAnnotation( 227 | AnnotationSpec.builder(Table::class.java) 228 | .addMember("name", "\$S", table.name) 229 | .build() 230 | ) 231 | } 232 | type 233 | }.let { 234 | type2Builder[typeName] = it 235 | } 236 | } 237 | 238 | // Generate many-to-many association table 239 | if (generator.table.association.get() != Association.NO) { 240 | tables.forEach { table -> 241 | // If the table has two columns and two foreign keys, it is a many-to-many association table 242 | if (table.columns.size != 2 || table.foreignKeys.size != 2) return@forEach 243 | 244 | val owningColumn = table.foreignKeys.first().column 245 | val inverseColumn = table.foreignKeys.last().column 246 | 247 | val owningTypeName = table.foreignKeys.first().reference.tableName.snakeToCamelCase() 248 | val inverseTypeName = table.foreignKeys.last().reference.tableName.snakeToCamelCase() 249 | 250 | type2Builder[owningTypeName]?.addMethod( 251 | MethodSpec.methodBuilder(inverseTypeName.firstCharLowercase().toPlural()) 252 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 253 | .returns( 254 | ParameterizedTypeName.get( 255 | ClassName.get("java.util", "List"), 256 | ClassName.get(packageName, inverseTypeName) 257 | ) 258 | ) 259 | .addAnnotation(ManyToMany::class.java) 260 | .also { 261 | if (generator.table.joinTable.get()) { 262 | it.addAnnotation( 263 | AnnotationSpec.builder(JoinTable::class.java) 264 | .addMember("name", "\$S", table.name) 265 | .addMember( 266 | "joinColumns", "\$L", AnnotationSpec.builder(JoinColumn::class.java) 267 | .addMember("name", "\$S", owningColumn.name) 268 | .build() 269 | ) 270 | .addMember( 271 | "inverseJoinColumns", "\$L", AnnotationSpec.builder(JoinColumn::class.java) 272 | .addMember("name", "\$S", inverseColumn.name) 273 | .build() 274 | ).build() 275 | ) 276 | } 277 | } 278 | .build() 279 | ) 280 | 281 | type2Builder[inverseTypeName]?.addMethod( 282 | MethodSpec.methodBuilder(owningTypeName.firstCharLowercase().toPlural()) 283 | .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) 284 | .returns( 285 | ParameterizedTypeName.get( 286 | ClassName.get("java.util", "List"), 287 | ClassName.get(packageName, owningTypeName) 288 | ) 289 | ).addAnnotation( 290 | AnnotationSpec.builder(ManyToMany::class.java) 291 | .addMember("mappedBy", "\$S", inverseTypeName.firstCharLowercase().toPlural()) 292 | .build() 293 | ).build() 294 | ) 295 | } 296 | } 297 | 298 | // Write to file 299 | type2Builder.forEach { (_, type) -> 300 | JavaFile.builder(packageName, type.build()) 301 | .indent(generator.poet.indent.get()) 302 | .build() 303 | .writeTo(projectDir.resolve(generator.target.srcDir.get())) 304 | } 305 | connect.close() 306 | } 307 | 308 | private fun getTypeName(typeMappings: Map, column: Column): TypeName { 309 | return typeMappings[column.type.lowercase(Locale.ROOT)] 310 | ?.let { 311 | ClassName.get( 312 | it.substring(0, it.lastIndexOf(".")), 313 | it.substring(it.lastIndexOf(".") + 1) 314 | ) 315 | }?.let { 316 | if (!column.nullable && it.isBoxedPrimitive) { 317 | it.unbox() 318 | } else { 319 | it 320 | } 321 | } 322 | ?: ClassName.get(java.lang.String::class.java) 323 | } 324 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/service/impl/KotlinEntityGenerateService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.service.impl 18 | 19 | import cn.enaium.jimmer.gradle.extension.Association 20 | import cn.enaium.jimmer.gradle.extension.Generator 21 | import cn.enaium.jimmer.gradle.model.Column 22 | import cn.enaium.jimmer.gradle.model.ForeignKey 23 | import cn.enaium.jimmer.gradle.service.BASE_ENTITY 24 | import cn.enaium.jimmer.gradle.service.EntityGenerateService 25 | import cn.enaium.jimmer.gradle.utility.* 26 | import com.squareup.kotlinpoet.* 27 | import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy 28 | import org.babyfish.jimmer.sql.* 29 | import java.io.File 30 | import java.util.* 31 | 32 | /** 33 | * @author Enaium 34 | */ 35 | class KotlinEntityGenerateService : EntityGenerateService { 36 | /** 37 | * Generate entity 38 | * @param generator Generator 39 | * @return relative path and content 40 | */ 41 | override fun generate(projectDir: File, generator: Generator) { 42 | val idSuffix = "_${generator.table.primaryKey.get()}" 43 | 44 | val connect = getConnection(generator) 45 | 46 | val metaData = connect.metaData 47 | 48 | val tables = metaData.getTables( 49 | catalog = generator.jdbc.catalog.orNull, 50 | schemaPattern = generator.jdbc.schemaPattern.orNull, 51 | tableNamePattern = generator.jdbc.tableNamePattern.orNull 52 | ) 53 | 54 | val commonColumns = getCommonColumns(tables) 55 | 56 | val type2Builder = mutableMapOf() 57 | 58 | val packageName = generator.target.packageName.get() 59 | 60 | // Generate base entity 61 | if (commonColumns.isNotEmpty()) { 62 | TypeSpec.interfaceBuilder(ClassName(packageName, BASE_ENTITY)).let { 63 | it.addProperties(commonColumns.map { column -> 64 | val propertyBuilder = PropertySpec.builder( 65 | column.name.snakeToCamelCase(firstCharUppercase = false), 66 | getTypeName(kotlinTypeMappings, column) 67 | ) 68 | if (column.name == generator.table.primaryKey.get()) { 69 | propertyBuilder.addAnnotation(Id::class) 70 | generator.table.idGeneratorType.orNull?.also { idGeneratorType -> 71 | propertyBuilder.addAnnotation( 72 | AnnotationSpec.builder(GeneratedValue::class) 73 | .addMember("generatorType = %T::class", ClassName.name(idGeneratorType)) 74 | .build() 75 | ) 76 | } 77 | } 78 | propertyBuilder.build() 79 | }) 80 | it.addAnnotation(MappedSuperclass::class) 81 | }.let { 82 | type2Builder[BASE_ENTITY] = it 83 | } 84 | } 85 | 86 | // Add fake association 87 | if (generator.table.association.get() == Association.FAKE) { 88 | tables.forEach { table -> 89 | table.columns.filter { commonColumns.contains(it).not() }.forEach { column -> 90 | if (column.name.endsWith(idSuffix)) { 91 | val foreignKey = ForeignKey( 92 | "${table.name}_${column.name}_id_fkey", 93 | table.name, 94 | column, 95 | tables.first { 96 | it.name == column.name.substring( 97 | 0, 98 | column.name.length - idSuffix.length 99 | ) 100 | }.columns.first { it.name == generator.table.primaryKey.get() }, 101 | real = false 102 | ) 103 | 104 | if (table.foreignKeys.contains(foreignKey).not()) { 105 | table.foreignKeys.add(foreignKey) 106 | } 107 | } 108 | } 109 | } 110 | } 111 | 112 | // Generate entity 113 | tables.forEach { table -> 114 | // Skip table without primary key 115 | if (table.primaryKeys.isEmpty()) { 116 | return@forEach 117 | } 118 | 119 | val typeName = table.name.snakeToCamelCase() 120 | TypeSpec.interfaceBuilder(ClassName(packageName, typeName)).let { type -> 121 | if (commonColumns.isNotEmpty()) type.addSuperinterface(ClassName(packageName, BASE_ENTITY)) 122 | // Add table columns 123 | type.addProperties( 124 | table.columns 125 | .filter { 126 | // Exclude common columns 127 | commonColumns.contains(it).not() 128 | } 129 | .filter { 130 | // Exclude id column 131 | if (generator.table.idView.get().not()) it.name.endsWith( 132 | idSuffix, 133 | true 134 | ).not() else true 135 | } 136 | .map { column -> 137 | val propertyBuilder = PropertySpec.builder( 138 | column.name.snakeToCamelCase(firstCharUppercase = false), 139 | getTypeName(kotlinTypeMappings, column).copy(nullable = column.nullable) 140 | ) 141 | 142 | if (generator.table.column.get()) { 143 | propertyBuilder.addAnnotation( 144 | AnnotationSpec.builder(org.babyfish.jimmer.sql.Column::class) 145 | .addMember("name = %S", column.name) 146 | .build() 147 | ) 148 | } 149 | 150 | if (generator.table.comment.get()) { 151 | column.remark?.let { 152 | propertyBuilder.addKdoc(it) 153 | } 154 | } 155 | 156 | if (column.name.endsWith(idSuffix, true)) { 157 | propertyBuilder.addAnnotation(IdView::class) 158 | } 159 | propertyBuilder.build() 160 | } 161 | ) 162 | 163 | // Add table associations 164 | if (generator.table.association.get() != Association.NO) { 165 | type.addProperties(table.foreignKeys.map { foreignKey -> 166 | val referenceTypeName = foreignKey.reference.tableName.snakeToCamelCase() 167 | 168 | val unique = table.uniqueKeys.filter { it.columns.size == 1 }.map { it.columns.first() } 169 | .contains(foreignKey.column) 170 | 171 | // owning side 172 | val own = PropertySpec.builder( 173 | referenceTypeName.firstCharLowercase(), 174 | ClassName(packageName, referenceTypeName).copy(nullable = foreignKey.column.nullable) 175 | ).addAnnotation( 176 | AnnotationSpec.builder( 177 | if (unique) OneToOne::class else ManyToOne::class 178 | ).build() 179 | ) 180 | 181 | // inverse side 182 | type2Builder[referenceTypeName]?.addProperty( 183 | PropertySpec.builder( 184 | typeName.firstCharLowercase().let { 185 | if (unique) { 186 | it 187 | } else { 188 | it.toPlural() 189 | } 190 | }, 191 | if (unique) { 192 | ClassName(packageName, typeName).copy(nullable = true) 193 | } else { 194 | List::class.asTypeName().parameterizedBy(ClassName(packageName, typeName)) 195 | } 196 | ).addAnnotation( 197 | AnnotationSpec.builder( 198 | if (unique) OneToOne::class else OneToMany::class 199 | ).addMember("mappedBy = %S", referenceTypeName.firstCharLowercase()).build() 200 | ).build() 201 | ) 202 | 203 | own.build() 204 | }) 205 | } 206 | 207 | type.addAnnotation(Entity::class) 208 | if (generator.table.name.get()) { 209 | type.addAnnotation( 210 | AnnotationSpec.builder(Table::class) 211 | .addMember("name = %S", table.name) 212 | .build() 213 | ) 214 | } 215 | type 216 | }.let { 217 | type2Builder[typeName] = it 218 | } 219 | } 220 | 221 | // Generate many-to-many association table 222 | if (generator.table.association.get() != Association.NO) { 223 | tables.forEach { table -> 224 | // If the table has two columns and two foreign keys, it is a many-to-many association table 225 | if (table.columns.size != 2 || table.foreignKeys.size != 2) return@forEach 226 | 227 | 228 | val owningColumn = table.foreignKeys.first().column 229 | val inverseColumn = table.foreignKeys.last().column 230 | 231 | val owningTypeName = table.foreignKeys.first().reference.tableName.snakeToCamelCase() 232 | val inverseTypeName = table.foreignKeys.last().reference.tableName.snakeToCamelCase() 233 | 234 | type2Builder[owningTypeName]?.addProperty( 235 | PropertySpec.builder( 236 | inverseTypeName.firstCharLowercase().toPlural(), 237 | List::class.asTypeName().parameterizedBy(ClassName(packageName, inverseTypeName)) 238 | ) 239 | .addAnnotation(ManyToMany::class) 240 | .also { 241 | if (generator.table.joinTable.get()) { 242 | it.addAnnotation( 243 | AnnotationSpec.builder(JoinTable::class) 244 | .addMember("name = %S", table.name) 245 | .addMember( 246 | "joinColumns = [%T(name = %S)]", 247 | JoinColumn::class, 248 | owningColumn.name 249 | ) 250 | .addMember( 251 | "inverseJoinColumns = [%T(name = %S)]", 252 | JoinColumn::class, 253 | inverseColumn.name 254 | ) 255 | .build() 256 | ) 257 | } 258 | } 259 | .build() 260 | ) 261 | 262 | type2Builder[inverseTypeName]?.addProperty( 263 | PropertySpec.builder( 264 | owningTypeName.firstCharLowercase().toPlural(), 265 | List::class.asTypeName().parameterizedBy(ClassName(packageName, owningTypeName)) 266 | ).addAnnotation( 267 | AnnotationSpec.builder(ManyToMany::class) 268 | .addMember("mappedBy = %S", inverseTypeName.firstCharLowercase().toPlural()) 269 | .build() 270 | ).build() 271 | ) 272 | } 273 | } 274 | 275 | // Write to file 276 | for ((tableName, typeBuilder) in type2Builder) { 277 | FileSpec.builder(packageName, tableName) 278 | .indent(generator.poet.indent.get()) 279 | .addType(typeBuilder.build()).build() 280 | .writeTo(projectDir.resolve(generator.target.srcDir.get())) 281 | } 282 | connect.close() 283 | } 284 | 285 | private fun getTypeName(typeMappings: Map, column: Column): TypeName { 286 | return typeMappings[column.type.lowercase(Locale.ROOT)] 287 | ?.let { 288 | ClassName( 289 | it.substring(0, it.lastIndexOf(".")), 290 | it.substring(it.lastIndexOf(".") + 1) 291 | ) 292 | } 293 | ?: String::class.asTypeName().copy(nullable = column.nullable) 294 | } 295 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/task/AllProjectDependencies.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.task 18 | 19 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 20 | import org.gradle.api.DefaultTask 21 | import org.gradle.api.tasks.TaskAction 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | open class AllProjectDependencies : DefaultTask() { 27 | 28 | private val rootProject = project.rootProject 29 | 30 | init { 31 | group = "jimmer" 32 | description = "Get all project dependencies" 33 | } 34 | 35 | @TaskAction 36 | fun allProjectDependencies() { 37 | val rootProject = rootProject 38 | val allProjects = rootProject.allprojects 39 | val map = mutableMapOf>() 40 | try { 41 | allProjects.forEach { p -> 42 | p.configurations.named { it == "runtimeClasspath" }.takeIf { it.isNotEmpty() } 43 | ?.named("runtimeClasspath") 44 | ?.also { 45 | map[p.name] = it.get().map { it.absolutePath } 46 | } 47 | p.configurations.named { it == "debugRuntimeClasspath" }.takeIf { it.isNotEmpty() } 48 | ?.named("debugRuntimeClasspath")?.also { 49 | map[p.name] = it.get().map { it.absolutePath } 50 | } 51 | } 52 | } catch (_: Throwable) { 53 | 54 | } 55 | rootProject.logger.lifecycle(jacksonObjectMapper().writeValueAsString(map)) 56 | } 57 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/task/GenerateEntityTask.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.task 18 | 19 | import cn.enaium.jimmer.gradle.extension.JimmerExtension 20 | import cn.enaium.jimmer.gradle.extension.Language 21 | import cn.enaium.jimmer.gradle.service.impl.JavaEntityGenerateService 22 | import cn.enaium.jimmer.gradle.service.impl.KotlinEntityGenerateService 23 | import cn.enaium.jimmer.gradle.utility.javaTypeMappings 24 | import cn.enaium.jimmer.gradle.utility.kotlinTypeMappings 25 | import org.gradle.api.DefaultTask 26 | import org.gradle.api.tasks.TaskAction 27 | import java.net.URLClassLoader 28 | import java.sql.Connection 29 | import java.sql.Driver 30 | import java.sql.DriverManager 31 | import java.sql.DriverPropertyInfo 32 | import java.util.* 33 | import java.util.logging.Logger 34 | 35 | /** 36 | * @author Enaium 37 | */ 38 | open class GenerateEntityTask : DefaultTask() { 39 | 40 | private val extension = project.extensions.getByType(JimmerExtension::class.java) 41 | private val configurations = project.configurations 42 | private val projectDir = project.projectDir 43 | 44 | init { 45 | group = "jimmer" 46 | description = "Generate entity" 47 | } 48 | 49 | @TaskAction 50 | fun generateEntity() { 51 | val generator = extension.generator 52 | 53 | if (extension.language.get() == Language.KOTLIN) { 54 | kotlinTypeMappings.putAll(generator.table.typeMappings.get()) 55 | } else if (extension.language.get() == Language.JAVA) { 56 | javaTypeMappings.putAll(generator.table.typeMappings.get()) 57 | } 58 | 59 | generator.jdbc.driver.takeIf { it.isPresent }?.also driver@{ driver -> 60 | configurations.named("runtimeClasspath").get() 61 | .find { file -> file.name.startsWith(driver.get().module) } 62 | ?.also { 63 | generator.jdbc.ddl.isPresent && return@also 64 | DriverManager.registerDriver( 65 | DiverWrapper( 66 | Class.forName( 67 | driver.get().className, true, 68 | URLClassLoader(arrayOf(it.toURI().toURL()), this.javaClass.classLoader) 69 | ).getConstructor() 70 | .newInstance() as Driver 71 | ) 72 | ) 73 | } ?: run { 74 | if (!generator.jdbc.ddl.isPresent) { 75 | throw RuntimeException("Failed to find driver module") 76 | } 77 | } 78 | } ?: run { 79 | if (!generator.jdbc.ddl.isPresent) { 80 | throw RuntimeException("Driver not configured") 81 | } 82 | } 83 | if (extension.language.get() == Language.KOTLIN) { 84 | KotlinEntityGenerateService().generate(projectDir, generator) 85 | } else if (extension.language.get() == Language.JAVA) { 86 | JavaEntityGenerateService().generate(projectDir, generator) 87 | } else { 88 | throw RuntimeException("Unknown language ${extension.language}") 89 | } 90 | } 91 | } 92 | 93 | private class DiverWrapper(private val driver: Driver) : Driver { 94 | override fun connect(url: String, info: Properties): Connection { 95 | return driver.connect(url, info) 96 | } 97 | 98 | override fun acceptsURL(url: String): Boolean { 99 | return driver.acceptsURL(url) 100 | } 101 | 102 | override fun getPropertyInfo(url: String, info: Properties): Array { 103 | return driver.getPropertyInfo(url, info) 104 | } 105 | 106 | override fun getMajorVersion(): Int { 107 | return driver.majorVersion 108 | } 109 | 110 | override fun getMinorVersion(): Int { 111 | return driver.minorVersion 112 | } 113 | 114 | override fun jdbcCompliant(): Boolean { 115 | return driver.jdbcCompliant() 116 | } 117 | 118 | override fun getParentLogger(): Logger { 119 | return driver.parentLogger 120 | } 121 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/task/GenerateLspDependenciesTask.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.task 18 | 19 | import com.fasterxml.jackson.databind.ObjectMapper 20 | import com.fasterxml.jackson.databind.node.ArrayNode 21 | import com.fasterxml.jackson.databind.node.JsonNodeFactory 22 | import com.fasterxml.jackson.databind.node.ObjectNode 23 | import org.gradle.api.DefaultTask 24 | import org.gradle.api.tasks.TaskAction 25 | import kotlin.io.path.* 26 | 27 | /** 28 | * @author Enaium 29 | */ 30 | open class GenerateLspDependenciesTask : DefaultTask() { 31 | 32 | private val configurations = project.configurations 33 | private val projectDir = project.projectDir 34 | 35 | init { 36 | group = "jimmer" 37 | description = "Generate dependencies for LSP" 38 | } 39 | 40 | @TaskAction 41 | fun generateLspDependency() { 42 | val lspHome = Path(System.getProperty("user.home")).resolve("jimmer-dto-lsp") 43 | 44 | if (lspHome.resolve("server.jar").exists().not()) { 45 | return 46 | } 47 | 48 | val dependenciesFile = lspHome.resolve("dependencies.json") 49 | 50 | if (dependenciesFile.exists().not()) { 51 | dependenciesFile.createParentDirectories() 52 | dependenciesFile.createFile() 53 | dependenciesFile.writeText("{}") 54 | } 55 | 56 | val dependenciesJson = ObjectMapper().readTree(dependenciesFile.readText()) 57 | val dependencies = configurations.named("runtimeClasspath").get() 58 | 59 | (dependenciesJson as ObjectNode).set( 60 | projectDir.absolutePath, 61 | JsonNodeFactory.instance.arrayNode().apply { 62 | dependencies.forEach { 63 | add(it.absolutePath) 64 | } 65 | }) 66 | 67 | dependenciesFile.writeText(ObjectMapper().writeValueAsString(dependenciesJson)) 68 | } 69 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/utility/const.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.utility 18 | 19 | /** 20 | * @author Enaium 21 | */ 22 | const val KEEP_IS_PREFIX = "jimmer.keepIsPrefix" 23 | const val SOURCE_INCLUDES = "jimmer.source.includes" 24 | const val SOURCE_EXCLUDES = "jimmer.source.excludes" 25 | const val DTO_DIRS = "jimmer.dto.dirs" 26 | const val DTO_TEST_DIRS = "jimmer.dto.testDirs" 27 | const val DTO_MUTABLE = "jimmer.dto.mutable" 28 | const val DTO_DEFAULT_NULLABLE_INPUT_MODIFIER = "jimmer.dto.defaultNullableInputModifier" 29 | const val DTO_HIBERNATE_VALIDATOR_ENHANCEMENT = "jimmer.dto.hibernateValidatorEnhancement" 30 | const val CLIENT_CHECKED_EXCEPTION = "jimmer.client.checkedException" 31 | const val CLIENT_IGNORE_JDK_WARNING = "jimmer.client.ignoreJdkWarning" 32 | const val ENTRY_OBJECTS = "jimmer.entry.objects" 33 | const val ENTRY_TABLES = "jimmer.entry.tables" 34 | const val ENTRY_TABLE_EXES = "jimmer.entry.tableExes" 35 | const val ENTRY_FETCHERS = "jimmer.entry.fetchers" 36 | const val IMMUTABLE_IS_MODULE_REQUIRED = "jimmer.immutable.isModuleRequired" 37 | const val KSP_PLUGIN_ID = "com.google.devtools.ksp" 38 | const val SPRINGBOOT_PLUGIN_ID = "org.springframework.boot" 39 | const val KSP_TASK_NAME = "kspKotlin" 40 | const val KSP_DEBUG_TASK_NAME = "kspDebugKotlin" 41 | const val JIMMER_GROUP = "org.babyfish.jimmer" 42 | const val JIMMER_SPRINGBOOT_NAME = "jimmer-spring-boot-starter" 43 | const val JIMMER_SQL_NAME = "jimmer-sql" 44 | const val JIMMER_SQL_KOTLIN_NAME = "jimmer-sql-kotlin" 45 | const val JIMMER_KSP_NAME = "jimmer-ksp" 46 | const val JIMMER_APT_NAME = "jimmer-apt" 47 | const val PRE_TASK_NAME = "prepareKotlinBuildScriptModel" -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/utility/dependency.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.utility 18 | 19 | import org.gradle.api.Project 20 | import org.gradle.api.artifacts.dsl.DependencyHandler 21 | import org.gradle.api.internal.tasks.JvmConstants 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | internal fun DependencyHandler.implementation(dependency: String) { 27 | add(JvmConstants.IMPLEMENTATION_CONFIGURATION_NAME, dependency) 28 | } 29 | 30 | internal fun DependencyHandler.annotationProcessor(dependency: String) { 31 | add(JvmConstants.ANNOTATION_PROCESSOR_CONFIGURATION_NAME, dependency) 32 | } 33 | 34 | internal fun DependencyHandler.ksp(dependency: String) { 35 | add("ksp", dependency) 36 | } 37 | 38 | internal fun Project.hasDependency( 39 | artifact: String, 40 | name: String = JvmConstants.IMPLEMENTATION_CONFIGURATION_NAME 41 | ): Boolean { 42 | var has = false 43 | configurations.getByName(name).dependencies.all { 44 | if (it.name == artifact) { 45 | has = true 46 | return@all 47 | } 48 | } 49 | return has 50 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/utility/extension.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.utility 18 | 19 | import org.gradle.api.initialization.dsl.VersionCatalogBuilder 20 | 21 | /** 22 | * @author Enaium 23 | */ 24 | internal fun VersionCatalogBuilder.lib(alias: String, artifact: String): VersionCatalogBuilder.LibraryAliasBuilder { 25 | return library(alias, JIMMER_GROUP, "jimmer-$artifact") 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/utility/jdbc.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.utility 18 | 19 | import cn.enaium.jimmer.gradle.model.* 20 | import java.sql.DatabaseMetaData 21 | import java.sql.ResultSet 22 | import java.util.concurrent.CopyOnWriteArraySet 23 | 24 | /** 25 | * @author Enaium 26 | */ 27 | internal enum class ColumnLabel { 28 | COLUMN_NAME, TABLE_NAME, TYPE_NAME, REMARKS, COLUMN_DEF, NULLABLE, PK_NAME, FKCOLUMN_NAME, PKTABLE_NAME, PKCOLUMN_NAME, FK_NAME, INDEX_NAME 29 | } 30 | 31 | private fun ResultSet.toColumn(tableName: String): Column { 32 | return Column( 33 | getString(ColumnLabel.COLUMN_NAME.name), 34 | tableName, 35 | getString(ColumnLabel.TYPE_NAME.name), 36 | getString(ColumnLabel.REMARKS.name), 37 | getString(ColumnLabel.COLUMN_DEF.name), 38 | getBoolean(ColumnLabel.NULLABLE.name) 39 | ) 40 | } 41 | 42 | internal fun DatabaseMetaData.getTables( 43 | catalog: String? = null, 44 | schemaPattern: String? = null, 45 | tableNamePattern: String? = null 46 | ): Set
{ 47 | return getTables(catalog, schemaPattern, tableNamePattern, arrayOf("TABLE")).use { tableResult -> 48 | val tables = mutableSetOf
() 49 | while (tableResult.next()) { 50 | val tableName = tableResult.getString(ColumnLabel.TABLE_NAME.name) 51 | val columns = getColumns(tableName) 52 | val primaryKeys = getPrimaryKeys(tableName) 53 | val foreignKeys = getForeignKeys(tableName) 54 | val uniqueKeys = getUniqueKeys(tableName) 55 | tables.add(Table(tableName, columns, primaryKeys, foreignKeys, uniqueKeys)) 56 | } 57 | tables 58 | } 59 | } 60 | 61 | internal fun DatabaseMetaData.getColumns(tableName: String): Set { 62 | return getColumns(null, null, tableName, null).use { column -> 63 | val columns = mutableSetOf() 64 | while (column.next()) { 65 | columns.add(column.toColumn(tableName)) 66 | } 67 | columns 68 | } 69 | } 70 | 71 | internal fun DatabaseMetaData.getPrimaryKeys(tableName: String): Set { 72 | return getPrimaryKeys(null, null, tableName).use { primaryKey -> 73 | val primaryKeys = mutableSetOf() 74 | while (primaryKey.next()) { 75 | val columnName = primaryKey.getString(ColumnLabel.COLUMN_NAME.name) 76 | val column = getColumns(tableName).first { it.name == columnName } 77 | primaryKeys.add(PrimaryKey(primaryKey.getString(ColumnLabel.PK_NAME.name), tableName, column)) 78 | } 79 | primaryKeys 80 | } 81 | } 82 | 83 | internal fun DatabaseMetaData.getForeignKeys(tableName: String): MutableSet { 84 | return getImportedKeys(null, null, tableName).use { foreignKey -> 85 | val foreignKeys = mutableSetOf() 86 | while (foreignKey.next()) { 87 | val fkColumnName = foreignKey.getString(ColumnLabel.FKCOLUMN_NAME.name) 88 | val fkColumn = getColumns(tableName).first { it.name == fkColumnName } 89 | val pkTableName = foreignKey.getString(ColumnLabel.PKTABLE_NAME.name) 90 | val pkColumnName = foreignKey.getString(ColumnLabel.PKCOLUMN_NAME.name) 91 | val pkColumn = getColumns(pkTableName).first { it.name == pkColumnName } 92 | foreignKeys.add(ForeignKey(foreignKey.getString(ColumnLabel.FK_NAME.name), tableName, fkColumn, pkColumn)) 93 | } 94 | foreignKeys 95 | } 96 | } 97 | 98 | internal fun DatabaseMetaData.getUniqueKeys(tableName: String): Set { 99 | val uniqueKey2Columns = mutableMapOf>() 100 | getIndexInfo(null, null, tableName, true, false).use { uniqueKey -> 101 | while (uniqueKey.next()) { 102 | val name = uniqueKey.getString(ColumnLabel.INDEX_NAME.name) 103 | val column = uniqueKey.getString(ColumnLabel.COLUMN_NAME.name) 104 | if (uniqueKey2Columns.containsKey(name)) { 105 | uniqueKey2Columns[name]!!.add(column) 106 | } else { 107 | uniqueKey2Columns[name] = CopyOnWriteArraySet(listOf(column)) 108 | } 109 | } 110 | } 111 | return uniqueKey2Columns.map { (name, columns) -> 112 | UniqueKey(name, tableName, columns.map { getColumns(tableName).first { column -> column.name == it } }) 113 | }.toSet() 114 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/utility/mapping.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.utility 18 | 19 | import java.math.BigDecimal 20 | import java.time.LocalDate 21 | import java.time.LocalDateTime 22 | import java.time.LocalTime 23 | import java.util.* 24 | 25 | /** 26 | * @author Enaium 27 | */ 28 | internal val kotlinTypeMappings = mutableMapOf( 29 | "tinyint" to Byte::class.qualifiedName!!, 30 | "smallint" to Short::class.qualifiedName!!, 31 | "integer" to Int::class.qualifiedName!!, 32 | "bigint" to Long::class.qualifiedName!!, 33 | "decimal" to BigDecimal::class.qualifiedName!!, 34 | "numeric" to BigDecimal::class.qualifiedName!!, 35 | "varchar" to String::class.qualifiedName!!, 36 | "text" to String::class.qualifiedName!!, 37 | "date" to LocalDate::class.qualifiedName!!, 38 | "time" to LocalTime::class.qualifiedName!!, 39 | "datetime" to LocalDateTime::class.qualifiedName!!, 40 | "timestamp" to LocalDateTime::class.qualifiedName!!, 41 | "bool" to Boolean::class.qualifiedName!!, 42 | "boolean" to Boolean::class.qualifiedName!!, 43 | "uuid" to UUID::class.qualifiedName!!, 44 | "int2" to Short::class.qualifiedName!!, 45 | "int4" to Int::class.qualifiedName!!, 46 | "int8" to Long::class.qualifiedName!!, 47 | "float4" to Float::class.qualifiedName!!, 48 | "float8" to Double::class.qualifiedName!!, 49 | ) 50 | 51 | internal val javaTypeMappings = mutableMapOf( 52 | "tinyint" to java.lang.Byte::class.java.name, 53 | "smallint" to java.lang.Short::class.java.name, 54 | "integer" to java.lang.Integer::class.java.name, 55 | "bigint" to java.lang.Long::class.java.name, 56 | "decimal" to BigDecimal::class.java.name, 57 | "numeric" to BigDecimal::class.java.name, 58 | "varchar" to java.lang.String::class.java.name, 59 | "text" to java.lang.String::class.java.name, 60 | "date" to LocalDate::class.java.name, 61 | "time" to LocalTime::class.java.name, 62 | "datetime" to LocalDateTime::class.java.name, 63 | "timestamp" to LocalDateTime::class.java.name, 64 | "bool" to java.lang.Boolean::class.java.name, 65 | "boolean" to java.lang.Boolean::class.java.name, 66 | "uuid" to UUID::class.java.name, 67 | "int2" to java.lang.Short::class.java.name, 68 | "int4" to java.lang.Integer::class.java.name, 69 | "int8" to java.lang.Long::class.java.name, 70 | "float4" to java.lang.Float::class.java.name, 71 | "float8" to java.lang.Double::class.java.name, 72 | ) -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/utility/plugin.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.utility 18 | 19 | import org.gradle.api.plugins.PluginContainer 20 | 21 | /** 22 | * @author Enaium 23 | */ 24 | internal val PluginContainer.hasJava: Boolean 25 | get() = hasPlugin("java") 26 | 27 | internal val PluginContainer.hasKotlin: Boolean 28 | get() = hasPlugin("org.jetbrains.kotlin.jvm") || hasPlugin("org.jetbrains.kotlin.multiplatform") || hasPlugin("org.jetbrains.kotlin.android") 29 | 30 | internal val PluginContainer.hasKsp: Boolean 31 | get() = hasPlugin(KSP_PLUGIN_ID) 32 | 33 | internal val PluginContainer.hasSpringBoot: Boolean 34 | get() = hasPlugin(SPRINGBOOT_PLUGIN_ID) -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/utility/string.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.utility 18 | 19 | import java.util.* 20 | 21 | /** 22 | * @author Enaium 23 | */ 24 | internal fun String.snakeToCamelCase( 25 | firstCharUppercase: Boolean = true, 26 | ): String { 27 | return this.split("_") 28 | .joinToString("") { 29 | it.replaceFirstChar { firstChar -> firstChar.uppercase(Locale.getDefault()) } 30 | }.let { 31 | if (!firstCharUppercase) { 32 | it.replaceFirstChar { firstChar -> firstChar.lowercase(Locale.getDefault()) } 33 | } else { 34 | it 35 | } 36 | } 37 | } 38 | 39 | internal fun String.firstCharLowercase(): String { 40 | return this.replaceFirstChar { firstChar -> firstChar.lowercase(Locale.getDefault()) } 41 | } 42 | 43 | internal fun String.firstCharUppercase(): String { 44 | return this.replaceFirstChar { firstChar -> firstChar.uppercase(Locale.getDefault()) } 45 | } 46 | 47 | internal fun String.toPlural(): String { 48 | return if (this.matches(Regex(".*(s|x|z|sh|ch)$"))) { 49 | "${this}es" 50 | } else if (this.matches(Regex(".*[^aeiou]y$"))) { 51 | "${this.substring(0, this.length - 1)}ies" 52 | } else if (this.matches(Regex(".*[^aeiou]o$"))) { 53 | "${this}es" 54 | } else if (this.matches(Regex(".*[^aeiou]f$"))) { 55 | "${this.substring(0, this.length - 1)}ves" 56 | } else if (this.matches(Regex(".*[^aeiou]fe$"))) { 57 | "${this.substring(0, this.length - 2)}ves" 58 | } else { 59 | "${this}s" 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/utility/task.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.utility 18 | 19 | import org.gradle.api.Task 20 | import org.gradle.api.tasks.TaskContainer 21 | import org.gradle.api.tasks.compile.JavaCompile 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | internal val TaskContainer.hasKsp: Boolean 27 | get() = findByName(KSP_TASK_NAME) != null 28 | 29 | internal val TaskContainer.hasDebugKsp: Boolean 30 | get() = findByName(KSP_DEBUG_TASK_NAME) != null 31 | 32 | internal val TaskContainer.hasPre: Boolean 33 | get() = findByName(PRE_TASK_NAME) != null 34 | 35 | internal val TaskContainer.hasCompileJava: Boolean 36 | get() = findByName("compileJava") != null 37 | 38 | internal val TaskContainer.hasCompileKotlin: Boolean 39 | get() = findByName("compileKotlin") != null 40 | 41 | internal val TaskContainer.hasCompileDebugKotlin: Boolean 42 | get() = findByName("compileDebugKotlin") != null 43 | 44 | internal fun TaskContainer.compileJava(action: (JavaCompile) -> Unit) { 45 | withType(JavaCompile::class.java) { 46 | action(it) 47 | } 48 | } 49 | 50 | internal fun TaskContainer.kspKotlin(action: (Task) -> Unit) { 51 | getByName(KSP_TASK_NAME) { 52 | action(it) 53 | } 54 | } 55 | 56 | internal fun TaskContainer.kspDebugKotlin(action: (Task) -> Unit) { 57 | getByName(KSP_DEBUG_TASK_NAME) { 58 | action(it) 59 | } 60 | } 61 | 62 | internal fun TaskContainer.compileKotlin(action: (Task) -> Unit) { 63 | getByName("compileKotlin") { 64 | action(it) 65 | } 66 | } 67 | 68 | internal fun TaskContainer.compileDebugKotlin(action: (Task) -> Unit) { 69 | getByName("compileDebugKotlin") { 70 | action(it) 71 | } 72 | } -------------------------------------------------------------------------------- /src/main/kotlin/cn/enaium/jimmer/gradle/utility/utility.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.utility 18 | 19 | import com.squareup.kotlinpoet.ClassName 20 | 21 | /** 22 | * @author Enaium 23 | */ 24 | internal fun hasClass(className: String): Boolean { 25 | return try { 26 | Class.forName(className) 27 | true 28 | } catch (e: ClassNotFoundException) { 29 | false 30 | } 31 | } 32 | 33 | internal fun ClassName.Companion.name(name: String): ClassName { 34 | return ClassName( 35 | name.substring(0, name.lastIndexOf(".")), 36 | name.substring(name.lastIndexOf(".") + 1) 37 | ) 38 | } 39 | 40 | internal fun className(name: String): com.squareup.javapoet.ClassName { 41 | return com.squareup.javapoet.ClassName.get( 42 | name.substring(0, name.lastIndexOf(".")), 43 | name.substring(name.lastIndexOf(".") + 1) 44 | ) 45 | } -------------------------------------------------------------------------------- /src/test/kotlin/cn/enaium/jimmer/gradle/integration/AbstractGeneratorEntityTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.integration 18 | 19 | import cn.enaium.jimmer.gradle.extension.Driver 20 | import cn.enaium.jimmer.gradle.extension.Language 21 | import cn.enaium.jimmer.gradle.util.ProjectTest 22 | import org.gradle.testkit.runner.BuildResult 23 | import org.gradle.testkit.runner.TaskOutcome 24 | import kotlin.test.assertEquals 25 | 26 | /** 27 | * @author Enaium 28 | */ 29 | abstract class AbstractGeneratorEntityTest(name: String = "generateEntity") { 30 | 31 | private val projectTest = ProjectTest(name) 32 | 33 | private val entities = listOf("Answer", "BaseEntity", "Comment", "People", "Post", "Profile", "Question", "Topic") 34 | 35 | fun assertGenerateTask(buildResult: BuildResult, language: Language) { 36 | assertEquals(buildResult.task(":generateEntity")?.outcome, TaskOutcome.SUCCESS) 37 | val lang = if (language == Language.KOTLIN) "kotlin" else "java" 38 | val extension = if (language == Language.KOTLIN) "kt" else "java" 39 | val packagePath = projectTest.testProjectDir.resolve("src") 40 | .resolve("main") 41 | .resolve(lang) 42 | .resolve("cn") 43 | .resolve("enaium") 44 | 45 | entities.forEach { 46 | val fileName = "$it.$extension" 47 | val entity = packagePath.resolve(fileName) 48 | assertEquals(entity.exists(), true) 49 | assertEquals( 50 | entity.readText(), 51 | object {}.javaClass.getResource("/generated/entity/$lang/$fileName")!!.readText() 52 | ) 53 | } 54 | } 55 | 56 | fun create( 57 | url: String, 58 | username: String, 59 | password: String, 60 | driver: Driver, 61 | language: Language, 62 | driverDependency: String 63 | ): BuildResult { 64 | return projectTest.create( 65 | "generateEntity", mapOf( 66 | "url" to url, 67 | "username" to username, 68 | "password" to password, 69 | "driver" to driver.name, 70 | "language" to language.name, 71 | "driverDependency" to driverDependency 72 | ) 73 | ) 74 | } 75 | 76 | fun create( 77 | driver: Driver, 78 | language: Language 79 | ): BuildResult { 80 | return projectTest.create( 81 | "generateEntity", mapOf( 82 | "driver" to driver.name, 83 | "language" to language.name 84 | ) 85 | ) 86 | } 87 | } -------------------------------------------------------------------------------- /src/test/kotlin/cn/enaium/jimmer/gradle/integration/AptArgumentTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.integration 18 | 19 | import cn.enaium.jimmer.gradle.extension.InputDtoModifier 20 | import cn.enaium.jimmer.gradle.util.ProjectTest 21 | import cn.enaium.jimmer.gradle.utility.* 22 | import org.gradle.testkit.runner.TaskOutcome 23 | import org.junit.jupiter.api.Test 24 | import kotlin.test.assertEquals 25 | 26 | /** 27 | * @author Enaium 28 | */ 29 | class AptArgumentTest { 30 | @Test 31 | fun test() { 32 | val argument = mutableMapOf() 33 | var content = "" 34 | argument[KEEP_IS_PREFIX] = true 35 | argument[SOURCE_EXCLUDES] = listOf("src/main/java") 36 | argument[SOURCE_EXCLUDES] = listOf("src/test/java") 37 | argument[DTO_DIRS] = listOf("src/main/java") 38 | argument[DTO_TEST_DIRS] = listOf("src/test/java") 39 | argument[DTO_DEFAULT_NULLABLE_INPUT_MODIFIER] = InputDtoModifier.FIXED 40 | argument[DTO_HIBERNATE_VALIDATOR_ENHANCEMENT] = true 41 | argument[CLIENT_CHECKED_EXCEPTION] = true 42 | argument[CLIENT_IGNORE_JDK_WARNING] = true 43 | argument[ENTRY_OBJECTS] = "Drafts" 44 | argument[ENTRY_TABLES] = "Tables" 45 | argument[ENTRY_TABLE_EXES] = "TableExes" 46 | argument[ENTRY_FETCHERS] = "Fetchers" 47 | 48 | for ((key, value) in argument) { 49 | when (value) { 50 | is List<*> -> { 51 | content += """$key = listOf("${value[0].toString()}")""" 52 | content += "\n" 53 | } 54 | 55 | is InputDtoModifier -> { 56 | content += """$key = InputDtoModifier.${value.name}""" 57 | content += "\n" 58 | } 59 | 60 | is String -> { 61 | content += """$key = "$value"""" 62 | content += "\n" 63 | } 64 | 65 | else -> { 66 | content += """$key = $value""" 67 | content += "\n" 68 | } 69 | } 70 | } 71 | 72 | val taskName = "aptArgument" 73 | 74 | content += """tasks.create("$taskName") {""" 75 | content += "\n" 76 | content += """doLast {""" 77 | content += "\n" 78 | for ((k, v) in argument) { 79 | val value = when (v) { 80 | is List<*> -> v[0].toString() 81 | is InputDtoModifier -> v.name.lowercase() 82 | else -> v.toString() 83 | } 84 | content += """if (tasks.compileJava.get().options.compilerArgs.indexOf("-A$k=$value") == -1) {""" 85 | content += "\n" 86 | content += """error("$k")""" 87 | content += "\n" 88 | content += "}" 89 | content += "\n" 90 | } 91 | content += "\n" 92 | content += "}" 93 | content += "\n" 94 | content += "}" 95 | 96 | content += """""" 97 | 98 | val projectTest = ProjectTest("aptArgument") 99 | val task = projectTest.create(taskName, mapOf("content" to content)).task(":$taskName") 100 | assertEquals(task?.outcome, TaskOutcome.SUCCESS) 101 | projectTest.clear() 102 | } 103 | } -------------------------------------------------------------------------------- /src/test/kotlin/cn/enaium/jimmer/gradle/integration/DDLGeneratorTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.integration 18 | 19 | import cn.enaium.jimmer.gradle.extension.Driver 20 | import cn.enaium.jimmer.gradle.extension.Language 21 | import org.junit.jupiter.api.Test 22 | 23 | /** 24 | * @author Enaium 25 | */ 26 | class DDLGeneratorTest : AbstractGeneratorEntityTest("generateDDL") { 27 | @Test 28 | fun generateDDL() { 29 | val kotlin = create(Driver.POSTGRESQL, Language.KOTLIN) 30 | assertGenerateTask(kotlin, Language.KOTLIN) 31 | 32 | val java = create(Driver.POSTGRESQL, language = Language.JAVA) 33 | assertGenerateTask(java, Language.JAVA) 34 | } 35 | } -------------------------------------------------------------------------------- /src/test/kotlin/cn/enaium/jimmer/gradle/integration/H2GeneratorTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.integration 18 | 19 | import cn.enaium.jimmer.gradle.extension.Driver 20 | import cn.enaium.jimmer.gradle.extension.Language 21 | import org.gradle.testkit.runner.BuildResult 22 | import org.junit.jupiter.api.Test 23 | 24 | /** 25 | * @author Enaium 26 | */ 27 | class H2GeneratorTest : AbstractGeneratorEntityTest() { 28 | 29 | private val driverDependency = "com.h2database:h2:2.3.232" 30 | 31 | @Test 32 | fun generateEntity() { 33 | val kotlin = create(language = Language.KOTLIN) 34 | assertGenerateTask(kotlin, Language.KOTLIN) 35 | 36 | val java = create(language = Language.JAVA) 37 | assertGenerateTask(java, Language.JAVA) 38 | } 39 | 40 | private fun create(language: Language): BuildResult { 41 | return create( 42 | "jdbc:h2:mem:test;DATABASE_TO_LOWER=true;INIT=RUNSCRIPT FROM 'src/test/resources/mariadb.sql'", 43 | "", 44 | "", 45 | Driver.H2, 46 | language, 47 | driverDependency 48 | ) 49 | } 50 | } -------------------------------------------------------------------------------- /src/test/kotlin/cn/enaium/jimmer/gradle/integration/KspArgumentTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.integration 18 | 19 | import cn.enaium.jimmer.gradle.extension.InputDtoModifier 20 | import cn.enaium.jimmer.gradle.util.ProjectTest 21 | import cn.enaium.jimmer.gradle.utility.* 22 | import org.gradle.testkit.runner.TaskOutcome 23 | import org.junit.jupiter.api.Test 24 | import kotlin.test.assertEquals 25 | 26 | /** 27 | * @author Enaium 28 | */ 29 | class KspArgumentTest { 30 | @Test 31 | fun test() { 32 | val argument = mutableMapOf() 33 | var content = "" 34 | argument[DTO_DIRS] = listOf("src/main/kotlin") 35 | argument[DTO_TEST_DIRS] = listOf("src/test/kotlin") 36 | argument[DTO_MUTABLE] = true 37 | argument[DTO_DEFAULT_NULLABLE_INPUT_MODIFIER] = InputDtoModifier.FIXED 38 | argument[CLIENT_CHECKED_EXCEPTION] = true 39 | argument[IMMUTABLE_IS_MODULE_REQUIRED] = true 40 | 41 | for ((key, value) in argument) { 42 | when (value) { 43 | is List<*> -> { 44 | content += """$key = listOf("${value[0].toString()}")""" 45 | content += "\n" 46 | } 47 | 48 | is InputDtoModifier -> { 49 | content += """$key = InputDtoModifier.${value.name}""" 50 | content += "\n" 51 | } 52 | 53 | is String -> { 54 | content += """$key = "$value"""" 55 | content += "\n" 56 | } 57 | 58 | else -> { 59 | content += """$key = $value""" 60 | content += "\n" 61 | } 62 | } 63 | } 64 | 65 | val taskName = "kspArgument" 66 | 67 | content += """tasks.create("$taskName") {""" 68 | content += "\n" 69 | content += """doLast {""" 70 | content += "\n" 71 | for ((k, v) in argument) { 72 | val value = when (v) { 73 | is List<*> -> v[0].toString() 74 | is InputDtoModifier -> v.name.lowercase() 75 | else -> v.toString() 76 | } 77 | content += """if (ksp.arguments["$k"] != "$value") {""" 78 | content += "\n" 79 | content += """error("$k")""" 80 | content += "\n" 81 | content += "}" 82 | content += "\n" 83 | } 84 | content += "\n" 85 | content += "}" 86 | content += "\n" 87 | content += "}" 88 | 89 | 90 | val projectTest = ProjectTest("kspArgument") 91 | val task = projectTest.create(taskName, mapOf("content" to content)).task(":$taskName") 92 | assertEquals(task?.outcome, TaskOutcome.SUCCESS) 93 | projectTest.clear() 94 | } 95 | } -------------------------------------------------------------------------------- /src/test/kotlin/cn/enaium/jimmer/gradle/integration/MariaDBGeneratorTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.integration 18 | 19 | import cn.enaium.jimmer.gradle.extension.Driver 20 | import cn.enaium.jimmer.gradle.extension.Language 21 | import org.gradle.testkit.runner.BuildResult 22 | import org.junit.jupiter.api.AfterAll 23 | import org.junit.jupiter.api.BeforeAll 24 | import org.junit.jupiter.api.Test 25 | import org.testcontainers.containers.MariaDBContainer 26 | import java.sql.DriverManager 27 | 28 | /** 29 | * @author Enaium 30 | */ 31 | class MariaDBGeneratorTest : AbstractGeneratorEntityTest() { 32 | private val driverDependency = "org.mariadb.jdbc:mariadb-java-client:3.3.3" 33 | 34 | @Test 35 | fun generateEntity() { 36 | val kotlin = create(language = Language.KOTLIN) 37 | assertGenerateTask(kotlin, Language.KOTLIN) 38 | 39 | val java = create(language = Language.JAVA) 40 | assertGenerateTask(java, Language.JAVA) 41 | } 42 | 43 | private fun create(language: Language): BuildResult { 44 | return create( 45 | mariadb.jdbcUrl, 46 | mariadb.username, 47 | mariadb.password, 48 | Driver.MARIADB, 49 | language, 50 | driverDependency 51 | ) 52 | } 53 | 54 | companion object { 55 | private val mariadb: MariaDBContainer<*> = MariaDBContainer("mariadb:latest") 56 | 57 | 58 | @BeforeAll 59 | @JvmStatic 60 | fun beforeAll() { 61 | mariadb.start() 62 | 63 | Class.forName(mariadb.driverClassName) 64 | val createStatement = DriverManager.getConnection( 65 | "${mariadb.jdbcUrl}?allowMultiQueries=true", 66 | mariadb.username, 67 | mariadb.password 68 | ).createStatement() 69 | 70 | createStatement.execute(object {}::class.java.getResource("/mariadb.sql")!!.readText()) 71 | } 72 | 73 | @AfterAll 74 | @JvmStatic 75 | fun afterAll() { 76 | mariadb.stop() 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /src/test/kotlin/cn/enaium/jimmer/gradle/integration/PostgresSQLGeneratorTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Enaium 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.enaium.jimmer.gradle.integration 18 | 19 | import cn.enaium.jimmer.gradle.extension.Driver 20 | import cn.enaium.jimmer.gradle.extension.Language 21 | import org.gradle.testkit.runner.BuildResult 22 | import org.junit.jupiter.api.AfterAll 23 | import org.junit.jupiter.api.BeforeAll 24 | import org.junit.jupiter.api.Test 25 | import org.testcontainers.containers.PostgreSQLContainer 26 | import java.sql.DriverManager 27 | 28 | /** 29 | * @author Enaium 30 | */ 31 | class PostgresSQLGeneratorTest : AbstractGeneratorEntityTest() { 32 | private val driverDependency = "org.postgresql:postgresql:42.6.0" 33 | 34 | @Test 35 | fun generateEntity() { 36 | val kotlin = create(language = Language.KOTLIN) 37 | assertGenerateTask(kotlin, Language.KOTLIN) 38 | 39 | val java = create(language = Language.JAVA) 40 | assertGenerateTask(java, Language.JAVA) 41 | } 42 | 43 | private fun create(language: Language): BuildResult { 44 | return create( 45 | postgres.jdbcUrl, 46 | postgres.username, 47 | postgres.password, 48 | Driver.POSTGRESQL, 49 | language, 50 | driverDependency 51 | ) 52 | } 53 | 54 | companion object { 55 | private val postgres: PostgreSQLContainer<*> = PostgreSQLContainer("postgres:latest") 56 | 57 | 58 | @BeforeAll 59 | @JvmStatic 60 | fun beforeAll() { 61 | postgres.start() 62 | 63 | Class.forName(postgres.driverClassName) 64 | DriverManager.getConnection( 65 | postgres.jdbcUrl, 66 | postgres.username, 67 | postgres.password 68 | ).createStatement().execute(object {}::class.java.getResource("/postgres.sql")!!.readText()) 69 | } 70 | 71 | @AfterAll 72 | @JvmStatic 73 | fun afterAll() { 74 | postgres.stop() 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /src/test/kotlin/cn/enaium/jimmer/gradle/util/ProjectTest.kt: -------------------------------------------------------------------------------- 1 | package cn.enaium.jimmer.gradle.util 2 | 3 | import org.gradle.testkit.runner.BuildResult 4 | import org.gradle.testkit.runner.GradleRunner 5 | import org.gradle.util.GradleVersion 6 | import java.io.File 7 | import java.io.FileNotFoundException 8 | import java.nio.file.Files 9 | 10 | /** 11 | * @author Enaium 12 | */ 13 | class ProjectTest(private val name: String) { 14 | 15 | val testProjectDir: File = 16 | Files.createTempDirectory("jimmer-gradle-${name}-${System.currentTimeMillis()}").toFile() 17 | 18 | private fun copyInputFiles(stringMap: Map) { 19 | val baseProjectDir = File("src/test/resources/projects/${name}") 20 | if (!baseProjectDir.exists()) { 21 | throw FileNotFoundException("Failed to find project directory at:" + baseProjectDir.absolutePath) 22 | } 23 | baseProjectDir.walk().forEach { 24 | if (it.isDirectory) { 25 | return@forEach 26 | } 27 | val path = it.path.replace(baseProjectDir.path, "") 28 | val tempFile = File(testProjectDir, path) 29 | if (tempFile.exists()) { 30 | tempFile.delete() 31 | } 32 | tempFile.parentFile.mkdirs() 33 | val text = it.readText(Charsets.UTF_8) 34 | 35 | tempFile.writeText(stringMap.entries.fold(text) { acc, entry -> 36 | acc.replace("%{${entry.key}}", entry.value) 37 | }) 38 | } 39 | } 40 | 41 | fun clear() { 42 | testProjectDir.deleteRecursively() 43 | } 44 | 45 | fun create( 46 | task: String, 47 | stringMap: Map = mapOf(), 48 | ): BuildResult { 49 | copyInputFiles(stringMap) 50 | 51 | return GradleRunner.create().withProjectDir(testProjectDir).withArguments( 52 | task, 53 | "--stacktrace", 54 | "--warning-mode", 55 | "fail", 56 | "--gradle-user-home", 57 | File(System.getProperty("user.home"), ".gradle").absolutePath, 58 | ).withGradleVersion(GradleVersion.current().version).forwardOutput().withDebug(true) 59 | .build() 60 | } 61 | } -------------------------------------------------------------------------------- /src/test/resources/generated/entity/java/Answer.java: -------------------------------------------------------------------------------- 1 | package cn.enaium; 2 | 3 | import java.lang.String; 4 | import java.util.List; 5 | import java.util.UUID; 6 | import org.babyfish.jimmer.sql.Entity; 7 | import org.babyfish.jimmer.sql.IdView; 8 | import org.babyfish.jimmer.sql.ManyToOne; 9 | import org.babyfish.jimmer.sql.OneToMany; 10 | import org.babyfish.jimmer.sql.Table; 11 | 12 | @Entity 13 | @Table( 14 | name = "answer" 15 | ) 16 | public interface Answer extends BaseEntity { 17 | String content(); 18 | 19 | @IdView 20 | UUID peopleId(); 21 | 22 | @IdView 23 | UUID questionId(); 24 | 25 | @ManyToOne 26 | People people(); 27 | 28 | @ManyToOne 29 | Question question(); 30 | 31 | @OneToMany( 32 | mappedBy = "answer" 33 | ) 34 | List comments(); 35 | } 36 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/java/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package cn.enaium; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | import org.babyfish.jimmer.sql.Id; 6 | import org.babyfish.jimmer.sql.MappedSuperclass; 7 | 8 | @MappedSuperclass 9 | public interface BaseEntity { 10 | LocalDateTime createdTime(); 11 | 12 | LocalDateTime modifiedTime(); 13 | 14 | boolean deleted(); 15 | 16 | @Id 17 | UUID id(); 18 | } 19 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/java/Comment.java: -------------------------------------------------------------------------------- 1 | package cn.enaium; 2 | 3 | import java.lang.String; 4 | import java.util.UUID; 5 | import org.babyfish.jimmer.sql.Entity; 6 | import org.babyfish.jimmer.sql.IdView; 7 | import org.babyfish.jimmer.sql.ManyToOne; 8 | import org.babyfish.jimmer.sql.Table; 9 | import org.jetbrains.annotations.Nullable; 10 | 11 | @Entity 12 | @Table( 13 | name = "comment" 14 | ) 15 | public interface Comment extends BaseEntity { 16 | String content(); 17 | 18 | @IdView 19 | UUID peopleId(); 20 | 21 | @IdView 22 | @Nullable 23 | UUID commentId(); 24 | 25 | @IdView 26 | @Nullable 27 | UUID answerId(); 28 | 29 | @IdView 30 | @Nullable 31 | UUID postId(); 32 | 33 | @ManyToOne 34 | @Nullable 35 | Answer answer(); 36 | 37 | @ManyToOne 38 | @Nullable 39 | Comment comment(); 40 | 41 | @ManyToOne 42 | People people(); 43 | 44 | @ManyToOne 45 | @Nullable 46 | Post post(); 47 | } 48 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/java/People.java: -------------------------------------------------------------------------------- 1 | package cn.enaium; 2 | 3 | import java.lang.String; 4 | import java.util.List; 5 | import org.babyfish.jimmer.sql.Entity; 6 | import org.babyfish.jimmer.sql.OneToMany; 7 | import org.babyfish.jimmer.sql.OneToOne; 8 | import org.babyfish.jimmer.sql.Table; 9 | import org.jetbrains.annotations.Nullable; 10 | 11 | @Entity 12 | @Table( 13 | name = "people" 14 | ) 15 | public interface People extends BaseEntity { 16 | String phone(); 17 | 18 | String password(); 19 | 20 | @OneToMany( 21 | mappedBy = "people" 22 | ) 23 | List posts(); 24 | 25 | @OneToOne( 26 | mappedBy = "people" 27 | ) 28 | @Nullable 29 | Profile profile(); 30 | 31 | @OneToMany( 32 | mappedBy = "people" 33 | ) 34 | List questions(); 35 | 36 | @OneToMany( 37 | mappedBy = "people" 38 | ) 39 | List topics(); 40 | } 41 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/java/Post.java: -------------------------------------------------------------------------------- 1 | package cn.enaium; 2 | 3 | import java.lang.String; 4 | import java.util.List; 5 | import java.util.UUID; 6 | import org.babyfish.jimmer.sql.Entity; 7 | import org.babyfish.jimmer.sql.IdView; 8 | import org.babyfish.jimmer.sql.JoinColumn; 9 | import org.babyfish.jimmer.sql.JoinTable; 10 | import org.babyfish.jimmer.sql.ManyToMany; 11 | import org.babyfish.jimmer.sql.ManyToOne; 12 | import org.babyfish.jimmer.sql.Table; 13 | 14 | @Entity 15 | @Table( 16 | name = "post" 17 | ) 18 | public interface Post extends BaseEntity { 19 | String title(); 20 | 21 | String content(); 22 | 23 | @IdView 24 | UUID peopleId(); 25 | 26 | @ManyToOne 27 | People people(); 28 | 29 | @ManyToMany 30 | @JoinTable( 31 | name = "post_topic", 32 | joinColumns = @JoinColumn(name = "post_id"), 33 | inverseJoinColumns = @JoinColumn(name = "topic_id") 34 | ) 35 | List topics(); 36 | } 37 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/java/Profile.java: -------------------------------------------------------------------------------- 1 | package cn.enaium; 2 | 3 | import java.lang.String; 4 | import java.util.UUID; 5 | import org.babyfish.jimmer.sql.Entity; 6 | import org.babyfish.jimmer.sql.IdView; 7 | import org.babyfish.jimmer.sql.OneToOne; 8 | import org.babyfish.jimmer.sql.Table; 9 | 10 | @Entity 11 | @Table( 12 | name = "profile" 13 | ) 14 | public interface Profile extends BaseEntity { 15 | @IdView 16 | UUID peopleId(); 17 | 18 | String nickname(); 19 | 20 | String email(); 21 | 22 | @OneToOne 23 | People people(); 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/java/Question.java: -------------------------------------------------------------------------------- 1 | package cn.enaium; 2 | 3 | import java.lang.String; 4 | import java.util.List; 5 | import java.util.UUID; 6 | import org.babyfish.jimmer.sql.Entity; 7 | import org.babyfish.jimmer.sql.IdView; 8 | import org.babyfish.jimmer.sql.JoinColumn; 9 | import org.babyfish.jimmer.sql.JoinTable; 10 | import org.babyfish.jimmer.sql.ManyToMany; 11 | import org.babyfish.jimmer.sql.ManyToOne; 12 | import org.babyfish.jimmer.sql.Table; 13 | 14 | @Entity 15 | @Table( 16 | name = "question" 17 | ) 18 | public interface Question extends BaseEntity { 19 | String title(); 20 | 21 | String content(); 22 | 23 | @IdView 24 | UUID peopleId(); 25 | 26 | @ManyToOne 27 | People people(); 28 | 29 | @ManyToMany 30 | @JoinTable( 31 | name = "question_topic", 32 | joinColumns = @JoinColumn(name = "question_id"), 33 | inverseJoinColumns = @JoinColumn(name = "topic_id") 34 | ) 35 | List topics(); 36 | } 37 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/java/Topic.java: -------------------------------------------------------------------------------- 1 | package cn.enaium; 2 | 3 | import java.lang.String; 4 | import java.util.List; 5 | import java.util.UUID; 6 | import org.babyfish.jimmer.sql.Entity; 7 | import org.babyfish.jimmer.sql.IdView; 8 | import org.babyfish.jimmer.sql.ManyToMany; 9 | import org.babyfish.jimmer.sql.ManyToOne; 10 | import org.babyfish.jimmer.sql.Table; 11 | 12 | @Entity 13 | @Table( 14 | name = "topic" 15 | ) 16 | public interface Topic extends BaseEntity { 17 | String title(); 18 | 19 | @IdView 20 | UUID peopleId(); 21 | 22 | @ManyToOne 23 | People people(); 24 | 25 | @ManyToMany( 26 | mappedBy = "topics" 27 | ) 28 | List posts(); 29 | 30 | @ManyToMany( 31 | mappedBy = "topics" 32 | ) 33 | List questions(); 34 | } 35 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/kotlin/Answer.kt: -------------------------------------------------------------------------------- 1 | package cn.enaium 2 | 3 | import java.util.UUID 4 | import kotlin.String 5 | import kotlin.collections.List 6 | import org.babyfish.jimmer.sql.Entity 7 | import org.babyfish.jimmer.sql.IdView 8 | import org.babyfish.jimmer.sql.ManyToOne 9 | import org.babyfish.jimmer.sql.OneToMany 10 | import org.babyfish.jimmer.sql.Table 11 | 12 | @Entity 13 | @Table(name = "answer") 14 | public interface Answer : BaseEntity { 15 | public val content: String 16 | 17 | @IdView 18 | public val peopleId: UUID 19 | 20 | @IdView 21 | public val questionId: UUID 22 | 23 | @ManyToOne 24 | public val people: People 25 | 26 | @ManyToOne 27 | public val question: Question 28 | 29 | @OneToMany(mappedBy = "answer") 30 | public val comments: List 31 | } 32 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/kotlin/BaseEntity.kt: -------------------------------------------------------------------------------- 1 | package cn.enaium 2 | 3 | import java.time.LocalDateTime 4 | import java.util.UUID 5 | import kotlin.Boolean 6 | import org.babyfish.jimmer.sql.Id 7 | import org.babyfish.jimmer.sql.MappedSuperclass 8 | 9 | @MappedSuperclass 10 | public interface BaseEntity { 11 | public val createdTime: LocalDateTime 12 | 13 | public val modifiedTime: LocalDateTime 14 | 15 | public val deleted: Boolean 16 | 17 | @Id 18 | public val id: UUID 19 | } 20 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/kotlin/Comment.kt: -------------------------------------------------------------------------------- 1 | package cn.enaium 2 | 3 | import java.util.UUID 4 | import kotlin.String 5 | import org.babyfish.jimmer.sql.Entity 6 | import org.babyfish.jimmer.sql.IdView 7 | import org.babyfish.jimmer.sql.ManyToOne 8 | import org.babyfish.jimmer.sql.Table 9 | 10 | @Entity 11 | @Table(name = "comment") 12 | public interface Comment : BaseEntity { 13 | public val content: String 14 | 15 | @IdView 16 | public val peopleId: UUID 17 | 18 | @IdView 19 | public val commentId: UUID? 20 | 21 | @IdView 22 | public val answerId: UUID? 23 | 24 | @IdView 25 | public val postId: UUID? 26 | 27 | @ManyToOne 28 | public val answer: Answer? 29 | 30 | @ManyToOne 31 | public val comment: Comment? 32 | 33 | @ManyToOne 34 | public val people: People 35 | 36 | @ManyToOne 37 | public val post: Post? 38 | } 39 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/kotlin/People.kt: -------------------------------------------------------------------------------- 1 | package cn.enaium 2 | 3 | import kotlin.String 4 | import kotlin.collections.List 5 | import org.babyfish.jimmer.sql.Entity 6 | import org.babyfish.jimmer.sql.OneToMany 7 | import org.babyfish.jimmer.sql.OneToOne 8 | import org.babyfish.jimmer.sql.Table 9 | 10 | @Entity 11 | @Table(name = "people") 12 | public interface People : BaseEntity { 13 | public val phone: String 14 | 15 | public val password: String 16 | 17 | @OneToMany(mappedBy = "people") 18 | public val posts: List 19 | 20 | @OneToOne(mappedBy = "people") 21 | public val profile: Profile? 22 | 23 | @OneToMany(mappedBy = "people") 24 | public val questions: List 25 | 26 | @OneToMany(mappedBy = "people") 27 | public val topics: List 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/kotlin/Post.kt: -------------------------------------------------------------------------------- 1 | package cn.enaium 2 | 3 | import java.util.UUID 4 | import kotlin.String 5 | import kotlin.collections.List 6 | import org.babyfish.jimmer.sql.Entity 7 | import org.babyfish.jimmer.sql.IdView 8 | import org.babyfish.jimmer.sql.JoinColumn 9 | import org.babyfish.jimmer.sql.JoinTable 10 | import org.babyfish.jimmer.sql.ManyToMany 11 | import org.babyfish.jimmer.sql.ManyToOne 12 | import org.babyfish.jimmer.sql.Table 13 | 14 | @Entity 15 | @Table(name = "post") 16 | public interface Post : BaseEntity { 17 | public val title: String 18 | 19 | public val content: String 20 | 21 | @IdView 22 | public val peopleId: UUID 23 | 24 | @ManyToOne 25 | public val people: People 26 | 27 | @ManyToMany 28 | @JoinTable( 29 | name = "post_topic", 30 | joinColumns = [JoinColumn(name = "post_id")], 31 | inverseJoinColumns = [JoinColumn(name = "topic_id")], 32 | ) 33 | public val topics: List 34 | } 35 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/kotlin/Profile.kt: -------------------------------------------------------------------------------- 1 | package cn.enaium 2 | 3 | import java.util.UUID 4 | import kotlin.String 5 | import org.babyfish.jimmer.sql.Entity 6 | import org.babyfish.jimmer.sql.IdView 7 | import org.babyfish.jimmer.sql.OneToOne 8 | import org.babyfish.jimmer.sql.Table 9 | 10 | @Entity 11 | @Table(name = "profile") 12 | public interface Profile : BaseEntity { 13 | @IdView 14 | public val peopleId: UUID 15 | 16 | public val nickname: String 17 | 18 | public val email: String 19 | 20 | @OneToOne 21 | public val people: People 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/kotlin/Question.kt: -------------------------------------------------------------------------------- 1 | package cn.enaium 2 | 3 | import java.util.UUID 4 | import kotlin.String 5 | import kotlin.collections.List 6 | import org.babyfish.jimmer.sql.Entity 7 | import org.babyfish.jimmer.sql.IdView 8 | import org.babyfish.jimmer.sql.JoinColumn 9 | import org.babyfish.jimmer.sql.JoinTable 10 | import org.babyfish.jimmer.sql.ManyToMany 11 | import org.babyfish.jimmer.sql.ManyToOne 12 | import org.babyfish.jimmer.sql.Table 13 | 14 | @Entity 15 | @Table(name = "question") 16 | public interface Question : BaseEntity { 17 | public val title: String 18 | 19 | public val content: String 20 | 21 | @IdView 22 | public val peopleId: UUID 23 | 24 | @ManyToOne 25 | public val people: People 26 | 27 | @ManyToMany 28 | @JoinTable( 29 | name = "question_topic", 30 | joinColumns = [JoinColumn(name = "question_id")], 31 | inverseJoinColumns = [JoinColumn(name = "topic_id")], 32 | ) 33 | public val topics: List 34 | } 35 | -------------------------------------------------------------------------------- /src/test/resources/generated/entity/kotlin/Topic.kt: -------------------------------------------------------------------------------- 1 | package cn.enaium 2 | 3 | import java.util.UUID 4 | import kotlin.String 5 | import kotlin.collections.List 6 | import org.babyfish.jimmer.sql.Entity 7 | import org.babyfish.jimmer.sql.IdView 8 | import org.babyfish.jimmer.sql.ManyToMany 9 | import org.babyfish.jimmer.sql.ManyToOne 10 | import org.babyfish.jimmer.sql.Table 11 | 12 | @Entity 13 | @Table(name = "topic") 14 | public interface Topic : BaseEntity { 15 | public val title: String 16 | 17 | @IdView 18 | public val peopleId: UUID 19 | 20 | @ManyToOne 21 | public val people: People 22 | 23 | @ManyToMany(mappedBy = "topics") 24 | public val posts: List 25 | 26 | @ManyToMany(mappedBy = "topics") 27 | public val questions: List 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/mariadb.sql: -------------------------------------------------------------------------------- 1 | create table people 2 | ( 3 | created_time timestamp not null, 4 | modified_time timestamp not null, 5 | deleted bool default false not null, 6 | id uuid primary key, 7 | phone varchar(11) unique not null, 8 | password varchar(255) not null 9 | ); 10 | 11 | create table profile 12 | ( 13 | created_time timestamp not null, 14 | modified_time timestamp not null, 15 | deleted bool default false not null, 16 | id uuid primary key, 17 | people_id uuid unique not null references people (id), 18 | nickname varchar(50) unique not null, 19 | email varchar(50) unique not null 20 | ); 21 | 22 | create table topic 23 | ( 24 | created_time timestamp not null, 25 | modified_time timestamp not null, 26 | deleted bool default false not null, 27 | id uuid primary key, 28 | title varchar(50) unique not null, 29 | people_id uuid not null references people (id) 30 | ); 31 | 32 | create table question 33 | ( 34 | created_time timestamp not null, 35 | modified_time timestamp not null, 36 | deleted bool default false not null, 37 | id uuid primary key, 38 | title varchar(50) unique not null, 39 | content text not null, 40 | people_id uuid not null references people (id) 41 | ); 42 | 43 | create table answer 44 | ( 45 | created_time timestamp not null, 46 | modified_time timestamp not null, 47 | deleted bool default false not null, 48 | id uuid primary key, 49 | content text not null, 50 | people_id uuid not null references people (id), 51 | question_id uuid not null references question (id) 52 | ); 53 | 54 | create table question_topic 55 | ( 56 | question_id uuid not null references question (id), 57 | topic_id uuid not null references topic (id) 58 | ); 59 | 60 | create table post 61 | ( 62 | created_time timestamp not null, 63 | modified_time timestamp not null, 64 | deleted bool default false not null, 65 | id uuid primary key, 66 | title varchar(50) not null, 67 | content text not null, 68 | people_id uuid not null references people (id) 69 | ); 70 | 71 | create table post_topic 72 | ( 73 | post_id uuid not null references post (id), 74 | topic_id uuid not null references topic (id) 75 | ); 76 | 77 | create table comment 78 | ( 79 | created_time timestamp not null, 80 | modified_time timestamp not null, 81 | deleted bool default false not null, 82 | id uuid primary key, 83 | content text not null, 84 | people_id uuid not null references people (id), 85 | comment_id uuid references comment (id), 86 | answer_id uuid references answer (id), 87 | post_id uuid references post (id) 88 | ); -------------------------------------------------------------------------------- /src/test/resources/postgres.sql: -------------------------------------------------------------------------------- 1 | create table people 2 | ( 3 | created_time timestamp not null, 4 | modified_time timestamp not null, 5 | deleted bool default false not null, 6 | id uuid primary key, 7 | phone varchar(11) unique not null, 8 | password varchar(255) not null 9 | ); 10 | 11 | create table profile 12 | ( 13 | created_time timestamp not null, 14 | modified_time timestamp not null, 15 | deleted bool default false not null, 16 | id uuid primary key, 17 | people_id uuid unique references people (id) not null, 18 | nickname varchar(50) unique not null, 19 | email varchar(50) unique not null 20 | ); 21 | 22 | create table topic 23 | ( 24 | created_time timestamp not null, 25 | modified_time timestamp not null, 26 | deleted bool default false not null, 27 | id uuid primary key, 28 | title varchar(50) unique not null, 29 | people_id uuid references people (id) not null 30 | ); 31 | 32 | create table question 33 | ( 34 | created_time timestamp not null, 35 | modified_time timestamp not null, 36 | deleted bool default false not null, 37 | id uuid primary key, 38 | title varchar(50) unique not null, 39 | content text not null, 40 | people_id uuid references people (id) not null 41 | ); 42 | 43 | create table answer 44 | ( 45 | created_time timestamp not null, 46 | modified_time timestamp not null, 47 | deleted bool default false not null, 48 | id uuid primary key, 49 | content text not null, 50 | people_id uuid references people (id) not null, 51 | question_id uuid references question (id) not null 52 | ); 53 | 54 | create table question_topic 55 | ( 56 | 57 | question_id uuid references question (id) not null, 58 | topic_id uuid references topic (id) not null 59 | ); 60 | 61 | create table post 62 | ( 63 | created_time timestamp not null, 64 | modified_time timestamp not null, 65 | deleted bool default false not null, 66 | id uuid primary key, 67 | title varchar(50) not null, 68 | content text not null, 69 | people_id uuid references people (id) not null 70 | ); 71 | 72 | create table post_topic 73 | ( 74 | post_id uuid references post (id) not null, 75 | topic_id uuid references topic (id) not null 76 | ); 77 | 78 | create table comment 79 | ( 80 | created_time timestamp not null, 81 | modified_time timestamp not null, 82 | deleted bool default false not null, 83 | id uuid primary key, 84 | content text not null, 85 | people_id uuid references people (id) not null, 86 | comment_id uuid references comment (id), 87 | answer_id uuid references answer (id), 88 | post_id uuid references post (id) 89 | ); -------------------------------------------------------------------------------- /src/test/resources/projects/aptArgument/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import cn.enaium.jimmer.gradle.extension.InputDtoModifier 2 | 3 | plugins { 4 | java 5 | alias(jimmers.plugins.jimmer) 6 | } 7 | 8 | group = "cn.enaium" 9 | version = "0.0.1" 10 | 11 | %{content} -------------------------------------------------------------------------------- /src/test/resources/projects/aptArgument/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenLocal() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | } 7 | } 8 | 9 | plugins { 10 | id("cn.enaium.jimmer.gradle.setting") version System.getProperty("jimmer-gradle") 11 | } -------------------------------------------------------------------------------- /src/test/resources/projects/generateDDL/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import cn.enaium.jimmer.gradle.extension.Driver 2 | import cn.enaium.jimmer.gradle.extension.Language 3 | 4 | plugins { 5 | java 6 | id("cn.enaium.jimmer.gradle") version System.getProperty("jimmer-gradle") 7 | } 8 | 9 | group = "cn.enaium" 10 | version = "0.0.1" 11 | 12 | jimmer { 13 | language.set(Language.%{language}) 14 | generator { 15 | target { 16 | srcDir.set("src/main/%{language}".lowercase()) 17 | packageName.set("cn.enaium") 18 | } 19 | jdbc { 20 | driver.set(Driver.%{driver}) 21 | ddl.set(file("src/main/resources/schema.sql")) 22 | } 23 | table { 24 | idView.set(true) 25 | } 26 | } 27 | } 28 | 29 | repositories { 30 | mavenCentral() 31 | } -------------------------------------------------------------------------------- /src/test/resources/projects/generateDDL/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenLocal() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/resources/projects/generateDDL/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | create table people 2 | ( 3 | created_time timestamp not null, 4 | modified_time timestamp not null, 5 | deleted bool default false not null, 6 | id uuid primary key, 7 | phone varchar(11) unique not null, 8 | password varchar(255) not null 9 | ); 10 | 11 | create table profile 12 | ( 13 | created_time timestamp not null, 14 | modified_time timestamp not null, 15 | deleted bool default false not null, 16 | id uuid primary key, 17 | people_id uuid unique references people (id) not null, 18 | nickname varchar(50) unique not null, 19 | email varchar(50) unique not null 20 | ); 21 | 22 | create table topic 23 | ( 24 | created_time timestamp not null, 25 | modified_time timestamp not null, 26 | deleted bool default false not null, 27 | id uuid primary key, 28 | title varchar(50) unique not null, 29 | people_id uuid references people (id) not null 30 | ); 31 | 32 | create table question 33 | ( 34 | created_time timestamp not null, 35 | modified_time timestamp not null, 36 | deleted bool default false not null, 37 | id uuid primary key, 38 | title varchar(50) unique not null, 39 | content text not null, 40 | people_id uuid references people (id) not null 41 | ); 42 | 43 | create table answer 44 | ( 45 | created_time timestamp not null, 46 | modified_time timestamp not null, 47 | deleted bool default false not null, 48 | id uuid primary key, 49 | content text not null, 50 | people_id uuid references people (id) not null, 51 | question_id uuid references question (id) not null 52 | ); 53 | 54 | create table question_topic 55 | ( 56 | 57 | question_id uuid references question (id) not null, 58 | topic_id uuid references topic (id) not null 59 | ); 60 | 61 | create table post 62 | ( 63 | created_time timestamp not null, 64 | modified_time timestamp not null, 65 | deleted bool default false not null, 66 | id uuid primary key, 67 | title varchar(50) not null, 68 | content text not null, 69 | people_id uuid references people (id) not null 70 | ); 71 | 72 | create table post_topic 73 | ( 74 | post_id uuid references post (id) not null, 75 | topic_id uuid references topic (id) not null 76 | ); 77 | 78 | create table comment 79 | ( 80 | created_time timestamp not null, 81 | modified_time timestamp not null, 82 | deleted bool default false not null, 83 | id uuid primary key, 84 | content text not null, 85 | people_id uuid references people (id) not null, 86 | comment_id uuid references comment (id), 87 | answer_id uuid references answer (id), 88 | post_id uuid references post (id) 89 | ); -------------------------------------------------------------------------------- /src/test/resources/projects/generateEntity/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import cn.enaium.jimmer.gradle.extension.Driver 2 | import cn.enaium.jimmer.gradle.extension.Language 3 | 4 | plugins { 5 | java 6 | id("cn.enaium.jimmer.gradle") version System.getProperty("jimmer-gradle") 7 | } 8 | 9 | group = "cn.enaium" 10 | version = "0.0.1" 11 | 12 | jimmer { 13 | language.set(Language.%{language}) 14 | generator { 15 | target { 16 | srcDir.set("src/main/%{language}".lowercase()) 17 | packageName.set("cn.enaium") 18 | } 19 | jdbc { 20 | driver.set(Driver.%{driver}) 21 | url.set("%{url}") 22 | username.set("%{username}") 23 | password.set("%{password}") 24 | } 25 | table { 26 | idView.set(true) 27 | } 28 | } 29 | } 30 | 31 | repositories { 32 | mavenCentral() 33 | } 34 | 35 | dependencies { 36 | runtimeOnly("%{driverDependency}") 37 | } -------------------------------------------------------------------------------- /src/test/resources/projects/generateEntity/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenLocal() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | } 7 | } -------------------------------------------------------------------------------- /src/test/resources/projects/kspArgument/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import cn.enaium.jimmer.gradle.extension.InputDtoModifier 2 | import org.gradle.api.JavaVersion 3 | 4 | plugins { 5 | kotlin("jvm") version "2.0.21" 6 | alias(jimmers.plugins.ksp) version "2.0.21+" 7 | alias(jimmers.plugins.jimmer) 8 | } 9 | 10 | group = "cn.enaium" 11 | version = "0.0.1" 12 | 13 | %{content} -------------------------------------------------------------------------------- /src/test/resources/projects/kspArgument/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenLocal() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | } 7 | } 8 | 9 | plugins { 10 | id("cn.enaium.jimmer.gradle.setting") version System.getProperty("jimmer-gradle") 11 | } --------------------------------------------------------------------------------