Skip to content
Angel Sanadinov edited this page Jun 27, 2017 · 6 revisions

Data: Databases | Containers | Views

Overview

The data management of a core3 application is based around two main concepts: database abstraction layers and containers. In addition to that, there are views which can be used to further process and group data coming from the databases.

Views

Views provide a way to filter and transform associated container data, before any response is sent to a user/service.

//Base container view trait
trait ContainerView {
  def coreObjectID: ObjectID
  def coreObjectType: ContainerType
  def viewType: ContainerViewType
  def isAssociatedWith(container: Container): Boolean
  val fieldQueries: Map[String, ContainerQueryData]
  protected val fieldData: mutable.HashMap[String, Vector[Container]]

  def loadFieldData(field: String, data: Vector[Container]): Unit = {
    if (fieldData.contains(field)) {
      fieldData.put(field, data.map(c => c))
    }
  }

  def loadFieldsData(data: Map[String, Vector[Container]]): Unit = {
    data.foreach {
      case (field, currentData) => loadFieldData(field, currentData)
    }
  }
}

//Container view companion trait
trait JSONContainerViewCompanion {
  def toJsonData(container: ContainerView): JsValue
  def fromJsonData(data: JsValue): ContainerView
}

Core views

  • Group - A Group container only stores a list of object IDs and not the actual data. This view retrieves all of those objects.

Defining your own

  1. Extend the class trait (ContainerView) and define all view fields and queries:
import core3.database.containers.Container
import core3.database.views.{ContainerQueryData, ContainerView, JSONContainerViewCompanion}
import core3.database.{ContainerType, ContainerViewType, ObjectID, containers}
import play.api.libs.json._

import scala.collection.mutable

case class Group(private val core: containers.core.Group) extends ContainerView {

  //... constructors, additional members, etc ...

  override protected val fieldData: mutable.HashMap[String, Vector[Container]] = mutable.HashMap(
    "items" -> Vector.empty[Container]
  )

  override val fieldQueries = Map(
    "items" -> ContainerQueryData(
      containerType = core.itemsType,
      withFilter = {
        container =>
          core.items.contains(container.id)
      }
    )
  )

  //... constructors, additional members, etc ...

}
  1. Extend the companion trait (JSONContainerViewCompanion) and define the JSON serialization methods:
import core3.database.containers.Container
import core3.database.views.{ContainerQueryData, ContainerView, JSONContainerViewCompanion}
import core3.database.{ContainerType, ContainerViewType, ObjectID, containers}
import play.api.libs.json._

import scala.collection.mutable

object Group extends JSONContainerViewCompanion {
  def apply(core: containers.core.Group, items: Vector[Container]) = new Group(core, items)

  private val writes = Json.writes[Group]
  
  private val reads = Json.reads[Group]

  def toJsonData(container: ContainerView): JsValue = Json.toJson(container.asInstanceOf[Group])(writes)
  def fromJsonData(data: JsValue): ContainerView = data.as[Group](reads)
}
  1. Done

For complete container view implementations, see the core views package.

Container Query Data

The ContainerQueryData class describes how to retrieve the data for a specific view field:

/**
  * Class for storing container query configuration data.
  *
  * @param queryType       the query type to be performed
  * @param containerType   the container type to query
  * @param customQueryName the name of a custom query to execute (required, if query type is 'Custom')
  * @param queryParams     the parameters to use for the query (required, if query type is 'Custom')
  * @param withFilter      a function to be used for filtering the query results
  */
case class ContainerQueryData(
  queryType: QueryType,
  containerType: ContainerType,
  customQueryName: Option[String],
  queryParams: Option[Map[String, String]],
  withFilter: Option[(Container) => Boolean]) {
}

Note: Performing generic queries and filtering on them should be avoided as that retrieves all containers for the specified type.

Clone this wiki locally