Skip to content

Commit 2e2fa97

Browse files
committed
Merge codegen-kotlin Phase R — snapshot fixtures (J/K/Q) + README typed-enum fix
3 new snapshot regression fixtures: - entity-with-bidirectional-fk: Author cardinality=many → Post inferred FK on PostTable + AuthorRelations.kt with postsQuery extension fn - entity-with-view: source.rdb @kind=view → READ-ONLY VIEW Table, no autoIncrement, no FK refs - entity-with-stored-proc: source.rdb @kind=storedProc + @param on orderId → typed call(orderId: Long) function with SELECT * FROM ${PROC_NAME}(?) binding + result-row mapping KotlinCodegenSnapshotTest gained "relations" + "storedproc" generator-name arms in its when-switch. README typed-enum row corrected — Phase G shipped typed Kotlin enum class (separate <Entity><Field>.kt with @serializable, mapped via enumerationByName(name, 64, <Entity><Field>::class)). Test count bumped to 75. 75 module tests green (72 baseline + 3 new parameterized snapshot cases).
2 parents fb9d44e + 5fc0139 commit 2e2fa97

17 files changed

Lines changed: 190 additions & 6 deletions

File tree

server/java/codegen-kotlin/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Kotlin codegen target for Spring-Boot-Kotlin consumers on Exposed + Flyway. Emit
2626
| `field.timestamp` | `java.time.Instant` | `timestampWithTimeZone(name)` |
2727
| `field.currency` | `Long` (minor units — wire format invariant) | `long(name)` |
2828
| `field.uuid` | `java.util.UUID` | `uuid(name)` |
29-
| `field.enum` | `String` (TBD: typed enum class) | `varchar(name, 64)` |
29+
| `field.enum` | typed Kotlin `enum class` (separate `<Entity><Field>.kt` file with `@Serializable`) | `enumerationByName(name, 64, <Entity><Field>::class)` |
3030
| `field.object` (`@storage="flattened"`) | reference to the generated VO data class | per-sub-field columns: `<parent>_<sub>` |
3131
| `field.object` (`@storage="jsonb"` or default) | reference to the generated VO data class | single `jsonb(name, { Json.encodeToString(it) }, { Json.decodeFromString(it) })` |
3232

@@ -165,4 +165,4 @@ The shared cross-language codegen conformance corpus is **FR-007** — see [`doc
165165

166166
## Test count
167167

168-
45 tests in this module (`mvn -pl codegen-kotlin test`). Snapshot tests gate within-Java output stability; `kotlin-compile-testing` gates generated-code validity; an E2E test exercises the full loop including the Java `Renderer`.
168+
75 tests in this module (`mvn -pl codegen-kotlin test`). Snapshot tests gate within-Java output stability; `kotlin-compile-testing` gates generated-code validity; an E2E test exercises the full loop including the Java `Renderer`.

server/java/codegen-kotlin/src/test/kotlin/com/metaobjects/generator/kotlin/KotlinCodegenSnapshotTest.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ class KotlinCodegenSnapshotTest {
4848
val loader = loadString(name, metaText)
4949
for (g in config.generators) {
5050
val gen = when (g) {
51-
"entity" -> KotlinEntityGenerator()
52-
"table" -> KotlinExposedTableGenerator()
53-
"payload" -> KotlinPayloadGenerator()
54-
"validator" -> KotlinValidatorGenerator()
51+
"entity" -> KotlinEntityGenerator()
52+
"table" -> KotlinExposedTableGenerator()
53+
"payload" -> KotlinPayloadGenerator()
54+
"validator" -> KotlinValidatorGenerator()
55+
"relations" -> KotlinRelationsGenerator()
56+
"storedproc" -> KotlinStoredProcGenerator()
5557
else -> fail("unknown generator name in config: $g")
5658
}
5759
val args = mutableMapOf("outputDir" to outDir.toString())
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "generators": ["entity", "table", "relations"] }
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme::blog",
4+
"children": [
5+
{ "object.entity": { "name": "Author", "children": [
6+
{ "field.long": { "name": "id" } },
7+
{ "field.string": { "name": "name", "@maxLength": 100 } },
8+
{ "relationship.composition": { "name": "posts",
9+
"@cardinality": "many",
10+
"@objectRef": "Post",
11+
"@onDelete": "cascade" } },
12+
{ "source.rdb": { "@table": "authors" } },
13+
{ "identity.primary": { "@fields": "id", "@generation": "increment" } }
14+
] } },
15+
{ "object.entity": { "name": "Post", "children": [
16+
{ "field.long": { "name": "id" } },
17+
{ "field.string": { "name": "title", "@maxLength": 200 } },
18+
{ "source.rdb": { "@table": "posts" } },
19+
{ "identity.primary": { "@fields": "id", "@generation": "increment" } }
20+
] } }
21+
]
22+
}
23+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "generators": ["entity", "storedproc"] }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme::ops",
4+
"children": [
5+
{ "object.entity": { "name": "OrderReport", "children": [
6+
{ "field.long": { "name": "orderId", "@param": true } },
7+
{ "field.string": { "name": "status", "@maxLength": 50 } },
8+
{ "field.long": { "name": "totalCents" } },
9+
{ "source.rdb": { "@kind": "storedProc", "@table": "get_order_report" } }
10+
] } }
11+
]
12+
}
13+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "generators": ["entity", "table"] }
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme::report",
4+
"children": [
5+
{ "object.entity": { "name": "SalesReport", "children": [
6+
{ "field.long": { "name": "id" } },
7+
{ "field.string": { "name": "regionName", "@maxLength": 100 } },
8+
{ "field.long": { "name": "totalCents" } },
9+
{ "source.rdb": { "@table": "v_sales_report", "@kind": "view" } },
10+
{ "identity.primary": { "@fields": "id" } }
11+
] } }
12+
]
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package acme.blog
2+
3+
import kotlin.Long
4+
import kotlin.String
5+
import kotlinx.serialization.Serializable
6+
7+
/**
8+
* GENERATED — do not hand-edit. Regenerated from metadata.
9+
*/
10+
@Serializable
11+
public data class Author(
12+
public val id: Long? = null,
13+
public val name: String? = null,
14+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package acme.blog
2+
3+
import org.jetbrains.exposed.sql.Query
4+
import org.jetbrains.exposed.sql.selectAll
5+
6+
/** GENERATED — extension fns for `Author` to-many relationships. Do not hand-edit. */
7+
/** Query `Author.posts` (cardinality=many) on the Post side. */
8+
fun AuthorTable.postsQuery(authorId: Long): Query =
9+
PostTable.selectAll().where { PostTable.authorId eq authorId }

0 commit comments

Comments
 (0)