Skip to content

Commit 6bd1cfb

Browse files
authored
FIX: DB Schema generator (#388)
* Update CodeGenApi.kt * Update Schema.kt * Update Schema.kt * fix: postgres data type for double to float8 * fix: Support a tags field on the entity column * fix: Entities - auto-load of required w/ override * fix: tests to ensure double type
1 parent f96b637 commit 6bd1cfb

8 files changed

Lines changed: 90 additions & 7 deletions

File tree

src/data/data/src/main/kotlin/kiit/data/sql/vendors/Postgres.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ object PostgresTypes : DbTypes() {
6666
override val localDateTimeType = DataTypeMap(DataType.DTLocalDateTime, "TIMESTAMP", Types.JLocalDateTimeClass)
6767
override val zonedDateTimeType = DataTypeMap(DataType.DTZonedDateTime, "TIMESTAMPTZ", Types.JZonedDateTimeClass)
6868
override val dateTimeType = DataTypeMap(DataType.DTDateTime, "TIMESTAMPTZ", Types.JDateTimeClass)
69+
override val doubleType = DataTypeMap(DataType.DTDouble, "FLOAT8", Types.JDoubleClass)
70+
6971

7072

7173
override val lookup:Map<DataType, DataTypeMap> = mapOf(

src/data/entities/src/main/kotlin/kiit/entities/EntityRepo.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ open class EntityRepo<TId, T>(
3434
: SqlRepo<TId, T>(db, meta, mapper, syntax, hooks, mode) where TId : Comparable<TId>, T : Any {
3535

3636
private val lookup:Map<String, String> = if(mapper is EntityMapper<*, *>) {
37-
mapper.model.fields.map { it.name to it.storedName }.toMap()
37+
mapper.model.fields.associate { it.name to it.storedName }
3838
}
3939
else {
4040
mapOf()

src/data/entities/src/main/kotlin/kiit/entities/Id.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ annotation class Id(
3131
annotation class Column(
3232
val name: String = "",
3333
val desc: String = "",
34-
val required: Boolean = true,
34+
val required: Boolean = false,
3535
val unique: Boolean = false,
3636
val updatable: Boolean = true,
3737
val indexed: Boolean = false,
3838
val length: Int = 0,
3939
val defaultVal: String = "",
4040
val encrypt: Boolean = false,
41-
val example: String = ""
41+
val example: String = "",
42+
val tags: Array<String> = [],
4243
)

src/data/entities/src/main/kotlin/kiit/entities/Schema.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,20 @@ object Schema {
5151

5252
@JvmStatic
5353
fun column(prop: KProperty<*>, anno: Column, namer: Namer?, checkForId:Boolean, idFieldName:String?):ModelField {
54-
val name = if (anno.name.isNullOrEmpty()) prop.name else anno.name
54+
val name = anno.name.ifEmpty { prop.name }
5555
val cat = idFieldName?.let {
5656
if(it == name)
5757
FieldCategory.Id
5858
else
5959
FieldCategory.Data
6060
} ?: FieldCategory.Data
6161

62-
val required = anno.required
62+
// Get whether its required based on nullable property.
63+
val required = when {
64+
!prop.returnType.isMarkedNullable -> true
65+
anno.required -> true
66+
else -> false
67+
}
6368
val length = anno.length
6469
val encrypt = anno.encrypt
6570
val fieldKType = prop.returnType
@@ -76,7 +81,8 @@ object Schema {
7681
maxLength = length,
7782
encrypt = encrypt,
7883
cat = cat,
79-
namer = namer
84+
namer = namer,
85+
tags = anno.tags.toList()
8086
)
8187
return field
8288
}

src/lib/kotlin/slatekit-tests/src/test/kotlin/test/data/repo/Repo_Postgres_Tests.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package test.data.repo
22

33
import kiit.common.data.Vendor
4+
import kiit.data.sql.vendors.PostgresTypes
45
import kiit.entities.Entities
56
import kiit.entities.EntityLongId
67
import kiit.entities.EntityRepo
8+
import kiit.entities.mapper.EntityMapper
79
import kotlinx.coroutines.runBlocking
810
import org.junit.Assert
911
import org.junit.Test
@@ -38,5 +40,8 @@ open class Repo_Postgres_Tests : Repo_Common_Tests() {
3840
val repo = entities.repo(EntityLongId(), Long::class, User5::class, Vendor.Postgres)
3941
Assert.assertEquals("user", repo.meta.table.name)
4042
Assert.assertEquals("unit_tests", repo.meta.table.schema)
43+
val mapper = repo.mapper as EntityMapper<Long, User5>
44+
val field = mapper.model.fields.first { it.name == "salary" }
45+
Assert.assertEquals(PostgresTypes.doubleType.metaType, field.dataTpe)
4146
}
4247
}

src/lib/kotlin/slatekit-tests/src/test/kotlin/test/entities/Entity_Service_Registry_Tests.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import org.junit.Test
1717
import kiit.common.data.*
1818
import kiit.entities.*
1919
import test.setup.User5
20+
import test.setup.UserTypes
2021

2122
class Entity_Service_Registry_Tests {
2223

@@ -29,6 +30,24 @@ class Entity_Service_Registry_Tests {
2930
}
3031

3132

33+
@Test
34+
fun can_load_model_field_required_from_type() {
35+
val model = Schema.load(UserTypes::class, UserTypes::id.name)
36+
37+
// Case 1: Type is required
38+
val email = model.fields.first { it.name == "email" }
39+
Assert.assertEquals(true, email.isRequired)
40+
41+
// Case 2: Type is nullable ( Optional )
42+
val website = model.fields.first { it.name == "website" }
43+
Assert.assertEquals(false, website.isRequired)
44+
45+
// Case 3: Type is nullable ( Optional ), but annotation marked as required
46+
val link = model.fields.first { it.name == "link" }
47+
Assert.assertEquals(true, link.isRequired)
48+
}
49+
50+
3251
@Test
3352
fun can_register(){
3453
val info = entities.getInfo<User5>()

src/lib/kotlin/slatekit-tests/src/test/kotlin/test/setup/UserNormal.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,56 @@ data class User5(
171171
}
172172

173173

174+
@Table("user", schema = "unit_tests")
175+
data class UserTypes(
176+
@Id()
177+
override val id: Long = 0,
178+
179+
@Column(length = 50)
180+
val userId: String = Random.uuid(),
181+
182+
@Column(length = 100)
183+
val email: String = "",
184+
185+
@Column(length = 100)
186+
val website: String? = null,
187+
188+
@Column(length = 100, required = true)
189+
val link: String? = null,
190+
191+
@Column()
192+
val isActive: Boolean = false,
193+
194+
@Column()
195+
val level: Int = 35,
196+
197+
@Column()
198+
val salary: Double = 20.5,
199+
200+
@Column(name = "createdat", required = true)
201+
val createdAt: DateTime = DateTime.now(),
202+
203+
@Column(name = "createdby", required = true)
204+
val createdBy: Long = 0,
205+
206+
@Column(name = "updatedat")
207+
val updatedAt: DateTime? = null,
208+
209+
@Column(name = "updatedby")
210+
val updatedBy: Long? = null
211+
) : EntityWithId<Long>, EntityUpdatable<Long, UserTypes> {
212+
213+
override fun isPersisted(): Boolean = id > 0
214+
215+
/**
216+
* sets the id on the entity and returns the entity with updated id.
217+
* @param id
218+
* @return
219+
*/
220+
override fun withId(id: Long): UserTypes {
221+
return this.copy(id = id)
222+
}
223+
}
174224

175225
data class UserNullable(
176226
@Id()

src/services/apis/src/main/kotlin/kiit/apis/tools/code/CodeGenApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import kiit.results.Notice
1616
* slatekit.codegen.toJava -templatesFolder="user://git/slatekit/scripts/templates/codegen/java" -outputFolder="user://dev/temp/codegen/java" -packageName="myapp" -classFile="" -methodFile="" -modelFile=""
1717
* slatekit.codegen.toKotlin -templatesFolder="usr://dev/tmp/slatekit/slatekit/scripts/templates/codegen/kotlin" -outputFolder="usr://dev/tmp/codegen/kotlin" -packageName="myapp"
1818
*/
19-
@Api(area = "slatekit", name = "codegen", desc = "client code generator", verb = Verbs.AUTO, sources = [Sources.CLI])
19+
@Api(area = "kiit", name = "codegen", desc = "client code generator", verb = Verbs.AUTO, sources = [Sources.CLI])
2020
class CodeGenApi : HostAware {
2121

2222
private var host: ApiServer? = null

0 commit comments

Comments
 (0)