diff --git a/.github/workflows/deploy-document.yml b/.github/workflows/deploy-document.yml
index c985bba..322dbce 100644
--- a/.github/workflows/deploy-document.yml
+++ b/.github/workflows/deploy-document.yml
@@ -3,8 +3,12 @@ name: Deploy Document
on:
push:
branches: [master]
+ paths:
+ - 'document/**'
pull_request:
branches: [master]
+ paths:
+ - 'document/**'
workflow_dispatch:
permissions:
diff --git a/core/build.gradle.kts b/core/build.gradle.kts
index 5c0fed0..4829db5 100644
--- a/core/build.gradle.kts
+++ b/core/build.gradle.kts
@@ -6,12 +6,6 @@ plugins {
group = "cn.enaium"
version = "${property("version")}"
-sourceSets {
- main {
- resources.srcDir("../shared/src/main/resources")
- }
-}
-
repositories {
mavenCentral()
intellijPlatform {
@@ -38,6 +32,7 @@ dependencies {
implementation(libs.kotlinpoet)
implementation(libs.javapoet)
implementation(libs.antlr4.intellij.adaptor)
+ implementation(libs.h2)
implementation(project(":common"))
}
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/EntityGenerate.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/EntityGenerate.kt
index a93c3cc..a73ff9f 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/EntityGenerate.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/EntityGenerate.kt
@@ -19,6 +19,7 @@ package cn.enaium.jimmer.buddy.database.generate
import cn.enaium.jimmer.buddy.database.model.Column
import cn.enaium.jimmer.buddy.database.model.GenerateEntityModel
import cn.enaium.jimmer.buddy.database.model.Table
+import com.intellij.openapi.project.Project
import java.nio.file.Path
/**
@@ -26,7 +27,7 @@ import java.nio.file.Path
*/
interface EntityGenerate {
fun generate(
- projectDir: Path,
+ project: Project,
generateEntity: GenerateEntityModel,
tables: Set
): List
@@ -36,6 +37,54 @@ interface EntityGenerate {
.filter { it -> it.value.size == tables.count { it.primaryKeys.isNotEmpty() } }.map { it.value.first() }
.toSet()
}
+
+ fun replaceName(tables: Set, generateEntity: GenerateEntityModel): Set {
+ return tables.map { table ->
+ table.copy(
+ name = table.name.replace(Regex(generateEntity.tableNameRegex), generateEntity.tableNameReplace),
+ columns = table.columns.map { column ->
+ column.copy(
+ name = column.name.replace(
+ Regex(generateEntity.columnNameRegex),
+ generateEntity.columnNameReplace
+ )
+ )
+ }.toSet(),
+ primaryKeys = table.primaryKeys.map { primaryKey ->
+ primaryKey.copy(
+ column = primaryKey.column.copy(
+ name = primaryKey.column.name.replace(
+ Regex(generateEntity.columnNameRegex),
+ generateEntity.columnNameReplace
+ )
+ )
+ )
+ }.toSet(),
+ foreignKeys = table.foreignKeys.map { foreignKey ->
+ foreignKey.copy(
+ column = foreignKey.column.copy(
+ name = foreignKey.column.name.replace(
+ Regex(generateEntity.columnNameRegex),
+ generateEntity.columnNameReplace
+ )
+ )
+ )
+ }.toMutableSet(),
+ uniqueKeys = table.uniqueKeys.map { uniqueKey ->
+ uniqueKey.copy(
+ columns = uniqueKey.columns.map { column ->
+ column.copy(
+ name = column.name.replace(
+ Regex(generateEntity.columnNameRegex),
+ generateEntity.columnNameReplace
+ )
+ )
+ }.toSet()
+ )
+ }.toSet()
+ )
+ }.toSet()
+ }
}
internal const val BASE_ENTITY = "BaseEntity"
\ No newline at end of file
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/JavaEntityGenerate.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/JavaEntityGenerate.kt
index 1713def..f71e252 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/JavaEntityGenerate.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/JavaEntityGenerate.kt
@@ -19,10 +19,14 @@ package cn.enaium.jimmer.buddy.database.generate
import cn.enaium.jimmer.buddy.database.model.Column
import cn.enaium.jimmer.buddy.database.model.ForeignKey
import cn.enaium.jimmer.buddy.database.model.GenerateEntityModel
+import cn.enaium.jimmer.buddy.extensions.template.BuddyTemplateFile
import cn.enaium.jimmer.buddy.storage.JimmerBuddySetting
import cn.enaium.jimmer.buddy.utility.firstCharLowercase
import cn.enaium.jimmer.buddy.utility.snakeToCamelCase
import cn.enaium.jimmer.buddy.utility.toPlural
+import com.intellij.ide.fileTemplates.FileTemplateManager
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.project.guessProjectDir
import com.squareup.javapoet.*
import org.babyfish.jimmer.sql.*
import org.jetbrains.annotations.Nullable
@@ -38,10 +42,13 @@ class JavaEntityGenerate : EntityGenerate {
val javaTypeMappings = JimmerBuddySetting.INSTANCE.state.typeMapping.mapValues { it.value.javaType }
override fun generate(
- projectDir: Path,
+ project: Project,
generateEntity: GenerateEntityModel,
tables: Set
): List {
+
+ val tables = replaceName(tables, generateEntity)
+
val idSuffix = "_${generateEntity.primaryKeyName}"
val commonColumns = getCommonColumns(tables)
@@ -111,6 +118,15 @@ class JavaEntityGenerate : EntityGenerate {
}
}
+ try {
+ val templateManager = FileTemplateManager.getInstance(project)
+ templateManager.getInternalTemplate(BuddyTemplateFile.GENERATE_ENTITY_DOC).also {
+ type.addJavadoc(it.getText(templateManager.defaultProperties))
+ }
+ } catch (_: Throwable) {
+
+ }
+
if (commonColumns.isNotEmpty()) type.addSuperinterface(ClassName.get(packageName, BASE_ENTITY))
// Add table columns
type.addMethods(
@@ -289,12 +305,12 @@ class JavaEntityGenerate : EntityGenerate {
}
// Write to file
- return type2Builder.map { (_, type) ->
- projectDir.resolve(generateEntity.relativePath).also {
+ return type2Builder.mapNotNull { (_, type) ->
+ project.guessProjectDir()?.toNioPath()?.resolve(generateEntity.relativePath)?.let {
JavaFile.builder(packageName, type.build())
.indent(" ")
.build()
- .writeTo(it)
+ .writeToPath(it)
}
}
}
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/KotlinEntityGenerate.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/KotlinEntityGenerate.kt
index f623d65..dbb595e 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/KotlinEntityGenerate.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/generate/KotlinEntityGenerate.kt
@@ -19,10 +19,14 @@ package cn.enaium.jimmer.buddy.database.generate
import cn.enaium.jimmer.buddy.database.model.Column
import cn.enaium.jimmer.buddy.database.model.ForeignKey
import cn.enaium.jimmer.buddy.database.model.GenerateEntityModel
+import cn.enaium.jimmer.buddy.extensions.template.BuddyTemplateFile
import cn.enaium.jimmer.buddy.storage.JimmerBuddySetting
import cn.enaium.jimmer.buddy.utility.firstCharLowercase
import cn.enaium.jimmer.buddy.utility.snakeToCamelCase
import cn.enaium.jimmer.buddy.utility.toPlural
+import com.intellij.ide.fileTemplates.FileTemplateManager
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.project.guessProjectDir
import com.squareup.kotlinpoet.*
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import org.babyfish.jimmer.sql.*
@@ -37,10 +41,13 @@ class KotlinEntityGenerate : EntityGenerate {
val kotlinTypeMappings = JimmerBuddySetting.INSTANCE.state.typeMapping.mapValues { it.value.kotlinType }
override fun generate(
- projectDir: Path,
+ project: Project,
generateEntity: GenerateEntityModel,
tables: Set
): List {
+
+ val tables = replaceName(tables, generateEntity)
+
val idSuffix = "_${generateEntity.primaryKeyName}"
val commonColumns = getCommonColumns(tables)
@@ -110,6 +117,15 @@ class KotlinEntityGenerate : EntityGenerate {
}
}
+ try {
+ val templateManager = FileTemplateManager.getInstance(project)
+ templateManager.getInternalTemplate(BuddyTemplateFile.GENERATE_ENTITY_DOC).also {
+ type.addKdoc(it.getText(templateManager.defaultProperties))
+ }
+ } catch (_: Throwable) {
+
+ }
+
if (commonColumns.isNotEmpty()) type.addSuperinterface(ClassName(packageName, BASE_ENTITY))
// Add table columns
type.addProperties(
@@ -265,8 +281,8 @@ class KotlinEntityGenerate : EntityGenerate {
}
// Write to file
- return type2Builder.map { (tableName, typeBuilder) ->
- projectDir.resolve(generateEntity.relativePath).also {
+ return type2Builder.mapNotNull { (tableName, typeBuilder) ->
+ project.guessProjectDir()?.toNioPath()?.resolve(generateEntity.relativePath)?.let {
FileSpec.builder(packageName, tableName)
.indent(" ")
.addType(typeBuilder.build()).build()
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/model/GenerateEntityModel.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/model/GenerateEntityModel.kt
index dc740ec..d4d30c6 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/model/GenerateEntityModel.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/model/GenerateEntityModel.kt
@@ -24,16 +24,20 @@ import com.intellij.openapi.observable.properties.PropertyGraph
*/
class GenerateEntityModel : BaseState() {
private val graph: PropertyGraph = PropertyGraph()
- val relativePathProperty = graph.property("")
- val packageNameProperty = graph.property("")
+ val relativePathProperty = graph.property("")
+ val packageNameProperty = graph.property("")
val languageProperty = graph.property(Language.KOTLIN)
- val commentProperty = graph.property(false)
- val tableAnnotationProperty = graph.property(false)
- val columnAnnotationProperty = graph.property(false)
- val idViewAnnotationProperty = graph.property(false)
- val joinTableAnnotationProperty = graph.property(false)
- val primaryKeyNameProperty = graph.property("id")
+ val commentProperty = graph.property(false)
+ val tableAnnotationProperty = graph.property(false)
+ val columnAnnotationProperty = graph.property(false)
+ val idViewAnnotationProperty = graph.property(false)
+ val joinTableAnnotationProperty = graph.property(false)
+ val primaryKeyNameProperty = graph.property("id")
val associationProperty = graph.property(Association.REAL)
+ val tableNameRegexProperty = graph.property("")
+ val tableNameReplaceProperty = graph.property("")
+ val columnNameRegexProperty = graph.property("")
+ val columnNameReplaceProperty = graph.property("")
val relativePath: String by relativePathProperty
val packageName: String by packageNameProperty
@@ -45,6 +49,10 @@ class GenerateEntityModel : BaseState() {
val joinTableAnnotation: Boolean by joinTableAnnotationProperty
val primaryKeyName: String by primaryKeyNameProperty
val association: Association by associationProperty
+ val tableNameRegex: String by tableNameRegexProperty
+ val tableNameReplace: String by tableNameReplaceProperty
+ val columnNameRegex: String by columnNameRegexProperty
+ val columnNameReplace: String by columnNameReplaceProperty
enum class Language(val text: String) {
KOTLIN("Kotlin"),
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/model/UniqueKey.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/model/UniqueKey.kt
index 75d953b..3e6bd74 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/model/UniqueKey.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/database/model/UniqueKey.kt
@@ -22,7 +22,7 @@ package cn.enaium.jimmer.buddy.database.model
data class UniqueKey(
val name: String,
val tableName: String,
- val columns: List,
+ val columns: Set,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/AddDatabase.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/AddDatabase.kt
index 69fe1b8..bd30011 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/AddDatabase.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/AddDatabase.kt
@@ -18,6 +18,7 @@ package cn.enaium.jimmer.buddy.dialog
import cn.enaium.jimmer.buddy.storage.JimmerBuddySetting
import cn.enaium.jimmer.buddy.storage.JimmerBuddySetting.DatabaseItem
+import cn.enaium.jimmer.buddy.utility.jarFileChooserField
import com.intellij.openapi.components.BaseState
import com.intellij.openapi.observable.properties.PropertyGraph
import com.intellij.openapi.ui.DialogWrapper
@@ -58,6 +59,9 @@ class AddDatabase(val select: DatabaseItem? = null) : DialogWrapper(false) {
row("Table Name Pattern:") {
textField().align(Align.FILL).bindText(databaseModel.tableNamePatternProperty)
}
+ row("Driver File:") {
+ jarFileChooserField(databaseModel.driverFileProperty).align(Align.FILL)
+ }
}
}
@@ -73,19 +77,21 @@ class AddDatabase(val select: DatabaseItem? = null) : DialogWrapper(false) {
databaseModel.password,
databaseModel.catalog,
databaseModel.schemaPattern,
- databaseModel.tableNamePattern
+ databaseModel.tableNamePattern,
+ databaseModel.driverFile
)
super.doOKAction()
}
private inner class DatabaseModel : BaseState() {
private val graph: PropertyGraph = PropertyGraph()
- val uriProperty = graph.property(select?.uri ?: "")
+ val uriProperty = graph.property(select?.uri ?: "")
val usernameProperty = graph.property(select?.username ?: "")
val passwordProperty = graph.property(select?.password ?: "")
val catalogProperty = graph.property(select?.catalog ?: "")
val schemaPatternProperty = graph.property(select?.schemaPattern ?: "")
val tableNamePatternProperty = graph.property(select?.tableNamePattern ?: "")
+ val driverFileProperty = graph.property(select?.driverFile ?: "")
val uri: String by uriProperty
val username: String by usernameProperty
@@ -93,5 +99,6 @@ class AddDatabase(val select: DatabaseItem? = null) : DialogWrapper(false) {
val catalog: String by catalogProperty
val schemaPattern: String by schemaPatternProperty
val tableNamePattern: String by tableNamePatternProperty
+ val driverFile: String by driverFileProperty
}
}
\ No newline at end of file
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/GenerateEntityDialog.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/GenerateEntityDialog.kt
index d7438a8..ae3efd3 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/GenerateEntityDialog.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/GenerateEntityDialog.kt
@@ -24,6 +24,8 @@ import cn.enaium.jimmer.buddy.database.model.Table
import cn.enaium.jimmer.buddy.dialog.panel.TableTreeTable
import cn.enaium.jimmer.buddy.storage.JimmerBuddySetting
import cn.enaium.jimmer.buddy.utility.getTables
+import cn.enaium.jimmer.buddy.utility.packageChooserField
+import cn.enaium.jimmer.buddy.utility.relativeLocationField
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.guessProjectDir
import com.intellij.openapi.ui.DialogWrapper
@@ -45,6 +47,7 @@ import java.util.*
import java.util.logging.Logger
import javax.swing.JComponent
import kotlin.io.path.Path
+import kotlin.io.path.exists
import kotlin.io.path.isDirectory
import kotlin.io.path.name
import kotlin.io.path.walk
@@ -78,10 +81,10 @@ class GenerateEntityDialog(
return borderPanel {
addToTop(panel {
row("Relative Path:") {
- textField().align(Align.FILL).bindText(generateEntityModel.relativePathProperty)
+ relativeLocationField(project, generateEntityModel.relativePathProperty).align(Align.FILL)
}
row("Package Name:") {
- textField().align(Align.FILL).bindText(generateEntityModel.packageNameProperty)
+ packageChooserField(project, generateEntityModel.packageNameProperty).align(Align.FILL)
}
row("Language:") {
JimmerBuddy.Services.UI.segmentedButtonText(this, GenerateEntityModel.Language.entries) {
@@ -105,6 +108,14 @@ class GenerateEntityDialog(
it.text
}.bind(generateEntityModel.associationProperty)
}
+ row("Table Name Regex:") {
+ textField().align(Align.FILL).bindText(generateEntityModel.tableNameRegexProperty)
+ textField().align(Align.FILL).bindText(generateEntityModel.tableNameReplaceProperty)
+ }
+ row("Column Name Regex:") {
+ textField().align(Align.FILL).bindText(generateEntityModel.columnNameRegexProperty)
+ textField().align(Align.FILL).bindText(generateEntityModel.columnNameReplaceProperty)
+ }
}
})
addToCenter(tableTreeTable)
@@ -113,9 +124,9 @@ class GenerateEntityDialog(
private fun getTables(): Set {
val uri = databaseItem.uri
-
+ val isDDL = uri.startsWith("file:")
val jdbcDriver = JdbcDriver.entries.find { uri.startsWith("jdbc:${it.scheme}") } ?: let {
- if (uri.startsWith("file:")) {
+ if (isDDL) {
return@let JdbcDriver.H2
} else {
Messages.showErrorDialog(
@@ -146,23 +157,38 @@ class GenerateEntityDialog(
}
}
- listOfNotNull(
- Path(System.getProperty("user.home")).resolve(".gradle"),
- System.getenv("GRADLE_USER_HOME")?.takeIf { it.isNotBlank() }?.let { Path.of(it) },
- ).forEach { path ->
- path.resolve("caches/modules-2/files-2.1/${jdbcDriver.group}/${jdbcDriver.artifact}")
- .walk().findLast {
- it.isDirectory().not()
- && it.name.endsWith("-sources.jar").not()
- && it.name.endsWith("-javadoc.jar").not()
- && it.name.endsWith(".jar")
- }?.also {
- driverJarFile = it
- }
+ if (driverJarFile == null) {
+ listOfNotNull(
+ Path(System.getProperty("user.home")).resolve(".gradle"),
+ System.getenv("GRADLE_USER_HOME")?.takeIf { it.isNotBlank() }?.let { Path.of(it) },
+ ).forEach { path ->
+ path.resolve("caches/modules-2/files-2.1/${jdbcDriver.group}/${jdbcDriver.artifact}")
+ .walk().findLast {
+ it.isDirectory().not()
+ && it.name.endsWith("-sources.jar").not()
+ && it.name.endsWith("-javadoc.jar").not()
+ && it.name.endsWith(".jar")
+ }?.also {
+ driverJarFile = it
+ }
+ }
}
if (driverJarFile == null) {
- Messages.showErrorDialog("Failed to find driver jar, please check your maven or gradle cache", "Error")
+ driverJarFile = Path(databaseItem.driverFile).takeIf { it.exists() }
+ }
+
+ if (driverJarFile == null) {
+ if (isDDL) {
+ Messages.showErrorDialog(
+ "Failed to find H2 driver jar, please check your maven or gradle cache",
+ "Error"
+ )
+ } else if (databaseItem.driverFile.isNotBlank()) {
+ Messages.showErrorDialog("Driver file is not found", "Error");
+ } else {
+ Messages.showErrorDialog("Failed to find driver jar, please check your maven or gradle cache", "Error")
+ }
return emptySet()
}
@@ -184,11 +210,10 @@ class GenerateEntityDialog(
}
}
-
private fun getConnection(): Connection {
- return URI.create(databaseItem.uri).takeIf { it.scheme == "file" }?.let { ddl ->
+ return URI.create(databaseItem.uri.replace("\\", "/")).takeIf { it.scheme == "file" }?.let { ddl ->
DriverManager.getConnection(
- "jdbc:h2:mem:test;DATABASE_TO_LOWER=true;INIT=RUNSCRIPT FROM '${
+ "jdbc:h2:mem:jimmer-buddy-ddl;DATABASE_TO_LOWER=true;INIT=RUNSCRIPT FROM '${
ddl.toURL().toPath().absolutePath.replace(
"\\",
"/"
@@ -226,10 +251,9 @@ class GenerateEntityDialog(
}
}
- val projectDir = project.guessProjectDir() ?: return
JimmerBuddy.getWorkspace(project).asyncRefresh(
generate.generate(
- projectDir.toNioPath(),
+ project,
generateEntityModel,
result
)
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/NewDtoFileDialog.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/NewDtoFileDialog.kt
index 014477e..0d1539a 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/NewDtoFileDialog.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/dialog/NewDtoFileDialog.kt
@@ -18,7 +18,7 @@ package cn.enaium.jimmer.buddy.dialog
import cn.enaium.jimmer.buddy.JimmerBuddy
import cn.enaium.jimmer.buddy.dialog.panel.ImmutablePropsChoosePanel
-import cn.enaium.jimmer.buddy.extensions.template.JimmerProjectTemplateFile
+import cn.enaium.jimmer.buddy.extensions.template.BuddyTemplateFile
import cn.enaium.jimmer.buddy.utility.*
import com.intellij.diff.DiffContentFactory
import com.intellij.diff.DiffManager
@@ -75,7 +75,7 @@ class NewDtoFileDialog(
textField().align(Align.FILL).bindText(model.immutableNameProperty)
}
row("Package Name:") {
- textField().align(Align.FILL).bindText(model.packageNameProperty)
+ packageChooserField(project, model.packageNameProperty).align(Align.FILL)
}
row("DTO File Name:") {
textField().align(Align.FILL).bindText(model.dtoFileNameProperty)
@@ -118,7 +118,7 @@ class NewDtoFileDialog(
findProjectDir(sourceFile)?.also { projectDir ->
val dtoFile = projectDir.resolve("src/main/dto/${model.dtoFileName}.dto")
val fileTemplateManager = FileTemplateManager.getInstance(project)
- val dtoHeadTemplate = fileTemplateManager.getInternalTemplate(JimmerProjectTemplateFile.JIMMER_DTO_HEAD)
+ val dtoHeadTemplate = fileTemplateManager.getInternalTemplate(BuddyTemplateFile.JIMMER_DTO_HEAD)
val dtoHeadContent = dtoHeadTemplate.getText(
mapOf(
"IMMUTABLE_NAME" to model.immutableName,
@@ -126,7 +126,7 @@ class NewDtoFileDialog(
)
)
val dtoContentTemplate =
- fileTemplateManager.getInternalTemplate(JimmerProjectTemplateFile.JIMMER_DTO_CONTENT)
+ fileTemplateManager.getInternalTemplate(BuddyTemplateFile.JIMMER_DTO_CONTENT)
val dtoContent = dtoContentTemplate.getText(
mapOf(
"DTO_TYPES" to listOf(
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/template/JimmerProjectTemplateFile.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/template/BuddyTemplateFile.kt
similarity index 91%
rename from core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/template/JimmerProjectTemplateFile.kt
rename to core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/template/BuddyTemplateFile.kt
index a791fc6..13025c3 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/template/JimmerProjectTemplateFile.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/template/BuddyTemplateFile.kt
@@ -23,7 +23,7 @@ import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory
/**
* @author Enaium
*/
-class JimmerProjectTemplateFile : FileTemplateGroupDescriptorFactory {
+class BuddyTemplateFile : FileTemplateGroupDescriptorFactory {
companion object {
const val MAVEN_WRAPPER = "jimmer-maven-wrapper.properties"
@@ -34,6 +34,7 @@ class JimmerProjectTemplateFile : FileTemplateGroupDescriptorFactory {
const val GRADLE_TOML = "jimmer-gradle-toml.toml"
const val JIMMER_DTO_HEAD = "jimmer-dto-head.dto"
const val JIMMER_DTO_CONTENT = "jimmer-dto-content.dto"
+ const val GENERATE_ENTITY_DOC = "generate-entity-doc.txt"
}
override fun getFileTemplatesDescriptor(): FileTemplateGroupDescriptor {
@@ -46,6 +47,7 @@ class JimmerProjectTemplateFile : FileTemplateGroupDescriptorFactory {
group.addTemplate(GRADLE_TOML)
group.addTemplate(JIMMER_DTO_HEAD)
group.addTemplate(JIMMER_DTO_CONTENT)
+ group.addTemplate(GENERATE_ENTITY_DOC)
return group
}
}
\ No newline at end of file
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/wizard/JimmerProjectBuilderAdapter.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/wizard/JimmerProjectBuilderAdapter.kt
index 4e582d8..0cab51f 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/wizard/JimmerProjectBuilderAdapter.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/wizard/JimmerProjectBuilderAdapter.kt
@@ -16,7 +16,7 @@
package cn.enaium.jimmer.buddy.extensions.wizard
-import cn.enaium.jimmer.buddy.extensions.template.JimmerProjectTemplateFile
+import cn.enaium.jimmer.buddy.extensions.template.BuddyTemplateFile
import com.intellij.ide.fileTemplates.FileTemplateManager
import com.intellij.ide.util.projectWizard.WizardContext
import com.intellij.ide.wizard.GeneratorNewProjectWizardBuilderAdapter
@@ -245,7 +245,7 @@ class JimmerProjectBuilderAdapter(val jimmerWizard: JimmerProjectWizard = Jimmer
val fileTemplateManager = FileTemplateManager.getInstance(project)
when (projectModel.builder) {
JimmerProjectModel.Builder.GRADLE -> {
- val gradleWrapper = fileTemplateManager.getInternalTemplate(JimmerProjectTemplateFile.GRADLE_WRAPPER)
+ val gradleWrapper = fileTemplateManager.getInternalTemplate(BuddyTemplateFile.GRADLE_WRAPPER)
val gradleWrapperContent =
gradleWrapper.getText(mapOf("WRAPPER_VERSION" to projectModel.wrapperVersion))
val gradleWrapperPath = projectDir.resolve("gradle/wrapper/gradle-wrapper.properties")
@@ -253,7 +253,7 @@ class JimmerProjectBuilderAdapter(val jimmerWizard: JimmerProjectWizard = Jimmer
gradleWrapperPath.createParentDirectories()
}
gradleWrapperPath.writeText(gradleWrapperContent)
- val gradleToml = fileTemplateManager.getInternalTemplate(JimmerProjectTemplateFile.GRADLE_TOML)
+ val gradleToml = fileTemplateManager.getInternalTemplate(BuddyTemplateFile.GRADLE_TOML)
val gradleTomlContent = gradleToml.getText(
mapOf(
"versions" to versions,
@@ -263,7 +263,7 @@ class JimmerProjectBuilderAdapter(val jimmerWizard: JimmerProjectWizard = Jimmer
)
val gradleTomlPath = projectDir.resolve("gradle/libs.versions.toml")
gradleTomlPath.writeText(gradleTomlContent)
- val gradleBuild = fileTemplateManager.getInternalTemplate(JimmerProjectTemplateFile.GRADLE_BUILD)
+ val gradleBuild = fileTemplateManager.getInternalTemplate(BuddyTemplateFile.GRADLE_BUILD)
val gradleBuildContent = gradleBuild.getText(
mapOf(
"GROUP" to projectModel.group,
@@ -273,21 +273,21 @@ class JimmerProjectBuilderAdapter(val jimmerWizard: JimmerProjectWizard = Jimmer
)
val gradleBuildPath = projectDir.resolve("build.gradle.kts")
gradleBuildPath.writeText(gradleBuildContent)
- val gradleSettings = fileTemplateManager.getInternalTemplate(JimmerProjectTemplateFile.GRADLE_SETTINGS)
+ val gradleSettings = fileTemplateManager.getInternalTemplate(BuddyTemplateFile.GRADLE_SETTINGS)
val gradleSettingsContent = gradleSettings.getText(mapOf("ARTIFACT" to projectModel.artifact))
val gradleSettingsPath = projectDir.resolve("settings.gradle.kts")
gradleSettingsPath.writeText(gradleSettingsContent)
}
JimmerProjectModel.Builder.MAVEN -> {
- val mavenWrapper = fileTemplateManager.getInternalTemplate(JimmerProjectTemplateFile.MAVEN_WRAPPER)
+ val mavenWrapper = fileTemplateManager.getInternalTemplate(BuddyTemplateFile.MAVEN_WRAPPER)
val mavenWrapperContent = mavenWrapper.getText(mapOf("WRAPPER_VERSION" to projectModel.wrapperVersion))
val mavenWrapperPath = projectDir.resolve(".mvn/wrapper/maven-wrapper.properties")
if (mavenWrapperPath.exists().not()) {
mavenWrapperPath.createParentDirectories()
}
mavenWrapperPath.writeText(mavenWrapperContent)
- val mavenPom = fileTemplateManager.getInternalTemplate(JimmerProjectTemplateFile.MAVEN_POM)
+ val mavenPom = fileTemplateManager.getInternalTemplate(BuddyTemplateFile.MAVEN_POM)
val mavenPomContent = mavenPom.getText(
mapOf(
"GROUP" to projectModel.group,
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/wizard/JimmerProjectPanel.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/wizard/JimmerProjectPanel.kt
index 9fc8265..097a80a 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/wizard/JimmerProjectPanel.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/extensions/wizard/JimmerProjectPanel.kt
@@ -17,6 +17,7 @@
package cn.enaium.jimmer.buddy.extensions.wizard
import cn.enaium.jimmer.buddy.JimmerBuddy
+import cn.enaium.jimmer.buddy.utility.projectLocationField
import com.intellij.ide.IdeBundle
import com.intellij.ide.util.projectWizard.WizardContext
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
@@ -142,18 +143,4 @@ class JimmerProjectPanel(propertyGraph: PropertyGraph, private val wizardContext
wizardContext.defaultModuleName = entityNameProperty.get()
wizardContext.getUserData(JimmerBuddy.PROJECT_MODEL_PROP_KEY)?.set(projectModel)
}
-
- private fun Row.projectLocationField(
- locationProperty: GraphProperty,
- wizardContext: WizardContext,
- ): Cell {
- val fileChooserDescriptor =
- FileChooserDescriptorFactory.createSingleLocalFileDescriptor()
- .withFileFilter { it.isDirectory }
- .withPathToTextConvertor(::getPresentablePath)
- .withTextToPathConvertor(::getCanonicalPath)
- val title = IdeBundle.message("title.select.project.file.directory", wizardContext.presentationName)
- val property = locationProperty.transform(::getPresentablePath, ::getCanonicalPath)
- return textFieldWithBrowseButton(title, wizardContext.project, fileChooserDescriptor).bindText(property)
- }
}
\ No newline at end of file
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/storage/JimmerBuddySetting.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/storage/JimmerBuddySetting.kt
index f69a31e..a5dc3d8 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/storage/JimmerBuddySetting.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/storage/JimmerBuddySetting.kt
@@ -110,7 +110,8 @@ class JimmerBuddySetting : PersistentStateComponent
var password: String = "",
var catalog: String = "",
var schemaPattern: String = "",
- var tableNamePattern: String = ""
+ var tableNamePattern: String = "",
+ var driverFile: String = "",
)
data class JavaToKotlin(
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/utility/jdbc.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/utility/jdbc.kt
index 4932d94..44d1582 100644
--- a/core/src/main/kotlin/cn/enaium/jimmer/buddy/utility/jdbc.kt
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/utility/jdbc.kt
@@ -110,7 +110,7 @@ internal fun DatabaseMetaData.getUniqueKeys(tableName: String): Set {
}
}
return uniqueKey2Columns.map { (name, columns) ->
- UniqueKey(name, tableName, columns.map { getColumns(tableName).first { column -> column.name == it } })
+ UniqueKey(name, tableName, columns.map { getColumns(tableName).first { column -> column.name == it } }.toSet())
}.toSet()
}
diff --git a/core/src/main/kotlin/cn/enaium/jimmer/buddy/utility/ui.kt b/core/src/main/kotlin/cn/enaium/jimmer/buddy/utility/ui.kt
new file mode 100644
index 0000000..eae3f55
--- /dev/null
+++ b/core/src/main/kotlin/cn/enaium/jimmer/buddy/utility/ui.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2025 Enaium
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cn.enaium.jimmer.buddy.utility
+
+import com.intellij.icons.AllIcons
+import com.intellij.ide.IdeBundle
+import com.intellij.ide.util.PackageChooserDialog
+import com.intellij.ide.util.projectWizard.WizardContext
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
+import com.intellij.openapi.observable.properties.GraphProperty
+import com.intellij.openapi.observable.util.bind
+import com.intellij.openapi.observable.util.transform
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.project.guessProjectDir
+import com.intellij.openapi.ui.BrowseFolderDescriptor.Companion.withPathToTextConvertor
+import com.intellij.openapi.ui.BrowseFolderDescriptor.Companion.withTextToPathConvertor
+import com.intellij.openapi.ui.TextFieldWithBrowseButton
+import com.intellij.openapi.ui.addExtension
+import com.intellij.openapi.ui.getCanonicalPath
+import com.intellij.openapi.ui.getPresentablePath
+import com.intellij.ui.components.fields.ExpandableTextField
+import com.intellij.ui.components.fields.ExtendableTextField
+import com.intellij.ui.dsl.builder.Cell
+import com.intellij.ui.dsl.builder.Row
+import com.intellij.ui.dsl.builder.bindText
+import kotlin.io.path.Path
+import kotlin.io.path.absolutePathString
+import kotlin.io.path.pathString
+import kotlin.io.path.relativeTo
+
+/**
+ * @author Enaium
+ */
+fun Row.projectLocationField(
+ locationProperty: GraphProperty,
+ wizardContext: WizardContext,
+): Cell {
+ val fileChooserDescriptor =
+ FileChooserDescriptorFactory.createSingleLocalFileDescriptor()
+ .withFileFilter { it.isDirectory }
+ .withPathToTextConvertor(::getPresentablePath)
+ .withTextToPathConvertor(::getCanonicalPath)
+ val title = IdeBundle.message("title.select.project.file.directory", wizardContext.presentationName)
+ val property = locationProperty.transform(::getPresentablePath, ::getCanonicalPath)
+ return textFieldWithBrowseButton(title, wizardContext.project, fileChooserDescriptor).bindText(property)
+}
+
+fun Row.packageChooserField(
+ project: Project,
+ property: GraphProperty,
+): Cell {
+ return cell(ExtendableTextField().apply {
+ bind(property)
+ addExtension(AllIcons.Nodes.Package) {
+ val packageChooserDialog = PackageChooserDialog("Package Chooser", project)
+ if (packageChooserDialog.showAndGet()) {
+ packageChooserDialog.selectedPackage?.qualifiedName?.also {
+ property.set(it)
+ }
+ }
+ }
+ })
+}
+
+fun Row.relativeLocationField(
+ project: Project,
+ property: GraphProperty,
+): Cell {
+ val fileChooserDescriptor =
+ FileChooserDescriptorFactory.createSingleFolderDescriptor()
+ .withFileFilter { it.isDirectory }
+ .withPathToTextConvertor {
+ getPresentablePath(
+ Path(it).relativeTo(
+ project.guessProjectDir()?.toNioPath() ?: return@withPathToTextConvertor getPresentablePath(it)
+ ).pathString
+ )
+ }
+ .withTextToPathConvertor {
+ getCanonicalPath(
+ project.guessProjectDir()?.toNioPath()?.resolve(it)?.absolutePathString()
+ ?: return@withTextToPathConvertor getCanonicalPath(it)
+ )
+ }
+ return textFieldWithBrowseButton("Select Source", project, fileChooserDescriptor).bindText(property)
+}
+
+fun Row.jarFileChooserField(
+ locationProperty: GraphProperty,
+): Cell {
+ val fileChooserDescriptor =
+ FileChooserDescriptorFactory.createSingleFileDescriptor("jar")
+ .withFileFilter { it.isDirectory }
+ .withPathToTextConvertor(::getPresentablePath)
+ .withTextToPathConvertor(::getCanonicalPath)
+ val property = locationProperty.transform(::getPresentablePath, ::getCanonicalPath)
+ return textFieldWithBrowseButton("Jar Chooser", null, fileChooserDescriptor).bindText(property)
+}
\ No newline at end of file
diff --git a/core/src/main/resources/fileTemplates/j2ee/generate-entity-doc.txt.ft b/core/src/main/resources/fileTemplates/j2ee/generate-entity-doc.txt.ft
new file mode 100644
index 0000000..e69de29
diff --git a/gradle.properties b/gradle.properties
index e117fda..4132efa 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
kotlin.code.style=official
-version=1.7.0
+version=1.7.1
kotlin.daemon.jvmargs=-Xmx3G
org.gradle.jvmargs=-Xmx3G
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 897e26f..ae3dd50 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -9,6 +9,7 @@ javapoet = "1.13.0"
antlr4IntellijAdaptor = "0.1"
antlr = "4.13.2"
changelog = "2.2.1"
+h2 = "2.3.232"
[libraries]
jimmer-core = { module = "org.babyfish.jimmer:jimmer-core", version.ref = "jimmer" }
@@ -22,6 +23,7 @@ kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" }
javapoet = { module = "com.squareup:javapoet", version.ref = "javapoet" }
antlr4-intellij-adaptor = { module = "org.antlr:antlr4-intellij-adaptor", version.ref = "antlr4IntellijAdaptor" }
antlr = { module = "org.antlr:antlr4", version.ref = "antlr" }
+h2 = { module = "com.h2database:h2", version.ref = "h2" }
[plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 0f0704a..caea35c 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Thu Feb 13 20:15:24 CST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/since/shared/resources/META-INF/plugin.xml b/since/shared/resources/META-INF/plugin.xml
index 9a8d32c..3f26e4f 100644
--- a/since/shared/resources/META-INF/plugin.xml
+++ b/since/shared/resources/META-INF/plugin.xml
@@ -21,7 +21,7 @@
anchor="bottom" icon="/icons/log.svg"/>
-
+