Kotlin data access framework "EntityDream"

“EntityDream” is jdbc based kotlin database access framework (kotlin jvm only)
it is writed “PipeLine” design mode,
write a extension you can extend the framework feature,

current supported only mysql (Additional RDBMS database support can be added, Can be ported to Android)

features:
auto generate tables
support relationship entity field (hasOne, hasMany)

https://gitee.com/yeganaaa/EntityDream

usage examples:

1. define your table defination

class User(DataContext: IDataContext) : DBEntity(DataContext, User) {
    companion object : DBTable("User") {

        override var Comment: String = "ئەزا"
        val ID = idColumn("ID") comment "ID" primaryKey true
        val Name = stringColumn("Name") isN true default "Name@Empty" size 100 comment "ئىسمى"
        val Pwd = stringColumn("Pwd") isN false size 50 comment "پارولى" default "Password@Empty"
        val Age = byteColumn("Age") unsigned true notNull true default 0 comment "يىشى"
        val EMail = stringColumn("EMail") size 200 comment "ئىلخەت"
        val Money = doubleColumn("Money") notNull false comment "پۇلى"
        val BirthDay = dateTimeColumn("BirthDay") notNull true comment "تۇغۇلغان ۋاقتى"
        val CompanyID = intColumn("CompanyID") notNull true reference Company.ID unsigned true comment "CompanyID"

        init {
        //            unique(Name, Pwd)
            index(Name, Pwd) unique true
        }
    //        val Avatar = byteArrayColumn("Avatar") notNull false comment "باش سۈرەت"

    }

    var ID by User.ID
    var Name by User.Name
    var Pwd by User.Pwd
    var Age by User.Age
    var EMail by User.EMail
    var Money by User.Money
    var BirthDay by User.BirthDay
    var CompanyID by User.CompanyID
    var Company by hasOne(User.CompanyID){ Company(it) }

class Company(DataContext: IDataContext) : DBEntity(DataContext, Company) {
    companion object : DBTable("Company") {

        val ID = idColumn("ID") comment "ID"
        val Name = stringColumn("Name") comment "ئىسمى"
        var WebSite = stringColumn("WebSite") comment "تور ئادېرسى"
    }

    var ID by Company.ID
    var Name by Company.Name
    var WebSite by Company.WebSite
    val Users: QueriableCollection<User> by hasMany(User.CompanyID) { User(it) }
}

2. define your datacontext (database) object

object db : MySqlDataContext(DriverManager.getConnection("jdbc:mysql://127.0.0.1:3308/Hello", "yeganaaa", "Developer653125")) {
        val Users = dbCollection(User) { User(it) }
        val Companies = dbCollection(Company) { Company(it) }
    }

3. define your log extension (optional, not required)

val logger = object : PipeLineFeature<IPipeLineSubject, IDataContext>() {

        override val getMetaData: PipeLineFeatureMetaData by lazy { PipeLineFeatureMetaData(CorePipeLine.after, "Logger") }
        override val info: FeatureInfo by lazy { FeatureInfo("Logger", "Demo", "Sarkar Software Technologys", "yeganaaa", 1, "v0.1") }

//        var index = 0

        override fun PipeLineContext<IPipeLineSubject, IDataContext>.onExecute(subject: IPipeLineSubject) {
//                println((++index).toString() + "---" + subject.Name + "***********" + subject::class.java.simpleName)

            if (subject is TranslationSubject) {

                println("Generated SQL ->> " + subject.translationResult!!.fullSqlQuery)
            }
        }
    }

4. install the extension into datacontext

db.pipeLine.installFeature(logger)

5. generate your database tables

val result = db.createNewTables(User, Company)
println(result)

6. insert your data into database

//sample
    val company = Company(db).apply {
                Name = "Sarkar Software Technologys"
                WebSite = "http://www.sarkar.cn"
            }

        db.Companies.add(company)

        println("Insert before: ${company.ID}")
        db.saveChanges()
        println("Insert after: ${company.ID}")

        val usr = User(db).apply {
            Name = "مۇختەر مەخمۇت"
            Age = 24
            EMail = "yeganaaa@hotmail.com"
            Pwd = "Developer653125"
            Money = 22.45
            Company = company
            BirthDay = DateTime(1994, 3, 1, 8, 9, 10)

        }
        db.Users.add(usr)

