mirror of
https://github.com/tursom/TursomServer.git
synced 2025-01-01 07:50:47 +08:00
add Parser
This commit is contained in:
parent
4a9e3024ca
commit
32dea366e9
109
database/mongodb/src/main/kotlin/cn/tursom/mongodb/Aggregate.kt
Normal file
109
database/mongodb/src/main/kotlin/cn/tursom/mongodb/Aggregate.kt
Normal file
@ -0,0 +1,109 @@
|
||||
package cn.tursom.mongodb
|
||||
|
||||
import com.mongodb.MongoNamespace
|
||||
import com.mongodb.client.model.*
|
||||
import org.bson.conversions.Bson
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
|
||||
@Suppress("unused")
|
||||
object Aggregate {
|
||||
operator fun invoke(action: Aggregate.() -> Bson) = this.action()
|
||||
|
||||
fun addFields(vararg fields: Field<*>): Bson = Aggregates.addFields(fields.asList())
|
||||
fun addFields(fields: List<Field<*>>): Bson? = Aggregates.addFields(fields)
|
||||
|
||||
fun <TExpression, Boundary> bucket(
|
||||
groupBy: TExpression,
|
||||
boundaries: List<Boundary>
|
||||
): Bson = Aggregates.bucket(groupBy, boundaries)
|
||||
|
||||
fun <TExpression, TBoundary> bucket(
|
||||
groupBy: TExpression,
|
||||
boundaries: List<TBoundary>,
|
||||
options: BucketOptions
|
||||
): Bson = Aggregates.bucket(groupBy, boundaries, options)
|
||||
|
||||
|
||||
fun <TExpression> bucketAuto(groupBy: TExpression, buckets: Int): Bson = Aggregates.bucketAuto(groupBy, buckets)
|
||||
|
||||
fun <TExpression> bucketAuto(
|
||||
groupBy: TExpression,
|
||||
buckets: Int,
|
||||
options: BucketAutoOptions
|
||||
): Bson = Aggregates.bucketAuto(groupBy, buckets, options)
|
||||
|
||||
fun count(): Bson = Aggregates.count()
|
||||
fun count(field: String): Bson = Aggregates.count(field)
|
||||
|
||||
fun match(filter: Bson): Bson = Aggregates.match(filter)
|
||||
fun match(value: Any): Bson = Aggregates.match(MongoUtil.convertToBson(value))
|
||||
fun project(projection: Bson): Bson = Aggregates.project(projection)
|
||||
fun sort(sort: Bson): Bson = Aggregates.sort(sort)
|
||||
fun <TExpression> sortByCount(filter: TExpression): Bson = Aggregates.sortByCount(filter)
|
||||
fun skip(skip: Int): Bson = Aggregates.skip(skip)
|
||||
fun limit(limit: Int): Bson = Aggregates.limit(limit)
|
||||
|
||||
fun lookup(
|
||||
from: String,
|
||||
localField: String,
|
||||
foreignField: String,
|
||||
`as`: String
|
||||
): Bson = Aggregates.lookup(from, localField, foreignField, `as`)
|
||||
|
||||
fun lookup(from: String, pipeline: List<Bson?>, `as`: String): Bson = Aggregates.lookup(from, pipeline, `as`)
|
||||
fun <TExpression> lookup(
|
||||
from: String,
|
||||
let: List<Variable<TExpression>>? = null,
|
||||
pipeline: List<Bson>,
|
||||
`as`: String
|
||||
): Bson = Aggregates.lookup(from, let, pipeline, `as`)
|
||||
|
||||
|
||||
fun facet(facets: List<Facet>): Bson = Aggregates.facet(facets)
|
||||
fun facet(vararg facets: Facet): Bson = Aggregates.facet(facets.asList())
|
||||
|
||||
fun <TExpression> graphLookup(
|
||||
from: String,
|
||||
startWith: TExpression,
|
||||
connectFromField: String,
|
||||
connectToField: String,
|
||||
`as`: String
|
||||
): Bson = Aggregates.graphLookup(from, startWith, connectFromField, connectToField, `as`)
|
||||
|
||||
fun <TExpression> graphLookup(
|
||||
from: String,
|
||||
startWith: TExpression,
|
||||
connectFromField: String,
|
||||
connectToField: String,
|
||||
`as`: String,
|
||||
options: GraphLookupOptions
|
||||
): Bson = Aggregates.graphLookup(from, startWith, connectFromField, connectToField, `as`, options)
|
||||
|
||||
|
||||
fun <TExpression> group(
|
||||
id: TExpression? = null,
|
||||
vararg fieldAccumulators: BsonField
|
||||
): Bson = Aggregates.group(id, fieldAccumulators.asList())
|
||||
|
||||
fun <TExpression> group(
|
||||
id: TExpression? = null,
|
||||
fieldAccumulators: List<BsonField>
|
||||
): Bson = Aggregates.group(id, fieldAccumulators)
|
||||
|
||||
fun unwind(field: KProperty1<*, *>): Bson = Aggregates.unwind(MongoUtil.fieldName(field))
|
||||
fun unwind(field: KProperty1<*, *>, unwindOptions: UnwindOptions): Bson = Aggregates.unwind(MongoUtil.fieldName(field), unwindOptions)
|
||||
fun unwind(fieldName: String): Bson = Aggregates.unwind(fieldName)
|
||||
fun unwind(fieldName: String, unwindOptions: UnwindOptions): Bson = Aggregates.unwind(fieldName, unwindOptions)
|
||||
|
||||
fun out(collectionName: String): Bson = Aggregates.out(collectionName)
|
||||
|
||||
fun merge(collectionName: String): Bson = Aggregates.merge(collectionName)
|
||||
fun merge(namespace: MongoNamespace): Bson = Aggregates.merge(namespace)
|
||||
fun merge(collectionName: String, options: MergeOptions): Bson = Aggregates.merge(collectionName, options)
|
||||
fun merge(namespace: MongoNamespace, options: MergeOptions): Bson = Aggregates.merge(namespace, options)
|
||||
|
||||
fun <TExpression> replaceRoot(value: TExpression): Bson = Aggregates.replaceRoot(value)
|
||||
fun <TExpression> replaceWith(value: TExpression): Bson = Aggregates.replaceWith(value)
|
||||
fun sample(size: Int): Bson = Aggregates.sample(size)
|
||||
}
|
@ -2,6 +2,7 @@ package cn.tursom.mongodb
|
||||
|
||||
import cn.tursom.core.*
|
||||
import cn.tursom.mongodb.annotation.Ignore
|
||||
import com.mongodb.client.AggregateIterable
|
||||
import com.mongodb.client.FindIterable
|
||||
import com.mongodb.client.MongoCollection
|
||||
import com.mongodb.client.MongoDatabase
|
||||
@ -70,6 +71,7 @@ class MongoOperator<T : Any>(
|
||||
|
||||
fun list(where: Bson? = null): List<T> {
|
||||
val find = find(where)
|
||||
val iterator = find.iterator()
|
||||
return find.mapNotNull { Parser.parse(it, clazz) }
|
||||
}
|
||||
|
||||
@ -81,6 +83,24 @@ class MongoOperator<T : Any>(
|
||||
}
|
||||
}
|
||||
|
||||
fun get(filter: Bson? = null): Iterable<T> {
|
||||
val result = if (filter != null) {
|
||||
collection.find(filter)
|
||||
} else {
|
||||
collection.find()
|
||||
}
|
||||
|
||||
return object : Iterable<T> {
|
||||
override fun iterator(): Iterator<T> = object : Iterator<T> {
|
||||
val iterator = result.iterator()
|
||||
override fun hasNext(): Boolean = iterator.hasNext()
|
||||
override fun next(): T = Parser.parse(iterator.next(), clazz)!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun aggregate(vararg pipeline: Bson): AggregateIterable<Document> = aggregate(pipeline.asList())
|
||||
|
||||
private fun convertToBson(entity: Any): Document {
|
||||
val bson = Document()
|
||||
fields.forEach {
|
||||
@ -97,8 +117,7 @@ class MongoOperator<T : Any>(
|
||||
}.cast<T>()
|
||||
fields.forEach {
|
||||
val value = bson[MongoUtil.fieldName(it)] ?: return@forEach
|
||||
|
||||
MongoUtil.injectValue(bson, it.get(entity) ?: return@forEach, it)
|
||||
MongoUtil.injectValue(bson, value, it)
|
||||
}
|
||||
return entity
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
package cn.tursom.mongodb
|
||||
|
||||
import com.mongodb.client.model.Projections
|
||||
import org.bson.conversions.Bson
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
object Projection {
|
||||
operator fun invoke(action: Projection.() -> Bson) = this.action()
|
||||
|
||||
fun <T, TExpression> computed(field: KProperty1<out T, *>, expression: TExpression): Bson = computed(MongoUtil.fieldName(field), expression)
|
||||
fun <TExpression> computed(fieldName: String, expression: TExpression): Bson = Projections.computed(fieldName, expression)
|
||||
|
||||
fun <T> include(vararg fieldNames: KProperty1<out T, *>): Bson = Projections.include(fieldNames.map { MongoUtil.fieldName(it) })
|
||||
fun <T> include(fieldNames: Collection<KProperty1<out T, *>>): Bson = Projections.include(fieldNames.map { MongoUtil.fieldName(it) })
|
||||
fun include(vararg fieldNames: String): Bson = Projections.include(fieldNames.asList())
|
||||
fun include(fieldNames: List<String>): Bson = Projections.include(fieldNames)
|
||||
|
||||
fun <T> exclude(vararg fieldNames: KProperty1<out T, *>): Bson = Projections.exclude(fieldNames.map { MongoUtil.fieldName(it) })
|
||||
fun <T> exclude(fieldNames: Collection<KProperty1<out T, *>>): Bson = Projections.exclude(fieldNames.map { MongoUtil.fieldName(it) })
|
||||
fun exclude(vararg fieldNames: String): Bson = Projections.exclude(fieldNames.asList())
|
||||
fun exclude(fieldNames: List<String>): Bson = Projections.exclude(fieldNames)
|
||||
|
||||
fun excludeId(): Bson = Projections.excludeId()
|
||||
|
||||
fun <T> exclude(field: KProperty1<out T, *>): Bson = Projections.elemMatch(MongoUtil.fieldName(field))
|
||||
fun <T> exclude(field: KProperty1<out T, *>, filter: Bson): Bson = Projections.elemMatch(MongoUtil.fieldName(field), filter)
|
||||
fun elemMatch(fieldName: String): Bson = Projections.elemMatch(fieldName)
|
||||
fun elemMatch(fieldName: String, filter: Bson): Bson = Projections.elemMatch(fieldName, filter)
|
||||
|
||||
fun <T> metaTextScore(field: KProperty1<out T, *>): Bson = Projections.metaTextScore(MongoUtil.fieldName(field))
|
||||
fun metaTextScore(fieldName: String): Bson = Projections.metaTextScore(fieldName)
|
||||
|
||||
fun <T> slice(field: KProperty1<out T, *>, limit: Int): Bson = Projections.slice(MongoUtil.fieldName(field), limit)
|
||||
fun <T> slice(field: KProperty1<out T, *>, skip: Int, limit: Int): Bson = Projections.slice(MongoUtil.fieldName(field), skip, limit)
|
||||
fun slice(fieldName: String, limit: Int): Bson = Projections.slice(fieldName, limit)
|
||||
fun slice(fieldName: String, skip: Int, limit: Int): Bson = Projections.slice(fieldName, skip, limit)
|
||||
|
||||
fun fields(vararg projections: Bson): Bson = Projections.fields(projections.asList())
|
||||
fun fields(projections: List<Bson>): Bson = Projections.fields(projections)
|
||||
}
|
22
database/mongodb/src/main/kotlin/cn/tursom/mongodb/Sort.kt
Normal file
22
database/mongodb/src/main/kotlin/cn/tursom/mongodb/Sort.kt
Normal file
@ -0,0 +1,22 @@
|
||||
package cn.tursom.mongodb
|
||||
|
||||
import com.mongodb.client.model.Sorts
|
||||
import org.bson.conversions.Bson
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
object Sort {
|
||||
operator fun invoke(action: Sort.() -> Bson) = this.action()
|
||||
|
||||
fun <T> ascending(vararg fieldNames: KProperty1<out T, *>): Bson = Sorts.ascending(fieldNames.map { MongoUtil.fieldName(it) })
|
||||
fun <T> ascending(fieldNames: Collection<KProperty1<out T, *>>): Bson = Sorts.ascending(fieldNames.map { MongoUtil.fieldName(it) })
|
||||
fun ascending(vararg fieldNames: String): Bson = Sorts.ascending(fieldNames.asList())
|
||||
fun ascending(fieldNames: List<String>): Bson = Sorts.ascending(fieldNames)
|
||||
fun <T> descending(vararg fieldNames: KProperty1<out T, *>): Bson = Sorts.descending(fieldNames.map { MongoUtil.fieldName(it) })
|
||||
fun <T> descending(fieldNames: Collection<KProperty1<out T, *>>): Bson = Sorts.descending(fieldNames.map { MongoUtil.fieldName(it) })
|
||||
fun descending(vararg fieldNames: String): Bson = Sorts.descending(fieldNames.asList())
|
||||
fun descending(fieldNames: List<String>): Bson = Sorts.descending(fieldNames)
|
||||
fun <T> KProperty1<out T, *>.metaTextScore(): Bson = Sorts.metaTextScore(MongoUtil.fieldName(this))
|
||||
fun metaTextScore(fieldName: String): Bson = Sorts.metaTextScore(fieldName)
|
||||
fun orderBy(vararg sorts: Bson): Bson = Sorts.orderBy(sorts.asList())
|
||||
fun orderBy(sorts: List<Bson>): Bson = Sorts.orderBy(sorts)
|
||||
}
|
5
database/mongodb/src/test/kotlin/cn/tursom/main.kt
Normal file
5
database/mongodb/src/test/kotlin/cn/tursom/main.kt
Normal file
@ -0,0 +1,5 @@
|
||||
package cn.tursom
|
||||
|
||||
fun main() {
|
||||
|
||||
}
|
74
src/main/kotlin/cn/tursom/core/datastruct/AbstractList.kt
Normal file
74
src/main/kotlin/cn/tursom/core/datastruct/AbstractList.kt
Normal file
@ -0,0 +1,74 @@
|
||||
package cn.tursom.core.datastruct
|
||||
|
||||
interface AbstractList<T> : List<T> {
|
||||
|
||||
override fun contains(element: T): Boolean {
|
||||
forEach {
|
||||
if (it == element) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<T>): Boolean {
|
||||
elements.forEach {
|
||||
if (!contains(it)) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun get(index: Int): T {
|
||||
forEachIndexed { i, t ->
|
||||
if (index == i) {
|
||||
return t
|
||||
}
|
||||
}
|
||||
throw IndexOutOfBoundsException()
|
||||
}
|
||||
|
||||
override fun indexOf(element: T): Int {
|
||||
forEachIndexed { i, t ->
|
||||
if (t == element) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
return size == 0
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<T> = listIterator()
|
||||
|
||||
override fun lastIndexOf(element: T): Int {
|
||||
var lastIndex = -1
|
||||
forEachIndexed { i, t ->
|
||||
if (t == element) {
|
||||
lastIndex = i
|
||||
}
|
||||
}
|
||||
return lastIndex
|
||||
}
|
||||
|
||||
override fun listIterator(): ListIterator<T> = listIterator(0)
|
||||
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<T> = SubList(this, fromIndex, toIndex)
|
||||
}
|
||||
|
||||
class SubList<T>(val list: List<T>, val fromIndex: Int, val toIndex: Int) : AbstractList<T> {
|
||||
override val size: Int = toIndex - fromIndex
|
||||
|
||||
override fun listIterator(index: Int): ListIterator<T> = object : ListIterator<T> {
|
||||
var i: Int = index - 1
|
||||
|
||||
override fun hasPrevious(): Boolean = i > 0
|
||||
override fun previousIndex(): Int = i - 1
|
||||
override fun previous(): T = this@SubList[--i]
|
||||
override fun hasNext(): Boolean = i < this@SubList.size
|
||||
override fun nextIndex(): Int = i + 1
|
||||
override fun next(): T = this@SubList[++i]
|
||||
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ interface AbstractMutableList<T> : MutableList<T> {
|
||||
}
|
||||
|
||||
override fun subList(fromIndex: Int, toIndex: Int): MutableList<T> {
|
||||
return SubList(this, fromIndex, toIndex)
|
||||
return MutableSubList(this, fromIndex, toIndex)
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cn.tursom.core.datastruct
|
||||
|
||||
class SubList<T>(
|
||||
class MutableSubList<T>(
|
||||
val parent: MutableList<T>,
|
||||
val fromIndex: Int,
|
||||
val toIndex: Int
|
Loading…
Reference in New Issue
Block a user