├── .gitignore ├── .jvmopts ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── build.sbt ├── build ├── deploy.asc.enc ├── install_cassandra.sh ├── publish_develop.sh └── run_tests.sh ├── docs └── src │ └── main │ └── mdoc │ ├── README.md │ ├── basics │ ├── automated_schemas.md │ ├── batches.md │ ├── changelog.md │ ├── collection_operations.md │ ├── connectors.md │ ├── database.md │ ├── debugging.md │ ├── indexes │ │ └── sasi.md │ ├── json_columns.md │ ├── primitives.md │ └── tables.md │ ├── commercial │ └── support.md │ ├── comparison.md │ ├── migrate.md │ ├── querying │ ├── aggregation_functions.md │ ├── execution.md │ ├── options.md │ ├── select.md │ └── where_clause.md │ ├── quickstart.md │ └── roadmap.md ├── docs_bkp ├── README.md ├── basics │ ├── automated_schemas.md │ ├── batches.md │ ├── changelog.md │ ├── collection_operations.md │ ├── connectors.md │ ├── custom_types.md │ ├── database.md │ ├── debugging.md │ ├── indexes │ │ └── sasi.md │ ├── json_columns.md │ ├── primitives.md │ └── tables.md ├── commercial │ └── support.md ├── comparison.md ├── migrate.md ├── querying │ ├── aggregation_functions.md │ ├── execution.md │ ├── indexes │ │ └── sasi.md │ ├── insert.md │ ├── options.md │ ├── select.md │ └── where_clause.md ├── quickstart.md └── roadmap.md ├── phantom-connectors └── src │ ├── main │ └── scala │ │ └── com │ │ └── outworkers │ │ └── phantom │ │ └── connectors │ │ ├── CassandraConnection.scala │ │ ├── Connector.scala │ │ ├── ContactPoint.scala │ │ ├── DefaultSessionProvider.scala │ │ ├── KeySpaceBuilder.scala │ │ ├── Keyspace.scala │ │ ├── RootConnector.scala │ │ ├── SessionProvider.scala │ │ ├── Versions.scala │ │ └── package.scala │ └── test │ └── scala │ └── com │ └── outworkers │ └── phantom │ └── connectors │ └── CassandraConnectionTest.scala ├── phantom-dsl └── src │ ├── main │ └── scala │ │ └── com │ │ └── outworkers │ │ └── phantom │ │ ├── CassandraTable.scala │ │ ├── DefaultImports.scala │ │ ├── Manager.scala │ │ ├── NamingStrategy.scala │ │ ├── Row.scala │ │ ├── ScalaQueryContext.scala │ │ ├── SelectTable.scala │ │ ├── TableAliases.scala │ │ ├── builder │ │ ├── Bounds.scala │ │ ├── QueryBuilder.scala │ │ ├── batch │ │ │ └── BatchQuery.scala │ │ ├── clauses │ │ │ └── QueryCondition.scala │ │ ├── ops │ │ │ ├── Alteration.scala │ │ │ ├── ImplicitMechanism.scala │ │ │ ├── Modify.scala │ │ │ ├── Operators.scala │ │ │ ├── PartitionQueryColumn.scala │ │ │ ├── QueryColumn.scala │ │ │ ├── TokenOps.scala │ │ │ └── package.scala │ │ ├── primitives │ │ │ ├── AsciiValue.scala │ │ │ ├── Primitive.scala │ │ │ ├── PrimitiveMacro.scala │ │ │ └── Primitives.scala │ │ ├── query │ │ │ ├── AlterQuery.scala │ │ │ ├── CreateQuery.scala │ │ │ ├── DeleteQuery.scala │ │ │ ├── InsertQuery.scala │ │ │ ├── Parts.scala │ │ │ ├── Query.scala │ │ │ ├── QueryOptions.scala │ │ │ ├── SelectQuery.scala │ │ │ ├── TablePropertyClauses.scala │ │ │ ├── TruncateQuery.scala │ │ │ ├── UpdateQuery.scala │ │ │ ├── engine │ │ │ │ ├── CQLQuery.scala │ │ │ │ └── Parts.scala │ │ │ ├── execution │ │ │ │ ├── ExactlyOncePromise.scala │ │ │ │ ├── ExecutableCqlQuery.scala │ │ │ │ ├── ExecutableStatements.scala │ │ │ │ ├── ExecutionEngine.scala │ │ │ │ ├── FutureMonad.scala │ │ │ │ ├── QueryCollection.scala │ │ │ │ ├── QueryInterface.scala │ │ │ │ ├── RecordResult.scala │ │ │ │ ├── ResultQueryInterface.scala │ │ │ │ └── package.scala │ │ │ ├── options │ │ │ │ ├── Caching.scala │ │ │ │ ├── Compaction.scala │ │ │ │ ├── Compression.scala │ │ │ │ └── TableProperty.scala │ │ │ ├── prepared │ │ │ │ ├── ListValue.scala │ │ │ │ └── PreparedBuilder.scala │ │ │ └── sasi │ │ │ │ ├── mode.scala │ │ │ │ ├── ops.scala │ │ │ │ ├── sasi.scala │ │ │ │ └── types.scala │ │ ├── serializers │ │ │ ├── AlterQueryBuilder.scala │ │ │ ├── BaseModifiers.scala │ │ │ ├── BatchQueryBuilder.scala │ │ │ ├── CollectionModifiers.scala │ │ │ ├── CreateQueryBuilder.scala │ │ │ ├── DeleteQueryBuilder.scala │ │ │ ├── IndexModifiers.scala │ │ │ ├── InsertQueryBuilder.scala │ │ │ ├── KeySpaceQuerySerializer.scala │ │ │ ├── SASIQueryBuilder.scala │ │ │ ├── SelectQueryBuilder.scala │ │ │ ├── UpdateQueryBuilder.scala │ │ │ └── Utils.scala │ │ └── syntax │ │ │ └── CQLSyntax.scala │ │ ├── column │ │ ├── AbstractColumn.scala │ │ ├── CollectionColumn.scala │ │ ├── CollectionValueDefinition.scala │ │ ├── Column.scala │ │ ├── CounterColumn.scala │ │ ├── MapColumn.scala │ │ ├── OptionalColumn.scala │ │ ├── OptionalPrimitiveColumn.scala │ │ ├── PrimitiveColumn.scala │ │ └── TimeUUIDColumn.scala │ │ ├── database │ │ ├── Database.scala │ │ └── DatabaseProvider.scala │ │ ├── dsl │ │ └── package.scala │ │ ├── jdk8 │ │ ├── Shared.scala │ │ ├── indexed │ │ │ └── package.scala │ │ └── package.scala │ │ ├── keys │ │ ├── ClusteringOrder.scala │ │ ├── PrimaryKey.scala │ │ └── SASIIndex.scala │ │ ├── macros │ │ ├── BindHelper.scala │ │ ├── DatabaseHelper.scala │ │ ├── HListEqs.scala │ │ ├── RootMacro.scala │ │ ├── SingleGeneric.scala │ │ ├── TableHelper.scala │ │ ├── debug │ │ │ └── package.scala │ │ └── toolbelt │ │ │ ├── BlackboxToolbelt.scala │ │ │ ├── HListHelpers.scala │ │ │ └── WhiteboxToolbelt.scala │ │ └── ops │ │ ├── DbOps.scala │ │ ├── QueryContext.scala │ │ ├── SelectQueryOps.scala │ │ └── UpdateIncompleteQueryOps.scala │ └── test │ ├── resources │ └── logback-test.xml │ └── scala │ └── com │ └── outworkers │ └── phantom │ ├── JsonFormats.scala │ ├── PhantomSuite.scala │ ├── builder │ ├── batch │ │ ├── BatchQuerySerialisationTest.scala │ │ └── BatchQueryTest.scala │ ├── primitives │ │ ├── DerivedField.scala │ │ ├── NestedPrimitivesTest.scala │ │ ├── PrimitiveColumnRecipesTest.scala │ │ ├── PrimitiveRoundtripTests.scala │ │ ├── PrimitiveSerializationTests.scala │ │ ├── PrimitiveUtilsTest.scala │ │ ├── PrimitivesTest.scala │ │ └── package.scala │ ├── query │ │ ├── ColumnsSchemaTest.scala │ │ ├── KeySpaceSuite.scala │ │ ├── QueryOptionsTest.scala │ │ ├── bugs │ │ │ ├── ImbugBug.scala │ │ │ ├── QuotedSecondaryIndexes.scala │ │ │ └── SchemaBug663Test.scala │ │ ├── compilation │ │ │ ├── BatchRestrictionTest.scala │ │ │ ├── CompareAndSetRestrictionsTest.scala │ │ │ ├── IndexOperatorsRestrictionTests.scala │ │ │ ├── ModifyOperatorRestrictions.scala │ │ │ ├── TypeRestrictionsTest.scala │ │ │ └── WhereClauseRestrictionsTest.scala │ │ ├── db │ │ │ ├── batch │ │ │ │ ├── BatchTest.scala │ │ │ │ ├── CounterBatchTest.scala │ │ │ │ └── UnloggedBatchTest.scala │ │ │ ├── crud │ │ │ │ ├── CountTest.scala │ │ │ │ ├── CreateTest.scala │ │ │ │ ├── DeleteQueryTests.scala │ │ │ │ ├── DistinctTest.scala │ │ │ │ ├── InsertCasTest.scala │ │ │ │ ├── InsertTest.scala │ │ │ │ ├── ListOperatorsTest.scala │ │ │ │ ├── MapOperationsTest.scala │ │ │ │ ├── RelationalOperatorsTest.scala │ │ │ │ ├── SelectJsonTest.scala │ │ │ │ ├── SelectOptionalTest.scala │ │ │ │ ├── SelectTest.scala │ │ │ │ ├── SetOperationsTest.scala │ │ │ │ ├── TTLTest.scala │ │ │ │ ├── TruncateTest.scala │ │ │ │ └── UpdateQueryTest.scala │ │ │ ├── ordering │ │ │ │ ├── OrderByTest.scala │ │ │ │ └── TimeSeriesTest.scala │ │ │ ├── select │ │ │ │ └── PartialSelectTest.scala │ │ │ └── specialized │ │ │ │ ├── ConditionalQueriesTest.scala │ │ │ │ ├── ConsistencyLevelTests.scala │ │ │ │ ├── CounterColumnTest.scala │ │ │ │ ├── EnumColumnTest.scala │ │ │ │ ├── InOperatorTest.scala │ │ │ │ ├── IndexedCollectionsTest.scala │ │ │ │ ├── JodaDateTimeColumnTest.scala │ │ │ │ ├── JsonColumnTest.scala │ │ │ │ ├── OptionalIndexesTest.scala │ │ │ │ ├── SecondaryIndexTest.scala │ │ │ │ ├── SelectFunctionsTesting.scala │ │ │ │ ├── StaticColumnTest.scala │ │ │ │ ├── TimeUuidTest.scala │ │ │ │ └── TupleColumnTest.scala │ │ ├── engine │ │ │ └── CQLQueryTest.scala │ │ ├── execution │ │ │ └── QueryCollectionsTest.scala │ │ ├── prepared │ │ │ ├── BatchablePreparedInsertQueryTest.scala │ │ │ ├── ExactlyOncePromiseTests.scala │ │ │ ├── JsonPreparedInserts.scala │ │ │ ├── PreparedDeleteQueryTest.scala │ │ │ ├── PreparedInsertQueryTest.scala │ │ │ ├── PreparedSelectQueryTest.scala │ │ │ └── PreparedUpdateQueryTest.scala │ │ └── sasi │ │ │ ├── SASIIntegrationTest.scala │ │ │ ├── SASIOptionsTest.scala │ │ │ └── SASIQueriesTest.scala │ └── serializers │ │ ├── AlterQueryBuilderTest.scala │ │ ├── BasicQueryBuilderTest.scala │ │ ├── BatchQuerySerializationTest.scala │ │ ├── CollectionModifiersSerialisationTest.scala │ │ ├── CreateQueryBuilderTest.scala │ │ ├── CreateQuerySerialisationTest.scala │ │ ├── DeleteQueryBuilderTest.scala │ │ ├── DeleteQuerySerialisationTest.scala │ │ ├── InsertQueryBuilderTest.scala │ │ ├── InsertQuerySerializationTest.scala │ │ ├── KeySpaceSerializerTest.scala │ │ ├── PartsSerializationTest.scala │ │ ├── QuerySerializationTest.scala │ │ ├── SASIQueryBuilderTest.scala │ │ ├── SelectQueryBuilderTest.scala │ │ ├── SelectQuerySerialisationTest.scala │ │ ├── TokenQuerySerialisationTest.scala │ │ ├── UpdateQueryBuilderTest.scala │ │ ├── UpdateQuerySerializationTest.scala │ │ ├── WhereClauseOperatorsSerializationTest.scala │ │ └── datatypes │ │ ├── DataTypeSerializationTest.scala │ │ └── PasswordInfo.scala │ ├── database │ ├── BasicDatabase.scala │ ├── DatabaseInitialisationTests.scala │ ├── DatabaseProviderTest.scala │ └── DatabaseTest.scala │ ├── jdk8 │ ├── Jdk8PrimitivesTest.scala │ ├── Jdk8TimeColumnsTest.scala │ ├── Jdk8TimeUUIDTests.scala │ ├── Jdk8TimeuuidConvertTests.scala │ ├── indexed │ │ └── IndexedRoundtripTests.scala │ └── tables │ │ ├── ExtendedJdk8Primitives.scala │ │ ├── Jdk8Database.scala │ │ ├── OptionalPrimitivesJdk8.scala │ │ ├── PrimitivesJdk8.scala │ │ └── package.scala │ ├── json │ └── JsonTable.scala │ ├── sasi │ └── SASIIndexedArticles.scala │ └── tables │ ├── Articles.scala │ ├── BasicTable.scala │ ├── BasicTableMethods.scala │ ├── CounterTableTest.scala │ ├── IndexedCollectionsTable.scala │ ├── JsonTable.scala │ ├── ListCollectionTable.scala │ ├── MultipleKeys.scala │ ├── NamedArticlesByAuthor.scala │ ├── NamingStrategyDatabase.scala │ ├── NamingStrategyTests.scala │ ├── OptionalPrimitives.scala │ ├── OptionalPrimitivesCassandra22.scala │ ├── OptionalSecondaryIndexTable.scala │ ├── OrderedPartitionTable.scala │ ├── PrimaryCollectionTable.scala │ ├── PrimitivesCassandra22.scala │ ├── PrimitivesJoda.scala │ ├── PrimitivesTable.scala │ ├── Recipes.scala │ ├── ScalaTypesMapTable.scala │ ├── SecondaryIndexTable.scala │ ├── SessionsByUserId.scala │ ├── SkipRecordsByToken.scala │ ├── StaticTableTest.scala │ ├── TableHelperRuntimeTests.scala │ ├── TableHelperTest.scala │ ├── TableKeyGenerationTest.scala │ ├── TableKeyTests.scala │ ├── TestDatabase.scala │ ├── TestTable.scala │ ├── TestTable2.scala │ ├── TimeSeriesTable.scala │ ├── TimeSeriesTableWithTTL.scala │ ├── TupleColumnTable.scala │ ├── TupleTypeTable.scala │ ├── WideTable.scala │ ├── bugs │ ├── BatchBugTable.scala │ ├── ClientKeys.scala │ ├── JsonPreparedTable.scala │ ├── MapPrimitiveBug.scala │ ├── NonIndexQueryColumns.scala │ ├── OrgHierarchyByNode.scala │ ├── PrimitiveColumnRecipes.scala │ ├── Schema.scala │ ├── SchemaBug656Model.scala │ ├── SchemaBug656Table.scala │ ├── SchemaBug663Table.scala │ ├── SchemaBugModel.scala │ ├── SchemaBugSecondaryIndex.scala │ ├── SqlTimestampBug.scala │ ├── SymphonyBug.scala │ ├── TestCaseSchema.scala │ ├── TuplePartitionTable.scala │ └── VerizonPreparedUpdateBug.scala │ └── dbs │ └── SecondaryIndexOnlyDatabase.scala ├── phantom-example └── src │ ├── main │ ├── scala │ │ └── com │ │ │ └── outworkers │ │ │ └── phantom │ │ │ └── example │ │ │ ├── advanced │ │ │ ├── AdvancedRecipes.scala │ │ │ ├── AdvancedRecipesByTitle.scala │ │ │ └── RecipesDatabase.scala │ │ │ └── basics │ │ │ ├── CompositeKeyRecipes.scala │ │ │ ├── ExampleConnector.scala │ │ │ ├── SecondaryKeyRecipes.scala │ │ │ ├── SimpleRecipes.scala │ │ │ └── ThriftModels.scala │ └── thrift │ │ └── Sample.thrift │ └── test │ └── scala │ └── com │ └── outworkers │ └── phantom │ └── example │ ├── ExampleSuite.scala │ ├── advanced │ └── AdvancedRecipesTest.scala │ └── basics │ ├── CompositeKeyTests.scala │ └── SimpleRecipesTest.scala ├── phantom-finagle └── src │ ├── main │ └── scala │ │ └── com │ │ └── outworkers │ │ └── phantom │ │ └── finagle │ │ ├── ResultSpool.scala │ │ ├── execution │ │ ├── TwitterGuavaAdapter.scala │ │ └── TwitterQueryContext.scala │ │ └── package.scala │ └── test │ ├── resources │ └── logback-test.xml │ └── scala │ └── com │ └── outworkers │ └── phantom │ └── finagle │ ├── CreateQueryFinagleTests.scala │ ├── SelectFunctionsTesting.scala │ ├── SpoolBenchmarkPerformanceTest.scala │ ├── TwitterFutures.scala │ └── query │ └── prepared │ ├── BatchablePreparedInsertQueryTest.scala │ ├── ExactlyOncePromiseTests.scala │ ├── JsonPreparedInserts.scala │ ├── PreparedDeleteQueryTest.scala │ ├── PreparedInsertQueryTest.scala │ ├── PreparedSelectQueryTest.scala │ └── PreparedUpdateQueryTest.scala ├── phantom-monix └── src │ ├── main │ └── scala │ │ └── com │ │ └── outworkers │ │ └── phantom │ │ └── monix │ │ ├── execution │ │ ├── MonixImplicits.scala │ │ ├── MonixPromiseInterface.scala │ │ └── MonixQueryContext.scala │ │ └── package.scala │ └── test │ └── scala │ └── com │ └── outworkers │ └── phantom │ └── monix │ ├── CreateQueryMonixTests.scala │ ├── MonixSuite.scala │ └── SelectFunctionsTesting.scala ├── phantom-sbt └── src │ └── main │ ├── resources │ └── log4j.properties │ └── scala-2.10 │ └── com │ └── outworkers │ └── phantom │ └── sbt │ └── SbtPlugin.scala ├── phantom-streams └── src │ ├── main │ └── scala │ │ └── com │ │ └── outworkers │ │ └── phantom │ │ └── streams │ │ ├── ReactiveCassandra.scala │ │ ├── iteratee │ │ ├── Enumerator.scala │ │ └── Iteratee.scala │ │ ├── lib │ │ ├── EnumeratorPublisher.scala │ │ ├── EnumeratorSubscription.scala │ │ ├── EnumeratorSubscriptionFactory.scala │ │ ├── NonBlockingMutex.scala │ │ ├── RelaxedPublisher.scala │ │ ├── StateMachine.scala │ │ └── SubscriptionHandler.scala │ │ └── package.scala │ └── test │ ├── resources │ └── logback-test.xml │ └── scala │ └── com │ └── outworkers │ └── phantom │ └── streams │ └── suites │ ├── BatchSubscriberIntegrationTest.scala │ ├── BatchSubscriberWhiteboxTest.scala │ ├── CassandraTest.scala │ ├── EnumeratorPublisherSpec.scala │ ├── EventRecorder.scala │ ├── PublisherIntegrationTest.scala │ └── iteratee │ ├── BigTest.scala │ ├── IterateeBenchmarkPerformanceTest.scala │ ├── IterateeBigReadPerformanceTest.scala │ ├── IterateeInsertPerformanceTest.scala │ ├── IterateePerformanceTest.scala │ ├── IteratorTest.scala │ └── OperaPublisher.scala ├── phantom-thrift └── src │ ├── main │ ├── scala │ │ └── com │ │ │ └── outworkers │ │ │ └── phantom │ │ │ └── thrift │ │ │ ├── ThriftHelper.scala │ │ │ ├── columns │ │ │ └── Ops.scala │ │ │ └── package.scala │ └── thrift │ │ └── test.thrift │ └── test │ ├── resources │ ├── cassandra.yaml │ ├── log4j-embedded-cassandra.properties │ └── log4j.xml │ └── scala │ └── com │ └── outworkers │ └── phantom │ └── thrift │ ├── tests │ ├── ThriftRecord.scala │ ├── binary │ │ ├── BinarySuite.scala │ │ ├── suites │ │ │ ├── OptionalThriftColumnTest.scala │ │ │ ├── ThriftBinarySerializationTests.scala │ │ │ ├── ThriftColumnTest.scala │ │ │ ├── ThriftIndexTableTest.scala │ │ │ ├── ThriftListOperations.scala │ │ │ ├── ThriftMapColumnTest.scala │ │ │ └── ThriftSetOperationsTest.scala │ │ └── tables.scala │ ├── compact │ │ ├── CompactSuite.scala │ │ ├── suites │ │ │ ├── OptionalThriftColumnTest.scala │ │ │ ├── ThirftCompactSerializationTests.scala │ │ │ ├── ThriftColumnTest.scala │ │ │ ├── ThriftIndexTableTest.scala │ │ │ ├── ThriftListOperations.scala │ │ │ ├── ThriftMapColumnTest.scala │ │ │ └── ThriftSetOperationsTest.scala │ │ └── tables.scala │ └── tjson │ │ ├── TJsonSuite.scala │ │ ├── suites │ │ ├── OptionalThriftColumnTest.scala │ │ ├── ThriftColumnTest.scala │ │ ├── ThriftIndexTableTest.scala │ │ ├── ThriftListOperations.scala │ │ ├── ThriftMapColumnTest.scala │ │ ├── ThriftSetOperationsTest.scala │ │ └── ThriftTJsonSerializationTests.scala │ │ └── tables.scala │ └── util │ └── ThriftTestSuite.scala ├── project ├── Publishing.scala ├── build.properties └── plugins.sbt ├── scalastyle-config.xml └── version.sbt /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | *.jar 4 | *.jar.old 5 | 6 | atlassian-ide-plugin.xml 7 | 8 | 9 | # Eclipse specific 10 | .classpath 11 | .project 12 | .settings/ 13 | .metadata 14 | 15 | # Project statistics 16 | stats 17 | 18 | # Java heap dump files 19 | java_pid* 20 | 21 | 22 | # InteliJ IDEA 23 | *.iml 24 | .idea_modules/ 25 | .idea/ 26 | 27 | # sbt specific 28 | dist/* 29 | target/ 30 | lib_managed/ 31 | src_managed/ 32 | project/boot/ 33 | project/plugins/project/ 34 | 35 | # Scala-IDE specific 36 | .scala_dependencies 37 | 38 | # MacOS X specific 39 | .DS_Store 40 | 41 | # Atom editor specific 42 | _config.yml 43 | project/project/ 44 | build/deploy.asc 45 | build/git_credentials.asc -------------------------------------------------------------------------------- /.jvmopts: -------------------------------------------------------------------------------- 1 | -Xmx2G 2 | -Djava.net.preferIPv4Stack=true 3 | -XX:MetaspaceSize=512m 4 | -XX:MaxMetaspaceSize=1G 5 | -------------------------------------------------------------------------------- /build/deploy.asc.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outworkers/phantom/e35aeb956f0c77fff5411bd4f9104509545be958/build/deploy.asc.enc -------------------------------------------------------------------------------- /build/install_cassandra.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | python -V 4 | pip install --user 'pyOpenSSL' 5 | pip install --user 'ndg-httpsclient' 6 | 7 | pip install --user 'pyasn1' 8 | pip install --user 'urllib3' 9 | pip install --user 'requests[security]' 10 | pip install --user ccm 11 | 12 | echo "Installing Cassandra using ccm; version: ${CASSANDRA_VERSION}" 13 | ccm create test -v $CASSANDRA_VERSION -n 1 -s timeout 60 14 | ccm node1 showlog 15 | 16 | if [ -e "/var/log/cassandra/" ]; then 17 | cat /var/log/cassandra/system.log 18 | else 19 | echo "No lib directory found" 20 | fi 21 | 22 | -------------------------------------------------------------------------------- /build/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | function run_test_suite { 3 | if [ "${TRAVIS_SCALA_VERSION}" == "${TARGET_SCALA_VERSION}" ] && [ "${TRAVIS_JDK_VERSION}" == "oraclejdk8" ]; 4 | then 5 | echo "Running tests with coverage and report submission" 6 | sbt ++$TRAVIS_SCALA_VERSION coverage test coverageReport coverageAggregate coveralls 7 | test_exit_code=$? 8 | 9 | if [ "${TRAVIS_PULL_REQUEST}" == "true" ]; 10 | then 11 | 12 | if [ ${test_exit_code} -eq "0" ]; 13 | then 14 | 15 | echo "Running tut compilation" 16 | sbt ++$TRAVIS_SCALA_VERSION "project readme" "tut" 17 | local tut_exit_code=$? 18 | echo "Tut compilation exited with status $tut_exit_code" 19 | exit ${tut_exit_code} 20 | else 21 | echo "Unable to run tut compilation, test suite failed" 22 | exit ${test_exit_code} 23 | fi 24 | else 25 | echo "Not a pull request, no need to run tut compilation as it runs as part of sbt release" 26 | exit ${test_exit_code} 27 | fi 28 | else 29 | echo "Running tests without attempting to submit coverage reports or run tut" 30 | sbt "++$TRAVIS_SCALA_VERSION test" 31 | exit $? 32 | fi 33 | } 34 | 35 | run_test_suite -------------------------------------------------------------------------------- /docs/src/main/mdoc/querying/where_clause.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outworkers/phantom/e35aeb956f0c77fff5411bd4f9104509545be958/docs/src/main/mdoc/querying/where_clause.md -------------------------------------------------------------------------------- /docs_bkp/querying/where_clause.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outworkers/phantom/e35aeb956f0c77fff5411bd4f9104509545be958/docs_bkp/querying/where_clause.md -------------------------------------------------------------------------------- /phantom-connectors/src/main/scala/com/outworkers/phantom/connectors/Keyspace.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.connectors 17 | 18 | import com.datastax.driver.core.{ProtocolVersion, Session} 19 | 20 | import scala.annotation.implicitNotFound 21 | 22 | trait SessionAugmenter { 23 | 24 | def session: Session 25 | 26 | def protocolVersion: ProtocolVersion = { 27 | session.getCluster.getConfiguration.getProtocolOptions.getProtocolVersion 28 | } 29 | 30 | def isNewerThan(pv: ProtocolVersion): Boolean = { 31 | protocolVersion.compareTo(pv) > 0 32 | } 33 | 34 | def v3orNewer: Boolean = isNewerThan(ProtocolVersion.V2) 35 | 36 | def protocolConsistency: Boolean = isNewerThan(ProtocolVersion.V1) 37 | 38 | def v4orNewer: Boolean = isNewerThan(ProtocolVersion.V3) 39 | } 40 | 41 | trait SessionAugmenterImplicits { 42 | implicit class RichSession(val session: Session) extends SessionAugmenter 43 | } 44 | 45 | @implicitNotFound("You haven't provided a KeySpace in scope. Use a Connector to automatically inject one.") 46 | case class KeySpace(name: String) 47 | -------------------------------------------------------------------------------- /phantom-connectors/src/main/scala/com/outworkers/phantom/connectors/RootConnector.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.connectors 17 | 18 | import com.datastax.driver.core.Session 19 | 20 | trait RootConnector { 21 | 22 | implicit def space: KeySpace 23 | 24 | implicit def session: Session 25 | } 26 | -------------------------------------------------------------------------------- /phantom-connectors/src/main/scala/com/outworkers/phantom/connectors/SessionProvider.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.connectors 17 | 18 | import com.datastax.driver.core.{Cluster, Session} 19 | import org.slf4j.{Logger, LoggerFactory} 20 | 21 | /** 22 | * Responsible for providing Session instances of the 23 | * Cassandra driver for multiple keySpaces defined 24 | * in the same cluster. 25 | */ 26 | trait SessionProvider { 27 | 28 | lazy val logger: Logger = LoggerFactory.getLogger(this.getClass) 29 | 30 | def defaultKeyspaceCreationQuery(keySpace: String): String = { 31 | s""" 32 | |CREATE KEYSPACE IF NOT EXISTS $keySpace WITH replication = { 33 | | 'class': 'SimpleStrategy', 34 | | 'replication_factor' : 1 35 | |}; 36 | """.stripMargin 37 | } 38 | 39 | /** 40 | * The Cassandra driver's Cluster instance 41 | * used by this provider to create new 42 | * Session instances. 43 | */ 44 | def cluster: Cluster 45 | 46 | def space: KeySpace 47 | 48 | /** 49 | * Returns a Session instance for the keySpace 50 | * with the specified name. 51 | * 52 | * It is recommended that implementations 53 | * cache instances per keySpace, so that they 54 | * can hand out existing instances in case 55 | * a client asks for the same keySpace multiple 56 | * times. 57 | */ 58 | def session: Session 59 | } 60 | -------------------------------------------------------------------------------- /phantom-connectors/src/main/scala/com/outworkers/phantom/connectors/Versions.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.connectors 17 | 18 | import com.datastax.driver.core.{VersionNumber => DatastaxVersionNumber} 19 | 20 | sealed trait VersionBuilder { 21 | def apply(major: Int, minor: Int, patch: Int): DatastaxVersionNumber = { 22 | DatastaxVersionNumber.parse(s"$major.$minor.$patch") 23 | } 24 | } 25 | 26 | private object Version extends VersionBuilder 27 | 28 | object DefaultVersions { 29 | val `2.0.8` = Version(2, 0, 8) 30 | val `2.0.9` = Version(2, 0, 9) 31 | val `2.0.10` = Version(2, 0, 10) 32 | val `2.0.11` = Version(2, 0, 11) 33 | val `2.0.12` = Version(2, 0, 12) 34 | val `2.0.13` = Version(2, 0, 13) 35 | val `2.1.0` = Version(2, 1, 0) 36 | val `2.1.1` = Version(2, 1, 1) 37 | val `2.1.2` = Version(2, 1, 2) 38 | val `2.1.3` = Version(2, 1, 3) 39 | val `2.1.4` = Version(2, 1, 4) 40 | val `2.1.5` = Version(2, 1, 5) 41 | val `2.1.6` = Version(2, 1, 6) 42 | val `2.1.7` = Version(2, 1, 7) 43 | val `2.1.8` = Version(2, 1, 8) 44 | val `2.1.9` = Version(2, 1, 9) 45 | val `2.2.0` = Version(2, 2, 0) 46 | val `2.2.1` = Version(2, 2, 1) 47 | val `2.2.2` = Version(2, 2, 2) 48 | val `2.2.8` = Version(2, 2, 8) 49 | val `2.3.0` = Version(2, 3, 0) 50 | val `3.0.0` = Version(3, 0, 0) 51 | val `3.1.0` = Version(3, 1, 0) 52 | val `3.2.0` = Version(3, 2, 0) 53 | val `3.3.0` = Version(3, 3, 0) 54 | val `3.4.0` = Version(3, 4, 0) 55 | val `3.5.0` = Version(3, 5, 0) 56 | val `3.6.0` = Version(3, 6, 0) 57 | val `3.7.0` = Version(3, 7, 0) 58 | val `3.8.0` = Version(3, 8, 0) 59 | val `3.10.0` = Version(3, 10, 0) 60 | } -------------------------------------------------------------------------------- /phantom-connectors/src/main/scala/com/outworkers/phantom/connectors/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom 17 | 18 | import com.datastax.driver.core.Cluster 19 | 20 | package object connectors { 21 | 22 | type ClusterBuilder = (Cluster.Builder => Cluster.Builder) 23 | 24 | type VersionNumber = com.datastax.driver.core.VersionNumber 25 | 26 | @deprecated("Renamed to the more descriptive CassandraConnection", "2.0.0") 27 | type KeySpaceDef = com.outworkers.phantom.connectors.CassandraConnection 28 | } -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/Manager.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom 17 | 18 | import java.util.concurrent.Executors 19 | import org.slf4j.{Logger, LoggerFactory} 20 | import scala.concurrent.{ExecutionContext, ExecutionContextExecutor} 21 | 22 | object Manager { 23 | 24 | private[this] lazy val taskExecutor = Executors.newCachedThreadPool() 25 | 26 | implicit lazy val scalaExecutor: ExecutionContext = ExecutionContext.fromExecutor(taskExecutor) 27 | 28 | val logger: Logger = LoggerFactory.getLogger("com.outworkers.phantom") 29 | 30 | /** 31 | * Shuts down the default task executors for Guava ListenableFutures and for Scala Futures. 32 | * @deprecated ("Call shutdown on a [[com.outworkers.phantom.database.Database]] instead", "1.15.0") 33 | */ 34 | def shutdown(): Unit = { 35 | logger.info("Shutting down executors") 36 | taskExecutor.shutdown() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/Bounds.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder 17 | 18 | sealed trait LimitBound 19 | trait Limited extends LimitBound 20 | trait Unlimited extends LimitBound 21 | 22 | sealed trait OrderBound 23 | trait Ordered extends OrderBound 24 | trait Unordered extends OrderBound 25 | 26 | sealed trait ConsistencyBound 27 | trait Specified extends ConsistencyBound 28 | trait Unspecified extends ConsistencyBound 29 | 30 | sealed trait WhereBound 31 | trait Chainned extends WhereBound 32 | trait Unchainned extends WhereBound -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/ops/Alteration.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.ops 17 | 18 | import java.nio.ByteBuffer 19 | import java.util.UUID 20 | 21 | import org.joda.time.DateTime 22 | 23 | /** 24 | * Typeclass used to prevent invalid type alterations at compile time. 25 | * Cassandra only allows for specific changes of column types using ALTER Query 26 | * which means we need to somehow enforce the existing mechanism. 27 | * 28 | * We do so by requesting compile time implicit evidence that any type alteration must supply, 29 | * e.g. that Source and Target have a predefined allowed alteration. 30 | * 31 | * The list of allowed ops is found here: [[[https://docs.datastax.com/en/cql/3.1/cql/cql_reference/alter_table_r.html]]. 32 | * 33 | * @tparam Source The source type of the column. 34 | * @tparam Target The target type of the column. 35 | */ 36 | sealed trait Alteration[Source, Target] 37 | 38 | trait Alterations { 39 | implicit object IntToVarint extends Alteration[Int, BigInt] 40 | 41 | implicit object TimeUUIDToVarint extends Alteration[UUID, UUID] 42 | 43 | implicit object DoubleToBlob extends Alteration[Double, ByteBuffer] 44 | implicit object IntToBlob extends Alteration[Int, ByteBuffer] 45 | implicit object TimestampToBlob extends Alteration[DateTime, ByteBuffer] 46 | implicit object UUIDToBlob extends Alteration[UUID, ByteBuffer] 47 | } 48 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/ops/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder 17 | 18 | import java.nio.ByteBuffer 19 | 20 | import com.datastax.driver.core.Session 21 | 22 | package object ops { 23 | 24 | 25 | type TokenizerKey = (Session => RoutingKeyValue) 26 | } 27 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/primitives/AsciiValue.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.primitives 17 | 18 | case class AsciiValue(value: String) -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/query/Query.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query 17 | 18 | import com.outworkers.phantom.CassandraTable 19 | import com.outworkers.phantom.builder._ 20 | import com.outworkers.phantom.builder.query.execution.ExecutableCqlQuery 21 | import com.outworkers.phantom.connectors.SessionAugmenterImplicits 22 | 23 | abstract class RootQuery[ 24 | Table <: CassandraTable[Table, _], 25 | Record, 26 | Status <: ConsistencyBound 27 | ] extends SessionAugmenterImplicits { 28 | 29 | def queryString: String = executableQuery.qb.terminate.queryString 30 | 31 | def executableQuery: ExecutableCqlQuery 32 | } 33 | 34 | trait Batchable { 35 | def executableQuery: ExecutableCqlQuery 36 | } 37 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/query/execution/ExecutableCqlQuery.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.outworkers.phantom.builder.query.execution 18 | 19 | import com.datastax.driver.core.{Session, SimpleStatement, Statement} 20 | import com.outworkers.phantom.builder.ops.TokenizerKey 21 | import com.outworkers.phantom.builder.query.engine.CQLQuery 22 | import com.outworkers.phantom.builder.query.{QueryOptions, RoutingKeyModifier} 23 | 24 | 25 | case class ExecutableCqlQuery( 26 | qb: CQLQuery, 27 | options: QueryOptions = QueryOptions.empty, 28 | tokens: List[TokenizerKey] 29 | ) { 30 | 31 | def statement()(implicit session: Session): Statement = { 32 | options(RoutingKeyModifier(tokens).apply(new SimpleStatement(qb.terminate.queryString))) 33 | } 34 | } 35 | 36 | object ExecutableCqlQuery { 37 | def empty: ExecutableCqlQuery = ExecutableCqlQuery(CQLQuery.empty, QueryOptions.empty, Nil) 38 | } -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/query/execution/ExecutionEngine.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.execution 17 | 18 | import com.outworkers.phantom.ResultSet 19 | import scala.collection.compat._ 20 | 21 | 22 | trait ExecutionEngine[F[_]] { 23 | 24 | def future[M[X] <: IterableOnce[X]](col: QueryCollection[M]): F[M[ResultSet]] 25 | 26 | } 27 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/query/execution/QueryCollection.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.execution 17 | 18 | import scala.collection.compat._ 19 | 20 | class QueryCollection[M[X] <: IterableOnce[X]](val queries: M[ExecutableCqlQuery])( 21 | implicit cbf: BuildFrom[M[ExecutableCqlQuery], ExecutableCqlQuery, M[ExecutableCqlQuery]] 22 | ) { 23 | 24 | def isEmpty: Boolean = queries.iterator.isEmpty 25 | 26 | def size: Int = queries.iterator.size 27 | 28 | def appendAll(appendable: M[ExecutableCqlQuery]): QueryCollection[M] = { 29 | val builder = cbf.newBuilder(queries) 30 | 31 | for (q <- queries.iterator) builder += q 32 | for (q <- appendable.iterator) builder += q 33 | new QueryCollection(builder.result()) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/query/execution/RecordResult.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.outworkers.phantom.builder.query.execution 18 | 19 | import com.datastax.driver.core.PagingState 20 | import com.outworkers.phantom.ResultSet 21 | import com.outworkers.phantom.builder.query.Payload 22 | 23 | trait RecordResult[R] { 24 | 25 | def result: ResultSet 26 | 27 | def pagingState: PagingState = result.getExecutionInfo.getPagingState 28 | 29 | def incomingPayload: Payload = result.incomingPayload 30 | 31 | def state: Option[PagingState] = Option(result.getExecutionInfo.getPagingState) 32 | } 33 | 34 | case class ListResult[R]( 35 | records: List[R], 36 | result: ResultSet 37 | ) extends RecordResult[R] 38 | 39 | object ListResult { 40 | def apply[R](res: ResultSet, records: List[R]): ListResult[R] = ListResult(records, res) 41 | 42 | def apply[R](rec: (ResultSet, List[R])): ListResult[R] = apply(rec._2, rec._1) 43 | } 44 | 45 | case class IteratorResult[R](records: Iterator[R], result: ResultSet) extends RecordResult[R] -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/query/execution/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query 17 | 18 | import scala.concurrent.ExecutionContext 19 | 20 | package object execution { 21 | 22 | implicit class FunctorOps[F[_], T](val in: F[T])(implicit fMonad: FutureMonad[F]) { 23 | def zipWith[O, R](other: F[O])(fn: (T, O) => R)( 24 | implicit ctx: ExecutionContext 25 | ): F[R] = { 26 | for (r1 <- in; r2 <- other) yield fn(r1, r2) 27 | } 28 | 29 | def map[A](fn: T => A)( 30 | implicit ctx: ExecutionContext 31 | ): F[A] = fMonad.map(in)(fn) 32 | 33 | def flatMap[A](fn: T => F[A])( 34 | implicit ctx: ExecutionContext 35 | ): F[A] = fMonad.flatMap(in)(fn) 36 | } 37 | } -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/query/prepared/ListValue.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.prepared 17 | 18 | import com.outworkers.phantom.builder.primitives.Primitive 19 | 20 | /** 21 | * A special type wrapper for binding to prepared in statement values. 22 | * This is required because Cassandra wants a special kind of protocol level input 23 | * for such bind values. 24 | * 25 | * @tparam T The underlying primitive type held here. 26 | */ 27 | trait ListValue[T] extends Serializable { 28 | def value: List[T] 29 | 30 | override def toString: String = value.toString() 31 | 32 | override def equals(obj: Any): Boolean = { 33 | obj match { 34 | case l: ListValue[T] => l.value == value 35 | case _ => false 36 | } 37 | } 38 | 39 | override def hashCode(): Int = value.hashCode() 40 | } 41 | 42 | object ListValue { 43 | 44 | def apply[T](objects: T*): ListValue[T] = apply(objects.toList) 45 | 46 | def empty[T]: ListValue[T] = apply(List.empty[T]) 47 | 48 | def apply[T](list: List[T]): ListValue[T] = new ListValue[T] { 49 | override def value: List[T] = list 50 | } 51 | 52 | implicit def primitive[T]( 53 | implicit ev: Primitive[List[T]] 54 | ): Primitive[ListValue[T]] = { 55 | Primitive.derive[ListValue[T], List[T]](_.value)(ListValue.apply) 56 | } 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/query/sasi/mode.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.sasi 17 | 18 | import com.outworkers.phantom.builder.syntax.CQLSyntax 19 | 20 | abstract class Mode 21 | 22 | object Mode { 23 | class Contains extends Mode 24 | class Prefix extends Mode 25 | class Sparse extends Mode 26 | } 27 | 28 | trait ModeDef[M <: Mode] { 29 | def value: String 30 | } 31 | 32 | object ModeDef { 33 | implicit val containsDef: ModeDef[Mode.Contains] = new ModeDef[Mode.Contains] { 34 | override def value: String = CQLSyntax.SASI.Modes.Contains 35 | } 36 | 37 | implicit val sparseDef: ModeDef[Mode.Sparse] = new ModeDef[Mode.Sparse] { 38 | override def value: String = CQLSyntax.SASI.Modes.Sparse 39 | } 40 | 41 | implicit val prefixDef: ModeDef[Mode.Prefix] = new ModeDef[Mode.Prefix] { 42 | override def value: String = CQLSyntax.SASI.Modes.Prefix 43 | } 44 | } -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/serializers/BaseModifiers.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.serializers 17 | 18 | import com.outworkers.phantom.builder.query.engine.CQLQuery 19 | 20 | private[builder] trait BaseModifiers { 21 | 22 | protected[this] def modifier(column: String, op: String, value: String): CQLQuery = { 23 | CQLQuery(column).forcePad.append(op).forcePad.append(value) 24 | } 25 | 26 | protected[this] def modifier(column: String, op: String, value: CQLQuery): CQLQuery = { 27 | modifier(column, op, value.queryString) 28 | } 29 | 30 | protected[this] def collectionModifier(left: String, op: String, right: CQLQuery): CQLQuery = { 31 | CQLQuery(left).forcePad.append(op).forcePad.append(right) 32 | } 33 | 34 | protected[this] def collectionModifier(left: String, op: String, right: String): CQLQuery = { 35 | CQLQuery(left).forcePad.append(op).forcePad.append(right) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/serializers/BatchQueryBuilder.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.serializers 17 | 18 | import com.outworkers.phantom.builder.query.engine.CQLQuery 19 | import com.outworkers.phantom.builder.syntax.CQLSyntax 20 | 21 | private[phantom] class BatchQueryBuilder { 22 | 23 | def batch(batchType: String): CQLQuery = { 24 | CQLQuery(CQLSyntax.Batch.begin).pad.append(batchType).pad.append(CQLSyntax.Batch.batch) 25 | } 26 | 27 | def applyBatch(qb: CQLQuery): CQLQuery = { 28 | qb.forcePad.append(CQLSyntax.Batch.apply) 29 | .forcePad.append(CQLSyntax.Batch.batch) 30 | .append(CQLSyntax.Symbols.semicolon) 31 | } 32 | } -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/builder/serializers/SASIQueryBuilder.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.serializers 17 | 18 | import com.outworkers.phantom.builder.query.engine.CQLQuery 19 | import com.outworkers.phantom.builder.syntax.CQLSyntax 20 | 21 | class SASIQueryBuilder extends BaseModifiers { 22 | 23 | protected[this] def percentEscape(value: String): CQLQuery = { 24 | CQLQuery(CQLSyntax.Symbols.percent) 25 | .append(value) 26 | .append(CQLSyntax.Symbols.percent) 27 | } 28 | 29 | def likeAny(column: String, value: String): CQLQuery = { 30 | CQLQuery(column).forcePad 31 | .append(CQLSyntax.Operators.like) 32 | .forcePad.append(value) 33 | } 34 | 35 | def containsValue(value: String): CQLQuery = { 36 | CQLQuery.empty.appendSingleQuote(percentEscape(value)) 37 | } 38 | 39 | def prefixValue(value: String): CQLQuery = { 40 | CQLQuery.empty.appendSingleQuote(value + CQLSyntax.Symbols.percent) 41 | } 42 | 43 | def suffixValue(value: String): CQLQuery = { 44 | CQLQuery.empty.appendSingleQuote(CQLSyntax.Symbols.percent + value) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/column/CollectionValueDefinition.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.column 17 | 18 | trait CollectionValueDefinition[RR] { 19 | 20 | def valueAsCql(v: RR): String 21 | } 22 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/column/Column.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.column 17 | 18 | import com.outworkers.phantom.{ CassandraTable, Row } 19 | 20 | import scala.util.{Failure, Success, Try} 21 | 22 | abstract class Column[ 23 | Owner <: CassandraTable[Owner, Record], 24 | Record, 25 | T 26 | ](val table: CassandraTable[Owner, Record]) extends AbstractColumn[T] { 27 | 28 | def parse(r: Row): Try[T] 29 | 30 | def apply(r: Row): T = parse(r) match { 31 | case Success(value) => value 32 | case Failure(ex) => 33 | table.logger.error(s"Unable to parse value for column $name from row", ex) 34 | throw ex 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/column/CounterColumn.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.column 17 | 18 | import com.outworkers.phantom.builder.primitives.Primitive 19 | import com.outworkers.phantom.builder.syntax.CQLSyntax 20 | import com.outworkers.phantom.keys.Unmodifiable 21 | import com.outworkers.phantom.{CassandraTable, Row} 22 | 23 | import scala.util.{Failure, Success, Try} 24 | import scala.util.control.NonFatal 25 | 26 | private[phantom] trait CounterRestriction[T] 27 | 28 | class CounterColumn[ 29 | Owner <: CassandraTable[Owner, Record], 30 | Record 31 | ](table: CassandraTable[Owner, Record])(implicit primitive: Primitive[Long]) 32 | extends Column[Owner, Record, Long](table) with CounterRestriction[Long] with Unmodifiable { 33 | 34 | val cassandraType = CQLSyntax.Types.Counter 35 | 36 | override val isCounterColumn = true 37 | 38 | def parse(r: Row): Try[Long] = primitive.fromRow(name, r) recoverWith { 39 | case NonFatal(_) if r.isNull(name) => Success(0L) 40 | case e => Failure(e) 41 | } 42 | 43 | override def asCql(v: Long): String = primitive.asCql(v) 44 | } 45 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/column/OptionalColumn.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.column 17 | 18 | import com.outworkers.phantom.{ CassandraTable, Row } 19 | 20 | import scala.util.Try 21 | 22 | abstract class OptionalColumn[ 23 | Owner <: CassandraTable[Owner, Record], 24 | Record, 25 | T 26 | ]( 27 | table: CassandraTable[Owner, Record] 28 | ) extends AbstractColumn[Option[T]] { 29 | 30 | def apply(r: Row): Option[T] = optional(r).toOption 31 | 32 | def cassandraType: String 33 | 34 | def optional(r: Row): Try[T] 35 | } 36 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/column/OptionalPrimitiveColumn.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.column 17 | 18 | import com.outworkers.phantom.builder.syntax.CQLSyntax 19 | 20 | import scala.annotation.implicitNotFound 21 | import com.outworkers.phantom.{ CassandraTable, Row } 22 | import com.outworkers.phantom.builder.primitives.Primitive 23 | import com.outworkers.phantom.builder.query.engine.CQLQuery 24 | 25 | import scala.util.Try 26 | 27 | @implicitNotFound(msg = "Type ${T} must be a Cassandra primitive") 28 | class OptionalPrimitiveColumn[ 29 | Owner <: CassandraTable[Owner, Record], 30 | Record, 31 | @specialized(Int, Double, Float, Long, Boolean, Short) T 32 | ](table: CassandraTable[Owner, Record])(implicit ev: Primitive[T]) extends OptionalColumn[Owner, Record, T](table) { 33 | 34 | def cassandraType: String = ev.dataType 35 | 36 | def optional(r: Row): Try[T] = ev.fromRow(name, r) 37 | 38 | override def qb: CQLQuery = { 39 | val root = CQLQuery(name).forcePad.append(cassandraType) 40 | if (isStaticColumn) { 41 | root.forcePad.append(CQLSyntax.static) 42 | } else { 43 | root 44 | } 45 | } 46 | 47 | override def asCql(v: Option[T]): String = { 48 | v.map(Primitive[T].asCql).getOrElse(None.orNull.asInstanceOf[String]) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/column/PrimitiveColumn.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.column 17 | 18 | import com.outworkers.phantom.{ CassandraTable, Row } 19 | import com.outworkers.phantom.builder.QueryBuilder 20 | import com.outworkers.phantom.builder.primitives.Primitive 21 | import com.outworkers.phantom.builder.query.engine.CQLQuery 22 | import com.outworkers.phantom.builder.syntax.CQLSyntax 23 | 24 | import scala.annotation.implicitNotFound 25 | import scala.util.Try 26 | 27 | @implicitNotFound(msg = "Type ${RR} must be a Cassandra primitive") 28 | class PrimitiveColumn[ 29 | T <: CassandraTable[T, R], 30 | R, 31 | @specialized(Int, Double, Float, Long) RR 32 | ](t: CassandraTable[T, R])(implicit ev: Primitive[RR]) extends Column[T, R, RR](t) { 33 | 34 | def cassandraType: String = ev.cassandraType 35 | 36 | def asCql(v: RR): String = ev.asCql(v) 37 | 38 | def parse(r: Row): Try[RR] = ev.fromRow(name, r) 39 | 40 | override def qb: CQLQuery = { 41 | val root = CQLQuery(name).forcePad.append(cassandraType) 42 | 43 | if (isStaticColumn) { 44 | root.forcePad.append(CQLSyntax.static) 45 | } else if (shouldFreeze && ev.frozen) { 46 | CQLQuery(name).forcePad.append(QueryBuilder.Collections.frozen(cassandraType)) 47 | } else { 48 | root 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/column/TimeUUIDColumn.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.column 17 | 18 | import java.util.UUID 19 | 20 | import com.outworkers.phantom.CassandraTable 21 | import com.outworkers.phantom.builder.primitives.Primitive 22 | import com.outworkers.phantom.builder.syntax.CQLSyntax 23 | 24 | class TimeUUIDColumn[ 25 | T <: CassandraTable[T, R], 26 | R 27 | ](table: CassandraTable[T, R])( 28 | implicit ev: Primitive[UUID] 29 | ) extends PrimitiveColumn[T, R, UUID](table) { 30 | override val cassandraType = CQLSyntax.Types.TimeUUID 31 | } -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/database/DatabaseProvider.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.database 17 | 18 | import com.datastax.driver.core.{ProtocolVersion, Session, VersionNumber} 19 | import com.outworkers.phantom.connectors.{KeySpace, SessionAugmenterImplicits} 20 | 21 | trait DatabaseProvider[T <: Database[T]] extends SessionAugmenterImplicits { 22 | 23 | /** 24 | * @deprecated use [[cassandraVersionOpt]] instead. This method throws a RuntimeException when the version can't be determined. 25 | */ 26 | def cassandraVersion: Option[VersionNumber] = database.connector.cassandraVersion 27 | 28 | def cassandraVersionOpt: Option[VersionNumber] = database.connector.cassandraVersionOpt 29 | 30 | def cassandraVersions: Set[VersionNumber] = database.connector.cassandraVersions 31 | 32 | implicit def session: Session = database.session 33 | 34 | implicit lazy val protocolVersion: ProtocolVersion = session.protocolVersion 35 | 36 | implicit def space: KeySpace = database.space 37 | 38 | def database: T 39 | 40 | /** 41 | * A helper shorthand method. 42 | * @return A reference to the database object. 43 | */ 44 | def db: T = database 45 | } 46 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/jdk8/Shared.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.jdk8 17 | 18 | import java.time.Instant 19 | 20 | import com.outworkers.phantom.builder.primitives.Primitive 21 | import com.outworkers.phantom.builder.syntax.CQLSyntax 22 | 23 | trait Shared { 24 | 25 | implicit val instantPrimitive: Primitive[Instant] = Primitive.manuallyDerive[Instant, Long]( 26 | _.toEpochMilli, 27 | Instant.ofEpochMilli 28 | )(Primitive[Long])(CQLSyntax.Types.Timestamp) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/keys/ClusteringOrder.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.keys 17 | 18 | import com.outworkers.phantom.column.AbstractColumn 19 | 20 | /** 21 | * A trait mixable into a Column to allow clustering order. 22 | */ 23 | trait ClusteringOrder extends PrimaryKey { 24 | self: AbstractColumn[_] => 25 | override val isClusteringKey = true 26 | 27 | } 28 | 29 | trait Ascending { 30 | self: AbstractColumn[_] with ClusteringOrder => 31 | override val isAscending = true 32 | } 33 | 34 | trait Descending { 35 | self: AbstractColumn[_] with ClusteringOrder => 36 | } 37 | -------------------------------------------------------------------------------- /phantom-dsl/src/main/scala/com/outworkers/phantom/keys/SASIIndex.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.keys 17 | 18 | import com.outworkers.phantom.builder.query.engine.CQLQuery 19 | import com.outworkers.phantom.builder.query.sasi.{Analyzer, Mode} 20 | import com.outworkers.phantom.column.AbstractColumn 21 | 22 | trait SASIIndex[M <: Mode] { 23 | self: AbstractColumn[_] => 24 | 25 | def name: String 26 | 27 | def analyzer: Analyzer[M] 28 | 29 | def analyzerOptions: CQLQuery = analyzer.qb 30 | } 31 | 32 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/primitives/DerivedField.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.primitives 17 | 18 | import com.outworkers.util.samplers.Sample 19 | 20 | case class DerivedField(value: String) 21 | 22 | object DerivedField { 23 | implicit val recordPrimitive: Primitive[DerivedField] = { 24 | Primitive.derive[DerivedField, String](_.value)(DerivedField.apply) 25 | } 26 | } 27 | 28 | case class DerivedTupleField(value: String, num: Long) 29 | 30 | object DerivedTupleField { 31 | implicit val recordPrimitive: Primitive[DerivedTupleField] = { 32 | Primitive.derive[DerivedTupleField, (String, Long)](x => x.value -> x.num)(x => { 33 | val (a, b) = x 34 | DerivedTupleField(a, b) 35 | }) 36 | } 37 | } 38 | 39 | sealed trait HashStatus 40 | trait Serialized extends HashStatus 41 | trait Unserialized extends HashStatus 42 | 43 | sealed case class Username[T <: HashStatus](name: String) 44 | 45 | object Username { 46 | 47 | implicit val usernamePrimitive: Primitive[Username[Serialized]] = { 48 | Primitive.derive[Username[Serialized], String](_.name)(Username.apply) 49 | } 50 | 51 | implicit val usernameSampler: Sample[Username[Serialized]] = { 52 | Sample.iso[String, Username[Serialized]](Username.apply) 53 | } 54 | 55 | def apply(st: String, trigger: Int = 0): Username[Serialized] = new Username[Serialized](st) 56 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/ColumnsSchemaTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | 20 | class ColumnsSchemaTest extends PhantomSuite { 21 | 22 | 23 | it should "automatically freeze a tuple column using a set column" in { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/KeySpaceSuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query 17 | 18 | import com.outworkers.phantom.PhantomBaseSuite 19 | import com.outworkers.phantom.dsl._ 20 | import com.outworkers.phantom.tables.TestDatabase 21 | import com.outworkers.util.samplers.Sample 22 | import org.joda.time.{DateTime, DateTimeZone} 23 | import org.scalatest.{FreeSpec, Matchers, Suite} 24 | 25 | trait KeySpaceSuite { self: Suite => 26 | 27 | implicit val keySpace: KeySpace = KeySpace("phantom") 28 | } 29 | 30 | trait SerializationTest extends Matchers with TestDatabase.connector.Connector { 31 | self: Suite => 32 | 33 | def db: TestDatabase = TestDatabase 34 | 35 | implicit object JodaTimeSampler extends Sample[DateTime] { 36 | override def sample: DateTime = DateTime.now(DateTimeZone.UTC) 37 | } 38 | } 39 | 40 | trait QueryBuilderTest extends FreeSpec with PhantomBaseSuite with TestDatabase.connector.Connector -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/bugs/ImbugBug.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.bugs 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | import scala.concurrent.Future 21 | 22 | case class UserSchema( 23 | id: Int, 24 | firstName: String, 25 | lastName: String, 26 | dateOfBirth: LocalDate 27 | ) 28 | 29 | abstract class UserSchemaTable extends Table[UserSchemaTable, UserSchema] { 30 | override def tableName: String = "users" 31 | 32 | object id extends IntColumn with PartitionKey 33 | object firstName extends StringColumn 34 | object lastName extends StringColumn 35 | object dateOfBirth extends LocalDateColumn 36 | 37 | def checkUserId: Future[Option[Int]] = select(_.id).one() 38 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/bugs/QuotedSecondaryIndexes.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.bugs 17 | 18 | import com.outworkers.phantom.dsl.{Index, PartitionKey, Table} 19 | import com.outworkers.phantom.tables.SecondaryIndexRecord 20 | 21 | abstract class QuotedSecondaryIndexes extends Table[ 22 | QuotedSecondaryIndexes, 23 | SecondaryIndexRecord 24 | ] { 25 | object id extends UUIDColumn with PartitionKey 26 | object secondary extends UUIDColumn with Index { 27 | override def name: String = """"secondary_index"""" 28 | } 29 | object name extends StringColumn 30 | } 31 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/db/crud/DistinctTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.db.crud 17 | 18 | import java.util.UUID 19 | 20 | import com.outworkers.phantom.PhantomSuite 21 | import com.outworkers.phantom.dsl._ 22 | import com.outworkers.phantom.tables._ 23 | 24 | class DistinctTest extends PhantomSuite { 25 | 26 | override def beforeAll(): Unit = { 27 | super.beforeAll() 28 | database.tableWithCompoundKey.createSchema() 29 | } 30 | 31 | it should "return distinct primary keys" in { 32 | val rows = List( 33 | StubRecord(UUID.nameUUIDFromBytes("1".getBytes), "a"), 34 | StubRecord(UUID.nameUUIDFromBytes("1".getBytes), "b"), 35 | StubRecord(UUID.nameUUIDFromBytes("2".getBytes), "c"), 36 | StubRecord(UUID.nameUUIDFromBytes("3".getBytes), "d") 37 | ) 38 | 39 | val batch = rows.foldLeft(Batch.unlogged)((batch, row) => { 40 | batch.add( 41 | database.tableWithCompoundKey.insert 42 | .value(_.id, row.id) 43 | .value(_.second, UUID.nameUUIDFromBytes(row.name.getBytes)) 44 | .value(_.name, row.name) 45 | ) 46 | }) 47 | 48 | val chain = for { 49 | truncate <- TestDatabase.tableWithCompoundKey.truncate.future() 50 | batch <- batch.future() 51 | list <- TestDatabase.tableWithCompoundKey.select(_.id).distinct.fetch 52 | } yield list 53 | 54 | val expectedResult = rows.filter(_.name != "b").map(_.id) 55 | 56 | whenReady(chain) { res => 57 | res should contain only (expectedResult: _*) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/db/specialized/JodaDateTimeColumnTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.db.specialized 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | import com.outworkers.phantom.dsl._ 20 | import com.outworkers.phantom.tables._ 21 | import com.outworkers.util.samplers._ 22 | 23 | class JodaDateTimeColumnTest extends PhantomSuite { 24 | 25 | override def beforeAll(): Unit = { 26 | super.beforeAll() 27 | val _ = database.primitivesJoda.createSchema() 28 | } 29 | 30 | it should "correctly insert and extract a JodaTime date" in { 31 | val row = gen[JodaRow] 32 | 33 | val chain = for { 34 | _ <- database.primitivesJoda.store(row).future() 35 | select <- database.primitivesJoda.select.where(_.pkey eqs row.pkey).one() 36 | } yield select 37 | 38 | whenReady(chain) { res => 39 | res.value.pkey shouldEqual row.pkey 40 | res.value.intColumn shouldEqual row.intColumn 41 | res.value.timestamp shouldEqual row.timestamp 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/execution/QueryCollectionsTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.execution 17 | 18 | import com.outworkers.phantom.builder.query.QueryOptions 19 | import com.outworkers.phantom.builder.query.engine.CQLQuery 20 | import org.scalatest.{FlatSpec, Matchers} 21 | import com.outworkers.util.samplers._ 22 | 23 | class QueryCollectionsTest extends FlatSpec with Matchers { 24 | 25 | it should "create a simple collection of queries from an input source" in { 26 | val source = genSet[String]().map(CQLQuery.apply) 27 | val col = new QueryCollection[Set](source.map(ExecutableCqlQuery.apply(_, QueryOptions.empty, Nil))) 28 | 29 | col.size shouldEqual source.size 30 | col.queries.map(_.qb) should contain theSameElementsAs source 31 | } 32 | 33 | it should "append another collection to an existing QueryCollection" in { 34 | val source = genSet[String]().map(CQLQuery.apply) 35 | val appendable = genSet[String]().map(CQLQuery.apply) 36 | val col = new QueryCollection[Set](source.map(ExecutableCqlQuery.apply(_, QueryOptions.empty, Nil))) 37 | val colAppendable = appendable.map(ExecutableCqlQuery.apply(_, QueryOptions.empty, Nil)) 38 | 39 | col.size shouldEqual source.size 40 | col.queries.map(_.qb) should contain theSameElementsAs source 41 | 42 | val colFinal = col appendAll colAppendable 43 | 44 | colFinal.size shouldEqual (source.size + appendable.size) 45 | colFinal.queries.map(_.qb) should contain theSameElementsAs (source ++ appendable) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/prepared/BatchablePreparedInsertQueryTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.prepared 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | import com.outworkers.phantom.dsl._ 20 | import com.outworkers.phantom.tables.Recipe 21 | import com.outworkers.util.samplers._ 22 | 23 | class BatchablePreparedInsertQueryTest extends PhantomSuite { 24 | 25 | override def beforeAll(): Unit = { 26 | super.beforeAll() 27 | val _ = database.recipes.createSchema() 28 | } 29 | 30 | it should "serialize an prepared batch query" in { 31 | val sample1 = gen[Recipe] 32 | val sample2 = gen[Recipe] 33 | 34 | val query = database.recipes.insert 35 | .p_value(_.url, ?) 36 | .p_value(_.description, ?) 37 | .p_value(_.ingredients, ?) 38 | .p_value(_.servings, ?) 39 | .p_value(_.lastcheckedat, ?) 40 | .p_value(_.props, ?) 41 | .p_value(_.uid, ?) 42 | .prepare() 43 | 44 | val exec1 = query.bind(sample1) 45 | val exec2 = query.bind(sample2) 46 | 47 | val chain = for { 48 | _ <- Batch.unlogged.add(exec1, exec2).future() 49 | get <- database.recipes.select.where(_.url in List(sample1.url, sample2.url)).fetch() 50 | } yield get 51 | 52 | whenReady(chain) { res => 53 | res should contain theSameElementsAs List(sample1, sample2) 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/prepared/ExactlyOncePromiseTests.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.prepared 17 | 18 | import java.util.concurrent.atomic.AtomicInteger 19 | 20 | import com.outworkers.phantom.builder.query.execution.ExactlyOncePromise 21 | import org.scalatest.concurrent.ScalaFutures 22 | import org.scalatest.{FlatSpec, Matchers} 23 | 24 | import scala.concurrent.Future 25 | import com.outworkers.phantom.dsl._ 26 | 27 | class ExactlyOncePromiseTests extends FlatSpec with Matchers with ScalaFutures { 28 | 29 | it should "only execute the logic inside an exactly once promise a single time" in { 30 | val atomic = new AtomicInteger(0) 31 | 32 | val promise = new ExactlyOncePromise(Future(atomic.incrementAndGet())) 33 | 34 | val chain = for { 35 | _ <- promise.future 36 | _ <- promise.future 37 | _ <- promise.future 38 | four <- promise.future 39 | } yield four 40 | 41 | whenReady(chain) { res => 42 | res shouldEqual 1 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/query/prepared/JsonPreparedInserts.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.query.prepared 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | import com.outworkers.phantom.tables.bugs.NestedJsonRecord 20 | import com.outworkers.util.samplers._ 21 | import com.outworkers.phantom.dsl._ 22 | 23 | class JsonPreparedInserts extends PhantomSuite { 24 | 25 | override def beforeAll(): Unit = { 26 | super.beforeAll() 27 | val _ = database.jsonPreparedTable.createSchema() 28 | } 29 | 30 | it should "insert a record into cassandra using a prepared query" in { 31 | val sample = gen[NestedJsonRecord] 32 | 33 | val chain = for { 34 | _ <- database.jsonPreparedTable.insertItem(sample) 35 | one <- database.jsonPreparedTable.findById(sample.id) 36 | } yield one 37 | 38 | whenReady(chain) { res => 39 | res shouldBe defined 40 | res.value shouldEqual sample 41 | } 42 | } 43 | 44 | it should "insert a record into cassandra using the default store method" in { 45 | val sample = gen[NestedJsonRecord] 46 | 47 | val chain = for { 48 | _ <- database.jsonPreparedTable.storeRecord(sample) 49 | one <- database.jsonPreparedTable.findById(sample.id) 50 | } yield one 51 | 52 | whenReady(chain) { res => 53 | res shouldBe defined 54 | res.value shouldEqual sample 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/serializers/DeleteQueryBuilderTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.serializers 17 | 18 | import com.outworkers.phantom.builder.QueryBuilder 19 | import com.outworkers.phantom.builder.query.QueryBuilderTest 20 | import com.outworkers.phantom.dsl.? 21 | 22 | class DeleteQueryBuilderTest extends QueryBuilderTest { 23 | 24 | "The DELETE query builder" - { 25 | 26 | "should allow specifying column delete queries" in { 27 | val qb = QueryBuilder.Delete.deleteColumn("table", "col").queryString 28 | qb shouldEqual "DELETE col FROM table" 29 | } 30 | 31 | "should allow specifying full delete queries" in { 32 | val qb = QueryBuilder.Delete.delete("table").queryString 33 | qb shouldEqual "DELETE FROM table" 34 | } 35 | 36 | "should create prepared delete query conditions" in { 37 | val qb = QueryBuilder.Delete.deletePrepared("table", "column", ?).queryString 38 | qb shouldEqual "column[?]" 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/serializers/InsertQueryBuilderTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.serializers 17 | 18 | import com.outworkers.phantom.builder.QueryBuilder 19 | import com.outworkers.phantom.builder.query.engine.CQLQuery 20 | import com.outworkers.phantom.builder.query.QueryBuilderTest 21 | 22 | class InsertQueryBuilderTest extends QueryBuilderTest { 23 | 24 | "The INSERT query builder" - { 25 | 26 | "should allow appending columns and values to a query" - { 27 | 28 | "should serialize a sequence of appended values" in { 29 | val query = QueryBuilder.Insert.values(List(CQLQuery("a"), CQLQuery("b"))).queryString 30 | 31 | query shouldEqual "VALUES(a, b)" 32 | } 33 | 34 | "should serialize a sequence of column definitions" in { 35 | val query = QueryBuilder.Insert.columns(List(CQLQuery("a"), CQLQuery("b"))).queryString 36 | query shouldEqual "(a, b)" 37 | } 38 | 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/serializers/SASIQueryBuilderTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.serializers 17 | 18 | import com.outworkers.phantom.builder.QueryBuilder 19 | import com.outworkers.phantom.builder.query.SerializationTest 20 | import com.outworkers.util.samplers._ 21 | import org.scalatest.FlatSpec 22 | 23 | class SASIQueryBuilderTest extends FlatSpec with SerializationTest { 24 | 25 | it should "prefix a value clause" in { 26 | val value = gen[ShortString].value 27 | val qb = QueryBuilder.SASI.prefixValue(value).queryString 28 | 29 | qb shouldEqual s"'$value%'" 30 | } 31 | 32 | it should "suffix a value clause" in { 33 | val value = gen[ShortString].value 34 | val qb = QueryBuilder.SASI.suffixValue(value).queryString 35 | 36 | qb shouldEqual s"'%$value'" 37 | } 38 | 39 | 40 | it should "serialize a contains value clause" in { 41 | val value = gen[ShortString].value 42 | val qb = QueryBuilder.SASI.containsValue(value).queryString 43 | 44 | qb shouldEqual s"'%$value%'" 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/serializers/TokenQuerySerialisationTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.serializers 17 | 18 | import com.outworkers.phantom.builder.query.SerializationTest 19 | import com.outworkers.phantom.dsl._ 20 | import com.outworkers.phantom.tables.TestDatabase 21 | import com.outworkers.util.samplers._ 22 | import org.scalatest.{FlatSpec, Matchers} 23 | 24 | class TokenQuerySerialisationTest extends FlatSpec with SerializationTest with Matchers { 25 | 26 | it should "serialize a single column token clause" in { 27 | val id = gen[String] 28 | 29 | val qb = TestDatabase.enumTable.select.where(table => token(table.id) > token(id)).queryString 30 | 31 | qb shouldEqual s"SELECT * FROM phantom.enumTable WHERE TOKEN (id) > TOKEN ('$id');" 32 | } 33 | 34 | it should "serialize a single column prepared token function" in { 35 | val qb = TestDatabase.enumTable.select.where(table => token(table.id) > token(?)) 36 | 37 | qb.queryString shouldEqual s"SELECT * FROM phantom.enumTable WHERE TOKEN (id) > TOKEN (?);" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/builder/serializers/datatypes/PasswordInfo.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.builder.serializers.datatypes 17 | 18 | import com.outworkers.phantom.builder.primitives.Primitive 19 | 20 | /** 21 | * The password details. 22 | * 23 | * @param hasher The ID of the hasher used to hash this password. 24 | * @param password The hashed password. 25 | * @param salt The optional salt used when hashing. 26 | */ 27 | case class PasswordInfo( 28 | hasher: String, 29 | password: String, 30 | salt: Option[String] = None 31 | ) 32 | 33 | object PasswordInfo{ 34 | implicit val conversion: Primitive[PasswordInfo] = { 35 | Primitive.derive[PasswordInfo, (String, String, Option[String])](pi => (pi.hasher, pi.password, pi.salt)) { x => 36 | val (a, b, c) = x 37 | PasswordInfo(a, b, c) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/database/BasicDatabase.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.database 17 | 18 | import com.outworkers.phantom.tables._ 19 | 20 | class BasicDatabase extends Database[BasicDatabase](Connector.default) { 21 | object enumTable extends EnumTable with Connector 22 | object basicTable extends BasicTable with Connector 23 | object jsonTable extends JsonTable with Connector 24 | object recipes extends Recipes with Connector 25 | } 26 | 27 | object BasicDatabase extends BasicDatabase -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/database/DatabaseInitialisationTests.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.database 17 | 18 | import com.outworkers.phantom.PhantomBaseSuite 19 | import com.outworkers.phantom.dsl._ 20 | import com.outworkers.phantom.tables.bugs.SecondaryIndexItem 21 | import com.outworkers.phantom.tables.dbs.SecondaryIndexOnlyDatabase 22 | import com.outworkers.util.samplers._ 23 | import org.scalatest.FlatSpec 24 | 25 | class DatabaseInitialisationTests extends FlatSpec 26 | with PhantomBaseSuite 27 | with SecondaryIndexOnlyDatabase.connector.Connector { 28 | 29 | val specialDb = SecondaryIndexOnlyDatabase 30 | 31 | override def beforeAll(): Unit = { 32 | super.beforeAll() 33 | val _ = specialDb.create() 34 | } 35 | 36 | it should "automatically initialise Secondary Indexes" in { 37 | val sample = gen[SecondaryIndexItem] 38 | 39 | val chain = for { 40 | _ <- specialDb.schemaBugSecondaryIndex.store(sample).future() 41 | res <- specialDb.schemaBugSecondaryIndex.select.where(_.ref eqs sample.ref).one() 42 | } yield res 43 | 44 | whenReady(chain) { res => 45 | info("Querying by the secondary index should return the record") 46 | res.value shouldEqual sample 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/database/DatabaseProviderTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.database 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | import com.outworkers.phantom.tables.TestDatabase 20 | 21 | class DatabaseProviderTest extends PhantomSuite { 22 | it should "maintain a reference to the singleton object using the shorthand syntax" in { 23 | (db eq TestDatabase) shouldEqual true 24 | } 25 | 26 | it should "maintain a reference to the singleton object injected" in { 27 | (database eq TestDatabase) shouldEqual true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/jdk8/Jdk8PrimitivesTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.jdk8 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | import com.outworkers.phantom.dsl._ 20 | import org.scalatest.prop.GeneratorDrivenPropertyChecks 21 | import org.scalatest.{Matchers, OptionValues} 22 | import com.outworkers.phantom.jdk8.tables._ 23 | 24 | class Jdk8PrimitivesTest extends PhantomSuite with Matchers with OptionValues with GeneratorDrivenPropertyChecks { 25 | 26 | override def beforeAll(): Unit = { 27 | super.beforeAll() 28 | Jdk8Database.create() 29 | } 30 | 31 | it should "correctly convert a ZonedDateTime to a tuple and back" in { 32 | forAll { row: Jdk8Row => 33 | val chain = for { 34 | store <- Jdk8Database.primitivesJdk8.store(row).future() 35 | one <- Jdk8Database.primitivesJdk8.findByPkey(row.pkey) 36 | } yield one 37 | 38 | whenReady(chain) { res => 39 | res shouldBe defined 40 | res.value shouldEqual row 41 | } 42 | } 43 | } 44 | 45 | it should "correctly convert a optional datetime types to Cassandra and back" in { 46 | forAll { row: OptionalJdk8Row => 47 | val chain = for { 48 | store <- Jdk8Database.optionalPrimitivesJdk8.store(row).future() 49 | one <- Jdk8Database.optionalPrimitivesJdk8.findByPkey(row.pkey) 50 | } yield one 51 | 52 | whenReady(chain) { res => 53 | res shouldBe defined 54 | res.value shouldEqual row 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/jdk8/Jdk8TimeColumnsTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.jdk8 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | import com.outworkers.phantom.dsl._ 20 | import com.outworkers.phantom.jdk8.tables.{Jdk8Row, Jdk8Database, _} 21 | import com.outworkers.util.samplers._ 22 | 23 | class Jdk8TimeColumnsTest extends PhantomSuite { 24 | 25 | override def beforeAll(): Unit = { 26 | super.beforeAll() 27 | if (session.v4orNewer) { 28 | Jdk8Database.create() 29 | } 30 | } 31 | 32 | if (session.v4orNewer) { 33 | it should "correctly insert and extract java.time columns" in { 34 | val row = gen[Jdk8Row] 35 | 36 | val chain = for { 37 | store <- Jdk8Database.primitivesJdk8.store(row).future() 38 | select <- Jdk8Database.primitivesJdk8.select.where(_.pkey eqs row.pkey).one() 39 | } yield select 40 | 41 | whenReady(chain) { res => 42 | res.value shouldEqual row 43 | } 44 | } 45 | 46 | it should "correctly insert and extract optional java.time columns" in { 47 | val row = gen[OptionalJdk8Row] 48 | 49 | val chain = for { 50 | store <- Jdk8Database.optionalPrimitivesJdk8.store(row).future() 51 | select <- Jdk8Database.optionalPrimitivesJdk8.select.where(_.pkey eqs row.pkey).one() 52 | } yield select 53 | 54 | whenReady(chain) { res => 55 | res.value shouldEqual row 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/jdk8/Jdk8TimeuuidConvertTests.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.jdk8 17 | 18 | import org.scalatest.prop.GeneratorDrivenPropertyChecks 19 | import org.scalatest.{FlatSpec, Matchers} 20 | import com.outworkers.phantom.jdk8.tables._ 21 | 22 | class Jdk8TimeuuidConvertTests extends FlatSpec with Matchers with GeneratorDrivenPropertyChecks { 23 | 24 | implicit override val generatorDrivenConfig: PropertyCheckConfiguration = { 25 | PropertyCheckConfiguration(minSuccessful = 300) 26 | } 27 | 28 | it should "convert a ZonedDateTime to a Timeuuid and back using the ZoneID argument method" in { 29 | forAll(zonedDateTimeGen) { dt => 30 | dt.timeuuid.zonedDateTime(dt.getZone) shouldEqual dt 31 | } 32 | } 33 | 34 | it should "convert a ZonedDateTime to a Timeuuid and back using the string argument method" in { 35 | forAll(zonedDateTimeGen) { dt => 36 | dt.timeuuid.zonedDateTime(dt.getZone.getId) shouldEqual dt 37 | } 38 | } 39 | 40 | it should "convert a OffsetDateTime to a Timeuuid and back using the string method" in { 41 | forAll(offsetDateTimeGen) { dt => 42 | dt.timeuuid.offsetDateTime(dt.getOffset.getId) shouldEqual dt 43 | } 44 | } 45 | 46 | it should "convert a OffsetDateTime to a Timeuuid and back using the ZoneOffset overload method" in { 47 | forAll(offsetDateTimeGen) { dt => 48 | dt.timeuuid.offsetDateTime(dt.getOffset) shouldEqual dt 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/jdk8/tables/ExtendedJdk8Primitives.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.jdk8.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import com.outworkers.phantom.jdk8._ 20 | 21 | object ExtendedJdk8Primitives { 22 | 23 | implicit val tpPrimitive: Primitive[OffsetDateTime] = OffsetDateTimeIsPrimitive()(Primitive[(Long, String)]()) 24 | implicit val zonedDt: Primitive[ZonedDateTime] = zonedDateTimePrimitive()(Primitive[(Long, String)]()) 25 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/jdk8/tables/Jdk8Database.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.jdk8.tables 17 | 18 | import com.outworkers.phantom.connectors.CassandraConnection 19 | import com.outworkers.phantom.database.Database 20 | import com.outworkers.phantom.tables.Connector 21 | 22 | class Jdk8Database(override val connector: CassandraConnection) extends Database[Jdk8Database](connector) { 23 | object primitivesJdk8 extends PrimitivesJdk8 with Connector 24 | object optionalPrimitivesJdk8 extends OptionalPrimitivesJdk8 with Connector 25 | } 26 | 27 | object Jdk8Database extends Jdk8Database(Connector.default) -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/jdk8/tables/OptionalPrimitivesJdk8.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.jdk8.tables 17 | 18 | import java.time.{LocalDate => _, OffsetDateTime => _, ZonedDateTime => _, _} 19 | 20 | import com.outworkers.phantom.dsl._ 21 | import com.outworkers.phantom.jdk8._ 22 | import ExtendedJdk8Primitives._ 23 | import scala.concurrent.Future 24 | 25 | case class OptionalJdk8Row( 26 | pkey: String, 27 | offsetDateTime: Option[OffsetDateTime], 28 | zonedDateTime: Option[ZonedDateTime], 29 | localDate: Option[JdkLocalDate], 30 | localDateTime: Option[JdkLocalDateTime] 31 | ) 32 | 33 | 34 | abstract class OptionalPrimitivesJdk8 extends Table[ 35 | OptionalPrimitivesJdk8, 36 | OptionalJdk8Row 37 | ] { 38 | 39 | object pkey extends StringColumn with PartitionKey 40 | 41 | object offsetDateTime extends OptionalCol[OffsetDateTime]() 42 | 43 | object zonedDateTime extends OptionalCol[ZonedDateTime] 44 | 45 | object localDate extends OptionalCol[JdkLocalDate] 46 | 47 | object localDateTime extends OptionalCol[JdkLocalDateTime] 48 | 49 | def findByPkey(pkey: String): Future[Option[OptionalJdk8Row]] = { 50 | select.where(_.pkey eqs pkey).one() 51 | } 52 | } 53 | 54 | case class User(id: Int, time: Instant) 55 | 56 | abstract class UserSchema extends Table[UserSchema, User] { 57 | object id extends IntColumn with PartitionKey 58 | object time extends Col[Instant] 59 | } 60 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/jdk8/tables/PrimitivesJdk8.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.jdk8.tables 17 | 18 | import java.time.{LocalDate, LocalDateTime, OffsetDateTime} 19 | 20 | import com.outworkers.phantom.dsl._ 21 | import com.outworkers.phantom.jdk8._ 22 | 23 | import scala.concurrent.Future 24 | import ExtendedJdk8Primitives._ 25 | 26 | case class Jdk8Row( 27 | pkey: String, 28 | offsetDateTime: OffsetDateTime, 29 | zonedDateTime: ZonedDateTime, 30 | localDate: LocalDate, 31 | localDateTime: LocalDateTime 32 | ) 33 | 34 | abstract class PrimitivesJdk8 extends Table[PrimitivesJdk8, Jdk8Row] { 35 | 36 | object pkey extends StringColumn with PartitionKey 37 | 38 | object offsetDateTime extends Col[OffsetDateTime] 39 | 40 | object zonedDateTime extends Col[ZonedDateTime] 41 | 42 | object localDate extends Col[LocalDate] 43 | 44 | object localDateTime extends Col[LocalDateTime] 45 | 46 | def findByPkey(pkey: String): Future[Option[Jdk8Row]] = { 47 | select.where(_.pkey eqs pkey).one() 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/json/JsonTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.json 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | import io.circe._ 21 | import io.circe.generic.semiauto._ 22 | import io.circe.parser._ 23 | import io.circe.syntax._ 24 | 25 | case class JsonRecord( 26 | prop1: String, 27 | prop2: String 28 | ) 29 | 30 | object JsonRecord { 31 | 32 | implicit val jsonDecoder: Decoder[JsonRecord] = deriveDecoder[JsonRecord] 33 | implicit val jsonEncoder: Encoder[JsonRecord] = deriveEncoder[JsonRecord] 34 | 35 | implicit val jsonPrimitive: Primitive[JsonRecord] = { 36 | Primitive.json[JsonRecord](_.asJson.noSpaces)(decode[JsonRecord](_).right.get) 37 | } 38 | } 39 | 40 | case class JsonClass( 41 | id: UUID, 42 | name: String, 43 | json: JsonRecord, 44 | optionalJson : Option[JsonRecord], 45 | jsonList: List[JsonRecord], 46 | jsonSet: Set[JsonRecord] 47 | ) 48 | 49 | abstract class JsonTable extends Table[JsonTable, JsonClass] { 50 | 51 | object id extends UUIDColumn with PartitionKey 52 | 53 | object name extends StringColumn 54 | 55 | object json extends JsonColumn[JsonRecord] 56 | 57 | object optionalJson extends OptionalJsonColumn[JsonRecord] 58 | 59 | object jsonList extends JsonListColumn[JsonRecord] 60 | 61 | object jsonSet extends JsonSetColumn[JsonRecord] 62 | 63 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/Articles.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | import scala.concurrent.Future 21 | 22 | case class Article( 23 | id: UUID, 24 | name: String, 25 | orderId: Long 26 | ) 27 | 28 | abstract class Articles extends Table[Articles, Article] { 29 | object id extends UUIDColumn with PartitionKey 30 | object name extends StringColumn 31 | object orderId extends LongColumn 32 | } 33 | 34 | 35 | abstract class ArticlesByAuthor extends Table[ArticlesByAuthor, Article] { 36 | object author_id extends UUIDColumn with PartitionKey 37 | object category extends UUIDColumn with PartitionKey 38 | object id extends UUIDColumn with PrimaryKey 39 | object name extends StringColumn 40 | object orderId extends LongColumn 41 | } 42 | 43 | 44 | case class User(id: UUID, name:String) 45 | 46 | abstract class Users extends Table[Users, User] { 47 | object id extends UUIDColumn with PartitionKey 48 | object name extends StringColumn 49 | 50 | def getById(id: UUID): Future[Option[User]] = { 51 | select.where(_.id eqs id).one() 52 | } 53 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/BasicTableMethods.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | 20 | class BasicTableMethods extends PhantomSuite { 21 | 22 | it should "retrieve the correct number of columns in a simple table" in { 23 | db.basicTable.columns.size shouldEqual 4 24 | } 25 | 26 | it should "retrieve the correct number of columns in a big table" in { 27 | db.complexCompoundKeyTable.columns.size shouldEqual 10 28 | } 29 | 30 | it should "retrieve the correct number of primary keys for a table" in { 31 | db.simpleCompoundKeyTable.primaryKeys.size shouldEqual 2 32 | db.simpleCompoundKeyTable.partitionKeys.size shouldEqual 1 33 | } 34 | 35 | it should "retrieve the correct number of clustering keys for a table" in { 36 | db.clusteringTable.clusteringColumns.size shouldEqual 2 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/CounterTableTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class CounterRecord(id: UUID, count: Long) 21 | 22 | abstract class CounterTableTest extends Table[ 23 | CounterTableTest, 24 | CounterRecord 25 | ] { 26 | object id extends UUIDColumn with PartitionKey 27 | object count_entries extends CounterColumn 28 | } 29 | 30 | abstract class SecondaryCounterTable extends Table[ 31 | SecondaryCounterTable, 32 | CounterRecord 33 | ] { 34 | object id extends UUIDColumn with PartitionKey 35 | object count_entries extends CounterColumn 36 | } 37 | 38 | abstract class BrokenCounterTableTest extends Table[ 39 | BrokenCounterTableTest, 40 | CounterRecord 41 | ] { 42 | object id extends UUIDColumn with PartitionKey 43 | object count_entries extends CounterColumn 44 | } 45 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/IndexedCollectionsTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | abstract class IndexedCollectionsTable extends Table[IndexedCollectionsTable, TestRow] { 21 | 22 | object key extends StringColumn with PartitionKey 23 | 24 | object list extends ListColumn[String] 25 | 26 | object setText extends SetColumn[String] with Index 27 | 28 | object mapTextToText extends MapColumn[String, String] with Index 29 | 30 | object setInt extends SetColumn[Int] 31 | 32 | object mapIntToText extends MapColumn[Int, String] with Index with Keys 33 | 34 | object mapIntToInt extends MapColumn[Int, Int] 35 | 36 | } 37 | 38 | 39 | abstract class IndexedEntriesTable extends Table[IndexedEntriesTable, TestRow] { 40 | 41 | object key extends StringColumn with PartitionKey 42 | 43 | object list extends ListColumn[String] 44 | 45 | object setText extends SetColumn[String] with Index 46 | 47 | object mapTextToText extends MapColumn[String, String] with Index 48 | 49 | object setInt extends SetColumn[Int] 50 | 51 | object mapIntToText extends MapColumn[Int, String] with Index with Keys 52 | 53 | object mapIntToInt extends MapColumn[Int, Int] with Index with Entries 54 | } 55 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/JsonTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import org.json4s.Extraction 20 | import org.json4s.native._ 21 | 22 | case class JsonTest(prop1: String, prop2: String) 23 | 24 | object JsonTest { 25 | 26 | implicit val formats = org.json4s.DefaultFormats 27 | 28 | implicit val jsonPrimitive: Primitive[JsonTest] = { 29 | Primitive.json[JsonTest](js => compactJson(renderJValue(Extraction.decompose(js))))(JsonParser.parse(_).extract[JsonTest]) 30 | } 31 | } 32 | 33 | case class JsonClass( 34 | id: UUID, 35 | name: String, 36 | json: JsonTest, 37 | optionalJson : Option[JsonTest], 38 | jsonList: List[JsonTest], 39 | jsonSet: Set[JsonTest] 40 | ) 41 | 42 | abstract class JsonTable extends Table[JsonTable, JsonClass] { 43 | 44 | object id extends UUIDColumn with PartitionKey 45 | 46 | object name extends StringColumn 47 | 48 | object json extends JsonColumn[JsonTest] 49 | 50 | object optionalJson extends OptionalJsonColumn[JsonTest] 51 | 52 | object jsonList extends JsonListColumn[JsonTest] 53 | 54 | object jsonSet extends JsonSetColumn[JsonTest] 55 | 56 | } 57 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/ListCollectionTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class MyTestRow( 21 | key: String, 22 | optionA: Option[Int], 23 | stringlist: List[String] 24 | ) 25 | 26 | abstract class ListCollectionTable extends Table[ListCollectionTable, MyTestRow] { 27 | 28 | object key extends StringColumn with PartitionKey 29 | 30 | object optionA extends OptionalIntColumn 31 | 32 | object stringlist extends ListColumn[String] 33 | } 34 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/MultipleKeys.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class MultipleKeyRecord( 21 | pkey: String, 22 | int1: Int, 23 | int2: Int, 24 | int3: Int, 25 | int4: Int, 26 | int5: Int, 27 | int6: Int, 28 | int7: Int, 29 | timestamp: DateTime 30 | ) 31 | 32 | abstract class MultipleKeys extends Table[MultipleKeys, MultipleKeyRecord] { 33 | 34 | object pkey extends StringColumn with PartitionKey 35 | object intColumn1 extends IntColumn with PrimaryKey with Index 36 | object intColumn2 extends IntColumn with PrimaryKey 37 | object intColumn3 extends IntColumn with PrimaryKey 38 | object intColumn4 extends IntColumn with PrimaryKey 39 | object intColumn5 extends IntColumn with PrimaryKey 40 | object intColumn6 extends IntColumn with PrimaryKey 41 | object intColumn7 extends IntColumn with PrimaryKey 42 | object timestamp8 extends DateTimeColumn 43 | } 44 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/NamedArticlesByAuthor.scala: -------------------------------------------------------------------------------- 1 | package com.outworkers.phantom.macros.tables 2 | 3 | import com.outworkers.phantom.dsl._ 4 | import com.outworkers.phantom.tables.Article 5 | import com.outworkers.phantom.NamingStrategy.SnakeCase.caseSensitive 6 | 7 | abstract class NamedArticlesByAuthor extends Table[NamedArticlesByAuthor, Article] { 8 | object id extends UUIDColumn with PartitionKey 9 | object name extends StringColumn 10 | object orderId extends LongColumn 11 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/NamingStrategyDatabase.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import com.outworkers.phantom.macros.tables.NamedArticlesByAuthor 20 | 21 | class NamingStrategyDatabase( 22 | override val connector: CassandraConnection 23 | ) extends Database[NamingStrategyDatabase](connector) { 24 | 25 | object articlesByAuthor extends NamedArticlesByAuthor with Connector 26 | } 27 | 28 | object NamingStrategyDatabase extends NamingStrategyDatabase(Connector.default) -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/OptionalSecondaryIndexTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import java.util.UUID 19 | 20 | import com.outworkers.phantom.dsl._ 21 | 22 | import scala.concurrent.Future 23 | 24 | case class OptionalSecondaryRecord( 25 | id: UUID, 26 | secondary: Option[Int] 27 | ) 28 | 29 | abstract class OptionalSecondaryIndexTable extends Table[ 30 | OptionalSecondaryIndexTable, 31 | OptionalSecondaryRecord 32 | ] { 33 | object id extends UUIDColumn with PartitionKey 34 | object secondary extends OptionalIntColumn with Index 35 | 36 | def findById(id: UUID): Future[Option[OptionalSecondaryRecord]] = { 37 | select.where(_.id eqs id).one() 38 | } 39 | 40 | def findByOptionalSecondary(sec: Int): Future[Option[OptionalSecondaryRecord]] = { 41 | select.where(_.secondary eqs sec).one() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/OrderedPartitionTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | 21 | case class OrderedPartitionRecord( 22 | id: UUID, 23 | order: Long 24 | ) 25 | 26 | abstract class OrderedPartitionTable extends Table[ 27 | OrderedPartitionTable, 28 | OrderedPartitionRecord 29 | ] { 30 | object id extends UUIDColumn with PartitionKey 31 | object order extends LongColumn with ClusteringOrder 32 | } 33 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/PrimaryCollectionTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class PrimaryCollectionRecord( 21 | index: List[String], 22 | set: Set[String], 23 | map: Map[String, String], 24 | name: String, 25 | value: Int 26 | ) 27 | 28 | abstract class PrimaryCollectionTable extends Table[PrimaryCollectionTable, PrimaryCollectionRecord] { 29 | object listIndex extends ListColumn[String] with PartitionKey 30 | object setCol extends SetColumn[String] with PrimaryKey 31 | object mapCol extends MapColumn[String, String] with PrimaryKey 32 | object name extends StringColumn with PrimaryKey 33 | object value extends IntColumn 34 | } 35 | 36 | case class NestedCollections( 37 | id: UUID, 38 | text: String, 39 | nestedList: List[List[String]], 40 | nestedListSet: List[Set[String]], 41 | props: Map[String, List[String]], 42 | doubleProps: Map[Set[String], List[String]] 43 | ) 44 | 45 | abstract class NestedCollectionTable extends Table[ 46 | NestedCollectionTable, 47 | NestedCollections 48 | ] { 49 | object id extends UUIDColumn with PartitionKey 50 | object text extends StringColumn 51 | object nestedList extends ListColumn[List[String]] 52 | object nestedListSet extends ListColumn[Set[String]] 53 | object props extends MapColumn[String, List[String]] 54 | object doubleProps extends MapColumn[Set[String], List[String]] 55 | } 56 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/PrimitivesCassandra22.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import org.joda.time.LocalDate 20 | 21 | case class PrimitiveCassandra22( 22 | pkey: String, 23 | short: Short, 24 | byte: Byte, 25 | date: LocalDate 26 | ) 27 | 28 | abstract class PrimitivesCassandra22 extends Table[ 29 | PrimitivesCassandra22, 30 | PrimitiveCassandra22 31 | ] { 32 | 33 | object pkey extends StringColumn with PartitionKey 34 | 35 | object short extends SmallIntColumn 36 | 37 | object byte extends TinyIntColumn 38 | 39 | object date extends LocalDateColumn 40 | } 41 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/PrimitivesJoda.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.datastax.driver.core.PagingState 19 | import com.outworkers.phantom.dsl._ 20 | import org.joda.time.DateTime 21 | 22 | import scala.concurrent.Future 23 | 24 | case class JodaRow( 25 | pkey: String, 26 | intColumn: Int, 27 | timestamp: DateTime 28 | ) 29 | 30 | abstract class PrimitivesJoda extends Table[ 31 | PrimitivesJoda, 32 | JodaRow 33 | ] { 34 | object pkey extends StringColumn with PartitionKey 35 | object intColumn extends IntColumn 36 | object timestamp extends DateTimeColumn 37 | 38 | def fetchPage(limit: Int, paging: Option[PagingState]): Future[ListResult[JodaRow]] = { 39 | select.limit(limit).paginateRecord(paging) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/Recipes.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import org.joda.time.DateTime 20 | 21 | import scala.concurrent.Future 22 | 23 | case class Recipe( 24 | url: String, 25 | description: Option[String], 26 | ingredients: List[String], 27 | servings: Option[Int], 28 | lastCheckedAt: DateTime, 29 | props: Map[String, String], 30 | uid: UUID 31 | ) 32 | 33 | abstract class Recipes extends Table[Recipes, Recipe] { 34 | 35 | object url extends StringColumn with PartitionKey 36 | 37 | object description extends OptionalStringColumn 38 | 39 | object ingredients extends ListColumn[String] 40 | 41 | object servings extends OptionalIntColumn 42 | 43 | object lastcheckedat extends DateTimeColumn 44 | 45 | object props extends MapColumn[String, String] 46 | 47 | object uid extends UUIDColumn 48 | } 49 | 50 | case class SampleEvent(id: UUID, map: Map[Long, DateTime]) 51 | 52 | abstract class Events extends Table[Events, SampleEvent] { 53 | object id extends UUIDColumn with PartitionKey 54 | object map extends MapColumn[Long, DateTime] 55 | 56 | def findById(id: UUID): Future[Option[SampleEvent]] = { 57 | select.where(_.id eqs id).one() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/ScalaTypesMapTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | import scala.concurrent.Future 21 | 22 | case class ScalaPrimitiveMapRecord( 23 | id: UUID, 24 | map: Map[DateTime, BigDecimal] 25 | ) 26 | 27 | abstract class ScalaTypesMapTable extends Table[ 28 | ScalaTypesMapTable, 29 | ScalaPrimitiveMapRecord 30 | ] { 31 | 32 | object id extends UUIDColumn with PartitionKey 33 | object map extends MapColumn[DateTime, BigDecimal] 34 | 35 | def findById(id: UUID): Future[Option[ScalaPrimitiveMapRecord]] = { 36 | select.where(_.id eqs id).one() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/SecondaryIndexTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class SecondaryIndexRecord( 21 | primary: UUID, 22 | secondary: UUID, 23 | name: String 24 | ) 25 | 26 | abstract class SecondaryIndexTable extends Table[ 27 | SecondaryIndexTable, 28 | SecondaryIndexRecord 29 | ] { 30 | object id extends UUIDColumn with PartitionKey 31 | object secondary extends UUIDColumn with Index 32 | object name extends StringColumn 33 | } 34 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/SessionsByUserId.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import org.joda.time.DateTime 20 | 21 | import scala.concurrent.Future 22 | 23 | case class OAuth2Session( 24 | user_id: UUID, 25 | client_id: UUID, 26 | access_token: UUID, 27 | refresh_token: UUID, 28 | authorization_grant: UUID, 29 | remembered_token: Option[UUID], 30 | timestamp: DateTime 31 | ) 32 | 33 | /** 34 | * This table is used for the internal application. 35 | * If a session is found in this table for a given user, it means the respective user is authenticated. 36 | */ 37 | abstract class SessionsByUserId extends Table[ 38 | SessionsByUserId, 39 | OAuth2Session 40 | ] { 41 | 42 | object user_id extends UUIDColumn with PartitionKey 43 | object client_id extends UUIDColumn 44 | object access_token extends UUIDColumn 45 | object refresh_token extends UUIDColumn 46 | object authorization_grant extends UUIDColumn 47 | object remembered_token extends OptionalUUIDColumn 48 | object timestamp extends DateTimeColumn 49 | 50 | def findById(id: UUID): Future[Option[OAuth2Session]] = { 51 | select.where(_.user_id eqs id).one() 52 | } 53 | 54 | def deleteById(id: UUID): Future[ResultSet] = { 55 | delete.where(_.user_id eqs id).future() 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/StaticTableTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class StaticCollectionSingle( 21 | id: UUID, 22 | clusteringId: UUID, 23 | static: String 24 | ) 25 | 26 | abstract class StaticTableTest extends Table[ 27 | StaticTableTest, 28 | StaticCollectionSingle 29 | ] { 30 | 31 | object id extends UUIDColumn with PartitionKey 32 | object clusteringId extends UUIDColumn with ClusteringOrder with Descending 33 | object staticTest extends StringColumn with StaticColumn 34 | } 35 | 36 | case class StaticCollectionRecord( 37 | id: UUID, 38 | clustering: UUID, 39 | list: List[String] 40 | ) 41 | 42 | abstract class StaticCollectionTable extends Table[ 43 | StaticCollectionTable, 44 | StaticCollectionRecord 45 | ] { 46 | object id extends UUIDColumn with PartitionKey 47 | object clustering extends UUIDColumn with ClusteringOrder with Descending 48 | object staticList extends ListColumn[String] with StaticColumn 49 | } 50 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/TableHelperRuntimeTests.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import java.util.UUID 19 | 20 | import com.outworkers.phantom.PhantomSuite 21 | import com.outworkers.util.samplers._ 22 | import com.outworkers.phantom.dsl._ 23 | 24 | class TableHelperRuntimeTests extends PhantomSuite { 25 | 26 | override def beforeAll(): Unit = { 27 | super.beforeAll() 28 | database.tableTypeTuple.createSchema() 29 | val _ = database.sessionsByUser.createSchema() 30 | } 31 | 32 | it should "automatically generate an extractor for a tuple type" in { 33 | val sample = gen[(UUID, String, String)] 34 | val (id, _, _) = sample 35 | 36 | val chain = for { 37 | _ <- database.tableTypeTuple.store(sample).future() 38 | find <- database.tableTypeTuple.findById(id) 39 | } yield find 40 | 41 | whenReady(chain) { res => 42 | res shouldBe defined 43 | res.value shouldEqual sample 44 | } 45 | } 46 | 47 | it should "automatically generate a store type for an OAuth2Session domain case class" in { 48 | val sample = gen[OAuth2Session] 49 | 50 | val chain = for { 51 | _ <- database.sessionsByUser.store(sample).future() 52 | find <- database.sessionsByUser.select.where(_.user_id eqs sample.user_id).one() 53 | } yield find 54 | 55 | whenReady(chain) { res => 56 | res shouldBe defined 57 | res.value shouldEqual sample 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/TableKeyTests.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class StubRecord( 21 | id: UUID, 22 | name: String 23 | ) 24 | 25 | abstract class TableWithSingleKey extends Table[TableWithSingleKey, StubRecord] { 26 | object id extends UUIDColumn with PartitionKey 27 | object name extends StringColumn 28 | } 29 | 30 | abstract class TableWithCompoundKey extends Table[TableWithCompoundKey, StubRecord] { 31 | object id extends UUIDColumn with PartitionKey 32 | object second extends UUIDColumn with PrimaryKey 33 | object name extends StringColumn 34 | } 35 | 36 | abstract class TableWithCompositeKey extends Table[TableWithCompositeKey, StubRecord] { 37 | object id extends UUIDColumn with PartitionKey 38 | object second_part extends UUIDColumn with PartitionKey 39 | object second extends UUIDColumn with PrimaryKey 40 | object name extends StringColumn 41 | } 42 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/TestTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class TestRow( 21 | key: String, 22 | list: List[String], 23 | setText: Set[String], 24 | mapTextToText: Map[String, String], 25 | setInt: Set[Int], 26 | mapIntToText: Map[Int, String], 27 | mapIntToInt: Map[Int, Int] 28 | ) 29 | 30 | abstract class TestTable extends Table[TestTable, TestRow] { 31 | 32 | object key extends StringColumn with PartitionKey 33 | 34 | object list extends ListColumn[String] 35 | 36 | object setText extends SetColumn[String] 37 | 38 | object mapTextToText extends MapColumn[String, String] 39 | 40 | object setInt extends SetColumn[Int] 41 | 42 | object mapIntToText extends MapColumn[Int, String] 43 | 44 | object mapIntToInt extends MapColumn[Int, Int] 45 | } 46 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/TestTable2.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | case class SimpleStringClass(something: String) 19 | 20 | case class SimpleMapOfStringsClass(something: Map[String, Int]) 21 | 22 | case class TestList(key: String, l: List[String]) 23 | 24 | case class TestRow2( 25 | key: String, 26 | optionalInt: Option[Int], 27 | simpleMapOfString: SimpleMapOfStringsClass, 28 | optionalSimpleMapOfString: Option[SimpleMapOfStringsClass], 29 | mapOfStringToCaseClass: Map[String, SimpleMapOfStringsClass] 30 | ) -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/TimeSeriesTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import org.joda.time.DateTime 20 | 21 | import scala.concurrent.Future 22 | 23 | case class TimeSeriesRecord( 24 | id: UUID, 25 | name: String, 26 | timestamp: DateTime 27 | ) 28 | 29 | case class TimeUUIDRecord( 30 | user: UUID, 31 | id: UUID, 32 | name: String 33 | ) { 34 | def timestamp: DateTime = id.datetime 35 | } 36 | 37 | abstract class TimeSeriesTable extends Table[TimeSeriesTable, TimeSeriesRecord] { 38 | object id extends UUIDColumn with PartitionKey 39 | object name extends StringColumn 40 | object timestamp extends DateTimeColumn with ClusteringOrder with Descending { 41 | override val name = "unixTimestamp" 42 | } 43 | } 44 | 45 | abstract class TimeUUIDTable extends Table[TimeUUIDTable, TimeUUIDRecord] { 46 | 47 | object user extends UUIDColumn with PartitionKey 48 | object id extends TimeUUIDColumn with ClusteringOrder with Descending 49 | object name extends StringColumn 50 | 51 | def retrieve(user: UUID): Future[List[TimeUUIDRecord]] = { 52 | select.where(_.user eqs user).orderBy(_.id ascending).fetch() 53 | } 54 | 55 | def retrieveDescending(user: UUID): Future[List[TimeUUIDRecord]] = { 56 | select.where(_.user eqs user).orderBy(_.id descending).fetch() 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/TimeSeriesTableWithTTL.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | abstract class TimeSeriesTableWithTTL extends Table[ 21 | TimeSeriesTableWithTTL, 22 | TimeSeriesRecord 23 | ] { 24 | object id extends UUIDColumn with PartitionKey 25 | object name extends StringColumn 26 | object timestamp extends DateTimeColumn with ClusteringOrder with Descending 27 | } 28 | 29 | abstract class TimeSeriesTableWithTTL2 extends Table[ 30 | TimeSeriesTableWithTTL2, 31 | TimeSeriesRecord 32 | ] { 33 | object id extends UUIDColumn with PartitionKey 34 | object name extends StringColumn 35 | object timestamp extends DateTimeColumn 36 | } 37 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/TupleTypeTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables 17 | 18 | import com.outworkers.phantom.builder.primitives.{DerivedField, DerivedTupleField} 19 | 20 | import scala.concurrent.Future 21 | import com.outworkers.phantom.dsl._ 22 | 23 | abstract class TupleTypeTable extends Table[ 24 | TupleTypeTable, 25 | (UUID, String, String) 26 | ] { 27 | 28 | object id extends UUIDColumn with PartitionKey 29 | object name extends StringColumn 30 | object description extends StringColumn 31 | 32 | def findById(id: UUID): Future[Option[(UUID, String, String)]] = { 33 | select.where(_.id eqs id).one() 34 | } 35 | } 36 | 37 | case class DerivedRecord( 38 | id: UUID, 39 | description: String, 40 | rec: DerivedField, 41 | complex: DerivedTupleField 42 | ) 43 | 44 | abstract class DerivedPrimitivesTable extends Table[ 45 | DerivedPrimitivesTable, 46 | DerivedRecord 47 | ] { 48 | object id extends UUIDColumn with PartitionKey 49 | object description extends StringColumn 50 | object rec extends Col[DerivedField] 51 | object complex extends Col[DerivedTupleField] 52 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/BatchBugTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | import com.outworkers.phantom.builder.primitives.AsciiValue 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class BatchBugRecord( 21 | tenantId: Int, 22 | topic: AsciiValue, 23 | isScheduled: Boolean 24 | ) 25 | 26 | abstract class BatchBugTable extends Table[BatchBugTable, BatchBugRecord] { 27 | 28 | object tenantId extends IntColumn with PartitionKey 29 | 30 | object topic extends AsciiColumn with PrimaryKey 31 | 32 | object isScheduled extends Col[Boolean] 33 | 34 | lazy val prepared = 35 | insert() 36 | .p_value(_.tenantId, ?) 37 | .p_value(_.topic, ?) 38 | .value(_.isScheduled, false) 39 | .ifNotExists() 40 | .prepareAsync() 41 | 42 | } 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/ClientKeys.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import scala.concurrent.Future 20 | 21 | case class ClientKey(sessionId: UUID, key: String, other: String) 22 | 23 | abstract class ClientKeys extends Table[ClientKeys, ClientKey] { 24 | object sessionId extends UUIDColumn with PartitionKey 25 | object key extends StringColumn with ClusteringOrder 26 | object other extends StringColumn 27 | 28 | def findById(id: UUID): Future[Option[ClientKey]] = { 29 | select.where(_.sessionId eqs id).one() 30 | } 31 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/JsonPreparedTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import com.outworkers.phantom.ResultSet 19 | import com.outworkers.phantom.dsl._ 20 | import org.json4s.{DefaultFormats, Extraction} 21 | import org.json4s.native._ 22 | 23 | import scala.concurrent.Future 24 | 25 | case class JsonUser( 26 | id: Int, 27 | name: String 28 | ) 29 | 30 | object JsonUser { 31 | implicit val formats: DefaultFormats = org.json4s.DefaultFormats 32 | 33 | implicit val jsonPrimitive: Primitive[JsonUser] = { 34 | Primitive.json[JsonUser](js => compactJson(renderJValue(Extraction.decompose(js))))(JsonParser.parse(_).extract[JsonUser]) 35 | } 36 | } 37 | 38 | case class NestedJsonRecord( 39 | id: Int, 40 | name: String, 41 | description: Option[String], 42 | user: JsonUser 43 | ) 44 | 45 | abstract class JsonPreparedTable extends Table[JsonPreparedTable, NestedJsonRecord] { 46 | 47 | object id extends IntColumn with PartitionKey 48 | object name extends StringColumn 49 | object description extends OptionalStringColumn 50 | 51 | object user extends JsonColumn[JsonUser] 52 | 53 | lazy val preparedInsert = insert 54 | .p_value(_.id, ?) 55 | .p_value(_.name, ?) 56 | .p_value(_.description, ?) 57 | .p_value(_.user, ?) 58 | .prepareAsync() 59 | 60 | def insertItem(item: NestedJsonRecord): Future[ResultSet] = 61 | preparedInsert.flatMap(_.bind(item).future()) 62 | 63 | def findById(id: Int): Future[Option[NestedJsonRecord]] = { 64 | select.where(_.id eqs id).one() 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/NonIndexQueryColumns.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | import scala.concurrent.Future 21 | 22 | final case class TokenRecord( 23 | email: String, 24 | token: UUID, 25 | counter: Int 26 | ) 27 | 28 | abstract class TokensTable extends Table[TokensTable, TokenRecord] { 29 | object email extends StringColumn 30 | object token extends UUIDColumn with PartitionKey { 31 | override val name = "tokenuid" 32 | } 33 | object counter extends IntColumn 34 | 35 | def findById(id: UUID): Future[Option[TokenRecord]] = { 36 | select.where( _.token eqs id).one() 37 | } 38 | 39 | def deleteById(id: UUID) : Future[ResultSet] = { 40 | delete.where( _.token eqs id).future() 41 | } 42 | 43 | def expired(counter: Int): Future[List[TokenRecord]] = { 44 | 45 | /* PHANTOM NOT IMPLEMENTED FEATURE: 46 | * With "allow filtering" Cassandra allows to query 47 | * non indexed column. Restrictions are on querying part of multi column 48 | * partition key. You need Cassandra 3.10+ to be able to filter 49 | * on partition key columns. 50 | */ 51 | select.where(_.counter gte counter).allowFiltering().fetch() 52 | } 53 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/PrimitiveColumnRecipes.scala: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2013 - 2018 Outworkers Ltd. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package com.outworkers.phantom.tables.bugs 18 | 19 | import java.util.UUID 20 | 21 | import scala.concurrent.{Future => ScalaFuture} 22 | import com.outworkers.phantom.dsl._ 23 | import org.joda.time.DateTime 24 | 25 | case class NpeRecipe( 26 | id: UUID, 27 | name: String, 28 | title: String, 29 | author: String, 30 | description: String, 31 | ingredients: Set[String], 32 | props: Map[String, String], 33 | timestamp: DateTime 34 | ) 35 | 36 | 37 | abstract class PrimitiveColumnRecipes extends Table[PrimitiveColumnRecipes, NpeRecipe] { 38 | object id extends Col[UUID] with PartitionKey 39 | object name extends Col[String] 40 | object title extends Col[String] 41 | object author extends Col[String] 42 | object description extends Col[String] 43 | object ingredients extends Col[Set[String]] 44 | 45 | object props extends Col[Map[String, String]] 46 | 47 | object timestamp extends Col[DateTime] 48 | 49 | def findRecipeById(id: UUID): ScalaFuture[Option[NpeRecipe]] = { 50 | select.where(_.id eqs id).one() 51 | } 52 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/Schema.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | abstract class Schema extends Table[Schema, SchemaBugModel] { 21 | object id extends IntColumn with PartitionKey 22 | object quality extends IntColumn 23 | object name extends StringColumn 24 | object eventId extends LongColumn 25 | } 26 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/SchemaBug656Model.scala: -------------------------------------------------------------------------------- 1 | package com.outworkers.phantom.tables.bugs 2 | 3 | case class SchemaBug656Model(id: Int, name: String) 4 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/SchemaBug656Table.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | abstract class SchemaBug656Table extends Table[ 21 | SchemaBug656Table, SchemaBug656Model 22 | ] { 23 | 24 | object _1 extends IntColumn with PartitionKey 25 | object _2 extends StringColumn 26 | object _3 extends IntColumn 27 | object _4 extends IntColumn 28 | object _5 extends StringColumn 29 | object _6 extends StringColumn 30 | object _7 extends IntColumn 31 | object _8 extends IntColumn 32 | object _9 extends IntColumn 33 | object _10 extends StringColumn 34 | object _11 extends StringColumn 35 | object _12 extends StringColumn 36 | object _13 extends StringColumn 37 | object _14 extends IntColumn 38 | object _15 extends IntColumn 39 | object _16 extends IntColumn 40 | object _17 extends IntColumn 41 | object _18 extends IntColumn 42 | object _20 extends IntColumn 43 | object _21 extends StringColumn 44 | object _22 extends StringColumn 45 | object _23 extends StringColumn 46 | object _24 extends StringColumn 47 | object _25 extends StringColumn 48 | } 49 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/SchemaBug663Table.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | sealed trait SchemaRecord663 21 | case class SchemaBug663A(a: Int) extends SchemaRecord663 22 | case class SchemaBug663B(b: Int) extends SchemaRecord663 23 | 24 | abstract class SchemaBug663Table extends Table[SchemaBug663Table, SchemaRecord663] { 25 | object discriminator extends IntColumn with PartitionKey 26 | object a extends IntColumn 27 | object b extends IntColumn 28 | 29 | override def fromRow(row: Row): SchemaRecord663 = { 30 | if (discriminator(row) % 2 == 0) { 31 | SchemaBug663A(a(row)) 32 | } else { 33 | SchemaBug663B(b(row)) 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/SchemaBugModel.scala: -------------------------------------------------------------------------------- 1 | package com.outworkers.phantom.tables.bugs 2 | 3 | case class SchemaBugModel( 4 | id: Int, 5 | quality: Int, 6 | name: String 7 | ) 8 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/SchemaBugSecondaryIndex.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | abstract class SchemaBugSecondaryIndex extends Table[SchemaBugSecondaryIndex, SecondaryIndexItem] { 21 | 22 | object id extends UUIDColumn with PartitionKey 23 | object name extends Col[String] 24 | object ref extends Col[DateTime] with Index 25 | object date extends Col[DateTime] 26 | } 27 | 28 | case class SecondaryIndexItem( 29 | id: UUID, 30 | name: String, 31 | ref: DateTime, 32 | date: DateTime 33 | ) 34 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/SqlTimestampBug.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import java.sql.Timestamp 19 | 20 | import com.outworkers.phantom.dsl._ 21 | 22 | case class CompanyWideGenderDistributionYearly( 23 | enterprise_id: String, 24 | year: Timestamp, 25 | hired_female_count: BigInt, 26 | terminated_female_count: BigInt, 27 | hired_male_count: BigInt, 28 | terminated_male_count: BigInt, 29 | total_female_count: BigInt, 30 | total_male_count: BigInt 31 | ) 32 | 33 | abstract class YearlyGenderDistributionTable extends Table[YearlyGenderDistributionTable, CompanyWideGenderDistributionYearly] { 34 | object enterprise_id extends StringColumn with PartitionKey 35 | object year extends DateTimeColumn with ClusteringOrder with Descending 36 | object hired_female_count extends BigIntColumn 37 | object terminated_female_count extends BigIntColumn 38 | object hired_male_count extends BigIntColumn 39 | object terminated_male_count extends BigIntColumn 40 | object total_female_count extends BigIntColumn 41 | object total_male_count extends BigIntColumn 42 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/SymphonyBug.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import java.nio.ByteBuffer 19 | 20 | import com.outworkers.phantom.dsl._ 21 | 22 | import scala.concurrent.Future 23 | 24 | case class Shard(id: String, shardNo: Int, accountId: String, size: Int, data: ByteBuffer) 25 | 26 | abstract class ShardModel extends Table[ShardModel, Shard] { 27 | 28 | override def tableName: String = "shard" 29 | 30 | object id extends StringColumn with PartitionKey 31 | object shardNo extends IntColumn with PartitionKey 32 | 33 | object accountId extends StringColumn with ClusteringOrder 34 | object size extends IntColumn 35 | 36 | object data extends BlobColumn 37 | 38 | def find(id: String, shardNo: Int): Future[Array[Byte]] = { 39 | select(_.data).where(_.id eqs id).and(_.shardNo eqs shardNo).one() 40 | .map(_.map(_.array()).getOrElse(Array.emptyByteArray)) 41 | } 42 | 43 | def remove(id: String, accountId: String, shards: Int): Future[Boolean] = { 44 | val f = (1 to shards).map(x => delete.where(_.id eqs id).and(_.shardNo eqs x) 45 | .and(_.accountId eqs accountId) 46 | .future.map(_.wasApplied())).toList 47 | Future.sequence(f) map (_.forall(true ==)) 48 | } 49 | } 50 | 51 | class MediaDatabase(override val connector: CassandraConnection) extends Database[MediaDatabase](connector) { 52 | object ShardModel extends ShardModel with connector.Connector 53 | } -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/TestCaseSchema.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | case class TestCaseContext( 21 | epicId: Int, 22 | userStoryId: Int, 23 | name: String 24 | ) 25 | 26 | abstract class TestCaseSchema extends Table[ 27 | TestCaseSchema, 28 | TestCaseContext 29 | ] { 30 | object tenantId extends IntColumn with PartitionKey 31 | object productId extends IntColumn with PartitionKey 32 | object epicId extends IntColumn with PrimaryKey 33 | object userStoryId extends IntColumn with PrimaryKey 34 | object name extends StringColumn 35 | //object eventId extends LongColumn 36 | } 37 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/TuplePartitionTable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import java.util.UUID 19 | import com.outworkers.phantom.dsl._ 20 | import com.outworkers.phantom.builder.serializers.datatypes.PasswordInfo 21 | 22 | case class TuplePartitionRecord( 23 | id: PasswordInfo, 24 | rec: UUID, 25 | props: Map[String, String] 26 | ) 27 | 28 | abstract class TuplePartitionTable extends Table[TuplePartitionTable, TuplePartitionRecord] { 29 | object id extends Col[PasswordInfo] with PartitionKey 30 | object rec extends Col[UUID] 31 | object props extends Col[Map[String, String]] 32 | } 33 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/bugs/VerizonPreparedUpdateBug.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.bugs 17 | 18 | import com.outworkers.phantom.dsl._ 19 | 20 | import scala.concurrent.Future 21 | 22 | case class VerizonRecord( 23 | uid: String, 24 | name: String, 25 | description: String, 26 | oid: String, 27 | sid: String, 28 | createdOn: Long, 29 | lastUpdated: Long, 30 | isDeleted: Boolean 31 | ) 32 | 33 | abstract class VerizonSchema extends Table[VerizonSchema, VerizonRecord] { 34 | 35 | object uid extends StringColumn with PartitionKey 36 | 37 | object name extends StringColumn 38 | 39 | object description extends StringColumn 40 | 41 | object oid extends StringColumn with Index 42 | 43 | object sid extends StringColumn with Index 44 | 45 | object createdon extends LongColumn 46 | 47 | object lastupdated extends LongColumn 48 | 49 | object isdeleted extends BooleanColumn with Index 50 | 51 | def updateStatus(uid: String, status: Boolean): Future[ResultSet] = { 52 | update 53 | .where(_.uid eqs uid) 54 | .modify(_.isdeleted setTo status) 55 | .ifExists 56 | .consistencyLevel_=(ConsistencyLevel.LOCAL_QUORUM) 57 | .future() 58 | } 59 | 60 | lazy val updateDeleteStatus = update 61 | .where(_.uid eqs ?) 62 | .modify(_.isdeleted setTo ?) 63 | .ifExists 64 | .consistencyLevel_=(ConsistencyLevel.LOCAL_QUORUM) 65 | .prepareAsync() 66 | 67 | } 68 | -------------------------------------------------------------------------------- /phantom-dsl/src/test/scala/com/outworkers/phantom/tables/dbs/SecondaryIndexOnlyDatabase.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.tables.dbs 17 | 18 | import com.datastax.driver.core.SocketOptions 19 | import com.outworkers.phantom.connectors 20 | import com.outworkers.phantom.connectors.CassandraConnection 21 | import com.outworkers.phantom.database.Database 22 | import com.outworkers.phantom.dsl._ 23 | import com.outworkers.phantom.tables.bugs.SchemaBugSecondaryIndex 24 | 25 | object TestConnector { 26 | 27 | val specialTests: CassandraConnection = connectors.ContactPoint.local 28 | .withClusterBuilder(_.withSocketOptions( 29 | new SocketOptions() 30 | .setConnectTimeoutMillis(20000) 31 | .setReadTimeoutMillis(20000) 32 | ) 33 | ).noHeartbeat().keySpace( 34 | KeySpace("phantom_special").ifNotExists().`with`( 35 | replication eqs SimpleStrategy.replication_factor(1) 36 | ) 37 | ) 38 | } 39 | 40 | class SecondaryIndexOnlyDatabase( 41 | override val connector: CassandraConnection 42 | ) extends Database[SecondaryIndexOnlyDatabase](connector) { 43 | object schemaBugSecondaryIndex extends SchemaBugSecondaryIndex with Connector 44 | } 45 | 46 | object SecondaryIndexOnlyDatabase extends SecondaryIndexOnlyDatabase(TestConnector.specialTests) -------------------------------------------------------------------------------- /phantom-example/src/main/scala/com/outworkers/phantom/example/advanced/AdvancedRecipesByTitle.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.example.advanced 17 | 18 | import java.util.UUID 19 | 20 | import com.outworkers.phantom.dsl._ 21 | 22 | import scala.concurrent.{Future => ScalaFuture} 23 | 24 | // Now you want to enable querying Recipes by author. 25 | // Because of the massive performance overhead of filtering, 26 | // you can't really use a SecondaryKey for multi-billion record databases. 27 | 28 | // Instead, you create mapping tables and ensure consistency from the application level. 29 | // This will illustrate just how easy it is to do that with com.outworkers.phantom. 30 | abstract class AdvancedRecipesByTitle extends Table[AdvancedRecipesByTitle, (String, UUID)] { 31 | 32 | // In this table, the author will be PrimaryKey and PartitionKey. 33 | object title extends StringColumn with PartitionKey 34 | 35 | // The id is just another normal field. 36 | object id extends UUIDColumn 37 | 38 | override lazy val tableName = "recipes_by_title" 39 | 40 | // now you can have the tile in a where clause 41 | // without the performance impact of a secondary index. 42 | def findRecipeByTitle(title: String): ScalaFuture[Option[(String, UUID)]] = { 43 | select.where(_.title eqs title).one() 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /phantom-example/src/main/scala/com/outworkers/phantom/example/basics/ThriftModels.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.example.basics 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import com.outworkers.phantom.thrift.compact._ 20 | import com.outworkers.phantom.example.basics.thrift.SampleModel 21 | 22 | // Sample model here comes from the Thrift struct definition. 23 | // The IDL is available in phantom-example/src/main/thrift. 24 | case class SampleRecord( 25 | stuff: String, 26 | someList: List[String], 27 | thriftModel: SampleModel 28 | ) 29 | 30 | abstract class ThriftTable extends Table[ThriftTable, SampleRecord] { 31 | object id extends UUIDColumn with PartitionKey 32 | object stuff extends StringColumn 33 | object someList extends ListColumn[String] 34 | 35 | // By default, com.outworkers.phantom will use a compact Thrift serializer. 36 | // And store the records as strings in Cassandra. 37 | object thriftModel extends Col[SampleModel] 38 | } 39 | -------------------------------------------------------------------------------- /phantom-example/src/main/thrift/Sample.thrift: -------------------------------------------------------------------------------- 1 | namespace java com.outworkers.phantom.example.basics.thrift 2 | 3 | struct SampleModel { 4 | 1: required string id, 5 | 2: required string name, 6 | 3: optional string description 7 | } 8 | -------------------------------------------------------------------------------- /phantom-example/src/test/scala/com/outworkers/phantom/example/ExampleSuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.example 17 | 18 | import com.outworkers.phantom.PhantomBaseSuite 19 | import com.outworkers.phantom.dsl._ 20 | import com.outworkers.phantom.example.advanced.RecipesDatabase 21 | import org.scalatest.FlatSpec 22 | 23 | trait RecipesDbProvider extends DatabaseProvider[RecipesDatabase] { 24 | override def database: RecipesDatabase = RecipesDatabase 25 | } 26 | 27 | trait ExampleSuite extends FlatSpec with PhantomBaseSuite with RecipesDbProvider { 28 | 29 | override def beforeAll(): Unit = { 30 | super.beforeAll() 31 | database.create() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /phantom-example/src/test/scala/com/outworkers/phantom/example/basics/CompositeKeyTests.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.example.basics 17 | 18 | import com.outworkers.phantom.example.ExampleSuite 19 | import com.outworkers.util.samplers._ 20 | import com.outworkers.phantom.dsl._ 21 | 22 | class CompositeKeyTests extends ExampleSuite { 23 | 24 | it should "insert a new record in the table and retrieve it using the full primary key" in { 25 | val sample = gen[Recipe] 26 | 27 | val chain = for { 28 | store <- database.CompositeKeyRecipes.store(sample).future() 29 | rec <- database.CompositeKeyRecipes.findRecipeByIdAndName(sample.id, sample.name) 30 | } yield rec 31 | 32 | whenReady(chain) { res => 33 | res shouldBe defined 34 | res.value shouldEqual sample 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /phantom-finagle/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /phantom-finagle/src/test/scala/com/outworkers/phantom/finagle/CreateQueryFinagleTests.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.finagle 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | 20 | class CreateQueryFinagleTests extends PhantomSuite with TwitterFutures { 21 | 22 | it should "execute a simple query with secondary indexes with Twitter futures" in { 23 | whenReady(database.secondaryIndexTable.create.ifNotExists().future()) { res => 24 | info("The creation query of secondary indexes should execute successfully") 25 | res.forall(_.wasApplied() == true) shouldEqual true 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /phantom-finagle/src/test/scala/com/outworkers/phantom/finagle/SpoolBenchmarkPerformanceTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.finagle 17 | 18 | import com.outworkers.phantom.tables.{JodaRow, TestDatabase} 19 | import com.outworkers.util.samplers._ 20 | import com.twitter.util.{ Await, Future } 21 | import org.joda.time.{DateTime, DateTimeZone} 22 | import org.scalameter.api.{Gen => MeterGen, gen => _, _} 23 | import com.twitter.conversions.DurationOps._ 24 | 25 | class SpoolBenchmarkPerformanceTest extends Bench.LocalTime with TestDatabase.connector.Connector { 26 | 27 | TestDatabase.primitivesJoda.createSchema() 28 | TestDatabase.primitivesJoda.truncate() 29 | 30 | implicit object JodaTimeSampler extends Sample[DateTime] { 31 | override def sample: DateTime = DateTime.now(DateTimeZone.UTC) 32 | } 33 | 34 | val sampleSize = 30000 35 | Iterator.fill(sampleSize)(gen[JodaRow]).grouped(256).foreach { rs => 36 | val chain = rs.map(r => TestDatabase.primitivesJoda.store(r).future.map(_ => ())) 37 | Await.ready(Future.collect(chain), 1.minutes) 38 | } 39 | 40 | val sizes: MeterGen[Int] = MeterGen.range("size")(10000, 30000, 10000) 41 | 42 | performance of "ResultSpool" in { 43 | measure method "fetchSpool" in { 44 | using(sizes) in { size => 45 | Await.ready { 46 | TestDatabase.primitivesJoda.select.limit(size).fetchSpool().flatMap(_.force) 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /phantom-finagle/src/test/scala/com/outworkers/phantom/finagle/TwitterFutures.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.finagle 17 | 18 | import com.twitter.util.{Future, Return, Throw} 19 | import org.scalatest.concurrent.{ScalaFutures, Waiters} 20 | 21 | trait TwitterFutures extends Waiters with ScalaFutures { 22 | 23 | implicit def twitterFutureToConcept[T](f: Future[T]): FutureConcept[T] = new FutureConcept[T] { 24 | override def eitherValue: Option[Either[Throwable, T]] = f.poll match { 25 | case Some(Return(ret)) => Some(Right(ret)) 26 | case Some(Throw(err)) => Some(Left(err)) 27 | case None => None 28 | } 29 | 30 | override def isExpired: Boolean = false 31 | 32 | override def isCanceled: Boolean = false 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /phantom-finagle/src/test/scala/com/outworkers/phantom/finagle/query/prepared/ExactlyOncePromiseTests.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.finagle.query.prepared 17 | 18 | import java.util.concurrent.atomic.AtomicInteger 19 | 20 | import com.outworkers.phantom.builder.query.execution.ExactlyOncePromise 21 | import com.outworkers.phantom.finagle._ 22 | import com.twitter.util.Future 23 | import org.scalatest.concurrent.ScalaFutures 24 | import org.scalatest.{FlatSpec, Matchers} 25 | 26 | class ExactlyOncePromiseTests extends FlatSpec with Matchers with ScalaFutures with TwitterFutures { 27 | 28 | it should "only execute the logic inside an exactly once promise a single time" in { 29 | val atomic = new AtomicInteger(0) 30 | 31 | val promise = new ExactlyOncePromise(Future(atomic.incrementAndGet())) 32 | 33 | val chain = for { 34 | one <- promise.future 35 | two <- promise.future 36 | three <- promise.future 37 | four <- promise.future 38 | } yield four 39 | 40 | whenReady(chain) { res => 41 | res shouldEqual 1 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /phantom-monix/src/main/scala/com/outworkers/phantom/monix/execution/MonixImplicits.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.monix.execution 17 | 18 | import com.outworkers.phantom.builder.query.execution.{FutureMonad, PromiseInterface} 19 | import monix.eval.Task 20 | 21 | import scala.concurrent.ExecutionContext 22 | 23 | object MonixImplicits { 24 | 25 | implicit val taskInterface: PromiseInterface[Task, Task] = new MonixPromiseInterface 26 | 27 | implicit val taskMonad: FutureMonad[Task] = new FutureMonad[Task] { 28 | 29 | override def flatMap[A, B](source: Task[A])(fn: (A) => Task[B])( 30 | implicit ctx: ExecutionContext 31 | ): Task[B] = source flatMap fn 32 | 33 | override def map[A, B](source: Task[A])(f: (A) => B)( 34 | implicit ctx: ExecutionContext 35 | ): Task[B] = source map f 36 | 37 | override def pure[A](source: A): Task[A] = Task.pure(source) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /phantom-monix/src/main/scala/com/outworkers/phantom/monix/execution/MonixQueryContext.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.monix.execution 17 | 18 | import com.outworkers.phantom.ops.QueryContext 19 | import monix.eval.Task 20 | import monix.execution.Scheduler 21 | 22 | import scala.concurrent.Await 23 | import scala.concurrent.duration._ 24 | 25 | class MonixQueryContext()(implicit scheduler: Scheduler) extends QueryContext[Task, Task, Duration](10.seconds)( 26 | MonixImplicits.taskMonad, 27 | MonixImplicits.taskInterface 28 | ) { 29 | override def blockAwait[T](f: Task[T], timeout: Duration): T = { 30 | Await.result(f.runToFuture, timeout) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /phantom-monix/src/test/scala/com/outworkers/phantom/monix/CreateQueryMonixTests.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.monix 17 | 18 | class CreateQueryMonixTests extends MonixSuite { 19 | 20 | it should "execute a simple query with secondary indexes with Twitter futures" in { 21 | whenReady(database.secondaryIndexTable.create.ifNotExists().future()) { res => 22 | info("The creation query of secondary indexes should execute successfully") 23 | res.forall(_.wasApplied() == true) shouldEqual true 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /phantom-monix/src/test/scala/com/outworkers/phantom/monix/MonixSuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.monix 17 | 18 | import com.outworkers.phantom.PhantomSuite 19 | import monix.eval.Task 20 | import monix.execution.Scheduler.Implicits.global 21 | 22 | import scala.util.{Failure, Success} 23 | 24 | trait MonixSuite extends PhantomSuite { 25 | 26 | implicit def taskFutureConcept[T](f: Task[T]): FutureConcept[T] = new FutureConcept[T] { 27 | 28 | private[this] val source = f.memoize 29 | 30 | override def eitherValue: Option[Either[Throwable, T]] = { 31 | source.runToFuture.value match { 32 | case Some(Success(ret)) => Some(Right(ret)) 33 | case Some(Failure(err)) => Some(Left(err)) 34 | case None => None 35 | } 36 | } 37 | 38 | override def isExpired: Boolean = false 39 | 40 | override def isCanceled: Boolean = false 41 | } 42 | } -------------------------------------------------------------------------------- /phantom-sbt/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # for production, you should probably set the root to INFO 18 | # and the pattern to %c instead of %l. (%l is slower.) 19 | 20 | # output messages into a rolling log file as well as stdout 21 | log4j.rootLogger=ERROR,stdout,HColumnFamilyLogger 22 | 23 | # stdout 24 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 25 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 26 | log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c{3} - %m%n 27 | log4j.appender.stdout.follow=true 28 | 29 | log4j.appender.HColumnFamilyLogger=org.apache.log4j.ConsoleAppender 30 | log4j.appender.HColumnFamilyLogger.layout=org.apache.log4j.PatternLayout 31 | log4j.appender.HColumnFamilyLogger.layout.ConversionPattern=%m%n 32 | log4j.category.HColumnFamilyLogger=ERROR 33 | #log4j.category.org.apache=INFO, stdout -------------------------------------------------------------------------------- /phantom-streams/src/main/scala/com/outworkers/phantom/streams/lib/EnumeratorPublisher.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.streams.lib 17 | 18 | import play.api.libs.iteratee.Enumerator 19 | 20 | /** 21 | * Adapts an Enumerator to a Publisher. 22 | */ 23 | private[streams] final class EnumeratorPublisher[T]( 24 | val enum: Enumerator[T], 25 | val emptyElement: Option[T] = None) extends RelaxedPublisher[T] with EnumeratorSubscriptionFactory[T] -------------------------------------------------------------------------------- /phantom-streams/src/main/scala/com/outworkers/phantom/streams/lib/EnumeratorSubscriptionFactory.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.streams.lib 17 | 18 | import org.reactivestreams._ 19 | import play.api.libs.iteratee._ 20 | 21 | /** 22 | * Creates Subscriptions that link Subscribers to an Enumerator. 23 | */ 24 | private[streams] trait EnumeratorSubscriptionFactory[T] extends SubscriptionFactory[T] { 25 | 26 | def enum: Enumerator[T] 27 | def emptyElement: Option[T] 28 | 29 | override def createSubscription[U >: T]( 30 | subr: Subscriber[U], 31 | onSubscriptionEnded: SubscriptionHandle[U] => Unit 32 | ): EnumeratorSubscription[T, U] = { 33 | new EnumeratorSubscription[T, U](enum, emptyElement, subr, onSubscriptionEnded) 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /phantom-streams/src/main/scala/com/outworkers/phantom/streams/lib/RelaxedPublisher.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.streams.lib 17 | 18 | import org.reactivestreams._ 19 | 20 | /** 21 | * A Publisher which subscribes Subscribers without performing any 22 | * checking about whether he Suscriber is already subscribed. This 23 | * makes RelaxedPublisher a bit faster, but possibly a bit less safe, 24 | * than a CheckingPublisher. 25 | */ 26 | private[streams] abstract class RelaxedPublisher[T] extends Publisher[T] { 27 | self: SubscriptionFactory[T] => 28 | 29 | // Streams method 30 | final override def subscribe(subr: Subscriber[_ >: T]): Unit = { 31 | val handle: SubscriptionHandle[_] = createSubscription(subr, RelaxedPublisher.onSubscriptionEndedNop) 32 | handle.start() 33 | } 34 | 35 | } 36 | 37 | private[streams] object RelaxedPublisher { 38 | val onSubscriptionEndedNop: Any => Unit = _ => () 39 | } 40 | -------------------------------------------------------------------------------- /phantom-streams/src/main/scala/com/outworkers/phantom/streams/lib/StateMachine.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.streams.lib 17 | 18 | /** 19 | * A state machine with a non-blocking mutex protecting its state. 20 | */ 21 | private[streams] class StateMachine[S](initialState: S) { 22 | 23 | /** 24 | * The current state. Modifications to the state should be performed 25 | * inside the body of a call to `exclusive`. To read the state, it is 26 | * usually OK to read this field directly, even though its not volatile 27 | * or atomic, so long as you're happy about happens-before relationships. 28 | */ 29 | var state: S = initialState 30 | 31 | val mutex = new NonBlockingMutex() 32 | 33 | /** 34 | * Exclusive access to the state. The state is read and passed to 35 | * f. Inside f it is safe to modify the state, if desired. 36 | */ 37 | def exclusive(f: S => Unit): Unit = mutex.exclusive(f(state)) 38 | 39 | } 40 | -------------------------------------------------------------------------------- /phantom-streams/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /phantom-streams/src/test/scala/com/outworkers/phantom/streams/suites/EventRecorder.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.streams.suites 17 | 18 | import java.util.concurrent.LinkedBlockingQueue 19 | import scala.concurrent.duration.{ FiniteDuration, SECONDS, MILLISECONDS } 20 | 21 | /** 22 | * Utility for recording events in a queue. Useful for 23 | * checking the ordering properties of asynchronous code. Code that does 24 | * stuff records an event, then the test can check that events occur in 25 | * the right order and at the right time. 26 | */ 27 | class EventRecorder( 28 | nextTimeout: FiniteDuration = FiniteDuration(20, SECONDS), 29 | isEmptyDelay: FiniteDuration = FiniteDuration(200, MILLISECONDS) 30 | ) { 31 | 32 | private val events = new LinkedBlockingQueue[AnyRef] 33 | 34 | /** Record an event. */ 35 | def record(e: AnyRef): Boolean = events.add(e) 36 | 37 | /** Pull the next event, waiting up to `nextTimeout`. */ 38 | def next(): AnyRef = { 39 | events.poll(nextTimeout.length, nextTimeout.unit) 40 | } 41 | 42 | /** Wait for `isEmptyDelay` then check if the event queue is empty. */ 43 | def isEmptyAfterDelay(waitMillis: Long = 50): Boolean = { 44 | Thread.sleep(isEmptyDelay.toMillis) 45 | events.isEmpty 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /phantom-streams/src/test/scala/com/outworkers/phantom/streams/suites/iteratee/BigTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.streams.suites.iteratee 17 | 18 | import com.datastax.driver.core.{Session, SocketOptions} 19 | import com.outworkers.phantom.PhantomSuite 20 | import com.outworkers.phantom.connectors.ContactPoint 21 | 22 | trait BigTest extends PhantomSuite { 23 | 24 | val connectionTimeoutMillis = 1000 25 | 26 | override implicit lazy val session: Session = { 27 | ContactPoint.local.withClusterBuilder( 28 | _.withSocketOptions(new SocketOptions() 29 | .setReadTimeoutMillis(connectionTimeoutMillis) 30 | .setConnectTimeoutMillis(connectionTimeoutMillis) 31 | ) 32 | ).noHeartbeat().keySpace(space.name).session 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /phantom-streams/src/test/scala/com/outworkers/phantom/streams/suites/iteratee/OperaPublisher.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.streams.suites.iteratee 17 | 18 | import java.util.concurrent.atomic.AtomicInteger 19 | 20 | import com.outworkers.phantom.streams.suites.{Opera, OperaData} 21 | import org.reactivestreams.{Publisher, Subscriber, Subscription} 22 | 23 | object OperaPublisher extends Publisher[Opera] { 24 | 25 | val counter = new AtomicInteger(0) 26 | 27 | override def subscribe(s: Subscriber[_ >: Opera]): Unit = { 28 | s.onSubscribe(new Subscription { 29 | override def cancel(): Unit = () 30 | 31 | override def request(l: Long): Unit = { 32 | val start = counter.getAndIncrement() * l.toInt 33 | val end = start + l.toInt 34 | 35 | if (start < OperaData.operas.size) { 36 | OperaData.operas.slice(start, end).foreach(i => s.onNext(i)) 37 | } else { 38 | s.onComplete() 39 | } 40 | } 41 | }) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /phantom-thrift/src/main/scala/com/outworkers/phantom/thrift/ThriftHelper.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.thrift 17 | 18 | import com.twitter.scrooge.ThriftStructSerializer 19 | 20 | import scala.reflect.macros.blackbox 21 | 22 | trait ThriftHelper[ 23 | ValueType <: ThriftStruct, 24 | Serializer <: ThriftStructSerializer[ValueType] 25 | ] { 26 | def serializer: Serializer 27 | } 28 | 29 | object ThriftHelper { 30 | def apply[ 31 | T <: ThriftStruct, 32 | Serializer <: ThriftStructSerializer[T] 33 | ](implicit ev: ThriftHelper[T, Serializer]): ThriftHelper[T, Serializer] = ev 34 | 35 | implicit def materializer[ 36 | T <: ThriftStruct, 37 | Serializer <: ThriftStructSerializer[T] 38 | ]: ThriftHelper[T, Serializer] = macro ThriftHelperMacro.materialize[T, Serializer] 39 | } 40 | 41 | class ThriftHelperMacro(val c: blackbox.Context) { 42 | 43 | import c.universe._ 44 | 45 | private[this] val pkgRoot = q"_root_.com.outworkers.phantom.thrift" 46 | private[this] val scroogePkg = q"_root_.com.twitter.scrooge" 47 | 48 | def materialize[ 49 | T <: ThriftStruct : WeakTypeTag, 50 | Serializer : WeakTypeTag 51 | ]: Tree = { 52 | val tpe = weakTypeOf[T] 53 | val sTpe = weakTypeOf[Serializer] 54 | //sTpe.typeConstructor 55 | val valueCompanion = tpe.typeSymbol.companion 56 | val serializerCompanion = sTpe.typeSymbol.companion 57 | 58 | q""" 59 | new $pkgRoot.ThriftHelper[$tpe, $sTpe] { 60 | override val serializer: $sTpe = { 61 | $scroogePkg.$serializerCompanion.apply[$tpe]($valueCompanion) 62 | } 63 | } 64 | """ 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /phantom-thrift/src/main/scala/com/outworkers/phantom/thrift/columns/Ops.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.thrift.columns 17 | 18 | import com.outworkers.phantom.builder.primitives.Primitive 19 | import com.outworkers.phantom.thrift.ThriftHelper 20 | import com.twitter.scrooge.{ThriftStruct, ThriftStructSerializer} 21 | 22 | trait Ops[Serializer[X <: ThriftStruct] <: ThriftStructSerializer[X]] { 23 | 24 | type ThriftStruct = com.twitter.scrooge.ThriftStruct 25 | 26 | implicit def thriftPrimitive[ 27 | T <: ThriftStruct 28 | ](implicit hp: ThriftHelper[T, Serializer[T]]): Primitive[T] = { 29 | Primitive.derive[T, String](hp.serializer.toString)(hp.serializer.fromString) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /phantom-thrift/src/main/scala/com/outworkers/phantom/thrift/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom 17 | 18 | import com.outworkers.phantom.thrift.columns.Ops 19 | import com.twitter.scrooge._ 20 | 21 | package object thrift { 22 | 23 | type ThriftStruct = com.twitter.scrooge.ThriftStruct 24 | 25 | object binary extends Ops[BinaryThriftStructSerializer] 26 | object lazybinary extends Ops[LazyBinaryThriftStructSerializer] 27 | object tjson extends Ops[TJSONProtocolThriftSerializer] 28 | object compact extends Ops[CompactThriftSerializer] 29 | } 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /phantom-thrift/src/main/thrift/test.thrift: -------------------------------------------------------------------------------- 1 | namespace java com.outworkers.phantom.thrift.models 2 | 3 | struct ThriftTest { 4 | 1: required i32 id, 5 | 2: required string name, 6 | 3: required bool test 7 | } 8 | -------------------------------------------------------------------------------- /phantom-thrift/src/test/resources/log4j-embedded-cassandra.properties: -------------------------------------------------------------------------------- 1 | # for production, you should probably set the root to INFO 2 | # and the pattern to %c instead of %l. (%l is slower.) 3 | 4 | # output messages into a rolling log file as well as stdout 5 | log4j.rootLogger=ERROR,stdout,HColumnFamilyLogger 6 | 7 | # stdout 8 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 9 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 10 | log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c{3} - %m%n 11 | log4j.appender.stdout.follow=true 12 | 13 | log4j.appender.HColumnFamilyLogger=org.apache.log4j.ConsoleAppender 14 | log4j.appender.HColumnFamilyLogger.layout=org.apache.log4j.PatternLayout 15 | log4j.appender.HColumnFamilyLogger.layout.ConversionPattern=%m%n 16 | log4j.category.HColumnFamilyLogger=ERROR 17 | #log4j.category.org.apache=ERROR, stdout 18 | -------------------------------------------------------------------------------- /phantom-thrift/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /phantom-thrift/src/test/scala/com/outworkers/phantom/thrift/tests/ThriftRecord.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | package com.outworkers.phantom.thrift.tests.tjson 16 | */ 17 | package com.outworkers.phantom.thrift.tests 18 | 19 | import java.util.UUID 20 | 21 | import com.outworkers.phantom.thrift.models.ThriftTest 22 | 23 | case class ThriftRecord( 24 | id: UUID, 25 | name: String, 26 | struct: ThriftTest, 27 | thriftSet: Set[ThriftTest], 28 | thriftList: List[ThriftTest], 29 | thriftMap: Map[String, ThriftTest], 30 | optThrift: Option[ThriftTest] 31 | ) -------------------------------------------------------------------------------- /phantom-thrift/src/test/scala/com/outworkers/phantom/thrift/tests/binary/BinarySuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.thrift.tests.binary 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import com.outworkers.phantom.thrift.tests.binary 20 | import com.outworkers.phantom.thrift.util.ThriftTestSuite 21 | import org.scalatest.FlatSpec 22 | 23 | trait BinarySuite extends FlatSpec with ThriftTestSuite { 24 | protected[this] val thriftDb = binary.ThriftDatabase 25 | 26 | override def beforeAll(): Unit = { 27 | super.beforeAll() 28 | val _ = thriftDb.create() 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /phantom-thrift/src/test/scala/com/outworkers/phantom/thrift/tests/binary/suites/ThriftColumnTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.thrift.tests.binary.suites 17 | 18 | import com.datastax.driver.core.utils.UUIDs 19 | import com.outworkers.phantom.dsl._ 20 | import com.outworkers.phantom.thrift.tests.binary.BinarySuite 21 | import com.outworkers.util.samplers._ 22 | 23 | class ThriftColumnTest extends BinarySuite { 24 | 25 | it should "allow storing thrift columns" in { 26 | val id = UUIDs.timeBased() 27 | val sample = gen[ThriftTest] 28 | 29 | val insert = thriftDb.thriftColumnTable.insert 30 | .value(_.id, id) 31 | .value(_.name, sample.name) 32 | .value(_.ref, sample) 33 | .future() flatMap { 34 | _ => thriftDb.thriftColumnTable.select.where(_.id eqs id).one() 35 | } 36 | 37 | whenReady(insert) { result => 38 | result.value.struct shouldEqual sample 39 | } 40 | } 41 | 42 | it should "allow storing lists of thrift objects" in { 43 | val id = UUIDs.timeBased() 44 | val sample = gen[ThriftTest] 45 | val sample2 = gen[ThriftTest] 46 | val sampleList = Set(sample, sample2) 47 | 48 | val insert = thriftDb.thriftColumnTable.insert 49 | .value(_.id, id) 50 | .value(_.name, sample.name) 51 | .value(_.ref, sample) 52 | .value(_.thriftSet, sampleList) 53 | .future() flatMap { 54 | _ => thriftDb.thriftColumnTable.select.where(_.id eqs id).one() 55 | } 56 | 57 | whenReady(insert) { result => 58 | result.value.struct shouldEqual sample 59 | result.value.thriftSet shouldEqual sampleList 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /phantom-thrift/src/test/scala/com/outworkers/phantom/thrift/tests/compact/CompactSuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.thrift.tests.compact 17 | 18 | import com.outworkers.phantom.dsl._ 19 | import com.outworkers.phantom.thrift.tests.compact 20 | import com.outworkers.phantom.thrift.util.ThriftTestSuite 21 | import org.scalatest.FlatSpec 22 | 23 | trait CompactSuite extends FlatSpec with ThriftTestSuite { 24 | val thriftDb = compact.ThriftDatabase 25 | 26 | override def beforeAll(): Unit = { 27 | super.beforeAll() 28 | thriftDb.create() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /phantom-thrift/src/test/scala/com/outworkers/phantom/thrift/tests/tjson/TJsonSuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.thrift.tests.tjson 17 | import com.outworkers.phantom.dsl._ 18 | import com.outworkers.phantom.thrift.tests.tjson 19 | import com.outworkers.phantom.thrift.util.ThriftTestSuite 20 | import org.scalatest.FlatSpec 21 | 22 | trait TJsonSuite extends FlatSpec with ThriftTestSuite { 23 | val thriftDb = tjson.ThriftDatabase 24 | 25 | override def beforeAll(): Unit = { 26 | super.beforeAll() 27 | thriftDb.create() 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /phantom-thrift/src/test/scala/com/outworkers/phantom/thrift/tests/tjson/suites/ThriftColumnTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2020 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.outworkers.phantom.thrift.tests.tjson.suites 17 | 18 | import com.datastax.driver.core.utils.UUIDs 19 | import com.outworkers.phantom.finagle._ 20 | import com.outworkers.phantom.thrift.tests.tjson.TJsonSuite 21 | import com.outworkers.util.samplers._ 22 | 23 | class ThriftColumnTest extends TJsonSuite { 24 | 25 | it should "allow storing thrift columns" in { 26 | val id = UUIDs.timeBased() 27 | val sample = gen[ThriftTest] 28 | 29 | val insert = thriftDb.thriftColumnTable.insert 30 | .value(_.id, id) 31 | .value(_.name, sample.name) 32 | .value(_.ref, sample) 33 | .future() flatMap { 34 | _ => thriftDb.thriftColumnTable.select.where(_.id eqs id).one() 35 | } 36 | 37 | whenReady(insert) { result => 38 | result.value.struct shouldEqual sample 39 | } 40 | } 41 | 42 | it should "allow storing lists of thrift objects" in { 43 | val id = UUIDs.timeBased() 44 | val sample = gen[ThriftTest] 45 | val sample2 = gen[ThriftTest] 46 | val sampleList = Set(sample, sample2) 47 | 48 | val insert = thriftDb.thriftColumnTable.insert 49 | .value(_.id, id) 50 | .value(_.name, sample.name) 51 | .value(_.ref, sample) 52 | .value(_.thriftSet, sampleList) 53 | .future() flatMap { 54 | _ => thriftDb.thriftColumnTable.select.where(_.id eqs id).one() 55 | } 56 | 57 | whenReady(insert) { result => 58 | result.value.struct shouldEqual sample 59 | result.value.thriftSet shouldEqual sampleList 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.3.3 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 - 2017 Outworkers Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | resolvers ++= Seq( 17 | "jgit-repo" at "https://download.eclipse.org/jgit/maven", 18 | "Twitter Repo" at "https://maven.twttr.com/", 19 | Resolver.sonatypeRepo("releases"), 20 | Resolver.bintrayIvyRepo("sksamuel", "sbt-plugins"), 21 | Resolver.bintrayIvyRepo("twittercsl-ivy", "sbt-plugins"), 22 | Resolver.bintrayRepo("twittercsl", "sbt-plugins") 23 | ) 24 | 25 | lazy val scalaTravisEnv = sys.env.get("TRAVIS_SCALA_VERSION") 26 | def isScala210: Boolean = scalaTravisEnv.exists("2.10.6" ==) 27 | lazy val isCi = sys.env.get("CI").exists("true" == ) 28 | 29 | lazy val Versions = new { 30 | val scrooge = if (isCi && isScala210) "19.1.0" else "19.10.0" 31 | val scalaFix = "0.9.11" 32 | } 33 | 34 | addSbtPlugin("org.scoverage" %% "sbt-scoverage" % "1.6.0") 35 | 36 | addSbtPlugin("org.scoverage" %% "sbt-coveralls" % "1.2.7") 37 | 38 | addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1") 39 | 40 | addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.5") 41 | 42 | addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0") 43 | 44 | addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.5.0") 45 | 46 | addSbtPlugin("com.twitter" % "scrooge-sbt-plugin" % Versions.scrooge) 47 | 48 | addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.1.1" ) 49 | 50 | addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.12") 51 | 52 | libraryDependencies += "org.slf4j" % "slf4j-nop" % "1.7.22" 53 | 54 | -------------------------------------------------------------------------------- /version.sbt: -------------------------------------------------------------------------------- 1 | version in ThisBuild := "2.60.0-SNAPSHOT" 2 | --------------------------------------------------------------------------------