        println("Insert before: ${usr.ID}")
        db.saveChanges()
        println("Insert after: ${usr.ID}")

//sample
    val company = db.Companies.first { Company.WebSite equals "http://www.sarkar.cn" and (Company.Name notEquals "NotEqualThis") }

        val usr = User(db).apply {
            Name = "ئابدۇقادىر"
            Age = 24
            EMail = "Stilly@hotmail.com"
            Pwd = "Developer000000"
            Money = 30.45
            Company = company
            BirthDay = DateTime(1994, 3, 1, 8, 9, 10)

        }


        db.Users.add(usr)

        println(usr.ID)
        db.saveChanges()
        println(usr.ID)

7. update your data

val user = db.Companies.first { Company.WebSite equals "http://www.sarkar.cn" and (Company.Name notEquals "aaa") }.Users.first { User.Age greater 18 and (User.Money greater 0.toDouble()) and (User.Name startsWith "مۇختەر") }

    println(user.Name)

    user.Name = "ئىسىم ئۆزگەردى" //Name changed!

    db.saveChanges() //commit changes

8. delete your data

val user = db.Companies.first { Company.WebSite equals "http://www.sarkar.cn" and (Company.Name notEquals "aaa") }.Users.first { User.Age greater 18 and (User.Money greater 0.toDouble()) and (User.Name startsWith "مۇختەر") }

        println(user.Name)
        db.Users.remove(user)
        db.saveChanges()

9. query your data

//sample
    db.Companies.where { Company.WebSite equals "http://www.sarkar.cn" }.mid(Company.WebSite, 2, 4).first().Users.mid(User.Name, 2, 3).forEach {
                println(it.Name)
            }

//sample
    val avgMoney = db.Users.where { User.Name notStartsWith "Hell" and (User.Age greater 18) } skip 0 take 10 avg User.Money

            println(avgMoney)

//sample
db.Users.single { User.Pwd equals  "Developer653125" }

10. advanced extension samples

val setterTrigger = object: PipeLineFeature<IPipeLineSubject, IDataContext>(){
    override val getMetaData: PipeLineFeatureMetaData by lazy { PipeLineFeatureMetaData(CorePipeLine.beforeFilter, "My.Example.EntityDream.SetterTrigger") }
    override val info: FeatureInfo by lazy { FeatureInfo(
            "Extension Name is EntityDream Triggers",
            "this is a example extension of entity dream data access framework, the field is extension description",
            "Your company ",
            "Author Name",
            0 /*Version number*/,
            "v0.1" /*version code*/
    ) }

override fun PipeLineContext<IPipeLineSubject, IDataContext>.onExecute(subject: IPipeLineSubject) {
    if (subject is SetEntityFieldValueSubject)
    {
        println("field ${subject.column} changed to ${subject.value} of Entity: ${subject.entity}")

        if (subject.column == User.Name){
            subject.value = "Field changed!" //the field can be change
        }
      }
   }
}

val getterTrigger = object: PipeLineFeature<IPipeLineSubject, IDataContext>(){
    override val getMetaData: PipeLineFeatureMetaData by lazy { PipeLineFeatureMetaData(CorePipeLine.afterFilter, "My.Example.EntityDream.GetterTrigger") }
    override val info: FeatureInfo by lazy { FeatureInfo(
            "Extension Name is EntityDream Triggers",
            "this is a example extension of entity dream data access framework, the field is extension description",
            "Your company ",
            "Author Name",
            0 /*Version number*/,
            "v0.1" /*version code*/
    ) }

override fun PipeLineContext<IPipeLineSubject, IDataContext>.onExecute(subject: IPipeLineSubject) {
    if (subject is GetEntityFieldValueSubject)
    {
        println("field ${subject.column} oldValue: ${subject.value} of Entity: ${subject.entity}")

        if (subject.column == User.Name){
            subject.value = "New Fieldddddd@@@@Exposed" //replace new value
        }
     }
  }
}

//and install the two extension into datacontext

    db.pipeLine.installFeature(setterTrigger)
    db.pipeLine.installFeature(getterTrigger)

//execute the codes try your extensions
val user = db.Companies.first { Company.WebSite equals "http://www.sarkar.cn" and (Company.Name notEquals "aaa") }.Users.first { User.Age greater 18 and (User.Money greater 0.toDouble()) }

   user.Name = "Name Changed@@@" //Name changed!
   db.saveChanges()
   println(user.Name)

My english verry poor, sorry guys.

https://gitee.com/yeganaaa/EntityDream