Skip to content

Commit

Permalink
Merge 30592ce into eaf774c
Browse files Browse the repository at this point in the history
  • Loading branch information
alexflav23 committed May 20, 2015
2 parents eaf774c + 30592ce commit 539b83b
Show file tree
Hide file tree
Showing 17 changed files with 181 additions and 72 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ We publish phantom in 2 formats, stable releases and bleeding edge.
### Latest versions

- Latest stable version: 1.8.4 (Maven Central)
- Bleeding edge: 1.8.6 (Websudos OSS releases on Bintray)
- Bleeding edge: 1.8.9 (Websudos OSS releases on Bintray)

You will also be needing the default resolvers for Maven Central and the typesafe releases. Phantom will never rely on any snapshots or be published as a
snapshot version, the bleeding edge is always subject to internal scrutiny before any releases into the wild.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ trait CassandraConnector {

val manager: CassandraManager = DefaultCassandraManager

implicit def session: Session = manager.session
implicit def session: Session = {
manager.initIfNotInited(keySpace.name)
manager.session
}

def cassandraVersions: Set[VersionNumber] = {
manager.cassandraVersions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
package com.websudos.phantom.connectors

import org.scalatest.FlatSpec
import org.scalatest.{ FlatSpec, Matchers }

class ConnectorReferenceTest extends FlatSpec {

trait MyConnector extends SimpleCassandraConnector {
implicit val keySpace = KeySpace("test")
}

object Test extends MyConnector

object Test2 extends MyConnector


class ConnectorReferenceTest extends FlatSpec with Matchers {
it should "reference the same session inside multiple mixins of the same connector" in {
(Test.session eq Test2.session) shouldEqual true
}

it should "reference the same manager inside multiple mixins of the same connctor" in {
(Test.manager eq Test2.manager) shouldEqual true
}

it should "reference the same cluster inside multiple mixins of the same connctor" in {
(Test.manager.clusterRef eq Test2.manager.clusterRef) shouldEqual true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ abstract class CassandraTable[T <: CassandraTable[T, R], R] extends SelectTable[

final def delete()(implicit keySpace: KeySpace): DeleteQuery.Default[T, R] = DeleteQuery[T, R](this.asInstanceOf[T])

final def delete(clause: T => AbstractColumn[_])(implicit keySpace: KeySpace): DeleteQuery.Default[T, R] = DeleteQuery[T, R](this.asInstanceOf[T], clause(this.asInstanceOf[T]).name)
final def delete(clause: T => AbstractColumn[_])(implicit keySpace: KeySpace): DeleteQuery.Default[T, R] = {
DeleteQuery[T, R](this.asInstanceOf[T], clause(this.asInstanceOf[T]).name)
}

final def truncate()(implicit keySpace: KeySpace): TruncateQuery.Default[T, R] = TruncateQuery[T, R](this.asInstanceOf[T])

Expand All @@ -102,8 +104,6 @@ abstract class CassandraTable[T <: CassandraTable[T, R], R] extends SelectTable[

def clustered: Boolean = clusteringColumns.nonEmpty



/**
* This method will filter the columns from a Clustering Order definition.
* It is used to define TimeSeries tables, using the ClusteringOrder trait
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ private[phantom] object QueryBuilder {

case object Create extends CreateTableBuilder

case object Delete extends DeleteQueryBuilder

case object Update extends UpdateQueryBuilder

case object Collections extends CollectionModifiers
Expand Down Expand Up @@ -115,17 +117,6 @@ private[phantom] object QueryBuilder {
.forcePad.append(value.toString)
}

def delete(table: String): CQLQuery = {
CQLQuery(CQLSyntax.delete)
.forcePad.append(CQLSyntax.from)
.forcePad.append(table)
}

def deleteColumn(table: String, column: String): CQLQuery = {
CQLQuery(CQLSyntax.delete)
.forcePad.append(column)
.forcePad.append(CQLSyntax.from)
.forcePad.append(table)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ case class CQLQuery(queryString: String) {
def prependIfAbsent(st: CQLQuery): CQLQuery = prependIfAbsent(st.queryString)

def escape(st: String): String = "`" + st + "`"
def singleQuote(st: String): String = "'" + st + "'"
def singleQuote(st: String): String = "'" + st.replaceAll("'", "''") + "'"

def spaced: Boolean = queryString.endsWith(" ")
def pad: CQLQuery = if (spaced) this else CQLQuery(queryString + " ")
Expand All @@ -79,7 +79,7 @@ case class CQLQuery(queryString: String) {
object CQLQuery {
def empty: CQLQuery = CQLQuery("")

def escape(str: String): String = "'" + str + "'"
def escape(str: String): String = "'" + str.replaceAll("'", "''") + "'"

def apply(collection: TraversableOnce[String]): CQLQuery = CQLQuery(collection.mkString(", "))
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ object DeleteQuery {
type Default[T <: CassandraTable[T, _], R] = DeleteQuery[T, R, Unlimited, Unordered, Unspecified, Unchainned]

def apply[T <: CassandraTable[T, _], R](table: T)(implicit keySpace: KeySpace): DeleteQuery.Default[T, R] = {
new DeleteQuery(table, QueryBuilder.delete(QueryBuilder.keyspace(keySpace.name, table.tableName).queryString))
new DeleteQuery(table, QueryBuilder.Delete.delete(QueryBuilder.keyspace(keySpace.name, table.tableName).queryString))
}

def apply[T <: CassandraTable[T, _], R](table: T, col: String)(implicit keySpace: KeySpace): DeleteQuery.Default[T, R] = {
new DeleteQuery(table, QueryBuilder.deleteColumn(QueryBuilder.keyspace(keySpace.name, table.tableName).queryString, col))
new DeleteQuery(table, QueryBuilder.Delete.deleteColumn(QueryBuilder.keyspace(keySpace.name, table.tableName).queryString, col))
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.websudos.phantom.builder.serializers

import com.websudos.phantom.builder.query.CQLQuery
import com.websudos.phantom.builder.syntax.CQLSyntax

private[builder] class DeleteQueryBuilder {
def delete(table: String): CQLQuery = {
CQLQuery(CQLSyntax.delete)
.forcePad.append(CQLSyntax.from)
.forcePad.append(table)
}

def deleteColumn(table: String, column: String): CQLQuery = {
CQLQuery(CQLSyntax.delete)
.forcePad.append(column)
.forcePad.append(CQLSyntax.from)
.forcePad.append(table)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.websudos.phantom.builder.query

import org.scalatest.{Matchers, FlatSpec}
import com.websudos.util.testing._

class CQLQueryTest extends FlatSpec with Matchers {
it should "create an empty CQL query using the empty method on the companion object" in {
CQLQuery.empty.queryString shouldEqual ""
}

it should "automatically serialize a list of strings using the apply method from the companion object" in {
val list = List("test", "test2")

CQLQuery(list).queryString shouldEqual "test, test2"
}

it should "escape strings without single quotes inside them by wrapping the string in single quotes" in {
val test = gen[String]
CQLQuery.escape(test) shouldEqual s"'$test'"
}

it should "escape single quotes inside a string using the scape method of the companion" in {
val test = "test'"
CQLQuery.escape(test) shouldEqual "'test'''"
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -83,56 +83,70 @@ class InsertTest extends PhantomCassandraTestSuite {
}
}

it should "work fine with List, Set, Map" in {
val row = gen[TestRow]
it should "insert strings with single quotes inside them and automatically escape them" in {
val row = gen[TestRow].copy(key = "test'")

val rcp = TestTable.insert
.value(_.key, row.key)
.value(_.list, row.list)
.value(_.setText, row.setText)
.value(_.mapTextToText, row.mapTextToText)
.value(_.setInt, row.setInt)
.value(_.mapIntToText, row.mapIntToText)
.future() flatMap {
_ => {
for {
one <- TestTable.select.where(_.key eqs row.key).one
multi <- TestTable.select.fetch
} yield (one.get === row, multi.contains(row))
val chain = for {
store <- TestTable.store(row).future()
one <- TestTable.select.where(_.key eqs row.key).one
multi <- TestTable.select.fetch
} yield (one.get === row, multi.contains(row))

chain successful {
res => {
assert (res._1)
assert (res._2)
}
}
rcp successful {
}

it should "insert strings with single quotes inside them and automatically escape them with Twitter Futures" in {
val row = gen[TestRow].copy(key = "test'")

val chain = for {
store <- TestTable.store(row).execute()
one <- TestTable.select.where(_.key eqs row.key).get
multi <- TestTable.select.collect()
} yield (one.get === row, multi.contains(row))

chain successful {
res => {
assert (res._1)
assert (res._2)
}
}
}

it should "work fine with List, Set, Map and Twitter futures" in {
it should "work fine with List, Set, Map" in {
val row = gen[TestRow]

val rcp = TestTable.insert
.value(_.key, row.key)
.value(_.list, row.list)
.value(_.setText, row.setText)
.value(_.mapTextToText, row.mapTextToText)
.value(_.setInt, row.setInt)
.value(_.mapIntToText, row.mapIntToText)
.execute() flatMap {
_ => {
for {
one <- TestTable.select.where(_.key eqs row.key).get
multi <- TestTable.select.collect()
} yield (one, multi)
val chain = for {
store <- TestTable.store(row).future()
one <- TestTable.select.where(_.key eqs row.key).one
multi <- TestTable.select.fetch
} yield (one.get === row, multi.contains(row))

chain successful {
res => {
assert (res._1)
assert (res._2)
}
}
rcp successful {
res => {
res._1.isDefined shouldEqual true
res._1.get shouldEqual row
}

res._2.contains(row) shouldEqual true
it should "work fine with List, Set, Map and Twitter futures" in {
val row = gen[TestRow]

val chain = for {
store <- TestTable.store(row).execute()
one <- TestTable.select.where(_.key eqs row.key).get
multi <- TestTable.select.collect()
} yield (one.get === row, multi.contains(row))

chain successful {
res => {
assert (res._1)
assert (res._2)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.websudos.phantom.builder.serializers

import com.websudos.phantom.builder.query.QueryBuilderTest
import com.websudos.phantom.tables.TimeSeriesTable

class CreateQuerySerialisationTest extends QueryBuilderTest {
"The CREATE query builder" - {
"should generate clustering keys for a schema queries" - {
val qb = TimeSeriesTable.defineTableKey()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package com.websudos.phantom.builder.serializers

import com.websudos.phantom.builder.QueryBuilder
import com.websudos.phantom.builder.query.QueryBuilderTest

class DeleteQueryBuilderTest extends QueryBuilderTest {
"The DELETE query builder" - {

"should allow specifying column delete queries" - {
val qb = QueryBuilder.Delete.deleteColumn("table", "col").queryString
qb shouldEqual "DELETE col FROM table"
}

"should allow specifying full delete queries" - {
val qb = QueryBuilder.Delete.delete("table").queryString
qb shouldEqual "DELETE FROM table"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.websudos.phantom.builder.serializers

import com.websudos.phantom.builder.query.QueryBuilderTest
import com.websudos.phantom.tables.BasicTable

class DeleteQuerySerialisationTest extends QueryBuilderTest {
"The DELETE query builder" - {

"The DELETE query builder" - {
"should generate table column deletion queries" - {
"should create a delete query for a single column" - {
BasicTable.delete(_.id)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/
package com.websudos.phantom.tables

import com.websudos.phantom.builder.query.InsertQuery
import com.websudos.phantom.dsl._
import com.websudos.phantom.testkit._

Expand Down Expand Up @@ -69,5 +70,16 @@ sealed class TestTable extends CassandraTable[TestTable, TestRow] {

object TestTable extends TestTable with PhantomCassandraConnector {
override val tableName = "TestTable"

def store(row: TestRow): InsertQuery.Default[TestTable, TestRow] = {
insert
.value(_.key, row.key)
.value(_.list, row.list)
.value(_.setText, row.setText)
.value(_.mapTextToText, row.mapTextToText)
.value(_.setInt, row.setInt)
.value(_.mapIntToText, row.mapIntToText)
}

}

Loading

0 comments on commit 539b83b

Please sign in to comment.