Skip to content

Commit

Permalink
Merge pull request #75 from SchwarzIT/feature/reduce_size
Browse files Browse the repository at this point in the history
Feature/reduce size
  • Loading branch information
sbra0902 authored Aug 23, 2023
2 parents ba39e80 + 07091d8 commit c8b0341
Show file tree
Hide file tree
Showing 18 changed files with 254 additions and 194 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,68 @@ object PersistenceConfig {

interface Connector : TypeConversionErrorCallback {
val typeConversions: Map<KClass<*>, TypeConversion>
fun getDocument(id: String, dbName: String, onlyInclude: List<String>? = null): Map<String, Any>?
fun getDocuments(ids: List<String>, dbName: String, onlyInclude: List<String>? = null): List<Map<String, Any>?>
fun queryDoc(dbName: String, queryParams: Map<String, Any>, limit: Int? = null, onlyInclude: List<String>? = null): List<Map<String, Any>>
fun getDocument(
id: String,
dbName: String,
onlyInclude: List<String>? = null
): Map<String, Any>?

fun getDocuments(
ids: List<String>,
dbName: String,
onlyInclude: List<String>? = null
): List<Map<String, Any>?>

fun queryDoc(
dbName: String,
queryParams: Map<String, Any>,
limit: Int? = null,
onlyInclude: List<String>? = null
): List<Map<String, Any>>

@Throws(PersistenceException::class)
fun deleteDocument(id: String, dbName: String)

@Throws(PersistenceException::class)
fun upsertDocument(document: MutableMap<String, Any>, id: String?, dbName: String): Map<String, Any>
fun upsertDocument(
document: MutableMap<String, Any>,
id: String?,
dbName: String
): Map<String, Any>
}

interface SuspendingConnector : TypeConversionErrorCallback {

val typeConversions: Map<KClass<*>, TypeConversion>

suspend fun getDocument(id: String, dbName: String, onlyInclude: List<String>? = null): Map<String, Any>?

suspend fun getDocuments(ids: List<String>, dbName: String, onlyInclude: List<String>? = null): List<Map<String, Any>>

suspend fun queryDoc(dbName: String, queryParams: Map<String, Any>, limit: Int? = null, onlyInclude: List<String>? = null): List<Map<String, Any>>
suspend fun getDocument(
id: String,
dbName: String,
onlyInclude: List<String>? = null
): Map<String, Any>?

suspend fun getDocuments(
ids: List<String>,
dbName: String,
onlyInclude: List<String>? = null
): List<Map<String, Any>>

suspend fun queryDoc(
dbName: String,
queryParams: Map<String, Any>,
limit: Int? = null,
onlyInclude: List<String>? = null
): List<Map<String, Any>>

@Throws(PersistenceException::class)
suspend fun deleteDocument(id: String, dbName: String)

@Throws(PersistenceException::class)
suspend fun upsertDocument(document: MutableMap<String, Any>, id: String?, dbName: String): Map<String, Any>
suspend fun upsertDocument(
document: MutableMap<String, Any>,
id: String?,
dbName: String
): Map<String, Any>
}

val connector: Connector
Expand All @@ -52,6 +88,21 @@ object PersistenceConfig {
return mSuspendingConnector!!
}

fun getTypeConversion(type: KClass<*>): TypeConversion? {
if (mConnector != null) {
return connector.typeConversions[type]
} else if (mSuspendingConnector != null) {
return suspendingConnector.typeConversions[type]
}
throw RuntimeException("no database connector configured.. call PersistenceConfig.configure")
}

fun onTypeConversionError(errorWrapper: TypeConversionErrorWrapper) {
(mConnector ?: mSuspendingConnector)?.let {
it.invokeOnError(errorWrapper)
}
}

fun configure(connector: Connector) {
mConnector = connector
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.schwarz.crystalapi.util

import com.schwarz.crystalapi.PersistenceConfig
import java.lang.Exception
import kotlin.reflect.KClass

object CrystalWrap {

inline fun <T> get(
changes: MutableMap<String, Any?>,
doc: MutableMap<String, Any>,
fieldName: String,
clazz: KClass<*>,
noinline mapper: ((MutableMap<String, Any?>?) -> T?)? = null
): T? {
return (changes[fieldName] ?: doc[fieldName])?.let { value ->
mapper?.let {
mapper.invoke(value as? MutableMap<String, Any?>)
} ?: read(value, fieldName, clazz)
} ?: null
}

inline fun <T> getList(
changes: MutableMap<String, Any?>,
doc: MutableMap<String, Any>,
fieldName: String,
clazz: KClass<*>,
noinline mapper: ((List<MutableMap<String, Any?>>?) -> List<T>)? = null
): List<T>? {
return (changes[fieldName] ?: doc[fieldName])?.let { value ->
mapper?.let {
mapper.invoke(value as? List<MutableMap<String, Any?>>)
} ?: read(value, fieldName, clazz)
} ?: null
}

fun <T> set(
changes: MutableMap<String, Any?>,
fieldName: String,
value: T,
clazz: KClass<*>,
mapper: ((T) -> MutableMap<String, Any>)? = null
) {
val valueToSet = mapper?.let { it.invoke(value) } ?: write<T>(value, fieldName, clazz)
changes[fieldName] = valueToSet
}

inline fun <T> setList(
changes: MutableMap<String, Any?>,
fieldName: String,
value: List<T>?,
clazz: KClass<*>,
noinline mapper: ((List<T>) -> List<MutableMap<String, Any>>)? = null
) {
val valueToSet =
mapper?.let { if (value != null) it.invoke(value) else emptyList() } ?: write<T>(
value,
fieldName,
clazz
)
changes[fieldName] = valueToSet
}

fun <T> ensureTypes(map: Map<String, KClass<*>>, doc: Map<String, Any?>): Map<String, Any> {
val result = mutableMapOf<String, Any>()
for (entry in map) {
write<T>(doc[entry.key], entry.key, entry.value)?.let {
result[entry.key] = it
}
}
return result
}

fun <T, V> addDefaults(list: List<Array<Any>>, doc: MutableMap<String, V>) {
for (entry in list) {
val key = entry[0] as String
val clazz = entry[1] as KClass<*>
val value = entry[2] as Any
if (doc[key] == null) {
write<T>(value, key, clazz)?.let {
doc[key] = it as V
}
}
}
}

fun <T> read(
value: Any?,
fieldName: String,
clazz: KClass<*>
): T? {
return try {
val conversion =
PersistenceConfig.getTypeConversion(clazz) ?: return value as T?
return conversion.read(value) as T?
} catch (ex: Exception) {
PersistenceConfig.onTypeConversionError(
com.schwarz.crystalapi.TypeConversionErrorWrapper(
ex,
fieldName, value, clazz
)
)
null
}
}

fun <T> write(
value: Any?,
fieldName: String,
clazz: KClass<*>
): T? {
return try {
val conversion =
PersistenceConfig.getTypeConversion(clazz) ?: return value as T?
return conversion.write(value) as T?
} catch (ex: Exception) {
PersistenceConfig.onTypeConversionError(
com.schwarz.crystalapi.TypeConversionErrorWrapper(
ex,
fieldName, value, clazz
)
)
null
}
}
}
4 changes: 2 additions & 2 deletions crystal-map-processor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ apply plugin: 'kotlin-kapt'

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.squareup:kotlinpoet:1.6.0'
implementation 'com.squareup:kotlinpoet-metadata:1.6.0'
implementation 'com.squareup:kotlinpoet:1.13.2'
implementation 'com.squareup:kotlinpoet-metadata:1.13.2'
implementation project(path: ':crystal-map-api', configuration: 'default')
implementation 'org.apache.commons:commons-lang3:3.4'
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class CodeGenerator(private val filer: Filer) {
}

val codePath = processingEnvironment.options[CoachBaseBinderProcessor.KAPT_KOTLIN_GENERATED_OPTION_NAME]
val fileWithHeader = entityToGenerate.toBuilder().addComment(HEADER).build()
val fileWithHeader = entityToGenerate.toBuilder().addFileComment(HEADER).build()

// used for kapt returns null for legacy annotationprocessor declarations
if (codePath != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.schwarz.crystalprocessor.generation.model

import com.schwarz.crystalprocessor.model.entity.BaseEntityHolder
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeSpec
Expand All @@ -10,11 +11,11 @@ object BuilderClassGeneration {
fun generateBaseBuilder(holder: BaseEntityHolder): TypeSpec.Builder {
val builderBuilder = TypeSpec.classBuilder("Builder").primaryConstructor(FunSpec.constructorBuilder().addParameter("parent", holder.entityTypeName).build())
builderBuilder.addProperty(PropertySpec.builder("obj", holder.entityTypeName).initializer("parent").build())
builderBuilder.addFunction(FunSpec.builder("exit").addStatement("return obj").build())
builderBuilder.addFunction(FunSpec.builder("exit").addStatement("return obj").returns(holder.entityTypeName).build())
return builderBuilder
}

fun generateBuilderFun(): FunSpec {
return FunSpec.builder("builder").addStatement("return Builder(this)").build()
fun generateBuilderFun(holder: BaseEntityHolder): FunSpec {
return FunSpec.builder("builder").addStatement("return Builder(this)").returns(ClassName(holder.sourcePackage, "${holder.entitySimpleName}.Builder")).build()
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.schwarz.crystalprocessor.generation.model

import com.schwarz.crystalapi.util.CrystalWrap
import com.schwarz.crystalprocessor.model.entity.BaseEntityHolder
import com.schwarz.crystalprocessor.util.ConversionUtil
import com.schwarz.crystalprocessor.util.TypeUtil
Expand All @@ -13,30 +14,29 @@ object CblDefaultGeneration {

val type =
if (useNullableMap) TypeUtil.mutableMapStringAnyNullable() else TypeUtil.mutableMapStringAny()
val valueType =
if (useNullableMap) TypeUtil.anyNullable() else TypeUtil.any()

val typeConversionReturnType =
if (useNullableMap) TypeUtil.anyNullable() else TypeUtil.any()

val builder =
FunSpec.builder("addDefaults").addModifiers(KModifier.PRIVATE).addParameter("map", type)

builder.addStatement("%T.addDefaults<%T, %T>(listOf(", CrystalWrap::class, typeConversionReturnType, valueType)
for (fieldHolder in holder.fields.values) {

if (fieldHolder.isDefault) {
builder.beginControlFlow("if(map[%N] == null)", fieldHolder.constantName)
builder.addStatement(
"map.put(%N, " + fieldHolder.ensureType(
typeConversionReturnType,
ConversionUtil.convertStringToDesiredFormat(
fieldHolder.typeMirror,
fieldHolder.defaultValue
) + ", %N",
fieldHolder.constantName
) + "!!)",
fieldHolder.constantName
"arrayOf(%N, %T::class, ${ConversionUtil.convertStringToDesiredFormat(
fieldHolder.typeMirror,
fieldHolder.defaultValue
)}),",
fieldHolder.constantName, fieldHolder.fieldType
)
builder.endControlFlow()
}
}
builder.addStatement("), map)")
return builder.build()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ class CommonInterfaceGeneration {
val companionSpec = TypeSpec.companionObjectBuilder()
companionSpec.addFunctions(fromMapRepresent(holder))
companionSpec.addFunctions(toMapRepresent(holder))
companionSpec.addFunctions(TypeConversionMethodsGeneration(useSuspend).generate())

typeBuilder.addType(companionSpec.build())

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.schwarz.crystalprocessor.generation.model

import com.schwarz.crystalapi.util.CrystalWrap
import com.schwarz.crystalprocessor.model.entity.BaseEntityHolder
import com.schwarz.crystalprocessor.util.TypeUtil
import com.squareup.kotlinpoet.FunSpec
Expand All @@ -17,20 +18,12 @@ object EnsureTypesGeneration {
ensureTypes.addStatement("val result = %T()", explicitType)
ensureTypes.addStatement("result.putAll(doc)")

ensureTypes.addStatement("result.putAll(%T.ensureTypes<%T>(mapOf(", CrystalWrap::class, typeConversionReturnType)
for (field in holder.fields.values) {
ensureTypes.beginControlFlow(
"${
field.ensureType(
typeConversionReturnType,
"doc[%N], %N",
field.constantName,
field.constantName
)
}?.let"
)
ensureTypes.addStatement("result[%N] = it", field.constantName)
ensureTypes.endControlFlow()

ensureTypes.addStatement("%N to %T::class,", field.constantName, field.evaluateClazzForTypeConversion())
}
ensureTypes.addStatement("), doc))")

ensureTypes.addStatement("return result")
return ensureTypes.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class EntityGeneration {
companionSpec.addFunctions(create(holder, useSuspend))
companionSpec.addFunction(findById(holder, useSuspend))
companionSpec.addFunction(findByIds(holder, useSuspend))
companionSpec.addFunctions(TypeConversionMethodsGeneration(useSuspend).generate())

for (query in holder.queries) {
query.queryFun(holder.dbName, holder, useSuspend).let {
Expand Down Expand Up @@ -81,7 +80,7 @@ class EntityGeneration {
.addFunction(SetAllMethodGeneration().generate(holder, true))
.addFunction(id).superclass(holder.sourceElement.typeName)
.addFunction(toMap(holder, useSuspend))
.addFunction(BuilderClassGeneration.generateBuilderFun())
.addFunction(BuilderClassGeneration.generateBuilderFun(holder))

holder.deprecated?.addDeprecated(typeBuilder)

Expand Down
Loading

0 comments on commit c8b0341

Please sign in to comment.