cufyorg / moonkit

[ARCHIVED] DSL Based MongoDB driver wrapper for kotlin with an optional schema system
Apache License 2.0
4 stars 2 forks source link

Idea - Operation based (Non ORM) schema system #5

Closed LSafer closed 1 year ago

LSafer commented 1 year ago

Overview

Mutable objects are evil. Must not produce mutable objects.

Q: But, how properties of user classes will be initialized?

A: That is it, there won't be user classes. Instead, a user defines properties!

Goals

Suggested Syntax


// Just a marker
interface Product

// Holds minimum information
val Products = collection<Product>()

// Detached from the collection
val ProductName = OpField<Product, _>("name") {
    schema { StringCodec }
}

// Detached from the collection
val ProductCreatedAt = OpField<Product, _>("createdAt") {
    schema { Int64Codec }
}

suspend fun run() {
    val product = query(OpMonkt) {
        Products.findOne({ }) // QueryScope { Collection.findOne() }
    }

    product ?: error("Product Not Found")

    // `name` will always have the same value for
    // the same instance. Instances are immutable
    val name = product[ProductName]

    // mutations needs to be in mutation scope and
    // at the end of the scope the operations are
    // put in a single batch.
    // this way, actual driver variables like
    // connection, client and session or even the
    // actual collection instance is not needed to
    // be references on every instance.
    val ops = mutation {
        // This won't modify the name of `product`
        //  instead will add a mutation to this
        //  mutation scope.
        // the instance `product` will remain immutable
        product[ProductName] =
            "New Name"

        // This also won't do much.
        // `newProduct` will only have an `_id` property
        val newProduct = Products() // MutationScope { Collection.invoke() }
        newProduct[ProductName] =
            "Initial Name"
        newProduct[ProductCreatedAt] =
            System.currentTimeMillis()
    }

    // finally, once all the mutations are gathered.
    // they can be executed in one go.
    OpMonkt.execute(ops)
}