Skip to content

Commit

Permalink
Merge pull request #426 from websudos/release/timeuuid_fix
Browse files Browse the repository at this point in the history
Fixing timeuuid operator serialization and adding tests.
  • Loading branch information
alexflav23 committed Feb 24, 2016
2 parents 218c1a7 + d90838c commit 3f9a4f5
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 42 deletions.
10 changes: 9 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Changelog
<li><a href="#version-1.21.4">1.21.4 - 06.02.2016</a></li>
<li><a href="#version-1.21.5">1.21.5 - 11.02.2016</a></li>
<li><a href="#version-1.22.0">1.22.0 - 14.02.2016</a></li>
<li><a href="#version-1.22.1">1.22.1 - 24.02.2016</a></li>
</ul>


Expand Down Expand Up @@ -354,4 +355,11 @@ removed `session.newSimpleStatement`.

- PHANTOM-194: Fixed serialization of ```Table.select.distinct``` queries.
- Added support for `LocalDate` columns.
- Added `driver-extras` dependency from the Datastax set.
- Added `driver-extras` dependency from the Datastax set.

<a id="version-1.22.1">1.22.1</a>
================================

- Added a `DateTime` augmenter in the default package capable of producing `TimeUUID` values from a `DateTime`.
- Fixed serialization of `minTimeuuid` and `maxTimeuuid` clauses to use dates in ISO formats.
- Added tests to test `timeuuid` based date range selection with `minTimeuuid` and `maxTimeuuid`.
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ package com.websudos.phantom.builder.ops
import java.util.Date

