How leverage the features
your database provides.
CUSTOM DATA TYPES IN ECTO
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 2
Slide 2 text
INTRODUCTION
➤ Pedro Assumpcao
➤ Senior Software Engineer at CityBase
pedroassumpcao.ghost.io
@pedroassumpcao |> github.com
@pedroassumpcao |> twitter.com
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 3
Slide 3 text
AGENDA
➤ What problem we are trying to solve
➤ Context/Scenario
➤ How Ecto handles custom data types
➤ Creating a custom data type
➤ Querying a custom data type
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 4
Slide 4 text
WHAT PROBLEM WE ARE TRYING TO SOLVE
➤ Let's say we have two models: Product and Discount
➤ Product has price
➤ Discount has a percentage off based on a price range
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 5
Slide 5 text
WHAT PROBLEM WE ARE TRYING TO SOLVE
➤ Let's say we have two models: Product and Discount
➤ Product has price
➤ Discount has a percentage off based on a price range
➤ Our first attempt is in the Discount model:
➤ minimum_price
➤ maximum_price
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 6
Slide 6 text
No content
Slide 7
Slide 7 text
WHAT PROBLEM WE ARE TRYING TO SOLVE
➤ We should avoid queries like this:
➤ List percentage_off for a product price of $65:
SELECT percentage_off
FROM discounts
WHERE mininum_price <= 65 and maximum_price >= 65;
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 8
Slide 8 text
WHAT PROBLEM WE ARE TRYING TO SOLVE
➤ List all records based on a price range of $100 and $250:
SELECT *
FROM discounts
WHERE
(minimum_price < 100 AND maximum_price > 250)
OR (minimum_price between 100 and 250)
OR (maximum_price between 100 and 250);
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 9
Slide 9 text
HOW CAN WE DO THIS IN A
BETTER WAY?
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 10
Slide 10 text
CONTEXT/SCENARIO
➤ Postgres 9.2 introduced Range Types:
➤ int4range — Range of integer
➤ int8range — Range of bigint
➤ numrange — Range of numeric
➤ tsrange — Range of timestamp without time zone
➤ tstzrange — Range of timestamp with time zone
➤ daterange — Range of date
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 11
Slide 11 text
CONTEXT/SCENARIO
➤ Some range representation examples in Postgres:
➤ [2,14] => 2 ≤ x ≤ 14
➤ [2, 14) => 2 ≤ x < 14
➤ (2,14] => 2 < x ≤ 14
➤ (2,14) => 2 < x < 14
➤ [2,) => 2 ≤ x < ∞
➤ (,2] => -∞ < x ≤ 2
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 12
Slide 12 text
CONTEXT/SCENARIO
➤ Some examples of querying range types:
➤ List percentage_off for a product price of $65:
SELECT percentage_off
FROM discounts
WHERE 65::numeric <@ price_range;
➤ List all records based on a price range of $100 and $250:
SELECT *
FROM discounts
WHERE discounts.price_range && int4range(100, 250, '[]');
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 13
Slide 13 text
IN ELIXIR WORLD...
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 14
Slide 14 text
CONTEXT/SCENARIO
➤ Ecto is the database wrapper and DSL for queries
➤ Ecto works with database adapters:
➤ postgrex (Postgres)
➤ mariex (MySql)
➤ msql_ecto (MSSql)
➤ and others
➤ Each adapter knows better the database features and specifics
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 15
Slide 15 text
CONTEXT/SCENARIO
➤ Ecto only provides the most common data types:
➤ id, binary_id, uuid
➤ integer, float, decimal
➤ string, binary
➤ boolean
➤ date, time, utc_datetime
➤ list, map
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 16
Slide 16 text
No content
Slide 17
Slide 17 text
ECTO.TYPE BEHAVIOUR
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 18
Slide 18 text
WHAT IS A BEHAVIOUR?
➤ Separates the generic part (the behaviour module) of a component from the
specific part (the callback module)
➤ Perfect when modules share the same public API
➤ A behaviour module defines a set of functions
➤ The callback module implements them
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 19
Slide 19 text
CREATING A CUSTOM TYPE
➤ Ecto provides a behaviour called Ecto.Type:
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 20
Slide 20 text
CREATING A CUSTOM TYPE
type/0
➤ outputs the name of the database type
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 21
Slide 21 text
CREATING A CUSTOM TYPE
cast/1
➤ receives any term and validates
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 22
Slide 22 text
CREATING A CUSTOM TYPE
load/1
➤ loads the data from the adapter and outputs the custom type
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 23
Slide 23 text
CREATING A CUSTOM TYPE
dump/1
➤ receives a validated data and outputs an adapter type
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 24
Slide 24 text
USING A CUSTOM TYPE
➤ Migrations:
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 25
Slide 25 text
USING A CUSTOM TYPE
➤ Schemas:
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 26
Slide 26 text
QUERYING A CUSTOM TYPE
➤ Using fragment/1 you can perform any range specific operation that Postgres offers:
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 27
Slide 27 text
SUMMARY
➤ Postgres has data types that help us model properly
➤ Database adapters are close to the database features
➤ Ecto gives us flexibility to create our own types if we need
➤ Querying customized data types is easy
CHICAGO ELIXIR MEETUP - MAY/2017
Slide 28
Slide 28 text
FURTHER READING
➤ https://www.postgresql.org/docs/9.6/static/rangetypes.html
➤ http://pedroassumpcao.ghost.io/using-postgres-range-data-type-in-ecto/
➤ https://hexdocs.pm/ecto/Ecto.Type.html
➤ https://github.com/elixir-ecto/postgrex#data-representation
CHICAGO ELIXIR MEETUP - MAY/2017