diff --git a/pom.xml b/pom.xml index ab062bae1..c3bfd3b32 100644 --- a/pom.xml +++ b/pom.xml @@ -231,13 +231,13 @@ 10 false - **/test/unit/**/*.java - **/*UnitTests.java + **/test/unit/**/* + **/*UnitTests **/test/integration/**/*.java - **/**IntegrationTests.java - **/test/performance/**/*.java + **/**IntegrationTests + **/test/performance/**/* src/test/resources/logging.properties @@ -253,13 +253,13 @@ true false - **/test/integration/**/*.java - **/*IntegrationTests.java + **/test/integration/**/* + **/*IntegrationTests - **/test/unit/**/*.java - **/*UnitTests.java - **/test/performance/**/*.java + **/test/unit/**/* + **/*UnitTests + **/test/performance/**/* src/test/resources/logging.properties diff --git a/spring-data-cassandra/pom.xml b/spring-data-cassandra/pom.xml index 2d602d5ea..4f3879f3e 100644 --- a/spring-data-cassandra/pom.xml +++ b/spring-data-cassandra/pom.xml @@ -182,6 +182,45 @@ multithreadedtc + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin} + true + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin} + true + + + org.jetbrains.kotlin + kotlin-test-junit + ${kotlin} + test + + + com.nhaarman + mockito-kotlin + 1.5.0 + test + + + org.jetbrains.kotlin + kotlin-stdlib + + + org.jetbrains.kotlin + kotlin-reflect + + + org.mockito + mockito-core + + + diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/AsyncCassandraOperationsExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/AsyncCassandraOperationsExtensions.kt new file mode 100644 index 000000000..796e7f55e --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/AsyncCassandraOperationsExtensions.kt @@ -0,0 +1,287 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.datastax.driver.core.Statement +import org.springframework.data.cassandra.core.query.Query +import org.springframework.data.cassandra.core.query.Update +import org.springframework.data.domain.Slice +import org.springframework.util.concurrent.ListenableFuture +import kotlin.reflect.KClass + +/** + * Extensions for [AsyncCassandraOperations]. + * + * @author Mark Paluch + * @since 2.1 + */ + +// ------------------------------------------------------------------------- +// Methods dealing with static CQL +// ------------------------------------------------------------------------- + +/** + * Extension for [AsyncCassandraOperations.select] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.select(cql: String, entityClass: KClass): ListenableFuture> = + select(cql, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.select] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.select(cql: String): ListenableFuture> = + select(cql, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.select] providing a Consumer-like function. + */ +fun AsyncCassandraOperations.select(cql: String, entityClass: KClass, consumer: (T) -> Unit): ListenableFuture = + select(cql, consumer, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.select] providing a Consumer-like function leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.select(cql: String, crossinline consumer: (T) -> Unit): ListenableFuture = + select(cql, { consumer(it) }, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.selectOne] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.selectOne(cql: String, entityClass: KClass): ListenableFuture = + selectOne(cql, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.selectOne] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.selectOne(cql: String): ListenableFuture = + selectOne(cql, T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with com.datastax.driver.core.Statement +// ------------------------------------------------------------------------- + +/** + * Extension for [AsyncCassandraOperations.select] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.select(statement: Statement, entityClass: KClass): ListenableFuture> = + select(statement, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.select] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.select(statement: Statement): ListenableFuture> = + select(statement, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.select] providing a Consumer-like function. + */ +fun AsyncCassandraOperations.select(statement: Statement, entityClass: KClass, consumer: (T) -> Unit): ListenableFuture = + select(statement, consumer, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.select] providing a Consumer-like function leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.select(statement: Statement, crossinline consumer: (T) -> Unit): ListenableFuture = + select(statement, { consumer(it) }, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.slice] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.slice(statement: Statement, entityClass: KClass): ListenableFuture> = + slice(statement, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.slice] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.slice(statement: Statement): ListenableFuture> = + slice(statement, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.selectOne] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.selectOne(statement: Statement, entityClass: KClass): ListenableFuture = + selectOne(statement, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.selectOne] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.selectOne(statement: Statement): ListenableFuture = + selectOne(statement, T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with org.springframework.data.cassandra.core.query.Query +// ------------------------------------------------------------------------- + +/** + * Extension for [AsyncCassandraOperations.select] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.select(query: Query, entityClass: KClass): ListenableFuture> = + select(query, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.select] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.select(query: Query): ListenableFuture> = + select(query, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.select] providing a Consumer-like function. + */ +fun AsyncCassandraOperations.select(query: Query, entityClass: KClass, consumer: (T) -> Unit): ListenableFuture = + select(query, consumer, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.select] providing a Consumer-like function leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.select(query: Query, crossinline consumer: (T) -> Unit): ListenableFuture = + select(query, { consumer(it) }, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.slice] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.slice(query: Query, entityClass: KClass): ListenableFuture> = + slice(query, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.slice] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.slice(query: Query): ListenableFuture> = + slice(query, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.selectOne] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.selectOne(query: Query, entityClass: KClass): ListenableFuture = + selectOne(query, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.selectOne] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.selectOne(query: Query): ListenableFuture = + selectOne(query, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.update] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.update(query: Query, update: Update, entityClass: KClass): ListenableFuture = + update(query, update, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.update] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.update(query: Query, update: Update): ListenableFuture = + update(query, update, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.delete] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.delete(query: Query, entityClass: KClass): ListenableFuture = + delete(query, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.delete] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun AsyncCassandraOperations.delete(query: Query): ListenableFuture = + delete(query, T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with entities +// ------------------------------------------------------------------------- + +/** + * Extension for [AsyncCassandraOperations.count] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.count(entityClass: KClass): ListenableFuture = + count(entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.count] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.count(): ListenableFuture = + count(T::class.java) + +/** + * Extension for [AsyncCassandraOperations.count] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.count(query: Query, entityClass: KClass): ListenableFuture = + count(query, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.count] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.count(query: Query): ListenableFuture = + count(query, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.exists] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.exists(id: Any, entityClass: KClass): ListenableFuture = + exists(id, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.exists] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.exists(id: Any): ListenableFuture = + exists(id, T::class) + +/** + * Extension for [AsyncCassandraOperations.count] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.exists(query: Query, entityClass: KClass): ListenableFuture = + exists(query, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.count] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.exists(query: Query): ListenableFuture = + exists(query, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.selectOneById] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.selectOneById(id: Any, entityClass: KClass): ListenableFuture = + selectOneById(id, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.selectOneById] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.selectOneById(id: Any): ListenableFuture = + selectOneById(id, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.deleteById] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.deleteById(id: Any, entityClass: KClass): ListenableFuture = + deleteById(id, entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.deleteById] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.deleteById(id: Any): ListenableFuture = + deleteById(id, T::class.java) + +/** + * Extension for [AsyncCassandraOperations.truncate] providing a [KClass] based variant. + */ +fun AsyncCassandraOperations.truncate(entityClass: KClass): ListenableFuture = + truncate(entityClass.java) + +/** + * Extension for [AsyncCassandraOperations.truncate] leveraging reified type parameters. + */ +inline fun AsyncCassandraOperations.truncate(): ListenableFuture = + truncate(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/CassandraOperationsExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/CassandraOperationsExtensions.kt new file mode 100644 index 000000000..ef4956da4 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/CassandraOperationsExtensions.kt @@ -0,0 +1,300 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.datastax.driver.core.Statement +import org.springframework.data.cassandra.core.cql.CqlIdentifier +import org.springframework.data.cassandra.core.query.Query +import org.springframework.data.cassandra.core.query.Update +import org.springframework.data.domain.Slice +import java.util.stream.Stream +import kotlin.reflect.KClass + +/** + * Extensions for [CassandraOperations]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [CassandraOperations.getTableName] providing a [KClass] based variant. + */ +fun CassandraOperations.getTableName(entityClass: KClass): CqlIdentifier = + getTableName(entityClass.java) + +/** + * Extension for [CassandraOperations.getTableName] leveraging reified type parameters. + */ +inline fun CassandraOperations.getTableName(): CqlIdentifier = + getTableName(T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with static CQL +// ------------------------------------------------------------------------- + +/** + * Extension for [CassandraOperations.select] providing a [KClass] based variant. + */ +fun CassandraOperations.select(cql: String, entityClass: KClass): List = + select(cql, entityClass.java) + +/** + * Extension for [CassandraOperations.select] leveraging reified type parameters. + */ +inline fun CassandraOperations.select(cql: String): List = + select(cql, T::class.java) + +/** + * Extension for [CassandraOperations.stream] providing a [KClass] based variant. + */ +fun CassandraOperations.stream(cql: String, entityClass: KClass): Stream = + stream(cql, entityClass.java) + +/** + * Extension for [CassandraOperations.stream] leveraging reified type parameters. + */ +inline fun CassandraOperations.stream(cql: String): Stream = + stream(cql, T::class.java) + +/** + * Extension for [CassandraOperations.selectOne] providing a [KClass] based variant. + */ +fun CassandraOperations.selectOne(cql: String, entityClass: KClass): T? = + selectOne(cql, entityClass.java) + +/** + * Extension for [CassandraOperations.selectOne] leveraging reified type parameters. + */ +inline fun CassandraOperations.selectOne(cql: String): T? = + selectOne(cql, T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with com.datastax.driver.core.Statement +// ------------------------------------------------------------------------- + +/** + * Extension for [CassandraOperations.select] providing a [KClass] based variant. + */ +fun CassandraOperations.select(statement: Statement, entityClass: KClass): List = + select(statement, entityClass.java) + +/** + * Extension for [CassandraOperations.select] leveraging reified type parameters. + */ +inline fun CassandraOperations.select(statement: Statement): List = + select(statement, T::class.java) + +/** + * Extension for [CassandraOperations.slice] providing a [KClass] based variant. + */ +fun CassandraOperations.slice(statement: Statement, entityClass: KClass): Slice = + slice(statement, entityClass.java) + +/** + * Extension for [CassandraOperations.slice] leveraging reified type parameters. + */ +inline fun CassandraOperations.slice(statement: Statement): Slice = + slice(statement, T::class.java) + +/** + * Extension for [CassandraOperations.stream] providing a [KClass] based variant. + */ +fun CassandraOperations.stream(statement: Statement, entityClass: KClass): Stream = + stream(statement, entityClass.java) + +/** + * Extension for [CassandraOperations.stream] leveraging reified type parameters. + */ +inline fun CassandraOperations.stream(statement: Statement): Stream = + stream(statement, T::class.java) + +/** + * Extension for [CassandraOperations.selectOne] providing a [KClass] based variant. + */ +fun CassandraOperations.selectOne(statement: Statement, entityClass: KClass): T? = + selectOne(statement, entityClass.java) + +/** + * Extension for [CassandraOperations.selectOne] leveraging reified type parameters. + */ +inline fun CassandraOperations.selectOne(statement: Statement): T? = + selectOne(statement, T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with org.springframework.data.cassandra.core.query.Query +// ------------------------------------------------------------------------- + +/** + * Extension for [CassandraOperations.select] providing a [KClass] based variant. + */ +fun CassandraOperations.select(query: Query, entityClass: KClass): List = + select(query, entityClass.java) + +/** + * Extension for [CassandraOperations.select] leveraging reified type parameters. + */ +inline fun CassandraOperations.select(query: Query): List = + select(query, T::class.java) + +/** + * Extension for [CassandraOperations.slice] providing a [KClass] based variant. + */ +fun CassandraOperations.slice(query: Query, entityClass: KClass): Slice = + slice(query, entityClass.java) + +/** + * Extension for [CassandraOperations.slice] leveraging reified type parameters. + */ +inline fun CassandraOperations.slice(query: Query): Slice = + slice(query, T::class.java) + +/** + * Extension for [CassandraOperations.stream] providing a [KClass] based variant. + */ +fun CassandraOperations.stream(query: Query, entityClass: KClass): Stream = + stream(query, entityClass.java) + +/** + * Extension for [CassandraOperations.stream] leveraging reified type parameters. + */ +inline fun CassandraOperations.stream(query: Query): Stream = + stream(query, T::class.java) + +/** + * Extension for [CassandraOperations.selectOne] providing a [KClass] based variant. + */ +fun CassandraOperations.selectOne(query: Query, entityClass: KClass): T? = + selectOne(query, entityClass.java) + +/** + * Extension for [CassandraOperations.selectOne] leveraging reified type parameters. + */ +inline fun CassandraOperations.selectOne(query: Query): T? = + selectOne(query, T::class.java) + +/** + * Extension for [CassandraOperations.update] providing a [KClass] based variant. + */ +fun CassandraOperations.update(query: Query, update: Update, entityClass: KClass): Boolean = + update(query, update, entityClass.java) + +/** + * Extension for [CassandraOperations.update] leveraging reified type parameters. + */ +inline fun CassandraOperations.update(query: Query, update: Update): Boolean = + update(query, update, T::class.java) + +/** + * Extension for [CassandraOperations.delete] providing a [KClass] based variant. + */ +fun CassandraOperations.delete(query: Query, entityClass: KClass): Boolean = + delete(query, entityClass.java) + +/** + * Extension for [CassandraOperations.delete] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun CassandraOperations.delete(query: Query): Boolean = + delete(query, T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with entities +// ------------------------------------------------------------------------- + +/** + * Extension for [CassandraOperations.count] providing a [KClass] based variant. + */ +fun CassandraOperations.count(entityClass: KClass): Long = + count(entityClass.java) + +/** + * Extension for [CassandraOperations.count] leveraging reified type parameters. + */ +inline fun CassandraOperations.count(): Long = + count(T::class.java) + +/** + * Extension for [CassandraOperations.count] providing a [KClass] based variant. + */ +fun CassandraOperations.count(query: Query, entityClass: KClass): Long = + count(query, entityClass.java) + +/** + * Extension for [CassandraOperations.count] leveraging reified type parameters. + */ +inline fun CassandraOperations.count(query: Query): Long = + count(query, T::class.java) + +/** + * Extension for [CassandraOperations.exists] providing a [KClass] based variant. + */ +fun CassandraOperations.exists(id: Any, entityClass: KClass): Boolean = + exists(id, entityClass.java) + +/** + * Extension for [CassandraOperations.exists] leveraging reified type parameters. + */ +inline fun CassandraOperations.exists(id: Any): Boolean = + exists(id, T::class) + +/** + * Extension for [CassandraOperations.count] providing a [KClass] based variant. + */ +fun CassandraOperations.exists(query: Query, entityClass: KClass): Boolean = + exists(query, entityClass.java) + +/** + * Extension for [CassandraOperations.count] leveraging reified type parameters. + */ +inline fun CassandraOperations.exists(query: Query): Boolean = + exists(query, T::class.java) + +/** + * Extension for [CassandraOperations.selectOneById] providing a [KClass] based variant. + */ +fun CassandraOperations.selectOneById(id: Any, entityClass: KClass): T? = + selectOneById(id, entityClass.java) + +/** + * Extension for [CassandraOperations.selectOneById] leveraging reified type parameters. + */ +inline fun CassandraOperations.selectOneById(id: Any): T? = + selectOneById(id, T::class.java) + +/** + * Extension for [CassandraOperations.deleteById] providing a [KClass] based variant. + */ +fun CassandraOperations.deleteById(id: Any, entityClass: KClass): Boolean = + deleteById(id, entityClass.java) + +/** + * Extension for [CassandraOperations.deleteById] leveraging reified type parameters. + */ +inline fun CassandraOperations.deleteById(id: Any): Boolean = + deleteById(id, T::class.java) + +/** + * Extension for [CassandraOperations.truncate] providing a [KClass] based variant. + */ +fun CassandraOperations.truncate(entityClass: KClass): Unit = + truncate(entityClass.java) + +/** + * Extension for [CassandraOperations.truncate] leveraging reified type parameters. + */ +inline fun CassandraOperations.truncate(): Unit = + truncate(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableDeleteOperationExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableDeleteOperationExtensions.kt new file mode 100644 index 000000000..6717d14c2 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableDeleteOperationExtensions.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import kotlin.reflect.KClass + +/** + * Extensions for [ExecutableDeleteOperation]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [ExecutableRemoveOperation.delete] providing a [KClass] based variant. + */ +fun ExecutableDeleteOperation.delete(entityClass: KClass): ExecutableDeleteOperation.ExecutableDelete = + delete(entityClass.java) + +/** + * Extension for [ExecutableRemoveOperation.delete] leveraging reified type parameters. + */ +inline fun ExecutableDeleteOperation.delete(): ExecutableDeleteOperation.ExecutableDelete = + delete(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableInsertOperationExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableInsertOperationExtensions.kt new file mode 100644 index 000000000..9e1dd7b34 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableInsertOperationExtensions.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import kotlin.reflect.KClass + +/** + * Extensions for [ExecutableInsertOperation]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [ExecutableInsertOperation.insert] providing a [KClass] based variant. + */ +fun ExecutableInsertOperation.insert(entityClass: KClass): ExecutableInsertOperation.ExecutableInsert = + insert(entityClass.java) + +/** + * Extension for [ExecutableInsertOperation.insert] leveraging reified type parameters. + */ +inline fun ExecutableInsertOperation.insert(): ExecutableInsertOperation.ExecutableInsert = + insert(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableSelectOperationExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableSelectOperationExtensions.kt new file mode 100644 index 000000000..6a2abec57 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableSelectOperationExtensions.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import kotlin.reflect.KClass + +/** + * Extensions for [ExecutableSelectOperation]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [ExecutableSelectOperation.query] providing a [KClass] based variant. + */ +fun ExecutableSelectOperation.query(entityClass: KClass): ExecutableSelectOperation.ExecutableSelect = + query(entityClass.java) + +/** + * Extension for [ExecutableSelectOperation.query] leveraging reified type parameters. + */ +inline fun ExecutableSelectOperation.query(): ExecutableSelectOperation.ExecutableSelect = + query(T::class.java) + +/** + * Extension for [ExecutableSelectOperation.SelectWithProjection. as] providing a [KClass] based variant. + */ +fun ExecutableSelectOperation.SelectWithProjection<*>.asType(resultType: KClass): ExecutableSelectOperation.SelectWithQuery = + `as`(resultType.java) + +/** + * Extension for [ExecutableSelectOperation.FindWithProjection. as] leveraging reified type parameters. + */ +inline fun ExecutableSelectOperation.SelectWithProjection<*>.asType(): ExecutableSelectOperation.SelectWithQuery = + `as`(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableUpdateOperationExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableUpdateOperationExtensions.kt new file mode 100644 index 000000000..3be014be8 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ExecutableUpdateOperationExtensions.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import kotlin.reflect.KClass + +/** + * Extensions for [ExecutableUpdateOperation]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [ExecutableUpdateOperation.update] providing a [KClass] based variant. + */ +fun ExecutableUpdateOperation.update(entityClass: KClass): ExecutableUpdateOperation.ExecutableUpdate = + update(entityClass.java) + +/** + * Extension for [ExecutableUpdateOperation.update] leveraging reified type parameters. + */ +inline fun ExecutableUpdateOperation.update(): ExecutableUpdateOperation.ExecutableUpdate = + update(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveCassandraOperationsExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveCassandraOperationsExtensions.kt new file mode 100644 index 000000000..01a1cf3e0 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveCassandraOperationsExtensions.kt @@ -0,0 +1,227 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.datastax.driver.core.Statement +import org.springframework.data.cassandra.core.query.Query +import org.springframework.data.cassandra.core.query.Update +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono +import kotlin.reflect.KClass + +/** + * Extensions for [ReactiveCassandraOperations]. + * + * @author Mark Paluch + * @since 2.1 + */ + +// ------------------------------------------------------------------------- +// Methods dealing with static CQL +// ------------------------------------------------------------------------- + +/** + * Extension for [ReactiveCassandraOperations.select] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.select(cql: String, entityClass: KClass): Flux = + select(cql, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.select] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.select(cql: String): Flux = + select(cql, T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.selectOne] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.selectOne(cql: String, entityClass: KClass): Mono = + selectOne(cql, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.selectOne] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.selectOne(cql: String): Mono = + selectOne(cql, T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with com.datastax.driver.core.Statement +// ------------------------------------------------------------------------- + +/** + * Extension for [ReactiveCassandraOperations.select] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.select(statement: Statement, entityClass: KClass): Flux = + select(statement, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.select] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.select(statement: Statement): Flux = + select(statement, T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.selectOne] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.selectOne(statement: Statement, entityClass: KClass): Mono = + selectOne(statement, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.selectOne] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.selectOne(statement: Statement): Mono = + selectOne(statement, T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with org.springframework.data.cassandra.core.query.Query +// ------------------------------------------------------------------------- + +/** + * Extension for [ReactiveCassandraOperations.select] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.select(query: Query, entityClass: KClass): Flux = + select(query, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.select] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.select(query: Query): Flux = + select(query, T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.selectOne] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.selectOne(query: Query, entityClass: KClass): Mono = + selectOne(query, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.selectOne] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.selectOne(query: Query): Mono = + selectOne(query, T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.update] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.update(query: Query, update: Update, entityClass: KClass): Mono = + update(query, update, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.update] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.update(query: Query, update: Update): Mono = + update(query, update, T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.delete] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.delete(query: Query, entityClass: KClass): Mono = + delete(query, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.delete] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveCassandraOperations.delete(query: Query): Mono = + delete(query, T::class.java) + +// ------------------------------------------------------------------------- +// Methods dealing with entities +// ------------------------------------------------------------------------- + +/** + * Extension for [ReactiveCassandraOperations.count] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.count(entityClass: KClass): Mono = + count(entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.count] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.count(): Mono = + count(T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.count] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.count(query: Query, entityClass: KClass): Mono = + count(query, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.count] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.count(query: Query): Mono = + count(query, T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.exists] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.exists(id: Any, entityClass: KClass): Mono = + exists(id, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.exists] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.exists(id: Any): Mono = + exists(id, T::class) + +/** + * Extension for [ReactiveCassandraOperations.count] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.exists(query: Query, entityClass: KClass): Mono = + exists(query, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.count] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.exists(query: Query): Mono = + exists(query, T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.selectOneById] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.selectOneById(id: Any, entityClass: KClass): Mono = + selectOneById(id, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.selectOneById] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.selectOneById(id: Any): Mono = + selectOneById(id, T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.deleteById] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.deleteById(id: Any, entityClass: KClass): Mono = + deleteById(id, entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.deleteById] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.deleteById(id: Any): Mono = + deleteById(id, T::class.java) + +/** + * Extension for [ReactiveCassandraOperations.truncate] providing a [KClass] based variant. + */ +fun ReactiveCassandraOperations.truncate(entityClass: KClass): Mono = + truncate(entityClass.java) + +/** + * Extension for [ReactiveCassandraOperations.truncate] leveraging reified type parameters. + */ +inline fun ReactiveCassandraOperations.truncate(): Mono = + truncate(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveDeleteOperationExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveDeleteOperationExtensions.kt new file mode 100644 index 000000000..1b8a03671 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveDeleteOperationExtensions.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import kotlin.reflect.KClass + +/** + * Extensions for [ReactiveDeleteOperation]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [ReactiveDeleteOperation.delete] providing a [KClass] based variant. + */ +fun ReactiveDeleteOperation.delete(entityClass: KClass): ReactiveDeleteOperation.ReactiveDelete = + delete(entityClass.java) + +/** + * Extension for [ReactiveDeleteOperation.delete] leveraging reified type parameters. + */ +inline fun ReactiveDeleteOperation.delete(): ReactiveDeleteOperation.ReactiveDelete = + delete(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveInsertOperationExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveInsertOperationExtensions.kt new file mode 100644 index 000000000..d9c9d94a9 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveInsertOperationExtensions.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import kotlin.reflect.KClass + +/** + * Extensions for [ReactiveInsertOperation]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [ReactiveInsertOperation.insert] providing a [KClass] based variant. + */ +fun ReactiveInsertOperation.insert(entityClass: KClass): ReactiveInsertOperation.ReactiveInsert = + insert(entityClass.java) + +/** + * Extension for [ReactiveInsertOperation.insert] leveraging reified type parameters. + */ +inline fun ReactiveInsertOperation.insert(): ReactiveInsertOperation.ReactiveInsert = + insert(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveSelectOperationExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveSelectOperationExtensions.kt new file mode 100644 index 000000000..476d73991 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveSelectOperationExtensions.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import kotlin.reflect.KClass + +/** + * Extensions for [ReactiveSelectOperation]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [ReactiveSelectOperation.query] providing a [KClass] based variant. + */ +fun ReactiveSelectOperation.query(entityClass: KClass): ReactiveSelectOperation.ReactiveSelect = + query(entityClass.java) + +/** + * Extension for [ReactiveSelectOperation.query] leveraging reified type parameters. + */ +inline fun ReactiveSelectOperation.query(): ReactiveSelectOperation.ReactiveSelect = + query(T::class.java) + +/** + * Extension for [ReactiveSelectOperation.SelectWithProjection. as] providing a [KClass] based variant. + */ +fun ReactiveSelectOperation.SelectWithProjection<*>.asType(resultType: KClass): ReactiveSelectOperation.SelectWithQuery = + `as`(resultType.java) + +/** + * Extension for [ReactiveSelectOperation.FindWithProjection. as] leveraging reified type parameters. + */ +inline fun ReactiveSelectOperation.SelectWithProjection<*>.asType(): ReactiveSelectOperation.SelectWithQuery = + `as`(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveUpdateOperationExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveUpdateOperationExtensions.kt new file mode 100644 index 000000000..f2630bc9e --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/ReactiveUpdateOperationExtensions.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import kotlin.reflect.KClass + +/** + * Extensions for [ReactiveUpdateOperation]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [ReactiveUpdateOperation.update] providing a [KClass] based variant. + */ +fun ReactiveUpdateOperation.update(entityClass: KClass): ReactiveUpdateOperation.ReactiveUpdate = + update(entityClass.java) + +/** + * Extension for [ReactiveUpdateOperation.update] leveraging reified type parameters. + */ +inline fun ReactiveUpdateOperation.update(): ReactiveUpdateOperation.ReactiveUpdate = + update(T::class.java) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/cql/AsyncCqlOperationsExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/cql/AsyncCqlOperationsExtensions.kt new file mode 100644 index 000000000..e7434fdaf --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/cql/AsyncCqlOperationsExtensions.kt @@ -0,0 +1,112 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.cql + +import com.datastax.driver.core.ResultSet +import com.datastax.driver.core.Row +import com.datastax.driver.core.Statement +import org.springframework.util.concurrent.ListenableFuture +import kotlin.reflect.KClass + +/** + * Extensions for [AsyncCqlOperations]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [AsyncCqlOperations.queryForObject] providing a [KClass] based variant. + */ +fun AsyncCqlOperations.queryForObject(cql: String, entityClass: KClass): ListenableFuture = + queryForObject(cql, entityClass.java) + +/** + * Extension for [AsyncCqlOperations.queryForObject] leveraging reified type parameters. + */ +inline fun AsyncCqlOperations.queryForObject(cql: String): ListenableFuture = + queryForObject(cql, T::class.java) + +/** + * Extension for [AsyncCqlOperations.queryForObject] providing a [KClass] based variant. + */ +fun AsyncCqlOperations.queryForObject(cql: String, entityClass: KClass, vararg args: Any): ListenableFuture = + queryForObject(cql, entityClass.java, args) + +/** + * Extension for [AsyncCqlOperations.queryForObject] leveraging reified type parameters. + */ +inline fun AsyncCqlOperations.queryForObject(cql: String, vararg args: Any): ListenableFuture = + queryForObject(cql, T::class.java, args) + +/** + * Extension for [AsyncCqlOperations.queryForObject] leveraging reified type parameters. + */ +fun AsyncCqlOperations.queryForObject(cql: String, vararg args: Any, function: (Row, Int) -> T): ListenableFuture = + queryForObject(cql, function, args) + +/** + * Extension for [AsyncCqlOperations.queryForObject] providing a [KClass] based variant. + */ +fun AsyncCqlOperations.queryForObject(statement: Statement, entityClass: KClass): ListenableFuture = + queryForObject(statement, entityClass.java) + +/** + * Extension for [AsyncCqlOperations.queryForObject] leveraging reified type parameters. + */ +inline fun AsyncCqlOperations.queryForObject(statement: Statement): ListenableFuture = + queryForObject(statement, T::class.java) + +/** + * Extension for [AsyncCqlOperations.queryForList] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun AsyncCqlOperations.queryForList(cql: String): ListenableFuture> = + queryForList(cql, T::class.java) + +/** + * Extension for [AsyncCqlOperations.queryForList] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun AsyncCqlOperations.queryForList(cql: String, vararg args: Any): ListenableFuture> = + queryForList(cql, T::class.java, args) + +/** + * Extension for [AsyncCqlOperations.queryForList] providing a [KClass] based variant. + */ +fun AsyncCqlOperations.queryForList(statement: Statement, entityClass: KClass): ListenableFuture> = + queryForList(statement, entityClass.java) + +/** + * Extension for [AsyncCqlOperations.queryForList] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun AsyncCqlOperations.queryForList(statement: Statement): ListenableFuture> = + queryForList(statement, T::class.java) + +/** + * Extension for [AsyncCqlOperations.query] providing a ResultSetExtractor-like function + * variant: `query("...", arg1, argN){ rs -> }`. + */ +inline fun AsyncCqlOperations.query(cql: String, vararg args: Any, crossinline function: (ResultSet) -> T): ListenableFuture = + query(cql, ResultSetExtractor { function(it) }, *args) + +/** + * Extension for [AsyncCqlOperations.query] providing a RowMapper-like function + * variant: `query("...", arg1, argN){ row, i -> }`. + */ +fun AsyncCqlOperations.query(cql: String, vararg args: Any, function: (Row, Int) -> T): ListenableFuture> = + query(cql, RowMapper { row, i -> function(row, i) }, *args) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/cql/CqlOperationsExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/cql/CqlOperationsExtensions.kt new file mode 100644 index 000000000..31c8e595f --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/cql/CqlOperationsExtensions.kt @@ -0,0 +1,118 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.cql + +import com.datastax.driver.core.ResultSet +import com.datastax.driver.core.Row +import com.datastax.driver.core.Statement +import kotlin.reflect.KClass + +/** + * Extensions for [CqlOperations]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [CqlOperations.queryForObject] providing a [KClass] based variant. + */ +fun CqlOperations.queryForObject(cql: String, entityClass: KClass): T? = + queryForObject(cql, entityClass.java) + +/** + * Extension for [CqlOperations.queryForObject] leveraging reified type parameters. + */ +inline fun CqlOperations.queryForObject(cql: String): T? = + queryForObject(cql, T::class.java) + +/** + * Extension for [CqlOperations.queryForObject] providing a [KClass] based variant. + */ +fun CqlOperations.queryForObject(cql: String, entityClass: KClass, vararg args: Any): T? = + queryForObject(cql, entityClass.java, args) + +/** + * Extension for [CqlOperations.queryForObject] leveraging reified type parameters. + */ +inline fun CqlOperations.queryForObject(cql: String, vararg args: Any): T? = + queryForObject(cql, T::class.java, args) + +/** + * Extension for [CqlOperations.queryForObject] leveraging reified type parameters. + */ +fun CqlOperations.queryForObject(cql: String, vararg args: Any, function: (Row, Int) -> T): T? = + queryForObject(cql, function, args) + +/** + * Extension for [CqlOperations.queryForObject] providing a [KClass] based variant. + */ +fun CqlOperations.queryForObject(statement: Statement, entityClass: KClass): T? = + queryForObject(statement, entityClass.java) + +/** + * Extension for [CqlOperations.queryForObject] leveraging reified type parameters. + */ +inline fun CqlOperations.queryForObject(statement: Statement): T? = + queryForObject(statement, T::class.java) + +/** + * Extension for [CqlOperations.queryForList] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun CqlOperations.queryForList(cql: String): List = + queryForList(cql, T::class.java) + +/** + * Extension for [CqlOperations.queryForList] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun CqlOperations.queryForList(cql: String, vararg args: Any): List = + queryForList(cql, T::class.java, args) + +/** + * Extension for [CqlOperations.queryForList] providing a [KClass] based variant. + */ +fun CqlOperations.queryForList(statement: Statement, entityClass: KClass): List = + queryForList(statement, entityClass.java) + +/** + * Extension for [CqlOperations.queryForList] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun CqlOperations.queryForList(statement: Statement): List = + queryForList(statement, T::class.java) + +/** + * Extension for [CqlOperations.query] providing a ResultSetExtractor-like function + * variant: `query("...", arg1, argN){ rs -> }`. + */ +inline fun CqlOperations.query(cql: String, vararg args: Any, crossinline function: (ResultSet) -> T): T? = + query(cql, ResultSetExtractor { function(it) }, *args) + +/** + * Extension for [CqlOperations.query] providing a RowCallbackHandler-like function + * variant: `query("...", arg1, argN){ rs -> }`. + */ +fun CqlOperations.query(cql: String, vararg args: Any, function: (Row) -> Unit): Unit = + query(cql, RowCallbackHandler { function(it) }, *args) + +/** + * Extension for [CqlOperations.query] providing a RowMapper-like function + * variant: `query("...", arg1, argN){ row, i -> }`. + */ +fun CqlOperations.query(cql: String, vararg args: Any, function: (Row, Int) -> T): List = + query(cql, RowMapper { row, i -> function(row, i) }, *args) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/cql/ReactiveCqlOperationsExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/cql/ReactiveCqlOperationsExtensions.kt new file mode 100644 index 000000000..8d6a9cf6f --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/cql/ReactiveCqlOperationsExtensions.kt @@ -0,0 +1,114 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.cql + +import com.datastax.driver.core.Row +import com.datastax.driver.core.Statement +import org.reactivestreams.Publisher +import org.springframework.data.cassandra.ReactiveResultSet +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono +import kotlin.reflect.KClass + +/** + * Extensions for [ReactiveCqlOperations]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [ReactiveCqlOperations.queryForObject] providing a [KClass] based variant. + */ +fun ReactiveCqlOperations.queryForObject(cql: String, entityClass: KClass): Mono = + queryForObject(cql, entityClass.java) + +/** + * Extension for [ReactiveCqlOperations.queryForObject] leveraging reified type parameters. + */ +inline fun ReactiveCqlOperations.queryForObject(cql: String): Mono = + queryForObject(cql, T::class.java) + +/** + * Extension for [ReactiveCqlOperations.queryForObject] providing a [KClass] based variant. + */ +fun ReactiveCqlOperations.queryForObject(cql: String, entityClass: KClass, vararg args: Any): Mono = + queryForObject(cql, entityClass.java, args) + +/** + * Extension for [ReactiveCqlOperations.queryForObject] leveraging reified type parameters. + */ +inline fun ReactiveCqlOperations.queryForObject(cql: String, vararg args: Any): Mono = + queryForObject(cql, T::class.java, args) + +/** + * Extension for [ReactiveCqlOperations.queryForObject] leveraging reified type parameters. + */ +fun ReactiveCqlOperations.queryForObject(cql: String, vararg args: Any, function: (Row, Int) -> T): Mono = + queryForObject(cql, function, args) + +/** + * Extension for [ReactiveCqlOperations.queryForObject] providing a [KClass] based variant. + */ +fun ReactiveCqlOperations.queryForObject(statement: Statement, entityClass: KClass): Mono = + queryForObject(statement, entityClass.java) + +/** + * Extension for [ReactiveCqlOperations.queryForObject] leveraging reified type parameters. + */ +inline fun ReactiveCqlOperations.queryForObject(statement: Statement): Mono = + queryForObject(statement, T::class.java) + +/** + * Extension for [ReactiveCqlOperations.queryForFlux] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveCqlOperations.queryForFlux(cql: String): Flux = + queryForFlux(cql, T::class.java) + +/** + * Extension for [ReactiveCqlOperations.queryForFlux] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveCqlOperations.queryForFlux(cql: String, vararg args: Any): Flux = + queryForFlux(cql, T::class.java, args) + +/** + * Extension for [ReactiveCqlOperations.queryForFlux] providing a [KClass] based variant. + */ +fun ReactiveCqlOperations.queryForFlux(statement: Statement, entityClass: KClass): Flux = + queryForFlux(statement, entityClass.java) + +/** + * Extension for [ReactiveCqlOperations.queryForFlux] leveraging reified type parameters. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +inline fun ReactiveCqlOperations.queryForFlux(statement: Statement): Flux = + queryForFlux(statement, T::class.java) + +/** + * Extension for [ReactiveCqlOperations.query] providing a ResultSetExtractor-like function + * variant: `query("...", arg1, argN){ rs -> }`. + */ +inline fun ReactiveCqlOperations.query(cql: String, vararg args: Any, crossinline function: (ReactiveResultSet) -> Publisher): Flux = + query(cql, ReactiveResultSetExtractor { function(it) }, *args) + +/** + * Extension for [ReactiveCqlOperations.query] providing a RowMapper-like function + * variant: `query("...", arg1, argN){ row, i -> }`. + */ +fun ReactiveCqlOperations.query(cql: String, vararg args: Any, function: (Row, Int) -> T): Flux = + query(cql, RowMapper { row, i -> function(row, i) }, *args) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/query/CriteriaExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/query/CriteriaExtensions.kt new file mode 100644 index 000000000..b9a598faf --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/query/CriteriaExtensions.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.query + +/** + * Extensions for [Criteria]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [Criteria. is] providing an `isEqualTo` alias since `in` is a reserved keyword in Kotlin. + */ +fun Criteria.isEqualTo(o: Any?): CriteriaDefinition = `is`(o) + +/** + * Extension for [Criteria. in] providing an `inValues` alias since `in` is a reserved keyword in Kotlin. + */ +fun Criteria.inValues(c: Collection): CriteriaDefinition = `in`(c) + +/** + * Extension for [Criteria. in] providing an `inValues` alias since `in` is a reserved keyword in Kotlin. + */ +fun Criteria.inValues(vararg o: Any?): CriteriaDefinition = `in`(*o) + +/** + * Extension for [CriteriaDefinition] to concatenate [CriteriaDefinition] using infix and. + */ +infix fun CriteriaDefinition.and(criteriaDefinition: CriteriaDefinition): CriteriaDefinitions { + return CriteriaDefinitions(listOf(this, criteriaDefinition)) +} + +/** + * Extension for [where] providing a global where alias for an improved DSL. + */ +fun where(columnName: String): Criteria = Criteria.where(columnName) + +/** + * Extension for [CriteriaDefinitions] adding and infix operator to [CriteriaDefinitions]. + */ +infix fun CriteriaDefinitions.and(criteriaDefinition: CriteriaDefinition): CriteriaDefinitions { + return CriteriaDefinitions(this.criteriaDefinitions + listOf(criteriaDefinition)) +} + +/** + * Utility class to hold multiple [CriteriaDefinition]. + */ +class CriteriaDefinitions(internal val criteriaDefinitions: List) diff --git a/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/query/QueryExtensions.kt b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/query/QueryExtensions.kt new file mode 100644 index 000000000..688617708 --- /dev/null +++ b/spring-data-cassandra/src/main/kotlin/org/springframework/data/cassandra/core/query/QueryExtensions.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.query + +/** + * Extensions for [Query]. + * + * @author Mark Paluch + * @since 2.1 + */ + +/** + * Extension for [Query.query] providing a global query alias for an improved DSL. + */ +fun query(criteria: Criteria): Query = Query.query(criteria) + +/** + * Extension for [Query.query] providing a global query alias for an improved DSL. + */ +fun query(criteriaDefinitions: CriteriaDefinitions): Query = Query.query(criteriaDefinitions.criteriaDefinitions) + diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/AsyncCassandraOperationsExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/AsyncCassandraOperationsExtensionsUnitTests.kt new file mode 100644 index 000000000..3817b5911 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/AsyncCassandraOperationsExtensionsUnitTests.kt @@ -0,0 +1,353 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.datastax.driver.core.SimpleStatement +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.eq +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.core.query.Query +import org.springframework.data.cassandra.core.query.Update +import org.springframework.data.cassandra.domain.Person +import java.util.function.Consumer + +/** + * Unit tests for [AsyncCassandraOperationsExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class AsyncCassandraOperationsExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: AsyncCassandraOperations + + // ------------------------------------------------------------------------- + // Methods dealing with static CQL + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `select(String, KClass) extension should call its Java counterpart`() { + + operations.select("SELECT * FROM person", Person::class) + verify(operations).select("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `select(String) with reified type parameter extension should call its Java counterpart`() { + + operations.select("SELECT * FROM person") + verify(operations).select("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `select(String, KClass, Consumer) extension should call its Java counterpart`() { + + operations.select("SELECT * FROM person", Person::class) { p -> p.toString() } + verify(operations).select(eq("SELECT * FROM person"), any>(), eq(Person::class.java)) + } + + @Test // DATACASS-484 + fun `select(String, Consumer) with reified type parameter extension should call its Java counterpart`() { + + operations.select("SELECT * FROM person") { p -> p.toString() } + verify(operations).select(eq("SELECT * FROM person"), any>(), eq(Person::class.java)) + } + + @Test // DATACASS-484 + fun `selectOne(String, KClass) extension should call its Java counterpart`() { + + operations.selectOne("SELECT * FROM person", Person::class) + verify(operations).selectOne("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(String) with reified type parameter extension should call its Java counterpart`() { + + operations.selectOne("SELECT * FROM person") + verify(operations).selectOne("SELECT * FROM person", Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with com.datastax.driver.core.Statement + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `select(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.select(statement, Person::class) + verify(operations).select(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `select(Statement) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + operations.select(statement) + verify(operations).select(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `select(Statement, KClass, Consumer) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.select(statement, Person::class) { p -> p.toString() } + verify(operations).select(eq(statement), any>(), eq(Person::class.java)) + } + + @Test // DATACASS-484 + fun `select(Statement, Consumer) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.select(statement) { p -> p.toString() } + verify(operations).select(eq(statement), any>(), eq(Person::class.java)) + } + + @Test // DATACASS-484 + fun `slice(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.slice(statement, Person::class) + verify(operations).slice(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `slice(Statement) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.slice(statement) + verify(operations).slice(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.selectOne(statement, Person::class) + verify(operations).selectOne(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Statement) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.selectOne(statement) + verify(operations).selectOne(statement, Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with org.springframework.data.cassandra.core.query.Query + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `select(Query, KClass) extension should call its Java counterpart`() { + + operations.select(Query.empty(), Person::class) + verify(operations).select(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `select(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.select(Query.empty()) + verify(operations).select(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `select(Query, KClass, Consumer) extension should call its Java counterpart`() { + + operations.select(Query.empty(), Person::class) { p -> p.toString() } + verify(operations).select(eq(Query.empty()), any>(), eq(Person::class.java)) + } + + @Test // DATACASS-484 + fun `select(Query, Consumer) with reified type parameter extension should call its Java counterpart`() { + + operations.select(Query.empty()) { p -> p.toString() } + verify(operations).select(eq(Query.empty()), any>(), eq(Person::class.java)) + } + + @Test // DATACASS-484 + fun `slice(Query, KClass) extension should call its Java counterpart`() { + + operations.slice(Query.empty(), Person::class) + verify(operations).slice(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `slice(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.slice(Query.empty()) + verify(operations).slice(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Query, KClass) extension should call its Java counterpart`() { + + operations.selectOne(Query.empty(), Person::class) + verify(operations).selectOne(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.selectOne(Query.empty()) + verify(operations).selectOne(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `update(Query, Update, KClass) extension should call its Java counterpart`() { + + operations.update(Query.empty(), Update.empty(), Person::class) + verify(operations).update(Query.empty(), Update.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `update(Query, Update) with reified type parameter extension should call its Java counterpart`() { + + operations.update(Query.empty(), Update.empty()) + verify(operations).update(Query.empty(), Update.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `delete(Query, KClass) extension should call its Java counterpart`() { + + operations.delete(Query.empty(), Person::class) + verify(operations).delete(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `delete(Query,) with reified type parameter extension should call its Java counterpart`() { + + operations.delete(Query.empty()) + verify(operations).delete(Query.empty(), Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with entities + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `count(KClass) extension should call its Java counterpart`() { + + operations.count(Person::class) + verify(operations).count(Person::class.java) + } + + @Test // DATACASS-484 + fun `count() with reified type parameter extension should call its Java counterpart`() { + + operations.count() + verify(operations).count(Person::class.java) + } + + @Test // DATACASS-484 + fun `count(Query, KClass) extension should call its Java counterpart`() { + + operations.count(Query.empty(), Person::class) + verify(operations).count(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `count(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.count(Query.empty()) + verify(operations).count(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Any, KClass) extension should call its Java counterpart`() { + + operations.exists("id", Person::class) + verify(operations).exists("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Any) with reified type parameter extension should call its Java counterpart`() { + + operations.exists("id") + verify(operations).exists("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Query, KClass) extension should call its Java counterpart`() { + + operations.exists(Query.empty(), Person::class) + verify(operations).exists(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.exists(Query.empty()) + verify(operations).exists(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOneById(Any, KClass) extension should call its Java counterpart`() { + + operations.selectOneById("id", Person::class) + verify(operations).selectOneById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOneById(Any) with reified type parameter extension should call its Java counterpart`() { + + operations.selectOneById("id") + verify(operations).selectOneById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `deleteById(Any, KClass) extension should call its Java counterpart`() { + + operations.deleteById("id", Person::class) + verify(operations).deleteById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `deleteById(Any) with reified type parameter extension should call its Java counterpart`() { + + operations.deleteById("id") + verify(operations).deleteById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `truncate(KClass) extension should call its Java counterpart`() { + + operations.truncate(Person::class) + verify(operations).truncate(Person::class.java) + } + + @Test // DATACASS-484 + fun `truncate() with reified type parameter extension should call its Java counterpart`() { + + operations.truncate() + verify(operations).truncate(Person::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/CassandraOperationsExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/CassandraOperationsExtensionsUnitTests.kt new file mode 100644 index 000000000..f3a2dea6d --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/CassandraOperationsExtensionsUnitTests.kt @@ -0,0 +1,392 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.datastax.driver.core.SimpleStatement +import com.nhaarman.mockito_kotlin.doReturn +import com.nhaarman.mockito_kotlin.verify +import com.nhaarman.mockito_kotlin.whenever +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.core.cql.CqlIdentifier +import org.springframework.data.cassandra.core.query.Query +import org.springframework.data.cassandra.core.query.Update +import org.springframework.data.cassandra.domain.Person +import org.springframework.data.domain.SliceImpl + +/** + * Unit tests for [CassandraOperationsExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class CassandraOperationsExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: CassandraOperations + + @Test // DATACASS-484 + fun `getTableName(KClass) extension should call its Java counterpart`() { + + doReturn(CqlIdentifier.of("person")).whenever(operations).getTableName(Person::class.java) + + operations.getTableName(Person::class) + verify(operations).getTableName(Person::class.java) + } + + @Test // DATACASS-484 + fun `getTableName() with reified type parameter extension should call its Java counterpart`() { + + doReturn(CqlIdentifier.of("person")).whenever(operations).getTableName(Person::class.java) + + operations.getTableName() + verify(operations).getTableName(Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with static CQL + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `select(String, KClass) extension should call its Java counterpart`() { + + operations.select("SELECT * FROM person", Person::class) + verify(operations).select("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `select(String) with reified type parameter extension should call its Java counterpart`() { + + operations.select("SELECT * FROM person") + verify(operations).select("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `stream(String, KClass) extension should call its Java counterpart`() { + + operations.stream("SELECT * FROM person", Person::class) + verify(operations).stream("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `stream(String) with reified type parameter extension should call its Java counterpart`() { + + operations.stream("SELECT * FROM person") + verify(operations).stream("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(String, KClass) extension should call its Java counterpart`() { + + doReturn(Person("Walter", "White")).whenever(operations).selectOne("SELECT * FROM person", Person::class.java) + + operations.selectOne("SELECT * FROM person", Person::class) + verify(operations).selectOne("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(String) with reified type parameter extension should call its Java counterpart`() { + + doReturn(Person("Walter", "White")).whenever(operations).selectOne("SELECT * FROM person", Person::class.java) + + operations.selectOne("SELECT * FROM person") + verify(operations).selectOne("SELECT * FROM person", Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with com.datastax.driver.core.Statement + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `select(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.select(statement, Person::class) + verify(operations).select(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `select(Statement) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + operations.select(statement) + verify(operations).select(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `slice(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + doReturn(SliceImpl(listOf(Person("Walter", "White")))).whenever(operations).slice(statement, Person::class.java) + + operations.slice(statement, Person::class) + verify(operations).slice(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `slice(Statement) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + doReturn(SliceImpl(listOf(Person("Walter", "White")))).whenever(operations).slice(statement, Person::class.java) + + operations.slice(statement) + verify(operations).slice(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `stream(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.stream(statement, Person::class) + verify(operations).stream(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `stream(Statement) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.stream(statement) + verify(operations).stream(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + doReturn(Person("Walter", "White")).whenever(operations).selectOne(statement, Person::class.java) + + operations.selectOne(statement, Person::class) + verify(operations).selectOne(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Statement) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + doReturn(Person("Walter", "White")).whenever(operations).selectOne(statement, Person::class.java) + + operations.selectOne(statement) + verify(operations).selectOne(statement, Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with org.springframework.data.cassandra.core.query.Query + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `select(Query, KClass) extension should call its Java counterpart`() { + + operations.select(Query.empty(), Person::class) + verify(operations).select(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `select(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.select(Query.empty()) + verify(operations).select(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `slice(Query, KClass) extension should call its Java counterpart`() { + + doReturn(SliceImpl(listOf(Person("Walter", "White")))).whenever(operations).slice(Query.empty(), Person::class.java) + + operations.slice(Query.empty(), Person::class) + verify(operations).slice(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `slice(Query) with reified type parameter extension should call its Java counterpart`() { + + doReturn(SliceImpl(listOf(Person("Walter", "White")))).whenever(operations).slice(Query.empty(), Person::class.java) + + operations.slice(Query.empty()) + verify(operations).slice(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `stream(Query, KClass) extension should call its Java counterpart`() { + + operations.stream(Query.empty(), Person::class) + verify(operations).stream(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `stream(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.stream(Query.empty()) + verify(operations).stream(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Query, KClass) extension should call its Java counterpart`() { + + doReturn(Person("Walter", "White")).whenever(operations).selectOne(Query.empty(), Person::class.java) + + operations.selectOne(Query.empty(), Person::class) + verify(operations).selectOne(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Query) with reified type parameter extension should call its Java counterpart`() { + + doReturn(Person("Walter", "White")).whenever(operations).selectOne(Query.empty(), Person::class.java) + + operations.selectOne(Query.empty()) + verify(operations).selectOne(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `update(Query, Update, KClass) extension should call its Java counterpart`() { + + operations.update(Query.empty(), Update.empty(), Person::class) + verify(operations).update(Query.empty(), Update.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `update(Query, Update) with reified type parameter extension should call its Java counterpart`() { + + operations.update(Query.empty(), Update.empty()) + verify(operations).update(Query.empty(), Update.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `delete(Query, KClass) extension should call its Java counterpart`() { + + operations.delete(Query.empty(), Person::class) + verify(operations).delete(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `delete(Query,) with reified type parameter extension should call its Java counterpart`() { + + operations.delete(Query.empty()) + verify(operations).delete(Query.empty(), Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with entities + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `count(KClass) extension should call its Java counterpart`() { + + operations.count(Person::class) + verify(operations).count(Person::class.java) + } + + @Test // DATACASS-484 + fun `count() with reified type parameter extension should call its Java counterpart`() { + + operations.count() + verify(operations).count(Person::class.java) + } + + @Test // DATACASS-484 + fun `count(Query, KClass) extension should call its Java counterpart`() { + + operations.count(Query.empty(), Person::class) + verify(operations).count(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `count(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.count(Query.empty()) + verify(operations).count(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Any, KClass) extension should call its Java counterpart`() { + + operations.exists("id", Person::class) + verify(operations).exists("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Any) with reified type parameter extension should call its Java counterpart`() { + + operations.exists("id") + verify(operations).exists("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Query, KClass) extension should call its Java counterpart`() { + + operations.exists(Query.empty(), Person::class) + verify(operations).exists(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.exists(Query.empty()) + verify(operations).exists(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOneById(Any, KClass) extension should call its Java counterpart`() { + + doReturn(Person("Walter", "White")).whenever(operations).selectOneById("id", Person::class.java) + + operations.selectOneById("id", Person::class) + verify(operations).selectOneById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOneById(Any) with reified type parameter extension should call its Java counterpart`() { + + doReturn(Person("Walter", "White")).whenever(operations).selectOneById("id", Person::class.java) + + operations.selectOneById("id") + verify(operations).selectOneById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `deleteById(Any, KClass) extension should call its Java counterpart`() { + + operations.deleteById("id", Person::class) + verify(operations).deleteById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `deleteById(Any) with reified type parameter extension should call its Java counterpart`() { + + operations.deleteById("id") + verify(operations).deleteById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `truncate(KClass) extension should call its Java counterpart`() { + + operations.truncate(Person::class) + verify(operations).truncate(Person::class.java) + } + + @Test // DATACASS-484 + fun `truncate() with reified type parameter extension should call its Java counterpart`() { + + operations.truncate() + verify(operations).truncate(Person::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableDeleteOperationExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableDeleteOperationExtensionsUnitTests.kt new file mode 100644 index 000000000..9c9fc9ef0 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableDeleteOperationExtensionsUnitTests.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [ExecutableDeleteOperationExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ExecutableDeleteOperationExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: FluentCassandraOperations + + @Test // DATACASS-484 + fun `delete(KClass) extension should call its Java counterpart`() { + + operations.delete(Person::class); + verify(operations).delete(Person::class.java) + } + + @Test // DATACASS-484 + fun `delete() with reified type parameter extension should call its Java counterpart`() { + + operations.delete() + verify(operations).delete(Person::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableInsertOperationExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableInsertOperationExtensionsUnitTests.kt new file mode 100644 index 000000000..c6ec8e08c --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableInsertOperationExtensionsUnitTests.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [ExecutableInsertOperationExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ExecutableInsertOperationExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: FluentCassandraOperations + + @Test // DATACASS-484 + fun `insert(KClass) extension should call its Java counterpart`() { + + operations.insert(Person::class); + verify(operations).insert(Person::class.java) + } + + @Test // DATACASS-484 + fun `insert() with reified type parameter extension should call its Java counterpart`() { + + operations.insert() + verify(operations).insert(Person::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableSelectOperationExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableSelectOperationExtensionsUnitTests.kt new file mode 100644 index 000000000..0f1a4da19 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableSelectOperationExtensionsUnitTests.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person +import org.springframework.data.cassandra.domain.User + +/** + * Unit tests for [ExecutableSelectOperationExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ExecutableSelectOperationExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: FluentCassandraOperations + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operationWithProjection: ExecutableSelectOperation.SelectWithProjection + + @Test // DATACASS-484 + fun `query(KClass) extension should call its Java counterpart`() { + + operations.query(Person::class); + verify(operations).query(Person::class.java) + } + + @Test // DATACASS-484 + fun `query() with reified type parameter extension should call its Java counterpart`() { + + operations.query() + verify(operations).query(Person::class.java) + } + + @Test // DATACASS-484 + fun `asType(KClass) extension should call its Java counterpart`() { + + operationWithProjection.asType(User::class); + verify(operationWithProjection).`as`(User::class.java) + } + + @Test // DATACASS-484 + fun `asType() with reified type parameter extension should call its Java counterpart`() { + + operationWithProjection.asType(); + verify(operationWithProjection).`as`(User::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableUpdateOperationExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableUpdateOperationExtensionsUnitTests.kt new file mode 100644 index 000000000..a11f226a1 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ExecutableUpdateOperationExtensionsUnitTests.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [ExecutableUpdateOperationExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ExecutableUpdateOperationExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: FluentCassandraOperations + + @Test // DATACASS-484 + fun `update(KClass) extension should call its Java counterpart`() { + + operations.update(Person::class); + verify(operations).update(Person::class.java) + } + + @Test // DATACASS-484 + fun `update() with reified type parameter extension should call its Java counterpart`() { + + operations.update() + verify(operations).update(Person::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveCassandraOperationsExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveCassandraOperationsExtensionsUnitTests.kt new file mode 100644 index 000000000..f8717e6c2 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveCassandraOperationsExtensionsUnitTests.kt @@ -0,0 +1,272 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.datastax.driver.core.SimpleStatement +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.core.query.Query +import org.springframework.data.cassandra.core.query.Update +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [ReactiveCassandraOperationsExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ReactiveCassandraOperationsExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: ReactiveCassandraOperations + + // ------------------------------------------------------------------------- + // Methods dealing with static CQL + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `select(String, KClass) extension should call its Java counterpart`() { + + operations.select("SELECT * FROM person", Person::class) + verify(operations).select("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `select(String) with reified type parameter extension should call its Java counterpart`() { + + operations.select("SELECT * FROM person") + verify(operations).select("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(String, KClass) extension should call its Java counterpart`() { + + operations.selectOne("SELECT * FROM person", Person::class) + verify(operations).selectOne("SELECT * FROM person", Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(String) with reified type parameter extension should call its Java counterpart`() { + + operations.selectOne("SELECT * FROM person") + verify(operations).selectOne("SELECT * FROM person", Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with com.datastax.driver.core.Statement + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `select(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.select(statement, Person::class) + verify(operations).select(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `select(Statement) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + operations.select(statement) + verify(operations).select(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.selectOne(statement, Person::class) + verify(operations).selectOne(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Statement) with reified type parameter extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.selectOne(statement) + verify(operations).selectOne(statement, Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with org.springframework.data.cassandra.core.query.Query + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `select(Query, KClass) extension should call its Java counterpart`() { + + operations.select(Query.empty(), Person::class) + verify(operations).select(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `select(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.select(Query.empty()) + verify(operations).select(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Query, KClass) extension should call its Java counterpart`() { + + operations.selectOne(Query.empty(), Person::class) + verify(operations).selectOne(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOne(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.selectOne(Query.empty()) + verify(operations).selectOne(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `update(Query, Update, KClass) extension should call its Java counterpart`() { + + operations.update(Query.empty(), Update.empty(), Person::class) + verify(operations).update(Query.empty(), Update.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `update(Query, Update) with reified type parameter extension should call its Java counterpart`() { + + operations.update(Query.empty(), Update.empty()) + verify(operations).update(Query.empty(), Update.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `delete(Query, KClass) extension should call its Java counterpart`() { + + operations.delete(Query.empty(), Person::class) + verify(operations).delete(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `delete(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.delete(Query.empty()) + verify(operations).delete(Query.empty(), Person::class.java) + } + + // ------------------------------------------------------------------------- + // Methods dealing with entities + // ------------------------------------------------------------------------- + + @Test // DATACASS-484 + fun `count(KClass) extension should call its Java counterpart`() { + + operations.count(Person::class) + verify(operations).count(Person::class.java) + } + + @Test // DATACASS-484 + fun `count() with reified type parameter extension should call its Java counterpart`() { + + operations.count() + verify(operations).count(Person::class.java) + } + + @Test // DATACASS-484 + fun `count(Query, KClass) extension should call its Java counterpart`() { + + operations.count(Query.empty(), Person::class) + verify(operations).count(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `count(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.count(Query.empty()) + verify(operations).count(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Any, KClass) extension should call its Java counterpart`() { + + operations.exists("id", Person::class) + verify(operations).exists("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Any) with reified type parameter extension should call its Java counterpart`() { + + operations.exists("id") + verify(operations).exists("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Query, KClass) extension should call its Java counterpart`() { + + operations.exists(Query.empty(), Person::class) + verify(operations).exists(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `exists(Query) with reified type parameter extension should call its Java counterpart`() { + + operations.exists(Query.empty()) + verify(operations).exists(Query.empty(), Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOneById(Any, KClass) extension should call its Java counterpart`() { + + operations.selectOneById("id", Person::class) + verify(operations).selectOneById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `selectOneById(Any) with reified type parameter extension should call its Java counterpart`() { + + operations.selectOneById("id") + verify(operations).selectOneById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `deleteById(Any, KClass) extension should call its Java counterpart`() { + + operations.deleteById("id", Person::class) + verify(operations).deleteById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `deleteById(Any) with reified type parameter extension should call its Java counterpart`() { + + operations.deleteById("id") + verify(operations).deleteById("id", Person::class.java) + } + + @Test // DATACASS-484 + fun `truncate(KClass) extension should call its Java counterpart`() { + + operations.truncate(Person::class) + verify(operations).truncate(Person::class.java) + } + + @Test // DATACASS-484 + fun `truncate() with reified type parameter extension should call its Java counterpart`() { + + operations.truncate() + verify(operations).truncate(Person::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveDeleteOperationExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveDeleteOperationExtensionsUnitTests.kt new file mode 100644 index 000000000..944a64e61 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveDeleteOperationExtensionsUnitTests.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [ReactiveDeleteOperationExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ReactiveDeleteOperationExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: ReactiveFluentCassandraOperations + + @Test // DATACASS-484 + fun `delete(KClass) extension should call its Java counterpart`() { + + operations.delete(Person::class); + verify(operations).delete(Person::class.java) + } + + @Test // DATACASS-484 + fun `delete() with reified type parameter extension should call its Java counterpart`() { + + operations.delete() + verify(operations).delete(Person::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveInsertOperationExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveInsertOperationExtensionsUnitTests.kt new file mode 100644 index 000000000..65a36f826 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveInsertOperationExtensionsUnitTests.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [ReactiveInsertOperationExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ReactiveInsertOperationExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: ReactiveFluentCassandraOperations + + @Test // DATACASS-484 + fun `insert(KClass) extension should call its Java counterpart`() { + + operations.insert(Person::class); + verify(operations).insert(Person::class.java) + } + + @Test // DATACASS-484 + fun `insert() with reified type parameter extension should call its Java counterpart`() { + + operations.insert() + verify(operations).insert(Person::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveSelectOperationExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveSelectOperationExtensionsUnitTests.kt new file mode 100644 index 000000000..139778916 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveSelectOperationExtensionsUnitTests.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person +import org.springframework.data.cassandra.domain.User + +/** + * Unit tests for [ReactiveSelectOperationExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ReactiveSelectOperationExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: ReactiveFluentCassandraOperations + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operationWithProjection: ReactiveSelectOperation.SelectWithProjection + + @Test // DATACASS-484 + fun `query(KClass) extension should call its Java counterpart`() { + + operations.query(Person::class); + verify(operations).query(Person::class.java) + } + + @Test // DATACASS-484 + fun `query() with reified type parameter extension should call its Java counterpart`() { + + operations.query() + verify(operations).query(Person::class.java) + } + + @Test // DATACASS-484 + fun `asType(KClass) extension should call its Java counterpart`() { + + operationWithProjection.asType(User::class); + verify(operationWithProjection).`as`(User::class.java) + } + + @Test // DATACASS-484 + fun `asType() with reified type parameter extension should call its Java counterpart`() { + + operationWithProjection.asType(); + verify(operationWithProjection).`as`(User::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveUpdateOperationExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveUpdateOperationExtensionsUnitTests.kt new file mode 100644 index 000000000..2d6a14d6e --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/ReactiveUpdateOperationExtensionsUnitTests.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core + +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [ReactiveUpdateOperationExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ReactiveUpdateOperationExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: ReactiveFluentCassandraOperations + + @Test // DATACASS-484 + fun `update(KClass) extension should call its Java counterpart`() { + + operations.update(Person::class); + verify(operations).update(Person::class.java) + } + + @Test // DATACASS-484 + fun `update() with reified type parameter extension should call its Java counterpart`() { + + operations.update() + verify(operations).update(Person::class.java) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/cql/AsyncCqlOperationsExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/cql/AsyncCqlOperationsExtensionsUnitTests.kt new file mode 100644 index 000000000..7d98311d5 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/cql/AsyncCqlOperationsExtensionsUnitTests.kt @@ -0,0 +1,148 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.cql + +import com.datastax.driver.core.Row +import com.datastax.driver.core.SimpleStatement +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.eq +import com.nhaarman.mockito_kotlin.verify +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [AsyncCqlOperationsExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class AsyncCqlOperationsExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: AsyncCqlOperations + + @Test // DATACASS-484 + fun `queryForObject(String, KClass) extension should call its Java counterpart`() { + + operations.queryForObject("", Person::class) + verify(operations).queryForObject("", Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForObject(String) extension should call its Java counterpart`() { + + operations.queryForObject("") + verify(operations).queryForObject("", Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForObject(String, KClass, array) extension should call its Java counterpart`() { + + operations.queryForObject("", Person::class, "foo", "bar") + verify(operations).queryForObject("", Person::class.java, arrayOf("foo", "bar")) + } + + @Test // DATACASS-484 + fun `queryForObject(String, array) extension should call its Java counterpart`() { + + operations.queryForObject("", "foo", "bar") + verify(operations).queryForObject("", Person::class.java, arrayOf("foo", "bar")) + } + + @Test // DATACASS-484 + fun `queryForObject(String, RowMapper, array) extension should call its Java counterpart`() { + + operations.queryForObject("", 3) { rs: Row, _: Int -> rs.getInt(1) } + verify(operations).queryForObject(eq(""), any>(), eq(3)) + } + + @Test // DATACASS-484 + fun `queryForObject(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForObject(statement, Person::class) + verify(operations).queryForObject(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForObject(Statement) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForObject(statement) + verify(operations).queryForObject(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForList(String) extension should call its Java counterpart`() { + + operations.queryForList("") + verify(operations).queryForList("", Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForList(String, array) extension should call its Java counterpart`() { + + operations.queryForList("", "foo", "bar") + verify(operations).queryForList("", Person::class.java, arrayOf("foo", "bar")) + } + + @Test // DATACASS-484 + @Ignore("No such method: queryForList(CQL, RowMapper, Args), see DATACASS-538") + fun `queryForList(String, RowMapper, array) extension should call its Java counterpart`() { + + //operations.queryForList("", 3) { rs: Row, _: Int -> rs.getInt(1) } + verify(operations).queryForList(eq(""), any>(), eq(3)) + } + + @Test // DATACASS-484 + fun `queryForList(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForList(statement, Person::class) + verify(operations).queryForList(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForList(Statement) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForList(statement) + verify(operations).queryForList(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `query(String, ResultSetExtractor, array) extension should call its Java counterpart`() { + + operations.query("", 3) { rs -> Person("Walter", rs.single().getString(0)) } + verify(operations).query(eq(""), any>(), eq(3)) + } + + @Test // DATACASS-484 + fun `query(String, RowMapper, array) extension should call its Java counterpart`() { + + operations.query("", 3) { row, _ -> row.columnDefinitions } + verify(operations).query(eq(""), any>(), eq(3)) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/cql/CqlOperationsExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/cql/CqlOperationsExtensionsUnitTests.kt new file mode 100644 index 000000000..1faebdc7f --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/cql/CqlOperationsExtensionsUnitTests.kt @@ -0,0 +1,155 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.cql + +import com.datastax.driver.core.Row +import com.datastax.driver.core.SimpleStatement +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.eq +import com.nhaarman.mockito_kotlin.verify +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [CqlOperationsExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class CqlOperationsExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: CqlOperations + + @Test // DATACASS-484 + fun `queryForObject(String, KClass) extension should call its Java counterpart`() { + + operations.queryForObject("", Person::class) + verify(operations).queryForObject("", Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForObject(String) extension should call its Java counterpart`() { + + operations.queryForObject("") + verify(operations).queryForObject("", Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForObject(String, KClass, array) extension should call its Java counterpart`() { + + operations.queryForObject("", Person::class, "foo", "bar") + verify(operations).queryForObject("", Person::class.java, arrayOf("foo", "bar")) + } + + @Test // DATACASS-484 + fun `queryForObject(String, array) extension should call its Java counterpart`() { + + operations.queryForObject("", "foo", "bar") + verify(operations).queryForObject("", Person::class.java, arrayOf("foo", "bar")) + } + + @Test // DATACASS-484 + fun `queryForObject(String, RowMapper, array) extension should call its Java counterpart`() { + + operations.queryForObject("", 3) { rs: Row, _: Int -> rs.getInt(1) } + verify(operations).queryForObject(eq(""), any>(), eq(3)) + } + + @Test // DATACASS-484 + fun `queryForObject(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForObject(statement, Person::class) + verify(operations).queryForObject(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForObject(Statement) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForObject(statement) + verify(operations).queryForObject(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForList(String) extension should call its Java counterpart`() { + + operations.queryForList("") + verify(operations).queryForList("", Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForList(String, array) extension should call its Java counterpart`() { + + operations.queryForList("", "foo", "bar") + verify(operations).queryForList("", Person::class.java, arrayOf("foo", "bar")) + } + + @Test // DATACASS-484 + @Ignore("No such method: queryForList(CQL, RowMapper, Args), see DATACASS-538") + fun `queryForList(String, RowMapper, array) extension should call its Java counterpart`() { + + //operations.queryForList("", 3) { rs: Row, _: Int -> rs.getInt(1) } + verify(operations).queryForList(eq(""), any>(), eq(3)) + } + + @Test // DATACASS-484 + fun `queryForList(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForList(statement, Person::class) + verify(operations).queryForList(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForList(Statement) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForList(statement) + verify(operations).queryForList(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `query(String, ResultSetExtractor, array) extension should call its Java counterpart`() { + + operations.query("", 3) { rs -> Person("Walter", rs.single().getString(0)) } + verify(operations).query(eq(""), any>(), eq(3)) + } + + @Test // DATACASS-484 + fun `query(String, RowCallbackHandler, array) extension should call its Java counterpart`() { + + operations.query("", 3) { row -> row.columnDefinitions } + verify(operations).query(eq(""), any(), eq(3)) + } + + @Test // DATACASS-484 + fun `query(String, RowMapper, array) extension should call its Java counterpart`() { + + operations.query("", 3) { row, _ -> row.columnDefinitions } + verify(operations).query(eq(""), any>(), eq(3)) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/cql/ReactiveCqlOperationsExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/cql/ReactiveCqlOperationsExtensionsUnitTests.kt new file mode 100644 index 000000000..e3e5a859b --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/cql/ReactiveCqlOperationsExtensionsUnitTests.kt @@ -0,0 +1,148 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.cql + +import com.datastax.driver.core.Row +import com.datastax.driver.core.SimpleStatement +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.eq +import com.nhaarman.mockito_kotlin.verify +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.springframework.data.cassandra.domain.Person + +/** + * Unit tests for [ReactiveCqlOperationsExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class ReactiveCqlOperationsExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var operations: ReactiveCqlOperations + + @Test // DATACASS-484 + fun `queryForObject(String, KClass) extension should call its Java counterpart`() { + + operations.queryForObject("", Person::class) + verify(operations).queryForObject("", Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForObject(String) extension should call its Java counterpart`() { + + operations.queryForObject("") + verify(operations).queryForObject("", Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForObject(String, KClass, array) extension should call its Java counterpart`() { + + operations.queryForObject("", Person::class, "foo", "bar") + verify(operations).queryForObject("", Person::class.java, arrayOf("foo", "bar")) + } + + @Test // DATACASS-484 + fun `queryForObject(String, array) extension should call its Java counterpart`() { + + operations.queryForObject("", "foo", "bar") + verify(operations).queryForObject("", Person::class.java, arrayOf("foo", "bar")) + } + + @Test // DATACASS-484 + fun `queryForObject(String, RowMapper, array) extension should call its Java counterpart`() { + + operations.queryForObject("", 3) { rs: Row, _: Int -> rs.getInt(1) } + verify(operations).queryForObject(eq(""), any>(), eq(3)) + } + + @Test // DATACASS-484 + fun `queryForObject(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForObject(statement, Person::class) + verify(operations).queryForObject(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForObject(Statement) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForObject(statement) + verify(operations).queryForObject(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForFlux(String) extension should call its Java counterpart`() { + + operations.queryForFlux("") + verify(operations).queryForFlux("", Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForFlux(String, array) extension should call its Java counterpart`() { + + operations.queryForFlux("", "foo", "bar") + verify(operations).queryForFlux("", Person::class.java, arrayOf("foo", "bar")) + } + + @Test // DATACASS-484 + @Ignore("No such method: queryForFlux(CQL, RowMapper, Args), see DATACASS-538") + fun `queryForFlux(String, RowMapper, array) extension should call its Java counterpart`() { + + //operations.queryForFlux("", 3) { rs: Row, _: Int -> rs.getInt(1) } + verify(operations).queryForFlux(eq(""), any>(), eq(3)) + } + + @Test // DATACASS-484 + fun `queryForFlux(Statement, KClass) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForFlux(statement, Person::class) + verify(operations).queryForFlux(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `queryForFlux(Statement) extension should call its Java counterpart`() { + + val statement = SimpleStatement("SELECT * FROM person") + + operations.queryForFlux(statement) + verify(operations).queryForFlux(statement, Person::class.java) + } + + @Test // DATACASS-484 + fun `query(String, ResultSetExtractor, array) extension should call its Java counterpart`() { + + operations.query("", 3) { rs -> rs.rows().next().cast(Person::class.java) } + verify(operations).query(eq(""), any>(), eq(3)) + } + + @Test // DATACASS-484 + fun `query(String, RowMapper, array) extension should call its Java counterpart`() { + + operations.query("", 3) { row, _ -> row.columnDefinitions } + verify(operations).query(eq(""), any>(), eq(3)) + } +} diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/query/CriteriaExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/query/CriteriaExtensionsUnitTests.kt new file mode 100644 index 000000000..370ec8054 --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/query/CriteriaExtensionsUnitTests.kt @@ -0,0 +1,111 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.query + +import com.nhaarman.mockito_kotlin.verify +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnitRunner + +/** + * Unit tests for [CriteriaExtensions]. + * + * @author Mark Paluch + */ +@RunWith(MockitoJUnitRunner::class) +class CriteriaExtensionsUnitTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var criteria: Criteria + + @Test + fun `isEqualTo() extension should call its Java counterpart`() { + + val foo = "foo" + criteria.isEqualTo(foo) + + verify(criteria).`is`(foo) + } + + @Test + fun `isEqualTo() extension should support nullable value`() { + + criteria.isEqualTo(null) + + verify(criteria).`is`(null) + } + + @Test + fun `inValues(varags) extension should call its Java counterpart`() { + + val foo = "foo" + val bar = "bar" + + criteria.inValues(foo, bar) + + Mockito.verify(criteria).`in`(foo, bar) + } + + @Test + fun `inValues(varags) extension should support nullable values`() { + + criteria.inValues(null, null) + + Mockito.verify(criteria).`in`(null, null) + } + + @Test + fun `inValues(Collection) extension should call its Java counterpart`() { + + val c = listOf("foo", "bar") + + criteria.inValues(c) + + verify(criteria).`in`(c) + } + + @Test + fun `inValues(Collection) extension should support nullable values`() { + + val c = listOf("foo", null, "bar") + + criteria.inValues(c) + + verify(criteria).`in`(c) + } + + @Test + fun `where(String) should create Criteria`() { + + val criteria = where("foo").isEqualTo("bar"); + + assertThat(criteria.columnName.toCql()).isEqualTo("foo") + assertThat(criteria.predicate).isNotNull() + } + + @Test + fun `and(CriteriaDefinition) should concatenate criteria`() { + + val criteriaDefinitions = where("foo").isEqualTo("bar") and where("baz").isEqualTo("bar") and where("name").isEqualTo("Doe") + + assertThat(criteriaDefinitions.criteriaDefinitions).hasSize(3) + } +} + diff --git a/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/query/QueryExtensionsUnitTests.kt b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/query/QueryExtensionsUnitTests.kt new file mode 100644 index 000000000..983dad7ac --- /dev/null +++ b/spring-data-cassandra/src/test/kotlin/org/springframework/data/cassandra/core/query/QueryExtensionsUnitTests.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.cassandra.core.query + +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test + +/** + * Unit tests for [QueryExtensions]. + * + * @author Mark Paluch + */ +class QueryExtensionsUnitTests { + + @Test + fun `should create query from concatenated criteria`() { + + val query = query(where("foo").isEqualTo("bar") and // + where("baz").isEqualTo("bar") and // + where("name").isEqualTo("Doe")) + + assertThat(query.toString()).contains("foo = 'bar' AND baz = 'bar' AND name = 'Doe'") + } +} + diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc index 8d06eecc7..e96d8ff62 100644 --- a/src/main/asciidoc/new-features.adoc +++ b/src/main/asciidoc/new-features.adoc @@ -12,6 +12,7 @@ This chapter summarizes changes and new features for each release. * Support for Cassandra `time` columns via `LocalTime`. * Support for `map` columns using User-defined/converted types. * <> +* Kotlin extensions for Template API. [[new-features.2-0-0]] == What's new in Spring Data for Apache Cassandra 2.0