import com.datastax.driver.core.Session
import com.datastax.driver.core.utils.UUIDs
import com.websudos.phantom.builder.QueryBuilder
import com.websudos.phantom.builder.clauses.OperatorClause.Condition
import com.websudos.phantom.builder.clauses.{OperatorClause, TypedClause, WhereClause}
import com.websudos.phantom.builder.primitives.{DefaultPrimitives, Primitive}
import com.websudos.phantom.builder.query.SessionAugmenter
import com.websudos.phantom.builder.query.{CQLQuery, SessionAugmenter}
import com.websudos.phantom.builder.syntax.CQLSyntax
import com.websudos.phantom.column.{AbstractColumn, TimeUUIDColumn}
import org.joda.time.DateTime
Expand Down Expand Up @@ -91,35 +90,37 @@ sealed class NowCqlFunction extends CqlFunction {

sealed class MaxTimeUUID extends CqlFunction with DefaultPrimitives {

private[this] val datePrimitive = implicitly[Primitive[Date]]
private[this] val dateTimePrimitive = implicitly[Primitive[DateTime]]

def apply(date: Date): OperatorClause.Condition = {
new Condition(QueryBuilder.Select.maxTimeuuid(UUIDPrimitive.asCql(UUIDs.endOf(date.getTime))))
new Condition(
QueryBuilder.Select.maxTimeuuid(
CQLQuery.escape(new DateTime(date).toString())
)
)
}

def apply(date: DateTime): OperatorClause.Condition = {
new Condition(QueryBuilder.Select.maxTimeuuid(UUIDPrimitive.asCql(UUIDs.endOf(date.getMillis))))
new Condition(
QueryBuilder.Select.maxTimeuuid(
CQLQuery.escape(new DateTime(date).toString())
)
)
}
}

sealed class MinTimeUUID extends CqlFunction with DefaultPrimitives {

private[this] val datePrimitive = implicitly[Primitive[Date]]
private[this] val dateTimePrimitive = implicitly[Primitive[DateTime]]

def apply(date: Date): OperatorClause.Condition = {
new Condition(
QueryBuilder.Select.minTimeuuid(
UUIDPrimitive.asCql(UUIDs.startOf(date.getTime))
CQLQuery.escape(new DateTime(date).toString())
)
)
}

def apply(date: DateTime): OperatorClause.Condition = {
new Condition(
QueryBuilder.Select.minTimeuuid(
UUIDPrimitive.asCql(UUIDs.startOf(date.getMillis))
CQLQuery.escape(date.toString())
)
)
}
Expand Down Expand Up @@ -151,6 +152,7 @@ sealed class TokenConstructor[P <: HList, TP <: TokenTypes.Root](val mapper : Se

/**
* An equals comparison clause between token definitions.
*
* @param tk The token constructor to compare against.
* @tparam VL
* @return
Expand Down
18 changes: 14 additions & 4 deletions phantom-dsl/src/main/scala/com/websudos/phantom/dsl/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,19 @@ package com.websudos.phantom

import java.net.InetAddress
import java.nio.ByteBuffer
import java.util.Date
import java.util.{Date, Random}

import com.datastax.driver.core.utils.UUIDs
import com.datastax.driver.core.{ConsistencyLevel => CLevel, VersionNumber}
import com.websudos.phantom.batch.Batcher
import com.websudos.phantom.builder.QueryBuilder
import com.websudos.phantom.builder.clauses.{WhereClause, UpdateClause}
import com.websudos.phantom.builder.clauses.{UpdateClause, WhereClause}
import com.websudos.phantom.builder.ops._
import com.websudos.phantom.builder.primitives.{DefaultPrimitives, Primitive}
import com.websudos.phantom.builder.query.{DeleteImplicits, CQLQuery, CreateImplicits, SelectImplicits}
import com.websudos.phantom.builder.query.{CQLQuery, CreateImplicits, DeleteImplicits, SelectImplicits}
import com.websudos.phantom.builder.syntax.CQLSyntax
import com.websudos.phantom.util.ByteString
import shapeless.{HNil, ::}
import shapeless.{::, HNil}

import scala.util.Try

Expand Down Expand Up @@ -246,11 +247,20 @@ package object dsl extends ImplicitMechanism with CreateImplicits
/**
* Augments Cassandra VersionNumber descriptors to support simple comparison of versions.
* This allows for operations that can differ based on the Cassandra version used by the session.
*
* @param version The Cassandra version number.
*/
implicit class VersionAugmenter(val version: VersionNumber) extends AnyVal {
def <(other: VersionNumber): Boolean = version.compareTo(other) == -1
def ===(other: VersionNumber): Boolean = version.compareTo(other) == 0
def > (other: VersionNumber): Boolean = version.compareTo(other) == 1
}

implicit class DateTimeAugmenter(val date: DateTime) extends AnyVal {
def timeuuid(): UUID = {
val random = new Random()
new UUID(UUIDs.startOf(date.getMillis).getMostSignificantBits, random.nextLong())
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,20 @@ class TimeSeriesTest extends PhantomSuite {
TestDatabase.timeSeriesTable.insertSchema()
}

protected[this] final val durationOffset = 1000

it should "allow using naturally fetch the records in descending order for a descending clustering order" in {

var i = 0
val testUUID = gen[UUID]

val number = 5

val recordList = genList[TimeSeriesRecord](number).map(
item => {
i += 1
item.copy(id = TestDatabase.timeSeriesTable.testUUID, timestamp = item.timestamp.withDurationAdded(1000, i))
item.copy(
id = TestDatabase.timeSeriesTable.testUUID,
timestamp = item.timestamp.withDurationAdded(durationOffset, i)
)
})

val ts = recordList.map(_.timestamp.getSecondOfDay)
Expand Down Expand Up @@ -88,14 +91,15 @@ class TimeSeriesTest extends PhantomSuite {

it should "allow using naturally fetch the records in descending order for a descending clustering order with Twitter Futures" in {
var i = 0
val testUUID = gen[UUID]

val number = 5

val recordList = genList[TimeSeriesRecord](number).map(
item => {
i += 1
item.copy(id = TestDatabase.timeSeriesTable.testUUID, timestamp = item.timestamp.withDurationAdded(1000, i))
item.copy(
id = TestDatabase.timeSeriesTable.testUUID,
timestamp = item.timestamp.withDurationAdded(durationOffset, i)
)
})

val ts = recordList.map(_.timestamp.getSecondOfDay)
Expand Down Expand Up @@ -124,13 +128,15 @@ class TimeSeriesTest extends PhantomSuite {

it should "allow fetching the records in ascending order for a descending clustering order using order by clause" in {
var i = 0
val testUUID = gen[UUID]
val number = 5

val recordList = genList[TimeSeriesRecord](number).map(
item => {
i += 1
item.copy(id = TestDatabase.timeSeriesTable.testUUID, timestamp = item.timestamp.withDurationAdded(500, i))
item.copy(
id = TestDatabase.timeSeriesTable.testUUID,
timestamp = item.timestamp.withDurationAdded(durationOffset / 2, i)
)
})

val batch = recordList.foldLeft(Batch.unlogged) {
Expand Down Expand Up @@ -162,13 +168,15 @@ class TimeSeriesTest extends PhantomSuite {

it should "allow fetching the records in ascending order for a descending clustering order using order by clause with Twitter Futures" in {
var i = 0
val testUUID = gen[UUID]
val number = 5

val recordList = genList[TimeSeriesRecord](number).map(
item => {
i += 1
item.copy(id = TestDatabase.timeSeriesTable.testUUID, timestamp = item.timestamp.withDurationAdded(500, i))
item.copy(
id = TestDatabase.timeSeriesTable.testUUID,
timestamp = item.timestamp.withDurationAdded(durationOffset, i)
)
})

val batch = recordList.foldLeft(Batch.unlogged) {
Expand All @@ -182,7 +190,11 @@ class TimeSeriesTest extends PhantomSuite {
val chain = for {
truncate <- TestDatabase.timeSeriesTable.truncate.execute()
insert <- batch.execute()
chunks <- TestDatabase.timeSeriesTable.select.where(_.id eqs TestDatabase.timeSeriesTable.testUUID).orderBy(_.timestamp.asc).limit(number).collect()
chunks <- TestDatabase.timeSeriesTable
.select
.where(_.id eqs TestDatabase.timeSeriesTable.testUUID)
.orderBy(_.timestamp.asc).limit(number)
.collect()
} yield chunks

chain.successful {
Expand All @@ -194,13 +206,15 @@ class TimeSeriesTest extends PhantomSuite {

it should "allow fetching the records in descending order for a descending clustering order using order by clause" in {
var i = 0
val testUUID = gen[UUID]
val number = 5

val recordList = genList[TimeSeriesRecord](number).map(
item => {
i += 1
item.copy(id = TestDatabase.timeSeriesTable.testUUID, timestamp = item.timestamp.withDurationAdded(500, i))
item.copy(
id = TestDatabase.timeSeriesTable.testUUID,
timestamp = item.timestamp.withDurationAdded(durationOffset / 2, i)
)
})

val batch = recordList.foldLeft(Batch.unlogged) {
Expand All @@ -213,7 +227,12 @@ class TimeSeriesTest extends PhantomSuite {
val chain = for {
truncate <- TestDatabase.timeSeriesTable.truncate.future()
insert <- batch.future()
chunks <- TestDatabase.timeSeriesTable.select.where(_.id eqs TestDatabase.timeSeriesTable.testUUID).orderBy(_.timestamp.descending).limit(number).fetch()
chunks <- TestDatabase.timeSeriesTable
.select
.where(_.id eqs TestDatabase.timeSeriesTable.testUUID)
.orderBy(_.timestamp.descending)
.limit(number)
.fetch()
} yield chunks

chain.successful {
Expand All @@ -225,13 +244,15 @@ class TimeSeriesTest extends PhantomSuite {

it should "allow fetching the records in descending order for a descending clustering order using order by clause with Twitter Futures" in {
var i = 0
val testUUID = gen[UUID]
val number = 5

val recordList = genList[TimeSeriesRecord](number).map(
item => {
i += 1
item.copy(id = TestDatabase.timeSeriesTable.testUUID, timestamp = item.timestamp.withDurationAdded(500, i))
item.copy(
id = TestDatabase.timeSeriesTable.testUUID,
timestamp = item.timestamp.withDurationAdded(durationOffset, i)
)
})

val batch = recordList.foldLeft(Batch.unlogged) {
Expand All @@ -244,7 +265,10 @@ class TimeSeriesTest extends PhantomSuite {
val chain = for {
truncate <- TestDatabase.timeSeriesTable.truncate.execute()
insert <- batch.execute()
chunks <- TestDatabase.timeSeriesTable.select.where(_.id eqs TestDatabase.timeSeriesTable.testUUID).orderBy(_.timestamp.desc).limit(number).collect()
chunks <- TestDatabase.timeSeriesTable.select
.where(_.id eqs TestDatabase.timeSeriesTable.testUUID)
.orderBy(_.timestamp.desc).limit(number)
.collect()
} yield chunks

chain.successful {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ class SelectFunctionsTesting extends PhantomSuite {

val chain = for {
store <- database.timeuuidTable.store(record).future()
timestamp <- database.timeuuidTable.select.function(t => dateOf(t.id))
.where(_.id eqs record.id).one()
timestamp <- database.timeuuidTable.select.function(t => dateOf(t.id)).where(_.user eqs record.user)
.and(_.id eqs record.id).one()
} yield timestamp

whenReady(chain) {
Expand All @@ -88,8 +88,8 @@ class SelectFunctionsTesting extends PhantomSuite {

val chain = for {
store <- database.timeuuidTable.store(record).future()
timestamp <- database.timeuuidTable.select.function(t => unixTimestampOf(t.id))
.where(_.id eqs record.id).one()
timestamp <- database.timeuuidTable.select.function(t => unixTimestampOf(t.id)).where(_.user eqs record.user)
.and(_.id eqs record.id).one()
} yield timestamp

whenReady(chain) {
Expand Down
Loading

0 comments on commit 3f9a4f5

Please sign in to comment.