mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
[CORDA-1338]: Error with VaultQuery for entity inheriting from CommonSchemaV1.FungibleState - FIX (#3025)
This commit is contained in:
parent
327f3383f9
commit
b5e8dc5bd1
@ -7,6 +7,8 @@ import net.corda.core.internal.uncheckedCast
|
|||||||
import net.corda.core.schemas.PersistentState
|
import net.corda.core.schemas.PersistentState
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
|
import kotlin.jvm.internal.CallableReference
|
||||||
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KProperty1
|
import kotlin.reflect.KProperty1
|
||||||
import kotlin.reflect.jvm.javaGetter
|
import kotlin.reflect.jvm.javaGetter
|
||||||
|
|
||||||
@ -67,8 +69,21 @@ sealed class CriteriaExpression<O, out T> {
|
|||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
class Column<O, out C>(val name: String, val declaringClass: Class<*>) {
|
class Column<O, out C>(val name: String, val declaringClass: Class<*>) {
|
||||||
|
@Deprecated("Does not support fields from a MappedSuperclass. Use the equivalent that accepts a FieldInfo.")
|
||||||
constructor(field: Field) : this(field.name, field.declaringClass)
|
constructor(field: Field) : this(field.name, field.declaringClass)
|
||||||
constructor(property: KProperty1<O, C?>) : this(property.name, property.javaGetter!!.declaringClass)
|
constructor(field: FieldInfo) : this(field.name, field.entityClass)
|
||||||
|
constructor(property: KProperty1<O, C?>) : this(property.name, declaringClass(property))
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
fun <O, C> declaringClass(property: KProperty1<O, C?>): Class<*> {
|
||||||
|
return when (property) {
|
||||||
|
// This is to ensure that, for a JPA Entity, a field declared in a MappedSuperclass will not cause Hibernate to reject a query referencing it.
|
||||||
|
// TODO remove the cast and access the owner properly after it will be exposed as Kotlin's public API (https://youtrack.jetbrains.com/issue/KT-24170).
|
||||||
|
is CallableReference -> ((property as CallableReference).owner as KClass<*>).javaObjectType
|
||||||
|
else -> property.javaGetter!!.declaringClass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
@ -217,16 +232,23 @@ object Builder {
|
|||||||
fun <R : Comparable<R>> compare(operator: BinaryComparisonOperator, value: R) = ColumnPredicate.BinaryComparison(operator, value)
|
fun <R : Comparable<R>> compare(operator: BinaryComparisonOperator, value: R) = ColumnPredicate.BinaryComparison(operator, value)
|
||||||
fun <O, R> KProperty1<O, R?>.predicate(predicate: ColumnPredicate<R>) = CriteriaExpression.ColumnPredicateExpression(Column(this), predicate)
|
fun <O, R> KProperty1<O, R?>.predicate(predicate: ColumnPredicate<R>) = CriteriaExpression.ColumnPredicateExpression(Column(this), predicate)
|
||||||
|
|
||||||
fun <R> Field.predicate(predicate: ColumnPredicate<R>) = CriteriaExpression.ColumnPredicateExpression(Column<Any, R>(this), predicate)
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R> Field.predicate(predicate: ColumnPredicate<R>) = info().predicate(predicate)
|
||||||
|
fun <R> FieldInfo.predicate(predicate: ColumnPredicate<R>) = CriteriaExpression.ColumnPredicateExpression(Column<Any, R>(this), predicate)
|
||||||
|
|
||||||
fun <O, R> KProperty1<O, R?>.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<O, R>>? = null, orderBy: Sort.Direction? = null)
|
fun <O, R> KProperty1<O, R?>.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<O, R>>? = null, orderBy: Sort.Direction? = null)
|
||||||
= CriteriaExpression.AggregateFunctionExpression(Column(this), predicate, groupByColumns, orderBy)
|
= CriteriaExpression.AggregateFunctionExpression(Column(this), predicate, groupByColumns, orderBy)
|
||||||
|
|
||||||
fun <R> Field.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<Any, R>>? = null, orderBy: Sort.Direction? = null)
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R> Field.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<Any, R>>? = null, orderBy: Sort.Direction? = null) = info().functionPredicate(predicate, groupByColumns, orderBy)
|
||||||
|
|
||||||
|
fun <R> FieldInfo.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<Any, R>>? = null, orderBy: Sort.Direction? = null)
|
||||||
= CriteriaExpression.AggregateFunctionExpression(Column<Any, R>(this), predicate, groupByColumns, orderBy)
|
= CriteriaExpression.AggregateFunctionExpression(Column<Any, R>(this), predicate, groupByColumns, orderBy)
|
||||||
|
|
||||||
fun <O, R : Comparable<R>> KProperty1<O, R?>.comparePredicate(operator: BinaryComparisonOperator, value: R) = predicate(compare(operator, value))
|
fun <O, R : Comparable<R>> KProperty1<O, R?>.comparePredicate(operator: BinaryComparisonOperator, value: R) = predicate(compare(operator, value))
|
||||||
fun <R : Comparable<R>> Field.comparePredicate(operator: BinaryComparisonOperator, value: R) = predicate(compare(operator, value))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R : Comparable<R>> Field.comparePredicate(operator: BinaryComparisonOperator, value: R) = info().comparePredicate(operator, value)
|
||||||
|
fun <R : Comparable<R>> FieldInfo.comparePredicate(operator: BinaryComparisonOperator, value: R) = predicate(compare(operator, value))
|
||||||
|
|
||||||
fun <O, R> KProperty1<O, R?>.equal(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value))
|
fun <O, R> KProperty1<O, R?>.equal(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value))
|
||||||
fun <O, R> KProperty1<O, R?>.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value))
|
fun <O, R> KProperty1<O, R?>.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value))
|
||||||
@ -239,31 +261,57 @@ object Builder {
|
|||||||
fun <O, R : Comparable<R>> KProperty1<O, R?>.notIn(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection))
|
fun <O, R : Comparable<R>> KProperty1<O, R?>.notIn(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection))
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <R> Field.equal(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R> Field.equal(value: R) = info().equal(value)
|
||||||
|
@JvmStatic
|
||||||
|
fun <R> FieldInfo.equal(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value))
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <R> Field.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R> Field.notEqual(value: R) = info().notEqual(value)
|
||||||
|
@JvmStatic
|
||||||
|
fun <R> FieldInfo.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value))
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <R : Comparable<R>> Field.lessThan(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN, value)
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R : Comparable<R>> Field.lessThan(value: R) = info().lessThan(value)
|
||||||
|
@JvmStatic
|
||||||
|
fun <R : Comparable<R>> FieldInfo.lessThan(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN, value)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <R : Comparable<R>> Field.lessThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN_OR_EQUAL, value)
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R : Comparable<R>> Field.lessThanOrEqual(value: R) = info().lessThanOrEqual(value)
|
||||||
|
@JvmStatic
|
||||||
|
fun <R : Comparable<R>> FieldInfo.lessThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN_OR_EQUAL, value)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <R : Comparable<R>> Field.greaterThan(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN, value)
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R : Comparable<R>> Field.greaterThan(value: R) = info().greaterThan(value)
|
||||||
|
@JvmStatic
|
||||||
|
fun <R : Comparable<R>> FieldInfo.greaterThan(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN, value)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <R : Comparable<R>> Field.greaterThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL, value)
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R : Comparable<R>> Field.greaterThanOrEqual(value: R) = info().greaterThanOrEqual(value)
|
||||||
|
@JvmStatic
|
||||||
|
fun <R : Comparable<R>> FieldInfo.greaterThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL, value)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <R : Comparable<R>> Field.between(from: R, to: R) = predicate(ColumnPredicate.Between(from, to))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R : Comparable<R>> Field.between(from: R, to: R) = info().between(from, to)
|
||||||
|
@JvmStatic
|
||||||
|
fun <R : Comparable<R>> FieldInfo.between(from: R, to: R) = predicate(ColumnPredicate.Between(from, to))
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <R : Comparable<R>> Field.`in`(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.IN, collection))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R : Comparable<R>> Field.`in`(collection: Collection<R>) = info().`in`(collection)
|
||||||
|
fun <R : Comparable<R>> FieldInfo.`in`(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.IN, collection))
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <R : Comparable<R>> Field.notIn(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R : Comparable<R>> Field.notIn(collection: Collection<R>) = info().notIn(collection)
|
||||||
|
@JvmStatic
|
||||||
|
fun <R : Comparable<R>> FieldInfo.notIn(collection: Collection<R>) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection))
|
||||||
|
|
||||||
fun <R> equal(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value)
|
fun <R> equal(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value)
|
||||||
fun <R> notEqual(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value)
|
fun <R> notEqual(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value)
|
||||||
@ -282,19 +330,31 @@ object Builder {
|
|||||||
|
|
||||||
fun <O> KProperty1<O, String?>.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string))
|
fun <O> KProperty1<O, String?>.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun Field.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun Field.like(string: String) = info().like(string)
|
||||||
|
@JvmStatic
|
||||||
|
fun FieldInfo.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string))
|
||||||
|
|
||||||
fun <O> KProperty1<O, String?>.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string))
|
fun <O> KProperty1<O, String?>.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun Field.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun Field.notLike(string: String) = info().notLike(string)
|
||||||
|
@JvmStatic
|
||||||
|
fun FieldInfo.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string))
|
||||||
|
|
||||||
fun <O, R> KProperty1<O, R?>.isNull() = predicate(ColumnPredicate.NullExpression(NullOperator.IS_NULL))
|
fun <O, R> KProperty1<O, R?>.isNull() = predicate(ColumnPredicate.NullExpression(NullOperator.IS_NULL))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun Field.isNull() = predicate(ColumnPredicate.NullExpression<Any>(NullOperator.IS_NULL))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun Field.isNull() = info().isNull()
|
||||||
|
@JvmStatic
|
||||||
|
fun FieldInfo.isNull() = predicate(ColumnPredicate.NullExpression<Any>(NullOperator.IS_NULL))
|
||||||
|
|
||||||
fun <O, R> KProperty1<O, R?>.notNull() = predicate(ColumnPredicate.NullExpression(NullOperator.NOT_NULL))
|
fun <O, R> KProperty1<O, R?>.notNull() = predicate(ColumnPredicate.NullExpression(NullOperator.NOT_NULL))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun Field.notNull() = predicate(ColumnPredicate.NullExpression<Any>(NullOperator.NOT_NULL))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun Field.notNull() = info().notNull()
|
||||||
|
@JvmStatic
|
||||||
|
fun FieldInfo.notNull() = predicate(ColumnPredicate.NullExpression<Any>(NullOperator.NOT_NULL))
|
||||||
|
|
||||||
/** aggregate functions */
|
/** aggregate functions */
|
||||||
fun <O, R> KProperty1<O, R?>.sum(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
|
fun <O, R> KProperty1<O, R?>.sum(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
|
||||||
@ -302,19 +362,31 @@ object Builder {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun <R> Field.sum(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R> Field.sum(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) = info().sum<R>(groupByColumns?.map { it.info() }, orderBy)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun <R> FieldInfo.sum(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) =
|
||||||
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.SUM), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
|
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.SUM), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
|
||||||
|
|
||||||
fun <O, R> KProperty1<O, R?>.count() = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.COUNT))
|
fun <O, R> KProperty1<O, R?>.count() = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.COUNT))
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun Field.count() = functionPredicate(ColumnPredicate.AggregateFunction<Any>(AggregateFunctionType.COUNT))
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun Field.count() = info().count()
|
||||||
|
@JvmStatic
|
||||||
|
fun FieldInfo.count() = functionPredicate(ColumnPredicate.AggregateFunction<Any>(AggregateFunctionType.COUNT))
|
||||||
|
|
||||||
fun <O, R> KProperty1<O, R?>.avg(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
|
fun <O, R> KProperty1<O, R?>.avg(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
|
||||||
functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.AVG), groupByColumns?.map { Column(it) }, orderBy)
|
functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.AVG), groupByColumns?.map { Column(it) }, orderBy)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun <R> Field.avg(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R> Field.avg(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) = info().avg<R>(groupByColumns?.map { it.info() }, orderBy)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun <R> FieldInfo.avg(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) =
|
||||||
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.AVG), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
|
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.AVG), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
|
||||||
|
|
||||||
fun <O, R> KProperty1<O, R?>.min(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
|
fun <O, R> KProperty1<O, R?>.min(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
|
||||||
@ -322,7 +394,12 @@ object Builder {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun <R> Field.min(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R> Field.min(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) = info().min<R>(groupByColumns?.map { it.info() }, orderBy)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun <R> FieldInfo.min(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) =
|
||||||
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MIN), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
|
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MIN), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
|
||||||
|
|
||||||
fun <O, R> KProperty1<O, R?>.max(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
|
fun <O, R> KProperty1<O, R?>.max(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
|
||||||
@ -330,8 +407,50 @@ object Builder {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun <R> Field.max(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) =
|
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
|
||||||
|
fun <R> Field.max(groupByColumns: List<Field>? = null, orderBy: Sort.Direction? = null) = info().max<R>(groupByColumns?.map { it.info() }, orderBy)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun <R> FieldInfo.max(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) =
|
||||||
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MAX), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
|
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MAX), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
|
||||||
|
|
||||||
|
private fun Field.info(): FieldInfo = FieldInfo(name, declaringClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <A> builder(block: Builder.() -> A) = block(Builder)
|
inline fun <A> builder(block: Builder.() -> A) = block(Builder)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains information about a field from an entity class.
|
||||||
|
* Used as part of query criteria construction through [Builder], produced by function [getField].
|
||||||
|
* The constructor should not be invoked manually.
|
||||||
|
*
|
||||||
|
* @param name field name
|
||||||
|
* @param entityClass JPA entity class for the query
|
||||||
|
*/
|
||||||
|
class FieldInfo internal constructor(val name: String, val entityClass: Class<*>)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a [FieldInfo] for field with name [fieldName] in [entityClass].
|
||||||
|
*
|
||||||
|
* @param fieldName name of the field
|
||||||
|
* @param entityClass JPA entity class containing the field
|
||||||
|
* @throws NoSuchFieldException if no field with name [fieldName] is found in the class hierarchy of [entityClass]
|
||||||
|
*/
|
||||||
|
@Throws(NoSuchFieldException::class)
|
||||||
|
fun getField(fieldName: String, entityClass: Class<*>): FieldInfo {
|
||||||
|
return getField(fieldName, entityClass, entityClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(NoSuchFieldException::class)
|
||||||
|
private fun getField(fieldName: String, clazz: Class<*>?, invokingClazz: Class<*>): FieldInfo {
|
||||||
|
if (clazz == null) {
|
||||||
|
throw NoSuchFieldException(fieldName)
|
||||||
|
}
|
||||||
|
return try {
|
||||||
|
val field = clazz.getDeclaredField(fieldName)
|
||||||
|
return FieldInfo(field.name, invokingClazz)
|
||||||
|
} catch (e: NoSuchFieldException) {
|
||||||
|
getField(fieldName, clazz.superclass, invokingClazz)
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,8 @@ Unreleased
|
|||||||
|
|
||||||
* Refactor RPC Server Kryo observable serializer into it's own sub module
|
* Refactor RPC Server Kryo observable serializer into it's own sub module
|
||||||
|
|
||||||
|
* The Vault Criteria API has been extended to take a more precise specification of which class contains a field. This primarily impacts Java users; Kotlin users need take no action. The old methods have been deprecated but still work - the new methods avoid bugs that can occur when JPA schemas inherit from each other.
|
||||||
|
|
||||||
* Refactor RPC Client Kryo observable serializer into it's own sub module
|
* Refactor RPC Client Kryo observable serializer into it's own sub module
|
||||||
|
|
||||||
* Fix CORDA-1403 where a property of a class that implemented a generic interface could not be deserialized in
|
* Fix CORDA-1403 where a property of a class that implemented a generic interface could not be deserialized in
|
||||||
|
@ -50,12 +50,12 @@ class DummyFungibleContract : OnLedgerAsset<Currency, DummyFungibleContract.Comm
|
|||||||
issuerRef = this.amount.token.issuer.reference.bytes
|
issuerRef = this.amount.token.issuer.reference.bytes
|
||||||
)
|
)
|
||||||
is SampleCashSchemaV2 -> SampleCashSchemaV2.PersistentCashState(
|
is SampleCashSchemaV2 -> SampleCashSchemaV2.PersistentCashState(
|
||||||
_participants = this.participants.toMutableSet(),
|
participants = this.participants.toMutableSet(),
|
||||||
_owner = this.owner,
|
owner = this.owner,
|
||||||
_quantity = this.amount.quantity,
|
quantity = this.amount.quantity,
|
||||||
currency = this.amount.token.product.currencyCode,
|
currency = this.amount.token.product.currencyCode,
|
||||||
_issuerParty = this.amount.token.issuer.party,
|
issuerParty = this.amount.token.issuer.party,
|
||||||
_issuerRef = this.amount.token.issuer.reference
|
issuerRef = this.amount.token.issuer.reference
|
||||||
)
|
)
|
||||||
is SampleCashSchemaV3 -> SampleCashSchemaV3.PersistentCashState(
|
is SampleCashSchemaV3 -> SampleCashSchemaV3.PersistentCashState(
|
||||||
participants = this.participants.toMutableSet(),
|
participants = this.participants.toMutableSet(),
|
||||||
|
@ -7,37 +7,26 @@ import net.corda.core.utilities.OpaqueBytes
|
|||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Second version of a cash contract ORM schema that extends the common
|
* Second version of a cash contract ORM schema that extends the [CommonSchemaV1.FungibleState] abstract schema.
|
||||||
* [VaultFungibleState] abstract schema
|
|
||||||
*/
|
*/
|
||||||
object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 2,
|
object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 2,
|
||||||
mappedTypes = listOf(PersistentCashState::class.java)) {
|
mappedTypes = listOf(PersistentCashState::class.java)) {
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "cash_states_v2",
|
@Table(name = "cash_states_v2", indexes = [Index(name = "ccy_code_idx2", columnList = "ccy_code")])
|
||||||
indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code")))
|
|
||||||
class PersistentCashState(
|
class PersistentCashState(
|
||||||
|
|
||||||
@ElementCollection
|
|
||||||
@Column(name = "participants")
|
|
||||||
@CollectionTable(name="cash_states_v2_participants", joinColumns = arrayOf(
|
|
||||||
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
|
|
||||||
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")))
|
|
||||||
override var participants: MutableSet<AbstractParty>? = null,
|
|
||||||
|
|
||||||
/** product type */
|
/** product type */
|
||||||
@Column(name = "ccy_code", length = 3)
|
@Column(name = "ccy_code", length = 3)
|
||||||
var currency: String,
|
var currency: String,
|
||||||
|
participants: Set<AbstractParty>,
|
||||||
|
owner: AbstractParty,
|
||||||
|
quantity: Long,
|
||||||
|
issuerParty: AbstractParty,
|
||||||
|
issuerRef: OpaqueBytes
|
||||||
|
) : CommonSchemaV1.FungibleState(participants.toMutableSet(), owner, quantity, issuerParty, issuerRef.bytes) {
|
||||||
|
|
||||||
/** parent attributes */
|
@ElementCollection
|
||||||
@Transient
|
@Column(name = "participants")
|
||||||
val _participants: Set<AbstractParty>,
|
@CollectionTable(name="cash_states_v2_participants", joinColumns = [JoinColumn(name = "output_index", referencedColumnName = "output_index"), JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")])
|
||||||
@Transient
|
override var participants: MutableSet<AbstractParty>? = null
|
||||||
val _owner: AbstractParty,
|
}
|
||||||
@Transient
|
|
||||||
val _quantity: Long,
|
|
||||||
@Transient
|
|
||||||
val _issuerParty: AbstractParty,
|
|
||||||
@Transient
|
|
||||||
val _issuerRef: OpaqueBytes
|
|
||||||
) : CommonSchemaV1.FungibleState(_participants.toMutableSet(), _owner, _quantity, _issuerParty, _issuerRef.bytes)
|
|
||||||
}
|
}
|
||||||
|
@ -18,17 +18,8 @@ object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPap
|
|||||||
mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
|
mappedTypes = listOf(PersistentCommercialPaperState::class.java)) {
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "cp_states_v2",
|
@Table(name = "cp_states_v2",
|
||||||
indexes = arrayOf(Index(name = "ccy_code_index2", columnList = "ccy_code"),
|
indexes = [Index(name = "ccy_code_index2", columnList = "ccy_code"), Index(name = "maturity_index2", columnList = "maturity_instant")])
|
||||||
Index(name = "maturity_index2", columnList = "maturity_instant")))
|
|
||||||
class PersistentCommercialPaperState(
|
class PersistentCommercialPaperState(
|
||||||
|
|
||||||
@ElementCollection
|
|
||||||
@Column(name = "participants")
|
|
||||||
@CollectionTable(name="cp_states_v2_participants", joinColumns = arrayOf(
|
|
||||||
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
|
|
||||||
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")))
|
|
||||||
override var participants: MutableSet<AbstractParty>? = null,
|
|
||||||
|
|
||||||
@Column(name = "maturity_instant")
|
@Column(name = "maturity_instant")
|
||||||
var maturity: Instant,
|
var maturity: Instant,
|
||||||
|
|
||||||
@ -42,17 +33,16 @@ object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPap
|
|||||||
@Type(type = "corda-wrapper-binary")
|
@Type(type = "corda-wrapper-binary")
|
||||||
var faceValueIssuerRef: ByteArray,
|
var faceValueIssuerRef: ByteArray,
|
||||||
|
|
||||||
/** parent attributes */
|
participants: Set<AbstractParty>,
|
||||||
@Transient
|
owner: AbstractParty,
|
||||||
val _participants: Set<AbstractParty>,
|
quantity: Long,
|
||||||
@Transient
|
issuerParty: AbstractParty,
|
||||||
val _owner: AbstractParty,
|
issuerRef: OpaqueBytes
|
||||||
@Transient
|
) : CommonSchemaV1.FungibleState(participants.toMutableSet(), owner, quantity, issuerParty, issuerRef.bytes) {
|
||||||
// face value
|
|
||||||
val _quantity: Long,
|
@ElementCollection
|
||||||
@Transient
|
@Column(name = "participants")
|
||||||
val _issuerParty: AbstractParty,
|
@CollectionTable(name = "cp_states_v2_participants", joinColumns = [JoinColumn(name = "output_index", referencedColumnName = "output_index"), JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")])
|
||||||
@Transient
|
override var participants: MutableSet<AbstractParty>? = null
|
||||||
val _issuerRef: OpaqueBytes
|
}
|
||||||
) : CommonSchemaV1.FungibleState(_participants.toMutableSet(), _owner, _quantity, _issuerParty, _issuerRef.bytes)
|
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
e.message?.let { message ->
|
e.message?.let { message ->
|
||||||
if (message.contains("Not an entity"))
|
if (message.contains("Not an entity"))
|
||||||
throw VaultQueryException("""
|
throw VaultQueryException("""
|
||||||
Please register the entity '${entityClass.name.substringBefore('$')}'
|
Please register the entity '${entityClass.name}'
|
||||||
See https://docs.corda.net/api-persistence.html#custom-schema-registration for more information""")
|
See https://docs.corda.net/api-persistence.html#custom-schema-registration for more information""")
|
||||||
}
|
}
|
||||||
throw VaultQueryException("Parsing error: ${e.message}")
|
throw VaultQueryException("Parsing error: ${e.message}")
|
||||||
|
@ -20,6 +20,7 @@ import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria;
|
|||||||
import net.corda.finance.contracts.DealState;
|
import net.corda.finance.contracts.DealState;
|
||||||
import net.corda.finance.contracts.asset.Cash;
|
import net.corda.finance.contracts.asset.Cash;
|
||||||
import net.corda.finance.schemas.CashSchemaV1;
|
import net.corda.finance.schemas.CashSchemaV1;
|
||||||
|
import net.corda.finance.schemas.SampleCashSchemaV2;
|
||||||
import net.corda.node.services.api.IdentityServiceInternal;
|
import net.corda.node.services.api.IdentityServiceInternal;
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence;
|
import net.corda.nodeapi.internal.persistence.CordaPersistence;
|
||||||
import net.corda.nodeapi.internal.persistence.DatabaseTransaction;
|
import net.corda.nodeapi.internal.persistence.DatabaseTransaction;
|
||||||
@ -35,7 +36,6 @@ import org.junit.Test;
|
|||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -43,13 +43,13 @@ import java.util.stream.Collectors;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import static net.corda.core.node.services.vault.QueryCriteriaUtils.DEFAULT_PAGE_NUM;
|
import static java.util.Arrays.asList;
|
||||||
import static net.corda.core.node.services.vault.QueryCriteriaUtils.MAX_PAGE_SIZE;
|
import static java.util.Collections.singletonList;
|
||||||
|
import static net.corda.core.node.services.vault.Builder.sum;
|
||||||
|
import static net.corda.core.node.services.vault.QueryCriteriaUtils.*;
|
||||||
import static net.corda.core.utilities.ByteArrays.toHexString;
|
import static net.corda.core.utilities.ByteArrays.toHexString;
|
||||||
|
import static net.corda.testing.core.TestConstants.*;
|
||||||
import static net.corda.testing.internal.InternalTestUtilsKt.rigorousMock;
|
import static net.corda.testing.internal.InternalTestUtilsKt.rigorousMock;
|
||||||
import static net.corda.testing.core.TestConstants.BOC_NAME;
|
|
||||||
import static net.corda.testing.core.TestConstants.CHARLIE_NAME;
|
|
||||||
import static net.corda.testing.core.TestConstants.DUMMY_NOTARY_NAME;
|
|
||||||
import static net.corda.testing.node.MockServices.makeTestDatabaseAndMockServices;
|
import static net.corda.testing.node.MockServices.makeTestDatabaseAndMockServices;
|
||||||
import static net.corda.testing.node.MockServicesKt.makeTestIdentityService;
|
import static net.corda.testing.node.MockServicesKt.makeTestIdentityService;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@ -70,7 +70,7 @@ public class VaultQueryJavaTests {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws CertificateException, InvalidAlgorithmParameterException {
|
public void setUp() throws CertificateException, InvalidAlgorithmParameterException {
|
||||||
List<String> cordappPackages = Arrays.asList("net.corda.testing.internal.vault", "net.corda.finance.contracts.asset", CashSchemaV1.class.getPackage().getName());
|
List<String> cordappPackages = asList("net.corda.testing.internal.vault", "net.corda.finance.contracts.asset", CashSchemaV1.class.getPackage().getName());
|
||||||
IdentityService identitySvc = makeTestIdentityService(MEGA_CORP.getIdentity(), DUMMY_CASH_ISSUER_INFO.getIdentity(), DUMMY_NOTARY.getIdentity());
|
IdentityService identitySvc = makeTestIdentityService(MEGA_CORP.getIdentity(), DUMMY_CASH_ISSUER_INFO.getIdentity(), DUMMY_NOTARY.getIdentity());
|
||||||
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(
|
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(
|
||||||
cordappPackages,
|
cordappPackages,
|
||||||
@ -97,6 +97,29 @@ public class VaultQueryJavaTests {
|
|||||||
* Static queryBy() tests
|
* Static queryBy() tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void criteriaWithFieldFromMappedSuperclass() throws NoSuchFieldException {
|
||||||
|
FieldInfo quantity = getField("quantity", SampleCashSchemaV2.PersistentCashState.class);
|
||||||
|
FieldInfo currency = getField("currency", SampleCashSchemaV2.PersistentCashState.class);
|
||||||
|
|
||||||
|
CriteriaExpression.AggregateFunctionExpression<Object, Boolean> expression = sum(quantity, singletonList(currency), Sort.Direction.ASC);
|
||||||
|
VaultCustomQueryCriteria<SampleCashSchemaV2.PersistentCashState> criteria = new VaultCustomQueryCriteria(expression, Vault.StateStatus.UNCONSUMED, null);
|
||||||
|
|
||||||
|
database.transaction(tx -> vaultService.queryBy(FungibleAsset.class, criteria));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void criteriaWithFieldFromMappedSuperclassOfSuperclass() throws NoSuchFieldException {
|
||||||
|
FieldInfo quantity = getField("quantity", SampleCashSchemaV2.PersistentCashState.class);
|
||||||
|
FieldInfo currency = getField("currency", SampleCashSchemaV2.PersistentCashState.class);
|
||||||
|
FieldInfo stateRef = getField("stateRef", SampleCashSchemaV2.PersistentCashState.class);
|
||||||
|
|
||||||
|
CriteriaExpression.AggregateFunctionExpression<Object, Boolean> expression = sum(quantity, asList(currency, stateRef), Sort.Direction.ASC);
|
||||||
|
VaultCustomQueryCriteria<SampleCashSchemaV2.PersistentCashState> criteria = new VaultCustomQueryCriteria(expression, Vault.StateStatus.UNCONSUMED, null);
|
||||||
|
|
||||||
|
database.transaction(tx -> vaultService.queryBy(FungibleAsset.class, criteria));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unconsumedLinearStates() throws VaultQueryException {
|
public void unconsumedLinearStates() throws VaultQueryException {
|
||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
@ -126,7 +149,7 @@ public class VaultQueryJavaTests {
|
|||||||
List<StateRef> stateRefs = stateRefsStream.collect(Collectors.toList());
|
List<StateRef> stateRefs = stateRefsStream.collect(Collectors.toList());
|
||||||
|
|
||||||
SortAttribute.Standard sortAttribute = new SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_TXN_ID);
|
SortAttribute.Standard sortAttribute = new SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_TXN_ID);
|
||||||
Sort sorting = new Sort(Collections.singletonList(new Sort.SortColumn(sortAttribute, Sort.Direction.ASC)));
|
Sort sorting = new Sort(singletonList(new Sort.SortColumn(sortAttribute, Sort.Direction.ASC)));
|
||||||
VaultQueryCriteria criteria = new VaultQueryCriteria(Vault.StateStatus.UNCONSUMED, null, stateRefs);
|
VaultQueryCriteria criteria = new VaultQueryCriteria(Vault.StateStatus.UNCONSUMED, null, stateRefs);
|
||||||
Vault.Page<DummyLinearContract.State> results = vaultService.queryBy(DummyLinearContract.State.class, criteria, sorting);
|
Vault.Page<DummyLinearContract.State> results = vaultService.queryBy(DummyLinearContract.State.class, criteria, sorting);
|
||||||
|
|
||||||
@ -171,7 +194,7 @@ public class VaultQueryJavaTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void consumedDealStatesPagedSorted() throws VaultQueryException {
|
public void consumedDealStatesPagedSorted() throws VaultQueryException {
|
||||||
List<String> dealIds = Arrays.asList("123", "456", "789");
|
List<String> dealIds = asList("123", "456", "789");
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Triple<StateAndRef<LinearState>, UniqueIdentifier, Vault<DealState>> ids =
|
Triple<StateAndRef<LinearState>, UniqueIdentifier, Vault<DealState>> ids =
|
||||||
database.transaction((DatabaseTransaction tx) -> {
|
database.transaction((DatabaseTransaction tx) -> {
|
||||||
@ -184,18 +207,18 @@ public class VaultQueryJavaTests {
|
|||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
// consume states
|
// consume states
|
||||||
vaultFiller.consumeDeals((List<? extends StateAndRef<? extends DealState>>) ids.getThird().getStates());
|
vaultFiller.consumeDeals((List<? extends StateAndRef<? extends DealState>>) ids.getThird().getStates());
|
||||||
vaultFiller.consumeLinearStates(Collections.singletonList(ids.getFirst()));
|
vaultFiller.consumeLinearStates(singletonList(ids.getFirst()));
|
||||||
return tx;
|
return tx;
|
||||||
});
|
});
|
||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
// DOCSTART VaultJavaQueryExample2
|
// DOCSTART VaultJavaQueryExample2
|
||||||
Vault.StateStatus status = Vault.StateStatus.CONSUMED;
|
Vault.StateStatus status = Vault.StateStatus.CONSUMED;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<Class<LinearState>> contractStateTypes = new HashSet(Collections.singletonList(LinearState.class));
|
Set<Class<LinearState>> contractStateTypes = new HashSet(singletonList(LinearState.class));
|
||||||
|
|
||||||
QueryCriteria vaultCriteria = new VaultQueryCriteria(status, contractStateTypes);
|
QueryCriteria vaultCriteria = new VaultQueryCriteria(status, contractStateTypes);
|
||||||
|
|
||||||
List<UniqueIdentifier> linearIds = Collections.singletonList(ids.getSecond());
|
List<UniqueIdentifier> linearIds = singletonList(ids.getSecond());
|
||||||
QueryCriteria linearCriteriaAll = new LinearStateQueryCriteria(null, linearIds, Vault.StateStatus.UNCONSUMED, null);
|
QueryCriteria linearCriteriaAll = new LinearStateQueryCriteria(null, linearIds, Vault.StateStatus.UNCONSUMED, null);
|
||||||
QueryCriteria dealCriteriaAll = new LinearStateQueryCriteria(null, null, dealIds);
|
QueryCriteria dealCriteriaAll = new LinearStateQueryCriteria(null, null, dealIds);
|
||||||
|
|
||||||
@ -234,8 +257,8 @@ public class VaultQueryJavaTests {
|
|||||||
// DOCSTART VaultJavaQueryExample3
|
// DOCSTART VaultJavaQueryExample3
|
||||||
QueryCriteria generalCriteria = new VaultQueryCriteria(Vault.StateStatus.ALL);
|
QueryCriteria generalCriteria = new VaultQueryCriteria(Vault.StateStatus.ALL);
|
||||||
|
|
||||||
Field attributeCurrency = CashSchemaV1.PersistentCashState.class.getDeclaredField("currency");
|
FieldInfo attributeCurrency = getField("currency", CashSchemaV1.PersistentCashState.class);
|
||||||
Field attributeQuantity = CashSchemaV1.PersistentCashState.class.getDeclaredField("pennies");
|
FieldInfo attributeQuantity = getField("pennies", CashSchemaV1.PersistentCashState.class);
|
||||||
|
|
||||||
CriteriaExpression currencyIndex = Builder.equal(attributeCurrency, "USD");
|
CriteriaExpression currencyIndex = Builder.equal(attributeCurrency, "USD");
|
||||||
CriteriaExpression quantityIndex = Builder.greaterThanOrEqual(attributeQuantity, 10L);
|
CriteriaExpression quantityIndex = Builder.greaterThanOrEqual(attributeQuantity, 10L);
|
||||||
@ -275,7 +298,7 @@ public class VaultQueryJavaTests {
|
|||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
// DOCSTART VaultJavaQueryExample4
|
// DOCSTART VaultJavaQueryExample4
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<Class<ContractState>> contractStateTypes = new HashSet(Collections.singletonList(Cash.State.class));
|
Set<Class<ContractState>> contractStateTypes = new HashSet(singletonList(Cash.State.class));
|
||||||
|
|
||||||
VaultQueryCriteria criteria = new VaultQueryCriteria(Vault.StateStatus.UNCONSUMED, contractStateTypes);
|
VaultQueryCriteria criteria = new VaultQueryCriteria(Vault.StateStatus.UNCONSUMED, contractStateTypes);
|
||||||
DataFeed<Vault.Page<ContractState>, Vault.Update<ContractState>> results = vaultService.trackBy(ContractState.class, criteria);
|
DataFeed<Vault.Page<ContractState>, Vault.Update<ContractState>> results = vaultService.trackBy(ContractState.class, criteria);
|
||||||
@ -292,7 +315,7 @@ public class VaultQueryJavaTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void trackDealStatesPagedSorted() {
|
public void trackDealStatesPagedSorted() {
|
||||||
List<String> dealIds = Arrays.asList("123", "456", "789");
|
List<String> dealIds = asList("123", "456", "789");
|
||||||
UniqueIdentifier uid =
|
UniqueIdentifier uid =
|
||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
Vault<LinearState> states = vaultFiller.fillWithSomeTestLinearStates(10, null);
|
Vault<LinearState> states = vaultFiller.fillWithSomeTestLinearStates(10, null);
|
||||||
@ -303,11 +326,11 @@ public class VaultQueryJavaTests {
|
|||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
// DOCSTART VaultJavaQueryExample5
|
// DOCSTART VaultJavaQueryExample5
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<Class<ContractState>> contractStateTypes = new HashSet(Arrays.asList(DealState.class, LinearState.class));
|
Set<Class<ContractState>> contractStateTypes = new HashSet(asList(DealState.class, LinearState.class));
|
||||||
QueryCriteria vaultCriteria = new VaultQueryCriteria(Vault.StateStatus.UNCONSUMED, contractStateTypes);
|
QueryCriteria vaultCriteria = new VaultQueryCriteria(Vault.StateStatus.UNCONSUMED, contractStateTypes);
|
||||||
|
|
||||||
List<UniqueIdentifier> linearIds = Collections.singletonList(uid);
|
List<UniqueIdentifier> linearIds = singletonList(uid);
|
||||||
List<AbstractParty> dealParty = Collections.singletonList(MEGA_CORP.getParty());
|
List<AbstractParty> dealParty = singletonList(MEGA_CORP.getParty());
|
||||||
QueryCriteria dealCriteria = new LinearStateQueryCriteria(dealParty, null, dealIds);
|
QueryCriteria dealCriteria = new LinearStateQueryCriteria(dealParty, null, dealIds);
|
||||||
QueryCriteria linearCriteria = new LinearStateQueryCriteria(dealParty, linearIds, Vault.StateStatus.UNCONSUMED, null);
|
QueryCriteria linearCriteria = new LinearStateQueryCriteria(dealParty, linearIds, Vault.StateStatus.UNCONSUMED, null);
|
||||||
QueryCriteria dealOrLinearIdCriteria = dealCriteria.or(linearCriteria);
|
QueryCriteria dealOrLinearIdCriteria = dealCriteria.or(linearCriteria);
|
||||||
@ -351,9 +374,9 @@ public class VaultQueryJavaTests {
|
|||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
try {
|
try {
|
||||||
// DOCSTART VaultJavaQueryExample21
|
// DOCSTART VaultJavaQueryExample21
|
||||||
Field pennies = CashSchemaV1.PersistentCashState.class.getDeclaredField("pennies");
|
FieldInfo pennies = getField("pennies", CashSchemaV1.PersistentCashState.class);
|
||||||
|
|
||||||
QueryCriteria sumCriteria = new VaultCustomQueryCriteria(Builder.sum(pennies));
|
QueryCriteria sumCriteria = new VaultCustomQueryCriteria(sum(pennies));
|
||||||
QueryCriteria countCriteria = new VaultCustomQueryCriteria(Builder.count(pennies));
|
QueryCriteria countCriteria = new VaultCustomQueryCriteria(Builder.count(pennies));
|
||||||
QueryCriteria maxCriteria = new VaultCustomQueryCriteria(Builder.max(pennies));
|
QueryCriteria maxCriteria = new VaultCustomQueryCriteria(Builder.max(pennies));
|
||||||
QueryCriteria minCriteria = new VaultCustomQueryCriteria(Builder.min(pennies));
|
QueryCriteria minCriteria = new VaultCustomQueryCriteria(Builder.min(pennies));
|
||||||
@ -397,14 +420,14 @@ public class VaultQueryJavaTests {
|
|||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
try {
|
try {
|
||||||
// DOCSTART VaultJavaQueryExample22
|
// DOCSTART VaultJavaQueryExample22
|
||||||
Field pennies = CashSchemaV1.PersistentCashState.class.getDeclaredField("pennies");
|
FieldInfo pennies = getField("pennies", CashSchemaV1.PersistentCashState.class);
|
||||||
Field currency = CashSchemaV1.PersistentCashState.class.getDeclaredField("currency");
|
FieldInfo currency = getField("currency", CashSchemaV1.PersistentCashState.class);
|
||||||
|
|
||||||
QueryCriteria sumCriteria = new VaultCustomQueryCriteria(Builder.sum(pennies, Collections.singletonList(currency)));
|
QueryCriteria sumCriteria = new VaultCustomQueryCriteria(sum(pennies, singletonList(currency)));
|
||||||
QueryCriteria countCriteria = new VaultCustomQueryCriteria(Builder.count(pennies));
|
QueryCriteria countCriteria = new VaultCustomQueryCriteria(Builder.count(pennies));
|
||||||
QueryCriteria maxCriteria = new VaultCustomQueryCriteria(Builder.max(pennies, Collections.singletonList(currency)));
|
QueryCriteria maxCriteria = new VaultCustomQueryCriteria(Builder.max(pennies, singletonList(currency)));
|
||||||
QueryCriteria minCriteria = new VaultCustomQueryCriteria(Builder.min(pennies, Collections.singletonList(currency)));
|
QueryCriteria minCriteria = new VaultCustomQueryCriteria(Builder.min(pennies, singletonList(currency)));
|
||||||
QueryCriteria avgCriteria = new VaultCustomQueryCriteria(Builder.avg(pennies, Collections.singletonList(currency)));
|
QueryCriteria avgCriteria = new VaultCustomQueryCriteria(Builder.avg(pennies, singletonList(currency)));
|
||||||
|
|
||||||
QueryCriteria criteria = sumCriteria.and(countCriteria).and(maxCriteria).and(minCriteria).and(avgCriteria);
|
QueryCriteria criteria = sumCriteria.and(countCriteria).and(maxCriteria).and(minCriteria).and(avgCriteria);
|
||||||
Vault.Page<Cash.State> results = vaultService.queryBy(Cash.State.class, criteria);
|
Vault.Page<Cash.State> results = vaultService.queryBy(Cash.State.class, criteria);
|
||||||
@ -457,10 +480,10 @@ public class VaultQueryJavaTests {
|
|||||||
database.transaction(tx -> {
|
database.transaction(tx -> {
|
||||||
try {
|
try {
|
||||||
// DOCSTART VaultJavaQueryExample23
|
// DOCSTART VaultJavaQueryExample23
|
||||||
Field pennies = CashSchemaV1.PersistentCashState.class.getDeclaredField("pennies");
|
FieldInfo pennies = getField("pennies", CashSchemaV1.PersistentCashState.class);
|
||||||
Field currency = CashSchemaV1.PersistentCashState.class.getDeclaredField("currency");
|
FieldInfo currency = getField("currency", CashSchemaV1.PersistentCashState.class);
|
||||||
Field issuerPartyHash = CashSchemaV1.PersistentCashState.class.getDeclaredField("issuerPartyHash");
|
FieldInfo issuerPartyHash = getField("issuerPartyHash", CashSchemaV1.PersistentCashState.class);
|
||||||
QueryCriteria sumCriteria = new VaultCustomQueryCriteria(Builder.sum(pennies, Arrays.asList(issuerPartyHash, currency), Sort.Direction.DESC));
|
QueryCriteria sumCriteria = new VaultCustomQueryCriteria(sum(pennies, asList(issuerPartyHash, currency), Sort.Direction.DESC));
|
||||||
Vault.Page<Cash.State> results = vaultService.queryBy(Cash.State.class, sumCriteria);
|
Vault.Page<Cash.State> results = vaultService.queryBy(Cash.State.class, sumCriteria);
|
||||||
// DOCEND VaultJavaQueryExample23
|
// DOCEND VaultJavaQueryExample23
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import net.corda.finance.contracts.asset.cash.selection.AbstractCashSelection
|
|||||||
import net.corda.finance.schemas.CashSchemaV1
|
import net.corda.finance.schemas.CashSchemaV1
|
||||||
import net.corda.finance.schemas.CashSchemaV1.PersistentCashState
|
import net.corda.finance.schemas.CashSchemaV1.PersistentCashState
|
||||||
import net.corda.finance.schemas.CommercialPaperSchemaV1
|
import net.corda.finance.schemas.CommercialPaperSchemaV1
|
||||||
|
import net.corda.finance.schemas.SampleCashSchemaV2
|
||||||
import net.corda.finance.schemas.SampleCashSchemaV3
|
import net.corda.finance.schemas.SampleCashSchemaV3
|
||||||
import net.corda.node.internal.configureDatabase
|
import net.corda.node.internal.configureDatabase
|
||||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||||
@ -29,12 +30,18 @@ import net.corda.nodeapi.internal.persistence.DatabaseTransaction
|
|||||||
import net.corda.testing.core.*
|
import net.corda.testing.core.*
|
||||||
import net.corda.testing.internal.TEST_TX_TIME
|
import net.corda.testing.internal.TEST_TX_TIME
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import net.corda.testing.internal.vault.*
|
import net.corda.testing.internal.vault.DUMMY_LINEAR_CONTRACT_PROGRAM_ID
|
||||||
|
import net.corda.testing.internal.vault.DummyLinearContract
|
||||||
|
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1
|
||||||
|
import net.corda.testing.internal.vault.VaultFiller
|
||||||
import net.corda.testing.node.MockServices
|
import net.corda.testing.node.MockServices
|
||||||
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseAndMockServices
|
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseAndMockServices
|
||||||
import net.corda.testing.node.makeTestIdentityService
|
import net.corda.testing.node.makeTestIdentityService
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.*
|
import org.junit.ClassRule
|
||||||
|
import org.junit.Ignore
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
import org.junit.rules.ExpectedException
|
import org.junit.rules.ExpectedException
|
||||||
import org.junit.rules.ExternalResource
|
import org.junit.rules.ExternalResource
|
||||||
import java.lang.Thread.sleep
|
import java.lang.Thread.sleep
|
||||||
@ -229,6 +236,34 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
|
|||||||
/** Generic Query tests
|
/** Generic Query tests
|
||||||
(combining both FungibleState and LinearState contract types) */
|
(combining both FungibleState and LinearState contract types) */
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `criteria with field from mapped superclass`() {
|
||||||
|
database.transaction {
|
||||||
|
val expression = builder {
|
||||||
|
SampleCashSchemaV2.PersistentCashState::quantity.sum(
|
||||||
|
groupByColumns = listOf(SampleCashSchemaV2.PersistentCashState::currency),
|
||||||
|
orderBy = Sort.Direction.ASC
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val criteria = VaultCustomQueryCriteria(expression)
|
||||||
|
vaultService.queryBy<FungibleAsset<*>>(criteria)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `criteria with field from mapped superclass of superclass`() {
|
||||||
|
database.transaction {
|
||||||
|
val expression = builder {
|
||||||
|
SampleCashSchemaV2.PersistentCashState::quantity.sum(
|
||||||
|
groupByColumns = listOf(SampleCashSchemaV2.PersistentCashState::currency, SampleCashSchemaV2.PersistentCashState::stateRef),
|
||||||
|
orderBy = Sort.Direction.ASC
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val criteria = VaultCustomQueryCriteria(expression)
|
||||||
|
vaultService.queryBy<FungibleAsset<*>>(criteria)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `unconsumed states simple`() {
|
fun `unconsumed states simple`() {
|
||||||
database.transaction {
|
database.transaction {
|
||||||
|
Loading…
Reference in New Issue
Block a user