diff --git a/phantom-test/src/test/scala/com/newzly/phantom/dsl/BaseTest.scala b/phantom-test/src/test/scala/com/newzly/phantom/dsl/BaseTest.scala index 053c898c1..49315858b 100644 --- a/phantom-test/src/test/scala/com/newzly/phantom/dsl/BaseTest.scala +++ b/phantom-test/src/test/scala/com/newzly/phantom/dsl/BaseTest.scala @@ -7,21 +7,39 @@ import scala.concurrent.duration._ import org.scalatest.{ BeforeAndAfterEach, BeforeAndAfterAll, FlatSpec } import com.newzly.phantom.helper.{ CassandraCluster, TestHelper} import org.cassandraunit.utils.EmbeddedCassandraServerHelper +import java.util.concurrent.atomic.{AtomicInteger, AtomicBoolean} + +object Atomics { + val clusterStarted = new AtomicBoolean(false) + val startedTests = new AtomicInteger(0) +} class BaseTest extends FlatSpec with BeforeAndAfterEach with BeforeAndAfterAll with CassandraCluster { + override def beforeAll() { - TestHelper.initCluster + if (!Atomics.clusterStarted.get()) { + if (Atomics.clusterStarted.compareAndSet(false,true)) { + TestHelper.initCluster() + } + } + Atomics.startedTests.incrementAndGet() + while (!TestHelper.initialized) { + Thread.sleep(1000) + } } override def afterAll() { - cluster.shutdown() + val finished = Atomics.startedTests.decrementAndGet() + if (finished == 0) { + cluster.shutdown() + } } - implicit class SyncFuture[T](future: Future[T]) { + /*implicit class SyncFuture[T](future: Future[T]) { def sync(): T = { Await.result(future, 10 seconds) } - } + }*/ } diff --git a/phantom-test/src/test/scala/com/newzly/phantom/dsl/CRUDTests.scala b/phantom-test/src/test/scala/com/newzly/phantom/dsl/CRUDTests.scala deleted file mode 100644 index 44035b6df..000000000 --- a/phantom-test/src/test/scala/com/newzly/phantom/dsl/CRUDTests.scala +++ /dev/null @@ -1,706 +0,0 @@ -package com.newzly.phantom.dsl - -import com.newzly.phantom._ - -import org.scalatest.concurrent.ScalaFutures -import org.scalatest.Matchers - -import scala.concurrent.ExecutionContext.Implicits.global -import com.datastax.driver.core.{ Session, Row } -import scala.concurrent.{ Await, Future } -import java.net.InetAddress -import scala.concurrent.duration.Duration -import java.util.{Date, UUID} -import com.datastax.driver.core.utils.UUIDs - - -class CRUDTests extends BaseTest with ScalaFutures with Matchers { - implicit val session: Session = cassandraSession - - "Select" should "work fine" in { - - case class Primitive( - pkey: Int, - long: Long, - boolean: Boolean, - bDecimal: BigDecimal, - double: Double, - float: Float, - inet: java.net.InetAddress, - int: Int, - date: java.util.Date, - uuid: java.util.UUID, - bi: BigInt) - - class Primitives extends CassandraTable[Primitives, Primitive] { - override def fromRow(r: Row): Primitive = { - Primitive(pkey(r), long(r), boolean(r), bDecimal(r), double(r), float(r), inet(r), - int(r), date(r), uuid(r), bi(r)) - } - object pkey extends PrimitiveColumn[Int] - object long extends PrimitiveColumn[Long] - object boolean extends PrimitiveColumn[Boolean] - object bDecimal extends PrimitiveColumn[BigDecimal] - object double extends PrimitiveColumn[Double] - object float extends PrimitiveColumn[Float] - object inet extends PrimitiveColumn[java.net.InetAddress] - object int extends PrimitiveColumn[Int] - object date extends PrimitiveColumn[java.util.Date] - object uuid extends PrimitiveColumn[java.util.UUID] - object bi extends PrimitiveColumn[BigInt] - val _key = pkey - } - object Primitives extends Primitives { - override def tableName = "Primitives" - } - Primitives.create(_.pkey, - _.long, - _.boolean, - _.bDecimal, - _.double, - _.float, - _.inet, - _.int, - _.date, - _.uuid, - _.bi).execute().sync() - val row = Primitive(1, 2.toLong, true, BigDecimal("1.1"), 3.toDouble, 4.toFloat, - InetAddress.getByName("127.0.0.1"), 9, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), - BigInt(1002)) - val rcp = Primitives.insert - .value(_.pkey, row.pkey) - .value(_.long, row.long) - .value(_.boolean, row.boolean) - .value(_.bDecimal, row.bDecimal) - .value(_.double, row.double) - .value(_.float, row.float) - .value(_.inet, row.inet) - .value(_.int, row.int) - .value(_.date, row.date) - .value(_.uuid, row.uuid) - .value(_.bi, row.bi) - rcp.execute().sync() - - val recipeF: Future[Option[Primitive]] = Primitives.select.one - assert(recipeF.sync().get === row) - assert(Primitives.select.fetch.sync() contains (row)) - - val select1 = Primitives.select.where(_.pkey eqs 1).one.sync() - assert(select1.get === row) - } - - "Delete" should "work fine, when deleting the whole row" in { - val primitivesTable = - """|CREATE TABLE primitives( - |str text PRIMARY KEY, - |long bigint, - |boolean boolean, - |bDecimal decimal, - |double double, - |float float, - |inet inet, - |int int, - |date timestamp, - |uuid uuid, - |bi varint); - """.stripMargin - cassandraSession.execute(primitivesTable) - - case class Primitive( - str: String, - long: Long, - boolean: Boolean, - bDecimal: BigDecimal, - double: Double, - float: Float, - inet: java.net.InetAddress, - int: Int, - date: java.util.Date, - uuid: java.util.UUID, - bi: BigInt) - - class Primitives extends CassandraTable[Primitives, Primitive] { - override def fromRow(r: Row): Primitive = { - Primitive(str(r), long(r), boolean(r), bDecimal(r), double(r), float(r), inet(r), - int(r), date(r), uuid(r), bi(r)) - } - object str extends PrimitiveColumn[String] - object long extends PrimitiveColumn[Long] - object boolean extends PrimitiveColumn[Boolean] - object bDecimal extends PrimitiveColumn[BigDecimal] - object double extends PrimitiveColumn[Double] - object float extends PrimitiveColumn[Float] - object inet extends PrimitiveColumn[java.net.InetAddress] - object int extends PrimitiveColumn[Int] - object date extends PrimitiveColumn[java.util.Date] - object uuid extends PrimitiveColumn[java.util.UUID] - object bi extends PrimitiveColumn[BigInt] - val _key = str - } - object Primitives extends Primitives { - override def tableName = "Primitives" - } - - val row = Primitive("myString", 2.toLong, true, BigDecimal("1.1"), 3.toDouble, 4.toFloat, - InetAddress.getByName("127.0.0.1"), 9, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), - BigInt(1002)) - val rcp = Primitives.insert - .value(_.str, row.str) - .value(_.long, row.long) - .value(_.boolean, row.boolean) - .value(_.bDecimal, row.bDecimal) - .value(_.double, row.double) - .value(_.float, row.float) - .value(_.inet, row.inet) - .value(_.int, row.int) - .value(_.date, row.date) - .value(_.uuid, row.uuid) - .value(_.bi, row.bi) - rcp.execute().sync() - val recipeF: Future[Option[Primitive]] = Primitives.select.one - assert(recipeF.sync().get === row) - assert(Primitives.select.fetch.sync() contains row) - - val del = Primitives.delete where(_.str eqs "myString") - del.execute().sync() - - val recipeF2: Future[Option[Primitive]] = Primitives.select.one - val rowFromDb = recipeF2.sync() - assert(rowFromDb.isEmpty) - } - - "Update" should "work fine for primitives columns" in { - //char is not supported - //https://github.com/datastax/java-driver/blob/2.0/driver-core/src/main/java/com/datastax/driver/core/DataType.java - val primitivesTable = - """|CREATE TABLE primitives( - |str text PRIMARY KEY, - |long bigint, - |boolean boolean, - |bDecimal decimal, - |double double, - |float float, - |inet inet, - |int int, - |date timestamp, - |uuid uuid, - |bi varint); - """.stripMargin - cassandraSession.execute(primitivesTable) - - case class Primitive( - str: String, - long: Long, - boolean: Boolean, - bDecimal: BigDecimal, - double: Double, - float: Float, - inet: java.net.InetAddress, - int: Int, - date: java.util.Date, - uuid: java.util.UUID, - bi: BigInt) - - class Primitives extends CassandraTable[Primitives, Primitive]{ - override def fromRow(r: Row): Primitive = { - Primitive(str(r), long(r), boolean(r), bDecimal(r), double(r), float(r), inet(r), - int(r), date(r), uuid(r), bi(r)) - } - - object str extends PrimitiveColumn[String] - object long extends PrimitiveColumn[Long] - object boolean extends PrimitiveColumn[Boolean] - object bDecimal extends PrimitiveColumn[BigDecimal] - object double extends PrimitiveColumn[Double] - object float extends PrimitiveColumn[Float] - object inet extends PrimitiveColumn[java.net.InetAddress] - object int extends PrimitiveColumn[Int] - object date extends PrimitiveColumn[java.util.Date] - object uuid extends PrimitiveColumn[java.util.UUID] - object bi extends PrimitiveColumn[BigInt] - val _key = str - } - object Primitives extends Primitives { - override def tableName = "Primitives" - } - - val row = Primitive("myString", 2.toLong, true, BigDecimal("1.1"), 3.toDouble, 4.toFloat, - InetAddress.getByName("127.0.0.1"), 9, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), - BigInt(1002)) - val rcp = Primitives.insert - .value(_.str, row.str) - .value(_.long, row.long) - .value(_.boolean, row.boolean) - .value(_.bDecimal, row.bDecimal) - .value(_.double, row.double) - .value(_.float, row.float) - .value(_.inet, row.inet) - .value(_.int, row.int) - .value(_.date, row.date) - .value(_.uuid, row.uuid) - .value(_.bi, row.bi) - rcp.execute().sync() - val recipeF: Future[Option[Primitive]] = Primitives.select.one - assert(recipeF.sync().get === row) - assert(Primitives.select.fetch.sync() contains (row)) - - val updatedRow = Primitive("myString", 21.toLong, true, BigDecimal("11.11"), 31.toDouble, 41.toFloat, - InetAddress.getByName("127.1.1.1"), 911, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), - BigInt(1012)) - - Primitives.update. - //where(PrimitivesTable => QueryBuilder.eq("str", "myString")) - where(_.str eqs "myString") - .modify(_.long, updatedRow.long) - .modify(_.boolean, updatedRow.boolean) - .modify(_.bDecimal, updatedRow.bDecimal) - .modify(_.double, updatedRow.double) - .modify(_.float, updatedRow.float) - .modify(_.inet, updatedRow.inet) - .modify(_.int, updatedRow.int) - .modify(_.date, updatedRow.date) - .modify(_.uuid, updatedRow.uuid) - .modify(_.bi, updatedRow.bi).execute().sync() - - val recipeF2: Future[Option[Primitive]] = Primitives.select.one - val rowFromDb = recipeF2.sync().get - assert( rowFromDb === updatedRow) - assert(Primitives.select.fetch.sync() contains (updatedRow)) - } - - it should "work fine with List, Set, Map" in { - val createTestTable = - """|CREATE TABLE testTable( - |key text PRIMARY KEY, - |list list, - |setText set, - |mapTextToText map, - |setInt set, - |mapIntToText map ); - """.stripMargin - - cassandraSession.execute(createTestTable) - - case class TestRow(key: String, - list: Seq[String], - setText: Set[String], - mapTextToText: Map[String, String], - setInt: Set[Int], - mapIntToText: Map[Int, String]) - - class TestTable extends CassandraTable[TestTable, TestRow]{ - object key extends PrimitiveColumn[String] - object list extends SeqColumn[String] - object setText extends SetColumn[String] - object mapTextToText extends MapColumn[String, String] - object setInt extends SetColumn[Int] - object mapIntToText extends MapColumn[Int, String] - - def fromRow(r: Row): TestRow = { - TestRow(key(r), list(r), - setText(r), - mapTextToText(r), - setInt(r).toSet, - mapIntToText(r)) - } - val _key = key - } - val row = TestRow("w", Seq("ee", "pp", "ee3"), Set("u", "e"), Map("k" -> "val"), Set(1, 22, 2), - Map(3 -> "OO")) - object TestTable extends TestTable - 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) - - rcp.execute().sync() - val recipeF: Future[Option[TestRow]] = TestTable.select.one - assert(recipeF.sync().get === row) - assert(TestTable.select.fetch.sync() contains (row)) - val updatedRow = row.copy( - list = Seq ("new"), - setText = Set("newSet"), - mapTextToText = Map("n" -> "newVal"), - setInt = Set(3,4,7), - mapIntToText = Map (-1 -> "&&&") - ) - - TestTable.update - .where(_.key eqs "w") - .modify(_.list,updatedRow.list) - .modify(_.setText,updatedRow.setText) - .modify(_.mapTextToText,updatedRow.mapTextToText) - .modify(_.setInt,updatedRow.setInt) - .modify(_.mapIntToText,updatedRow.mapIntToText).execute().sync() - - val recipeF2: Future[Option[TestRow]] = TestTable.select.one - val rowFromDb = recipeF2.sync().get - assert( rowFromDb === updatedRow) - assert(TestTable.select.fetch.sync() contains (updatedRow)) - - } - - "Insert" should "work fine for primitives columns" in { - //char is not supported - //https://github.com/datastax/java-driver/blob/2.0/driver-core/src/main/java/com/datastax/driver/core/DataType.java - val primitivesTable = - """|CREATE TABLE primitives( - |str text PRIMARY KEY, - |long bigint, - |boolean boolean, - |bDecimal decimal, - |double double, - |float float, - |inet inet, - |int int, - |date timestamp, - |uuid uuid, - |bi varint); - """.stripMargin - cassandraSession.execute(primitivesTable) - - case class Primitive( - str: String, - long: Long, - boolean: Boolean, - bDecimal: BigDecimal, - double: Double, - float: Float, - inet: java.net.InetAddress, - int: Int, - date: java.util.Date, - uuid: java.util.UUID, - bi: BigInt) - - class Primitives extends CassandraTable[Primitives, Primitive] { - override def fromRow(r: Row): Primitive = { - Primitive(str(r), long(r), boolean(r), bDecimal(r), double(r), float(r), inet(r), - int(r), date(r), uuid(r), bi(r)) - } - - object str extends PrimitiveColumn[String] - object long extends PrimitiveColumn[Long] - - object boolean extends PrimitiveColumn[Boolean] - object bDecimal extends PrimitiveColumn[BigDecimal] - object double extends PrimitiveColumn[Double] - object float extends PrimitiveColumn[Float] - object inet extends PrimitiveColumn[InetAddress] - object int extends PrimitiveColumn[Int] - object date extends PrimitiveColumn[Date] - object uuid extends PrimitiveColumn[UUID] - object bi extends PrimitiveColumn[BigInt] - val _key = str - } - object Primitives extends Primitives { - override def tableName = "Primitives" - } - - val row = Primitive("myString", 2.toLong, true, BigDecimal("1.1"), 3.toDouble, 4.toFloat, - InetAddress.getByName("127.0.0.1"), 9, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), - BigInt(1002 - )) - val rcp = Primitives.insert - .value(_.str, row.str) - .value(_.long, row.long) - .value(_.boolean, row.boolean) - .value(_.bDecimal, row.bDecimal) - .value(_.double, row.double) - .value(_.float, row.float) - .value(_.inet, row.inet) - .value(_.int, row.int) - .value(_.date, row.date) - .value(_.uuid, row.uuid) - .value(_.bi, row.bi) - rcp.execute().sync() - val recipeF: Future[Option[Primitive]] = Primitives.select.one - assert(recipeF.sync().get === row) - - assert(Primitives.select.fetch.sync() contains (row)) - } - - it should "work fine with List, Set, Map" in { - val createTestTable = - """|CREATE TABLE TestTable( - |key text PRIMARY KEY, - |list list, - |setText set, - |mapTextToText map, - |setInt set, - |mapIntToText map ); - """.stripMargin - - cassandraSession.execute(createTestTable) - - case class TestRow(key: String, - list: Seq[String], - setText: Set[String], - mapTextToText: Map[String, String], - setInt: Set[Int], - mapIntToText: Map[Int, String]) - - class TestTable extends CassandraTable[TestTable, TestRow]{ - object key extends PrimitiveColumn[String] - object list extends SeqColumn[String] - object setText extends SetColumn[String] - object mapTextToText extends MapColumn[String, String] - object setInt extends SetColumn[Int] - object mapIntToText extends MapColumn[Int, String] - - def fromRow(r: Row): TestRow = { - TestRow(key(r), list(r), - setText(r), - mapTextToText(r), - setInt(r).toSet, - mapIntToText(r)) - } - val _key = key - } - val row = TestRow("w", Seq("ee", "pp", "ee3"), Set("u", "e"), Map("k" -> "val"), Set(1, 22, 2), - Map(3 -> "OO")) - object TestTable extends TestTable { - override def tableName = "TestTable" - } - 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) - - rcp.execute().sync() - val recipeF: Future[Option[TestRow]] = TestTable.select.one - assert(recipeF.sync().get === row) - - assert(TestTable.select.fetch.sync() contains (row)) - } - - it should "work fine with custom types" in { - val createTestTable = - """|CREATE TABLE MyTest( - |key text PRIMARY KEY, - |optionA int, - |classS text, - ); - """.stripMargin // - session.execute(createTestTable) - - case class ClassS(something: String) - //case class ClassS(something:Map[String,Int]) - case class TestRow(key: String, optionA: Option[Int], classS: ClassS) - - class MyTest extends CassandraTable[MyTest, TestRow] { - def fromRow(r: Row): TestRow = { - TestRow(key(r), optionA(r), classS(r)) - } - object key extends PrimitiveColumn[String] - object optionA extends OptionalPrimitiveColumn[Int] - object classS extends JsonTypeColumn[ClassS] - val _key = key - } - - val row = TestRow("someKey", Some(2), ClassS("lol")) - object MyTest extends MyTest { - override val tableName = "MyTest" - } - val rcp = MyTest.insert - .value(_.key, row.key) - .valueOrNull(_.optionA, row.optionA) - .value(_.classS, row.classS) - rcp.execute().sync() - val recipeF: Future[Option[TestRow]] = MyTest.select.one - assert(recipeF.sync().get === row) - - assert(MyTest.select.fetch.sync() contains (row)) - } - - it should "work fine with Mix" in { - - case class Author(firstName: String, lastName: String, bio: Option[String]) - - case class Recipe( - url: String, - description: Option[String], - ingredients: Seq[String], - author: Option[Author], - servings: Option[Int], - lastCheckedAt: java.util.Date, - props: Map[String, String]) - - class Recipes extends CassandraTable[Recipes, Recipe] { - - override def fromRow(r: Row): Recipe = { - Recipe(url(r), description(r), ingredients(r), author.optional(r), servings(r), last_checked_at(r), props(r)) - } - - object url extends PrimitiveColumn[String] - object description extends OptionalPrimitiveColumn[String] - object ingredients extends SeqColumn[String] - object author extends JsonTypeColumn[Author] - object servings extends OptionalPrimitiveColumn[Int] - object last_checked_at extends PrimitiveColumn[Date] - object props extends MapColumn[String, String] - object uid extends PrimitiveColumn[UUID] - val _key = url - } - implicit val formats = net.liftweb.json.DefaultFormats - val author = Author("Tony", "Clark", Some("great chef...")) - val r = Recipe("recipe_url", Some("desc"), Seq("ingr1", "ingr2"), Some(author), Some(4), new java.util.Date, Map("a" -> "b", "c" -> "d")) - - object Recipes extends Recipes { - override def tableName = "Recipes" - } - - Recipes.create(_.url, - _.description, - _.ingredients, - _.author, - _.servings, - _.last_checked_at, - _.props, - _.uid).execute().sync() - - val rcp = Recipes.insert - .value(_.url, r.url) - .valueOrNull(_.description, r.description) - .value(_.ingredients, r.ingredients) - .valueOrNull(_.author, r.author) - .valueOrNull(_.servings, r.servings) - .value(_.last_checked_at, r.lastCheckedAt) - .value(_.props, r.props) - .value(_.uid, UUIDs.timeBased()) - - rcp.execute().sync() - - val recipeF: Future[Option[Recipe]] = Recipes.select.one - recipeF.sync() - - } - - it should "support serializing/de-serializing to List " in { - - val createTestTable = - """|CREATE TABLE listtest( - |key text PRIMARY KEY, - |testlist list - ); - """.stripMargin // - session.execute(createTestTable) - - case class TestList(val key: String, val l: List[String]) - - class MyTest extends CassandraTable[MyTest, TestList] { - def fromRow(r: Row): TestList = { - TestList(key(r), testlist(r)); - } - object key extends PrimitiveColumn[String] - object testlist extends ListColumn[String] - val _key = key - } - - val row = TestList("someKey", List("test", "test2")) - - object MyTest extends MyTest { - override val tableName = "listtest" - } - - val recipeF: Future[Option[TestList]] = MyTest.select.one - whenReady(recipeF) { - res => { - res.isEmpty shouldEqual false - res.get should be(row) - } - } - - } - - - it should "support serializing/de-serializing empty lists " in { - - val createTestTable = - """|CREATE TABLE emptylisttest( - |key text PRIMARY KEY, - |list list - ); - """.stripMargin // - session.execute(createTestTable) - - case class TestList(val key: String, val l: List[String]) - - class MyTest extends CassandraTable[MyTest, TestList] { - def fromRow(r: Row): TestList = { - TestList(key(r), list(r)); - } - object key extends PrimitiveColumn[String] - object list extends ListColumn[String] - val _key = key - } - - val row = TestList("someKey", Nil) - - object MyTest extends MyTest { - override val tableName = "emptylisttest" - } - - MyTest.insert.value(_.key, row.key).value(_.list, row.l).execute().sync() - - val future = MyTest.select.one - whenReady(future) { - res => res.isEmpty shouldEqual false - } - } - - ignore should "work here but it fails- WE NEED TO FIX IT" in { - val createTestTable = - """|CREATE TABLE TestTable2( - |key text PRIMARY KEY, - |optionA int, - |classS text, - |optionS text - |mapIntoClass map - ); - """.stripMargin // #| - session.execute(createTestTable) - - case class ClassS(something: Map[String, Int]) - case class TestRow(key: String, optionA: Option[Int], classS: ClassS, optionS: Option[ClassS], map: Map[String, ClassS]) - - class TestTable2 extends CassandraTable[TestTable2, TestRow] { - def fromRow(r: Row): TestRow = { - TestRow(key(r), optionA(r), classS(r), optionS(r), mapIntoClass(r)) - } - object key extends PrimitiveColumn[String] - object optionA extends OptionalPrimitiveColumn[Int] - object classS extends JsonTypeColumn[ClassS] - object optionS extends JsonTypeColumn[Option[ClassS]] - object mapIntoClass extends JsonTypeColumn[Map[String, ClassS]] - val _key = key - } - - val row = TestRow("someKey", Some(2), ClassS(Map("k2" -> 5)), Some(ClassS(Map("k2" -> 5))), Map("5" -> ClassS(Map("p" -> 2)))) - - object TestTable2 extends TestTable2 { - override val tableName = "TestTable2" - } - - val rcp = TestTable2.insert - .value(_.key, row.key) - .valueOrNull(_.optionA, row.optionA) - .value(_.classS, row.classS) - .value(_.optionS, row.optionS) - .value(_.mapIntoClass, row.map) - - rcp.qb.enableTracing() - info(rcp.toString) - info(rcp.qb.toString) - rcp.execute().sync() - val recipeF: Future[Option[TestRow]] = TestTable2.select.one - assert(recipeF.sync().get === row) - assert(TestTable2.select.fetch.sync() contains (row)) - } - -} diff --git a/phantom-test/src/test/scala/com/newzly/phantom/dsl/IgnoredTests.scala b/phantom-test/src/test/scala/com/newzly/phantom/dsl/IgnoredTests.scala new file mode 100644 index 000000000..d2e065514 --- /dev/null +++ b/phantom-test/src/test/scala/com/newzly/phantom/dsl/IgnoredTests.scala @@ -0,0 +1,71 @@ +package com.newzly.phantom.dsl + +import com.newzly.phantom._ + +import org.scalatest.concurrent.ScalaFutures +import org.scalatest.Matchers + +import scala.concurrent.ExecutionContext.Implicits.global +import com.datastax.driver.core.{ Session, Row } +import scala.concurrent.{ Await, Future } +import java.net.InetAddress +import scala.concurrent.duration.Duration +import java.util.{Date, UUID} +import com.datastax.driver.core.utils.UUIDs +import com.newzly.phantom.helper.{ClassS, Tables} + + +class IgnoredTests extends BaseTest with ScalaFutures with Matchers with Tables { + + implicit val session: Session = cassandraSession + + ignore should "work here but it fails- WE NEED TO FIX IT" in { + val createTestTable = + """|CREATE TABLE TestTable2( + |key text PRIMARY KEY, + |optionA int, + |classS text, + |optionS text + |mapIntoClass map + ); + """.stripMargin // #| + session.execute(createTestTable) + + case class ClassSMap(something: Map[String, Int]) + case class TestRow(key: String, optionA: Option[Int], classS: ClassSMap, optionS: Option[ClassSMap], map: Map[String, ClassSMap]) + + class TestTable2 extends CassandraTable[TestTable2, TestRow] { + def fromRow(r: Row): TestRow = { + TestRow(key(r), optionA(r), classS(r), optionS(r), mapIntoClass(r)) + } + object key extends PrimitiveColumn[String] + object optionA extends OptionalPrimitiveColumn[Int] + object classS extends JsonTypeColumn[ClassSMap] + object optionS extends JsonTypeColumn[Option[ClassSMap]] + object mapIntoClass extends JsonTypeColumn[Map[String, ClassSMap]] + val _key = key + } + + val row = TestRow("someKey", Some(2), ClassSMap(Map("k2" -> 5)), Some(ClassSMap(Map("k2" -> 5))), Map("5" -> ClassSMap(Map("p" -> 2)))) + + object TestTable2 extends TestTable2 { + override val tableName = "TestTable2" + } + + val rcp = TestTable2.insert + .value(_.key, row.key) + .valueOrNull(_.optionA, row.optionA) + .value(_.classS, row.classS) + .value(_.optionS, row.optionS) + .value(_.mapIntoClass, row.map) + + rcp.qb.enableTracing() + info(rcp.toString) + info(rcp.qb.toString) + rcp.execute().sync() + val recipeF: Future[Option[TestRow]] = TestTable2.select.one + assert(recipeF.sync().get === row) + assert(TestTable2.select.fetch.sync() contains (row)) + } + +} diff --git a/phantom-test/src/test/scala/com/newzly/phantom/dsl/SkippingRecordsTest.scala b/phantom-test/src/test/scala/com/newzly/phantom/dsl/SkippingRecordsTest.scala index 96ada1592..247681df6 100644 --- a/phantom-test/src/test/scala/com/newzly/phantom/dsl/SkippingRecordsTest.scala +++ b/phantom-test/src/test/scala/com/newzly/phantom/dsl/SkippingRecordsTest.scala @@ -1,3 +1,4 @@ + package com.newzly.phantom.dsl import java.util.UUID @@ -11,22 +12,13 @@ import com.datastax.driver.core.utils.UUIDs import com.newzly.phantom.{ PrimitiveColumn, CassandraTable } import com.newzly.phantom.field.{ UUIDPk, LongOrderKey } import com.newzly.phantom.Implicits._ +import com.newzly.phantom.helper.Tables -class SkippingRecordsTest extends BaseTest with ScalaFutures { +class SkippingRecordsTest extends BaseTest with ScalaFutures with Tables { implicit val session: Session = cassandraSession - it should "allow skipping records " in { - val articlesTable = - """|CREATE TABLE articlestest( - |id uuid PRIMARY KEY, - |order_id bigint, - |name text); - """.stripMargin - cassandraSession.execute(articlesTable) - - val indexes = """CREATE INDEX order_id ON articlestest (order_id)""".stripMargin - cassandraSession.execute(indexes) + ignore should "allow skipping records " in { case class Article(val name: String, id: UUID, order_id: Long) class Articles extends CassandraTable[Articles, Article] with UUIDPk[Articles] with LongOrderKey[Articles] { @@ -71,3 +63,4 @@ class SkippingRecordsTest extends BaseTest with ScalaFutures { } } + diff --git a/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/DeleteTest.scala b/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/DeleteTest.scala new file mode 100644 index 000000000..e2c3c061b --- /dev/null +++ b/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/DeleteTest.scala @@ -0,0 +1,43 @@ +package com.newzly.phantom.dsl.crud + +import java.net.InetAddress +import scala.concurrent.Future +import com.newzly.phantom.dsl.BaseTest +import org.scalatest.concurrent.ScalaFutures +import org.scalatest.Matchers +import com.newzly.phantom.helper.Tables +import com.datastax.driver.core.Session +import scala.concurrent.ExecutionContext.Implicits.global + +class DeleteTest extends BaseTest with ScalaFutures with Matchers with Tables{ + implicit val session: Session = cassandraSession + + "Delete" should "work fine, when deleting the whole row" in { + + val row = Primitive("myString", 2.toLong, true, BigDecimal("1.1"), 3.toDouble, 4.toFloat, + InetAddress.getByName("127.0.0.1"), 9, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), + BigInt(1002)) + val rcp = Primitives.insert + .value(_.pkey, row.pkey) + .value(_.long, row.long) + .value(_.boolean, row.boolean) + .value(_.bDecimal, row.bDecimal) + .value(_.double, row.double) + .value(_.float, row.float) + .value(_.inet, row.inet) + .value(_.int, row.int) + .value(_.date, row.date) + .value(_.uuid, row.uuid) + .value(_.bi, row.bi) + rcp.execute().sync() + assert(Primitives.select.fetch.sync() contains row) + + val del = Primitives.delete.where(_.pkey eqs "myString") + del.execute().sync() + + val recipeF2: Future[Option[Primitive]] = Primitives.select.where(_.pkey eqs "myString").one + val rowFromDb = recipeF2.sync() + assert(rowFromDb.isEmpty) + } + +} diff --git a/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/InsertTest.scala b/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/InsertTest.scala new file mode 100644 index 000000000..904ba4d01 --- /dev/null +++ b/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/InsertTest.scala @@ -0,0 +1,154 @@ +package com.newzly.phantom.dsl.crud + +import com.newzly.phantom.dsl.BaseTest +import org.scalatest.concurrent.ScalaFutures +import org.scalatest.Matchers +import com.newzly.phantom.helper._ +import com.datastax.driver.core.{Row, Session} +import java.net.InetAddress +import scala.concurrent.Future +import scala.concurrent.ExecutionContext.Implicits.global +import com.newzly.phantom._ +import com.datastax.driver.core.utils.UUIDs +import scala.Some +import com.newzly.phantom.helper.ClassS +import com.newzly.phantom.helper.Author +import scala.Some + +class InsertTest extends BaseTest with ScalaFutures with Matchers with Tables{ + + implicit val session: Session = cassandraSession + "Insert" should "work fine for primitives columns" in { + //char is not supported + //https://github.com/datastax/java-driver/blob/2.0/driver-core/src/main/java/com/datastax/driver/core/DataType.java + + val row = Primitive("myStringInsert", 2.toLong, true, BigDecimal("1.1"), 3.toDouble, 4.toFloat, + InetAddress.getByName("127.0.0.1"), 9, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), + BigInt(1002 + )) + val rcp = Primitives.insert + .value(_.pkey, row.pkey) + .value(_.long, row.long) + .value(_.boolean, row.boolean) + .value(_.bDecimal, row.bDecimal) + .value(_.double, row.double) + .value(_.float, row.float) + .value(_.inet, row.inet) + .value(_.int, row.int) + .value(_.date, row.date) + .value(_.uuid, row.uuid) + .value(_.bi, row.bi) + rcp.execute().sync() + val recipeF: Future[Option[Primitive]] = Primitives.select.where(_.pkey eqs "myStringInsert").one + assert(recipeF.sync().get === row) + + assert(Primitives.select.fetch.sync() contains (row)) + } + + it should "work fine with List, Set, Map" in { + + val row = TestRow("w2", Seq("ee", "pp", "ee3"), Set("u", "e"), Map("k" -> "val"), Set(1, 22, 2), + Map(3 -> "OO")) + + 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) + + rcp.execute().sync() + val recipeF: Future[Option[TestRow]] = TestTable.select.where(_.key eqs "w2").one + assert(recipeF.sync().get === row) + + assert(TestTable.select.fetch.sync() contains (row)) + } + + + it should "work fine with custom types" in { + val row = MyTestRow("someKey", Some(2), ClassS("lol")) + + val rcp = MyTest.insert + .value(_.key, row.key) + .valueOrNull(_.optionA, row.optionA) + .value(_.classS, row.classS) + rcp.execute().sync() + val recipeF: Future[Option[MyTestRow]] = MyTest.select.one + assert(recipeF.sync().get === row) + + assert(MyTest.select.fetch.sync() contains (row)) + } + + it should "work fine with Mix" in { + implicit val formats = net.liftweb.json.DefaultFormats + val author = Author("Tony", "Clark", Some("great chef...")) + val r = Recipe("recipe_url", Some("desc"), Seq("ingr1", "ingr2"), Some(author), Some(4), new java.util.Date, Map("a" -> "b", "c" -> "d")) + + val rcp = Recipes.insert + .value(_.url, r.url) + .valueOrNull(_.description, r.description) + .value(_.ingredients, r.ingredients) + .valueOrNull(_.author, r.author) + .valueOrNull(_.servings, r.servings) + .value(_.last_checked_at, r.lastCheckedAt) + .value(_.props, r.props) + .value(_.uid, UUIDs.timeBased()) + + rcp.execute().sync() + + val recipeF: Future[Option[Recipe]] = Recipes.select.one + recipeF.sync() + + } + it should "support serializing/de-serializing empty lists " in { + class MyTest extends CassandraTable[MyTest, TestList] { + def fromRow(r: Row): TestList = { + TestList(key(r), list(r)); + } + object key extends PrimitiveColumn[String] + object list extends ListColumn[String] + val _key = key + } + + val row = TestList("someKey", Nil) + + object MyTest extends MyTest { + override val tableName = "emptylisttest" + } + + MyTest.insert.value(_.key, row.key).value(_.list, row.l).execute().sync() + + val future = MyTest.select.one + whenReady(future) { + res => res.isEmpty shouldEqual false + } + } + it should "support serializing/de-serializing to List " in { + case class TestList(val key: String, val l: List[String]) + + class MyTest extends CassandraTable[MyTest, TestList] { + def fromRow(r: Row): TestList = { + TestList(key(r), testlist(r)); + } + object key extends PrimitiveColumn[String] + object testlist extends ListColumn[String] + val _key = key + } + + val row = TestList("someKey", List("test", "test2")) + + object MyTest extends MyTest { + override val tableName = "listtest" + } + MyTest.insert.value(_.key,row.key).value(_.testlist,row.l).execute().sync() + val recipeF: Future[Option[TestList]] = MyTest.select.one + whenReady(recipeF) { + res => { + res.isEmpty shouldEqual false + res.get should be(row) + } + } + + } +} diff --git a/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/SelectTest.scala b/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/SelectTest.scala new file mode 100644 index 000000000..8475d5600 --- /dev/null +++ b/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/SelectTest.scala @@ -0,0 +1,37 @@ +package com.newzly.phantom.dsl.crud + +import com.newzly.phantom.dsl.BaseTest +import org.scalatest.concurrent.ScalaFutures +import org.scalatest.Matchers +import com.newzly.phantom.helper.Tables +import com.datastax.driver.core.Session +import java.net.InetAddress +import scala.concurrent.ExecutionContext.Implicits.global + +class SelectTest extends BaseTest with ScalaFutures with Matchers with Tables{ + + implicit val session: Session = cassandraSession + + "Select" should "work fine" in { + val row = Primitive("1", 2.toLong, true, BigDecimal("1.1"), 3.toDouble, 4.toFloat, + InetAddress.getByName("127.0.0.1"), 9, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), + BigInt(1002)) + val rcp = Primitives.insert + .value(_.pkey, row.pkey) + .value(_.long, row.long) + .value(_.boolean, row.boolean) + .value(_.bDecimal, row.bDecimal) + .value(_.double, row.double) + .value(_.float, row.float) + .value(_.inet, row.inet) + .value(_.int, row.int) + .value(_.date, row.date) + .value(_.uuid, row.uuid) + .value(_.bi, row.bi) + rcp.execute().sync() + assert(Primitives.select.fetch.sync() contains (row)) + + val select1 = Primitives.select.where(_.pkey eqs "1").one.sync() + assert(select1.get === row) + } +} diff --git a/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/UpdateTest.scala b/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/UpdateTest.scala new file mode 100644 index 000000000..4ba73d603 --- /dev/null +++ b/phantom-test/src/test/scala/com/newzly/phantom/dsl/crud/UpdateTest.scala @@ -0,0 +1,105 @@ +package com.newzly.phantom.dsl.crud + +import com.newzly.phantom.dsl.BaseTest +import org.scalatest.concurrent.ScalaFutures +import org.scalatest.Matchers +import com.newzly.phantom.helper.Tables +import com.datastax.driver.core.{Row, Session} +import java.net.InetAddress +import scala.concurrent.Future +import com.newzly.phantom._ +import scala.concurrent.ExecutionContext.Implicits.global + +class UpdateTest extends BaseTest with ScalaFutures with Matchers with Tables{ + + implicit val session: Session = cassandraSession + + "Update" should "work fine for primitives columns" in { + //char is not supported + //https://github.com/datastax/java-driver/blob/2.0/driver-core/src/main/java/com/datastax/driver/core/DataType.java + + val row = Primitive("myStringUpdate", 2.toLong, true, BigDecimal("1.1"), 3.toDouble, 4.toFloat, + InetAddress.getByName("127.0.0.1"), 9, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), + BigInt(1002)) + val rcp = Primitives.insert + .value(_.pkey, row.pkey) + .value(_.long, row.long) + .value(_.boolean, row.boolean) + .value(_.bDecimal, row.bDecimal) + .value(_.double, row.double) + .value(_.float, row.float) + .value(_.inet, row.inet) + .value(_.int, row.int) + .value(_.date, row.date) + .value(_.uuid, row.uuid) + .value(_.bi, row.bi) + rcp.execute().sync() + val recipeF: Future[Option[Primitive]] = Primitives.select.where(_.pkey eqs "myStringUpdate").one + assert(recipeF.sync().get === row) + assert(Primitives.select.fetch.sync() contains (row)) + + val updatedRow = Primitive("myStringUpdate", 21.toLong, true, BigDecimal("11.11"), 31.toDouble, 41.toFloat, + InetAddress.getByName("127.1.1.1"), 911, new java.util.Date, com.datastax.driver.core.utils.UUIDs.timeBased(), + BigInt(1012)) + + Primitives.update. + //where(PrimitivesTable => QueryBuilder.eq("str", "myString")) + where(_.pkey eqs "myStringUpdate") + .modify(_.long, updatedRow.long) + .modify(_.boolean, updatedRow.boolean) + .modify(_.bDecimal, updatedRow.bDecimal) + .modify(_.double, updatedRow.double) + .modify(_.float, updatedRow.float) + .modify(_.inet, updatedRow.inet) + .modify(_.int, updatedRow.int) + .modify(_.date, updatedRow.date) + .modify(_.uuid, updatedRow.uuid) + .modify(_.bi, updatedRow.bi).execute().sync() + + val recipeF2: Future[Option[Primitive]] = Primitives.select.where(_.pkey eqs "myStringUpdate").one + val rowFromDb = recipeF2.sync().get + assert( rowFromDb === updatedRow) + assert(Primitives.select.fetch.sync() contains (updatedRow)) + } + + it should "work fine with List, Set, Map" in { + + val row = TestRow("w", Seq("ee", "pp", "ee3"), Set("u", "e"), Map("k" -> "val"), Set(1, 22, 2), + Map(3 -> "OO")) + + 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) + + rcp.execute().sync() + + val recipeF: Future[Option[TestRow]] = TestTable.select.where(_.key eqs "w").one + assert(recipeF.sync().get === row) + assert(TestTable.select.fetch.sync() contains (row)) + val updatedRow = row.copy( + list = Seq ("new"), + setText = Set("newSet"), + mapTextToText = Map("n" -> "newVal"), + setInt = Set(3,4,7), + mapIntToText = Map (-1 -> "&&&") + ) + + TestTable.update + .where(_.key eqs "w") + .modify(_.list,updatedRow.list) + .modify(_.setText,updatedRow.setText) + .modify(_.mapTextToText,updatedRow.mapTextToText) + .modify(_.setInt,updatedRow.setInt) + .modify(_.mapIntToText,updatedRow.mapIntToText).execute().sync() + + val recipeF2: Future[Option[TestRow]] = TestTable.select.where(_.key eqs "w").one + val rowFromDb = recipeF2.sync().get + assert( rowFromDb === updatedRow) + assert(TestTable.select.fetch.sync() contains (updatedRow)) + + } +} diff --git a/phantom-test/src/test/scala/com/newzly/phantom/helper/CassandraCluster.scala b/phantom-test/src/test/scala/com/newzly/phantom/helper/CassandraCluster.scala index 9f4adf55c..96ba99d90 100644 --- a/phantom-test/src/test/scala/com/newzly/phantom/helper/CassandraCluster.scala +++ b/phantom-test/src/test/scala/com/newzly/phantom/helper/CassandraCluster.scala @@ -6,6 +6,7 @@ import org.apache.cassandra.io.util.FileUtils import org.cassandraunit.utils.EmbeddedCassandraServerHelper; object CassandraInst { + val embedded = EmbeddedCassandraServerHelper.startEmbeddedCassandra() lazy val cluster = Cluster.builder() .addContactPoint("localhost") .withPort(9142) diff --git a/phantom-test/src/test/scala/com/newzly/phantom/helper/Tables.scala b/phantom-test/src/test/scala/com/newzly/phantom/helper/Tables.scala new file mode 100644 index 000000000..e55c1a5a4 --- /dev/null +++ b/phantom-test/src/test/scala/com/newzly/phantom/helper/Tables.scala @@ -0,0 +1,201 @@ +package com.newzly.phantom.helper + +import com.newzly.phantom._ +import com.datastax.driver.core.{Session, Row} +import scala.concurrent.{Await, Future} +import scala.concurrent.duration._ +import scala.concurrent.ExecutionContext.Implicits.global +import java.util.{UUID, Date} + +case class ClassS(something: String) +case class Author(firstName: String, lastName: String, bio: Option[String]) +case class TestList(val key: String, val l: List[String]) + +trait Tables { + implicit class SyncFuture[T](future: Future[T]) { + def sync(): T = { + Await.result(future, 10 seconds) + } + } + case class Primitive( + pkey: String, + long: Long, + boolean: Boolean, + bDecimal: BigDecimal, + double: Double, + float: Float, + inet: java.net.InetAddress, + int: Int, + date: java.util.Date, + uuid: java.util.UUID, + bi: BigInt) + + class Primitives extends CassandraTable[Primitives, Primitive] { + override def fromRow(r: Row): Primitive = { + Primitive(pkey(r), long(r), boolean(r), bDecimal(r), double(r), float(r), inet(r), + int(r), date(r), uuid(r), bi(r)) + } + object pkey extends PrimitiveColumn[String] + object long extends PrimitiveColumn[Long] + object boolean extends PrimitiveColumn[Boolean] + object bDecimal extends PrimitiveColumn[BigDecimal] + object double extends PrimitiveColumn[Double] + object float extends PrimitiveColumn[Float] + object inet extends PrimitiveColumn[java.net.InetAddress] + object int extends PrimitiveColumn[Int] + object date extends PrimitiveColumn[java.util.Date] + object uuid extends PrimitiveColumn[java.util.UUID] + object bi extends PrimitiveColumn[BigInt] + val _key = pkey + } + object Primitives extends Primitives { + override def tableName = "Primitives" + } + + + case class TestRow(key: String, + list: Seq[String], + setText: Set[String], + mapTextToText: Map[String, String], + setInt: Set[Int], + mapIntToText: Map[Int, String]) + + class TestTable extends CassandraTable[TestTable, TestRow]{ + object key extends PrimitiveColumn[String] + object list extends SeqColumn[String] + object setText extends SetColumn[String] + object mapTextToText extends MapColumn[String, String] + object setInt extends SetColumn[Int] + object mapIntToText extends MapColumn[Int, String] + + def fromRow(r: Row): TestRow = { + TestRow(key(r), list(r), + setText(r), + mapTextToText(r), + setInt(r).toSet, + mapIntToText(r)) + } + val _key = key + } + object TestTable extends TestTable { + override def tableName = "TestTable" + } + + + + case class MyTestRow(key: String, optionA: Option[Int], classS: ClassS) + + class MyTest extends CassandraTable[MyTest, MyTestRow] { + def fromRow(r: Row): MyTestRow = { + MyTestRow(key(r), optionA(r), classS(r)) + } + object key extends PrimitiveColumn[String] + object optionA extends OptionalPrimitiveColumn[Int] + object classS extends JsonTypeColumn[ClassS] + val _key = key + } + object MyTest extends MyTest { + override val tableName = "MyTest" + } + + case class Recipe( + url: String, + description: Option[String], + ingredients: Seq[String], + author: Option[Author], + servings: Option[Int], + lastCheckedAt: java.util.Date, + props: Map[String, String]) + + class Recipes extends CassandraTable[Recipes, Recipe] { + + override def fromRow(r: Row): Recipe = { + Recipe(url(r), description(r), ingredients(r), author.optional(r), servings(r), last_checked_at(r), props(r)) + } + + object url extends PrimitiveColumn[String] + object description extends OptionalPrimitiveColumn[String] + object ingredients extends SeqColumn[String] + object author extends JsonTypeColumn[Author] + object servings extends OptionalPrimitiveColumn[Int] + object last_checked_at extends PrimitiveColumn[Date] + object props extends MapColumn[String, String] + object uid extends PrimitiveColumn[UUID] + val _key = url + } + object Recipes extends Recipes { + override def tableName = "Recipes" + } + private[helper] def createTables(implicit session: Session): Unit = { + Primitives.create(_.pkey, + _.long, + _.boolean, + _.bDecimal, + _.double, + _.float, + _.inet, + _.int, + _.date, + _.uuid, + _.bi).execute().sync() + + val createTestTable = + """|CREATE TABLE testTable( + |key text PRIMARY KEY, + |list list, + |setText set, + |mapTextToText map, + |setInt set, + |mapIntToText map ); + """.stripMargin + + session.execute(createTestTable) + + val myTestTable = + """|CREATE TABLE MyTest( + |key text PRIMARY KEY, + |optionA int, + |classS text, + ); + """.stripMargin // + session.execute(myTestTable) + + Recipes.create(_.url, + _.description, + _.ingredients, + _.author, + _.servings, + _.last_checked_at, + _.props, + _.uid).execute().sync() + + val emptylisttest = + """|CREATE TABLE emptylisttest( + |key text PRIMARY KEY, + |list list + ); + """.stripMargin // + session.execute(emptylisttest) + + val listtest = + """|CREATE TABLE listtest( + |key text PRIMARY KEY, + |testlist list + ); + """.stripMargin // + session.execute(listtest) + + val articlesTable = + """|CREATE TABLE articlestest( + |id uuid PRIMARY KEY, + |order_id bigint, + |name text); + """.stripMargin + session.execute(articlesTable) + + val indexes = """CREATE INDEX order_id ON articlestest (order_id)""".stripMargin + session.execute(indexes) + } + + +} diff --git a/phantom-test/src/test/scala/com/newzly/phantom/helper/TestHelper.scala b/phantom-test/src/test/scala/com/newzly/phantom/helper/TestHelper.scala index 6e8a2d8c8..6bc622630 100644 --- a/phantom-test/src/test/scala/com/newzly/phantom/helper/TestHelper.scala +++ b/phantom-test/src/test/scala/com/newzly/phantom/helper/TestHelper.scala @@ -1,30 +1,31 @@ package com.newzly.phantom.helper import org.cassandraunit.utils.EmbeddedCassandraServerHelper - -object TestHelper { - - var clusterInited = false; - - def isClusterInited: Boolean = this.synchronized { - clusterInited - } - - def initKeySpaces: Unit = this.synchronized { - val session = CassandraInst.cassandraSession; +import com.newzly.phantom.{PrimitiveColumn, CassandraTable} +import com.datastax.driver.core.{Session, Row} +import scala.concurrent.{Await, Future} +import scala.concurrent.duration._ +import java.util.concurrent.atomic.AtomicBoolean + +object TestHelper extends Tables{ + implicit val session: Session = CassandraInst.cassandraSession + private val isInitialized = new AtomicBoolean(false) + private[this] def initKeySpaces() = { session.execute("CREATE KEYSPACE testSpace WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};") session.execute("use testSpace;") } - def initCluster: Unit = { - this.synchronized { - if (isClusterInited == false) { - EmbeddedCassandraServerHelper.startEmbeddedCassandra() - clusterInited = true - } - } - + private[this] def initTables() = { + createTables } + def initCluster() = { + initKeySpaces + initTables + isInitialized.set(true) + } + def initialized = { + isInitialized.get() + } }