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

org.jetbrains.exposed.sql.IterableEx.kt Maven / Gradle / Ivy

There is a newer version: 0.17.14
Show newest version
package org.jetbrains.exposed.sql

import java.lang.IllegalStateException

interface SizedIterable: Iterable {
    fun limit(n: Int, offset: Int = 0): SizedIterable
    fun count(): Int
    fun empty(): Boolean
    fun forUpdate(): SizedIterable = this
    fun notForUpdate(): SizedIterable = this
    fun copy() : SizedIterable
    fun orderBy(vararg order: Pair, SortOrder>) : SizedIterable
}

fun  emptySized() : SizedIterable = EmptySizedIterable()

class EmptySizedIterable : SizedIterable, Iterator {
    override fun count(): Int = 0

    override fun limit(n: Int, offset: Int): SizedIterable = this

    override fun empty(): Boolean = true

    override operator fun iterator(): Iterator = this

    override operator fun next(): T {
        throw UnsupportedOperationException()
    }

    override fun hasNext(): Boolean = false

    override fun copy(): SizedIterable = this

    override fun orderBy(vararg order: Pair, SortOrder>): SizedIterable = this
}

class SizedCollection(val delegate: Collection): SizedIterable {
    constructor(vararg values: T) : this(values.toList())
    override fun limit(n: Int, offset: Int): SizedIterable = SizedCollection(delegate.drop(offset).take(n))

    override operator fun iterator() = delegate.iterator()
    override fun count() = delegate.size
    override fun empty() = delegate.isEmpty()
    override fun copy(): SizedIterable = SizedCollection(delegate)
    override fun orderBy(vararg order: Pair, SortOrder>): SizedIterable = this
}

class LazySizedCollection(_delegate: SizedIterable): SizedIterable {
    private var delegate: SizedIterable = _delegate

    private var _wrapper: List? = null
    private var _size: Int? = null
    private var _empty: Boolean? = null

    val wrapper: List get() {
        if (_wrapper == null) {
            _wrapper = delegate.toList()
        }
        return _wrapper!!
    }

    override fun limit(n: Int, offset: Int): SizedIterable = LazySizedCollection(delegate.limit(n, offset))
    override operator fun iterator() = wrapper.iterator()
    override fun count() = _wrapper?.size ?: _count()
    override fun empty() = _wrapper?.isEmpty() ?: _empty()
    override fun forUpdate(): SizedIterable {
        val localDelegate = delegate
        if (_wrapper != null && localDelegate is Query && localDelegate.hasCustomForUpdateState() && !localDelegate.isForUpdate()) {
            throw IllegalStateException("Impossible to change forUpdate state for loaded data")
        }
        if (_wrapper == null) {
            delegate = delegate.forUpdate()
        }
        return this
    }

    override fun notForUpdate(): SizedIterable {
        val localDelegate = delegate
        if(_wrapper != null && localDelegate is Query && localDelegate.hasCustomForUpdateState() && localDelegate.isForUpdate()) {
            throw IllegalStateException("Impossible to change forUpdate state for loaded data")
        }
        if (_wrapper == null) {
            delegate = delegate.notForUpdate()
        }
        return this
    }

    private fun _count(): Int {
        if (_size == null) {
            _size = delegate.count()
            _empty = (_size == 0)
        }
        return _size!!
    }

    private fun _empty(): Boolean {
        if (_empty == null) {
            _empty = delegate.empty()
            if (_empty == true) _size = 0
        }

        return _empty!!
    }

    override fun copy(): SizedIterable = LazySizedCollection(delegate.copy())

    override fun orderBy(vararg order: Pair, SortOrder>): SizedIterable {
        check(_wrapper == null) { "Can't order already loaded data" }
        delegate = delegate.orderBy(*order)
        return this
    }
}

infix fun  SizedIterable.mapLazy(f:(T)->R):SizedIterable {
    val source = this
    return object : SizedIterable {
        override fun limit(n: Int, offset: Int): SizedIterable = source.copy().limit(n, offset).mapLazy(f)
        override fun forUpdate(): SizedIterable = source.copy().forUpdate().mapLazy(f)
        override fun notForUpdate(): SizedIterable = source.copy().notForUpdate().mapLazy(f)
        override fun count(): Int = source.count()
        override fun empty(): Boolean = source.empty()
        override fun copy(): SizedIterable = source.copy().mapLazy(f)
        override fun orderBy(vararg order: Pair, SortOrder>) = source.orderBy(*order).mapLazy(f)

        override operator fun iterator(): Iterator {
            val sourceIterator = source.iterator()
            return object: Iterator {
                override operator fun next(): R = f(sourceIterator.next())

                override fun hasNext(): Boolean = sourceIterator.hasNext()
            }

        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy