All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.outworkers.phantom.example.basics.SimpleRecipes.scala Maven / Gradle / Ivy

There is a newer version: 2.12.1
Show newest version
/*
 * Copyright 2013 - 2017 Outworkers Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.outworkers.phantom.example.basics

import java.util.UUID

import scala.concurrent.{Future => ScalaFuture}
import com.outworkers.phantom.dsl._

/**
 * In this example we will create a simple table storing recipes.
 * Data modeling with com.outworkers.phantom is trivial and covers some of the more advanced features of Cassandra.
 *
 * Phantom will auto-generate the CQL3 table definition from your Scala code.
 * And you can automatically insert the schema during tests or even live environments.
 *
 * This is a very straightforward example, with a non composite Partition key
 */
case class Recipe(
 id: UUID,
 name: String,
 title: String,
 author: String,
 description: String,
 ingredients: Set[String],
 props: Map[String, String],
 timestamp: DateTime
)

// You can seal the class and only allow importing the companion object.
// The companion object is where you would implement your custom methods.
// Keep reading for examples.
abstract class Recipes extends Table[Recipes, Recipe] {

  object id extends  UUIDColumn with PartitionKey {
    // You can override the name of your key to whatever you like.
    // The default will be the name used for the object, in this case "id".
    override lazy val name = "the_primary_key"
  }

  // Now we define a column for each field in our case class.
  object name extends StringColumn
  object title extends StringColumn
  object author extends StringColumn
  object description extends StringColumn

  // Custom data types can be stored easily.
  // Cassandra collections target a small number of items, but usage is trivial.
  object ingredients extends SetColumn[String]

  object props extends MapColumn[String, String]

  object timestamp extends DateTimeColumn

  // you can even rename the table in the schema to whatever you like.
  override lazy val tableName = "my_custom_table"

  // now you have the full power of Cassandra in really cool one liners.
  // The future will do all the heavy lifting for you.
  // If there is an error you get a failed Future.
  // If there is no matching record you get a None.
  // The "one" method will select a single record, as it's name says.
  // It will always have a LIMIT 1 in the query sent to Cassandra.
  // select.where(_.id eqs UUID.randomUUID()).one() translates to
  // SELECT * FROM my_custom_table WHERE id = the_id_value LIMIT 1;
  def findRecipeById(id: UUID): ScalaFuture[Option[Recipe]] = {
    select.where(_.id eqs id).one()
  }

  // com.outworkers.phantom allows partial selects from any query.
  // this is currently limited to 22 fields.
  def findRecipeIngredients(id: UUID): ScalaFuture[Option[Set[String]]] = {
    select(_.ingredients).where(_.id eqs id).one()
  }

  // Because you are using a partition key, you can successfully using ordering
  // And you can paginate your records.
  // That's it, a really cool one liner.
  // The fetch method will collect an asynchronous lazy iterator into a Seq.
  // It's a good way to avoid boilerplate when retrieving a small number of items.
  def findRecipesPage(start: UUID, limit: Int): ScalaFuture[ListResult[Recipe]] = {
    select.where(_.id gtToken start).limit(limit).paginateRecord(_.setFetchSize(limit))
  }

  // Updating records is also really easy.
  // Updating one record is done like this
  def updateRecipeAuthor(id: UUID, author: String): ScalaFuture[ResultSet] = {
    update.where(_.id eqs id).modify(_.author setTo author).future()
  }

  // Updating records is also really easy.
  // Updating multiple fields at the same time is also easy.
  def updateRecipeAuthorAndName(id: UUID, name: String, author: String): ScalaFuture[ResultSet] = {
    update.where(_.id eqs id)
      .modify(_.name setTo name)
      .and(_.author setTo author)
      .future()
  }

  // Deleting records has the same restrictions and selecting.
  // If something is non primary, you cannot have it in a where clause.
  def deleteRecipeById(id: UUID): ScalaFuture[ResultSet] = {
    delete.where(_.id eqs id).future()
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy