Datastore
EntityType[T]
provides conversion between Scala type T
and Datastore Entity
. Custom support for type T
can be added with an implicit instance of EntityField[T]
.
import java.net.URI
case class Inner(long: Long, str: String, uri: URI)
case class Outer(inner: Inner)
val record = Outer(Inner(1L, "hello", URI.create("https://www.spotify.com")))
import magnolify.datastore._
import com.google.datastore.v1.Entity
// Encode custom type URI as String
implicit val uriField: EntityField[URI] = EntityField.from[String](URI.create)(_.toString)
val entityType = EntityType[Outer]
val entityBuilder: Entity.Builder = entityType.to(record)
val copy: Outer = entityType.from(entityBuilder.build)
Additional EntityField[T]
instances for Byte
, Char
, Short
, Int
, Float
, and enum-like types are available from import magnolify.datastore.unsafe._
. These conversions are unsafe due to potential overflow or encoding errors. Enum like types map to strings. See EnumType for more details.
To set a field as key, annotate the field with key
annotation.
import magnolify.datastore._
import com.google.protobuf.ByteString
// Leave projectId as empty, use current package as namespaceId and class name "Record" as kind
case class Record(@key k: String, v: Long)
// Custom projectId, namespaceId and kind.
case class ExplicitRecord(@key("my-project", "com.spotify", "MyKind") k: String, v: Long)
// Encode custom key type ByteString as String
case class ByteStringKey(@key k: ByteString)
implicit val kfByteString: KeyField[ByteString] = KeyField.at[ByteString](_.toStringUtf8)
// Encode custom key type RecordKey as String
case class RecordKey(s: String, l: Long)
case class NestedKey(@key k: RecordKey)
implicit val kfRecord: KeyField[RecordKey] = KeyField.at[RecordKey](r => r.s + r.l)
To exclude a property from indexes, annotate the field with excludeFromIndexes
annotation.
import magnolify.datastore._
case class Record(@excludeFromIndexes i: Int, @excludeFromIndexes(true) s: String)
To use a different field case format in target records, add an optional CaseMapper
argument to EntityType
. The following example maps firstName
& lastName
to first_name
& last_name
.
import magnolify.datastore._
import magnolify.shared.CaseMapper
import com.google.common.base.CaseFormat
case class LowerCamel(firstName: String, lastName: String)
val toSnakeCase = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.LOWER_UNDERSCORE).convert _
val entityType = EntityType[LowerCamel](CaseMapper(toSnakeCase))
entityType.to(LowerCamel("John", "Doe"))