All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dbtools.gen.android.kotlin.KotlinDatabaseBaseManagerRenderer.kt Maven / Gradle / Ivy

There is a newer version: 11.0.0
Show newest version
package org.dbtools.gen.android.kotlin

import org.dbtools.codegen.kotlin.KotlinClass
import org.dbtools.codegen.kotlin.KotlinObjectClass
import org.dbtools.codegen.kotlin.KotlinVal
import org.dbtools.gen.GenConfig
import org.dbtools.schema.schemafile.DatabaseSchema
import org.dbtools.schema.schemafile.SchemaDatabase
import org.dbtools.util.JavaUtil

class KotlinDatabaseBaseManagerRenderer(val genConfig: GenConfig, val outDir: String = "") {

    private val myClass = KotlinClass()
    private val myConstClass = KotlinObjectClass()
    private val constClassName = "DatabaseManagerConst"
    private var packageBase: String = ""

    fun generate(databaseSchema: DatabaseSchema, packageName: String) {
        println("Generating DatabaseBaseManager...")
        this.packageBase = packageName

        val className = "DatabaseBaseManager"
        myClass.apply { 
            name = className
            this.packageName = packageName
            extends = "AndroidDatabaseManager"
            abstract = true
        }
        myConstClass.apply {
            name = constClassName
            this.packageName = packageName
        }

        addHeader(myClass)
        addHeader(myConstClass)

        addImports()

        // constructor
        myClass.addImport("org.dbtools.android.domain.config.DatabaseConfig")
        myClass.addConstructor(listOf(KotlinVal("databaseConfig", "DatabaseConfig")), returnType = "super(databaseConfig)")
        createOnCreate(databaseSchema)
        createOnCreateViews(databaseSchema)

        myClass.writeToDisk(outDir, true)
        myConstClass.writeToDisk(outDir, true)
    }

    private fun addHeader(someClass: KotlinClass) {
        // Do not place date in file because it will cause a new check-in to scm
        var fileHeaderComment: String
        fileHeaderComment = "/*\n"
        fileHeaderComment += " * ${someClass.name}.kt\n"
        fileHeaderComment += " *\n"
        fileHeaderComment += " * GENERATED FILE - DO NOT EDIT\n"
        fileHeaderComment += " * CHECKSTYLE:OFF\n"
        fileHeaderComment += " * \n"
        fileHeaderComment += " */\n"
        someClass.fileHeaderComment = fileHeaderComment

        // Since this is generated code.... suppress all warnings
        someClass.addAnnotation("@Suppress(\"unused\", \"ConvertSecondaryConstructorToPrimary\", \"RemoveEmptySecondaryConstructorBody\")") // kotlin specific
        someClass.addAnnotation("@SuppressWarnings(\"all\")")
    }

    private fun addImports() {
        myClass.addImport("org.dbtools.android.domain.AndroidDatabase")
        myClass.addImport("org.dbtools.android.domain.AndroidBaseManager")
        myClass.addImport("org.dbtools.android.domain.AndroidDatabaseManager")
    }

    private fun createOnCreate(databaseSchema: DatabaseSchema) {
        val content = StringBuilder()
        content.append("logger.i(TAG, \"Creating database: \${androidDatabase.name}\")\n")

        for (database in databaseSchema.databases) {
            var databaseName = database.getName(true)

            val databaseConstName = JavaUtil.nameToJavaConst(databaseName) + "_DATABASE_NAME"
            val databaseMethodName = JavaUtil.nameToJavaConst(databaseName) + "_TABLES"
            myConstClass.addConstant(databaseConstName, "\"${database.getName(false)}\"" ).apply { const = true }
            createCreateDatabase(content, databaseConstName, databaseMethodName, database)
        }

        myClass.addFun("onCreate", parameters = listOf(KotlinVal("androidDatabase", "AndroidDatabase")), content = content.toString()).apply {
            override = true
        }
    }

    private fun createCreateDatabase(content: StringBuilder, databaseConstName: String, databaseMethodName: String, database: SchemaDatabase) {
        val varName = JavaUtil.sqlNameToJavaVariableName(databaseMethodName)
        val createDatabaseMethodName = "create" + Character.toUpperCase(varName[0]) + varName.substring(1)

        content.append("if (androidDatabase.name == $constClassName.$databaseConstName) {\n")
        content.append(TAB).append(createDatabaseMethodName).append("(androidDatabase)\n")
        content.append("}\n")

        val createDatabaseContent = StringBuilder()
        createDatabaseContent.append("val database = androidDatabase.databaseWrapper\n")
        createDatabaseContent.append("database.beginTransaction()\n")

        // include database name in base package name
        val databaseBasePackage = createDatabaseBasePackage(database)

        createDatabaseContent.append("\n// Enum Tables\n")
        for (table in database.tables) {
            if (table.isEnumerationTable) {
                createDatabaseContent.append("AndroidBaseManager.createTable(database, ")
                        .append(JavaUtil.createTableImport(databaseBasePackage, table.className) + "Const")
                        .append(".CREATE_TABLE)\n")
            }
        }

        createDatabaseContent.append("\n// Tables\n")
        for (table in database.tables) {
            if (!table.isEnumerationTable) {
                createDatabaseContent.append("AndroidBaseManager.createTable(database, ")
                        .append(JavaUtil.createTableImport(databaseBasePackage, table.className) + "Const")
                        .append(".CREATE_TABLE)\n")
            }
        }

        createDatabaseContent.append("\n")
        createDatabaseContent.append("database.setTransactionSuccessful()\n")
        createDatabaseContent.append("database.endTransaction()\n")

        myClass.addFun(createDatabaseMethodName, parameters = listOf(KotlinVal("androidDatabase", "AndroidDatabase")), content = createDatabaseContent.toString()).apply {
            open = true
        }
    }

