Custom data type
This chapter describes how to use user-specific or unsupported types in table definitions built with ldbc.
Add a new column to the table definition created in setup.
ALTER TABLE user ADD COLUMN status BOOLEAN NOT NULL DEFAULT TRUE;
Encoder
In ldbc, the value to be passed to a statement is represented by an Encoder
. The Encoder
is a trait to represent the value to be bound to a statement.
By implementing Encoder
, values passed to statements can be expressed as custom types.
Add Status
to the user information to represent the user's status.
enum Status(val done: Boolean, val name: String):
case Active extends Status(false, "Active")
case InActive extends Status(true, "InActive")
The following code example defines a custom type Encoder
.
This allows binding custom types to statements.
given Encoder[Status] with
override def encode(status: Status): Boolean = status.done
Custom types can be bound to statements just like any other parameter.
val program1: Executor[IO, Int] =
sql"INSERT INTO user (name, email, status) VALUES (${ "user 1" }, ${ "user@example.com" }, ${ Status.Active })".update
Now you can bind custom types to statements.
Decoder
In addition to parameters, ldbc provides a Decoder
to get a unique type from the execution result.
By implementing the Decoder
, you can get your own type from the result of statement execution.
The following code example shows how to use Decoder.Elem
to get a single data type.
given Decoder.Elem[Status] = Decoder.Elem.mapping[Boolean, Status] {
case true => Status.Active
case false => Status.InActive
}
val program2: Executor[IO, (String, String, Status)] =
sql"SELECT name, email, status FROM user WHERE id = 1".query[(String, String, Status)].unsafe
Now you can get a custom type from the execution result of a statement.