    private fun createOnCreateViews(databaseSchema: DatabaseSchema) {
        val createContent = StringBuilder()
        val dropContent = StringBuilder()

        createContent.append("logger.i(TAG, \"Creating database views: \${androidDatabase.name}\")\n")
        dropContent.append("logger.i(TAG, \"Dropping database views: \${androidDatabase.name}\")\n")

        for (database in databaseSchema.databases) {
            var databaseName = database.getName(true)

            val databaseConstName = JavaUtil.nameToJavaConst(databaseName) + "_DATABASE_NAME"
            val databaseMethodName = JavaUtil.nameToJavaConst(databaseName) + "_VIEWS"
            createCreateViews(createContent, databaseConstName, databaseMethodName, database)
            createDropViews(dropContent, databaseConstName, databaseMethodName, database)
        }

        val params = listOf(KotlinVal("androidDatabase", "AndroidDatabase"))
        myClass.addFun("onCreateViews", parameters = params, content = createContent.toString()).apply {
            override = true
        }
        myClass.addFun("onDropViews", parameters = params, content = dropContent.toString()).apply {
            override = true
        }
    }

    private fun createCreateViews(content: StringBuilder, databaseConstName: String, databaseMethodName: String, database: SchemaDatabase) {
        if (database.views.isEmpty()) {
            return
        }

        val varName = JavaUtil.sqlNameToJavaVariableName(databaseMethodName)
        val createDatabaseViewsMethodName = "create" + Character.toUpperCase(varName[0]) + varName.substring(1)

        content.append("if (androidDatabase.name == $constClassName.$databaseConstName) {\n")
        content.append(TAB).append(createDatabaseViewsMethodName).append("(androidDatabase)\n")
        content.append("}\n")

        val createDatabaseViewsContent = StringBuilder()

        createDatabaseViewsContent.append("val database = androidDatabase.databaseWrapper\n")
        createDatabaseViewsContent.append("database.beginTransaction()\n")

        // include database name in base package name
        val databaseBasePackage = createDatabaseBasePackage(database)

        createDatabaseViewsContent.append("\n// Views\n")
        for (view in database.views) {
            createDatabaseViewsContent.append("AndroidBaseManager.createTable(database, ")
                    .append(JavaUtil.createTableImport(databaseBasePackage, view.className) + "Manager")
                    .append(".CREATE_VIEW)\n")
        }

        createDatabaseViewsContent.append("\n")
        createDatabaseViewsContent.append("database.setTransactionSuccessful()\n")
        createDatabaseViewsContent.append("database.endTransaction()\n")

        myClass.addFun(createDatabaseViewsMethodName, parameters = listOf(KotlinVal("androidDatabase", "AndroidDatabase")), content = createDatabaseViewsContent.toString()).apply {
            open = true
        }
    }

    private fun createDropViews(content: StringBuilder, databaseConstName: String, databaseMethodName: String, database: SchemaDatabase) {
        if (database.views.isEmpty()) {
            return
        }

        val varName = JavaUtil.sqlNameToJavaVariableName(databaseMethodName)
        val dropDatabaseViewsMethodName = "drop" + Character.toUpperCase(varName[0]) + varName.substring(1)

        content.append("if (androidDatabase.name == $constClassName.$databaseConstName) {\n")
        content.append(TAB).append(dropDatabaseViewsMethodName).append("(androidDatabase)\n")
        content.append("}\n")

        val dropDatabaseViewsContent = StringBuilder()
        dropDatabaseViewsContent.append("val database = androidDatabase.databaseWrapper\n")
        dropDatabaseViewsContent.append("database.beginTransaction()\n")

        // include database name in base package name
        val databaseBasePackage = createDatabaseBasePackage(database)

        dropDatabaseViewsContent.append("\n// Views\n")
        for (view in database.views) {
            dropDatabaseViewsContent.append("AndroidBaseManager.dropTable(database, ")
                    .append(JavaUtil.createTableImport(databaseBasePackage, view.className) + "Manager")
                    .append(".DROP_VIEW)\n")
        }

        dropDatabaseViewsContent.append("\n")
        dropDatabaseViewsContent.append("database.setTransactionSuccessful()\n")
        dropDatabaseViewsContent.append("database.endTransaction()\n")

        myClass.addFun(dropDatabaseViewsMethodName, parameters = listOf(KotlinVal("androidDatabase", "AndroidDatabase")), content = dropDatabaseViewsContent.toString()).apply {
            open = true
        }
    }

    private fun createDatabaseBasePackage(database: SchemaDatabase): String {
        return packageBase + (if (genConfig.isIncludeDatabaseNameInPackage) "." + database.getName(true) else "")
    }

    fun setPackageBase(packageBase: String) {
        this.packageBase = packageBase
    }

    companion object {
        private val TAB = KotlinClass.tab
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy