SlideShare a Scribd company logo
1 of 52
Download to read offline
Ecto DSL
Domain specific language for writing queries and interacting with
databases in Elixir.
Yurii Bodarev
Back-end software developer
twitter.com/bodarev_yurii
github.com/yuriibodarev
Ecto official resources
github.com/elixir-ecto/ecto
hexdocs.pm/ecto/Ecto.html
pages.plataformatec.com.br/ebook-whats-new-in-ecto-2-0
Brief contents
• Elixir Data Structures
• Basic data types and structures
• Associative data structures
• Structs
• Pattern Matching
• Ecto
• Ecto.Repo
• Ecto.Schema
• Ecto.Changeset
• Ecto.Query
Basic data types and structures
• Atoms
• Lists
• Tuples
Atoms
Atoms are constants where their name is their own value.
iex> :hello
:hello
iex> :hello == :world
false
iex> true == :true
true
Lists (Linked)
Lists are used to manage dynamic, variable-sized collections of data of
any type.
iex> [1, "abc", true, 3]
[1, "abc", true, 3]
iex> length([1, 2, 3])
3
List - recursive structure
[head | tail]
iex> [1 | [2, 3, 4]]
[1, 2, 3, 4]
[head | [head | [head | tail…]]]
iex> [1 | [2 | [3 | [4 | []]]]]
[1, 2, 3, 4]
List - recursive structure
iex> hd([1, 2, 3, 4])
1
iex> tl([1, 2, 3, 4])
[2, 3, 4]
iex> tl([2, 3, 4])
[3, 4]
iex> tl([4])
[]
Tuples
Tuples are untyped structures often used to group a fixed number of elements
together.
iex> tuple = {:ok, "hello"}
{:ok, "hello"}
iex> elem(tuple, 1)
"hello"
iex> tuple_size(tuple)
2
Associative data structures
• Keyword lists
• Maps
List as key-value data structure
It is common to use a list of 2-item tuples as the representation of a
key-value data structure
iex> list = [{"a", 1}, {"b", 2}, {"c", 3}]
[{"a", 1}, {"b", 2}, {"c", 3}]
iex> List.keyfind(list, "b", 0)
{"b", 2}
Keyword lists
When we have a list of tuples and the first item of the tuple (i.e. the
key) is an atom, we call it a keyword list.
iex> [{:a, 1}, {:b, 2}, {:c, 3}]
[a: 1, b: 2, c: 3]
Keyword lists
Elixir supports a special syntax for defining such lists: [key: value]
iex> [a: 1, b: 2, c: 3] == [{:a, 1}, {:b, 2}, {:c, 3}]
true
• Keys must be atoms.
• Keys are ordered, as specified by the developer.
• Keys can be given more than once.
We can use all operations available to lists on keyword lists
iex> list = [a: 1, c: 3, b: 2]
[a: 1, c: 3, b: 2]
iex> hd(list)
{:a, 1}
iex> tl(list)
[c: 3, b: 2]
iex> list[:a]
1
iex> newlist = [a: 0] ++ list
[a: 0, a: 1, c: 3, b: 2]
iex> newlist[:a]
0
iex> list[:d]
nil
Keyword lists - default mechanism for passing options to
functions in Elixir
iex> if true, do: "THIS"
"THIS"
iex> if false, do: "THIS", else: "THAT"
"THAT"
iex> if(false, [do: "THIS", else: "THAT"])
"THAT"
When the keyword list is the last argument of a function, the square brackets
are optional.
Example of the Ecto query
query = from w in Weather,
where: w.prcp > 0,
where: w.temp < 20,
select: w
Maps
A map is a key-value store, where keys and values can be any term. A map is created using
the %{} syntax. Maps’ keys do not follow developer ordering.
iex> map = %{:a => 1, 2 => "b", "c" => 3}
%{2 => "b", :a => 1, "c" => 3}
iex> map[:a]
1
iex> map[2]
"b"
iex> map["d"]
nil
Maps
When all the keys in a map are atoms, you can use the keyword syntax.
iex> map = %{a: 1, b: 2, c: 3}
%{a: 1, b: 2, c: 3}
iex> map.a
1
iex> map.d
** (KeyError) key :d not found in: %{a: 1, b: 2, c: 3}
iex> %{map | c: 5}
%{a: 1, b: 2, c: 5}
iex> %{map | d: 0}
** (KeyError) key :d not found in: %{a: 1, b: 2, c: 3}
Structs
Structs are extensions built on top of maps that provide compile-time
checks and default values.
iex> defmodule User do
...> defstruct name: "Ivan", age: 25
...> end
iex> %User{}
%User{age: 25, name: "Ivan"}
Structs
iex> %User{name: "Maria"}
%User{age: 25, name: "Maria"}
iex> %User{other: "Something"}
** (KeyError) key :other not found in: %User{age:
25, name: "Ivan"}
Structs are bare maps underneath, but none of the protocols
implemented for maps are available for structs
iex> ivan = %User{}
%User{age: 25, name: "Ivan"}
iex> is_map(ivan)
true
iex> Map.keys(ivan)
[:__struct__, :age, :name]
iex> ivan.__struct__
User
iex> ivan[:age]
** (UndefinedFunctionError)
function User.fetch/2 is
undefined (User does not
implement the Access behaviour)
Pattern matching
iex> {a, b, c} = {:hello, "world", 42}
{:hello, "world", 42}
iex> a
:hello
iex> b
"world"
iex> c
42
A pattern match will error if the sides can’t be
matched
iex> {a, b, c} = {:hello, "world"}
** (MatchError) no match of right hand side value:
{:hello, "world"}
iex> {a, b, c} = [:hello, "world", 42]
** (MatchError) no match of right hand side value:
[:hello, "world", 42]
We can match on specific values
iex> {:ok, result} = {:ok, 13}
{:ok, 13}
iex> result
13
iex> {:ok, result} = {:error, "Not Found!"}
** (MatchError) no match of right hand side value:
{:error, "Not Found!"}
We can match on specific values
post = Repo.get!(Post, 42)
case Repo.delete post do
{:ok, struct} -> # Deleted with success
{:error, changeset} -> # Something went wrong
end
Pattern match on lists
iex> [a, b, c] = [1, 2, 3]
[1, 2, 3]
iex> b
2
iex> [head | tail] = [1, 2, 3]
[1, 2, 3]
iex> head
1
iex> tail
[2, 3]
iex> [] = [1, 2, 3]
** (MatchError) no match of
right hand side value: [1, 2, 3]
Pattern match on keyword lists
iex> [a: a] = [a: 1]
[a: 1]
iex> [a: a] = [a: 1, b: 2]
** (MatchError) no match of right hand side value: [a: 1, b: 2]
iex> [b: b, a: a] = [a: 1, b: 2]
** (MatchError) no match of right hand side value: [a: 1, b: 2]
Pattern match on maps
iex> %{} = %{a: 1, b: 2}
%{a: 1, b: 2}
iex> %{b: b} = %{a: 1, b: 2}
%{a: 1, b: 2}
iex> b
2
iex> %{c: c} = %{a: 1, b: 2}
** (MatchError) no match of right hand side value: %{a: 1, b: 2}
The pin ^ operator and _
iex> x = 2
2
iex> {1, ^x} = {1, 2}
{1, 2}
iex> {a, _} = {1, 2}
{1, 2}
iex> a
1
Ecto
Ecto is split into 4 main components:
• Ecto.Repo - repositories are wrappers around the data store.
• Ecto.Schema - schemas are used to map any data source into an Elixir
struct.
• Ecto.Changeset - allow developers to filter, cast, and validate changes
before we apply them to the data.
• Ecto.Query - written in Elixir syntax, queries are used to retrieve
information from a given repository.
Ecto playground
Ecto in not an ORM
github.com/yuriibodarev/Ecto_not_ORM
Requires: PostgreSQL
Run within IEx console: iex -S mix
Repositories
Via the repository, we can create, update, destroy and query existing
database entries.
Repositories
Ecto.Repo is a wrapper around the database. We can define a
repository as follows (libblogrepo.ex):
defmodule Blog.Repo do
use Ecto.Repo, otp_app: :blog
end
Repositories
A repository needs an adapter and credentials to communicate to the database.
Configuration for the Repo usually defined in your config/config.exs:
config :blog, Blog.Repo,
adapter: Ecto.Adapters.Postgres,
database: "blog_repo",
username: "postgres",
password: "postgres",
hostname: "localhost"
Repositories
Each repository in Ecto defines a start_link/0. Usually this function is invoked as part
of your application supervision tree (libblog.ex):
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [ worker(Blog.Repo, []), ]
opts = [strategy: :one_for_one, name: Blog.Supervisor]
Supervisor.start_link(children, opts)
end
Schema
Schemas allows developers to define the shape of their data. (libbloguser.ex)
defmodule Blog.User do
use Ecto.Schema
schema "users" do
field :name, :string
field :reputation, :integer, default: 0
has_many :posts, Blog.Post, on_delete: :delete_all
timestamps
end
end
Schema
By defining a schema, Ecto automatically defines a struct:
iex> user = %Blog.User{name: "Bill"}
%Blog.User{__meta__: #Ecto.Schema.Metadata<:built,
"users">, id: nil, inserted_at: nil, name: "Bill"},
posts: #Ecto.Association.NotLoaded<association
:posts is not loaded>, reputation: 0, updated_at:
nil}
Schema
Using Schema we can interact with a repository:
iex> user = %Blog.User{name: "Bill", reputation: 10}
%Blog.User{…}
iex> Blog.Repo.insert!(user)
%Blog.User{__meta__: #Ecto.Schema.Metadata<:loaded,
"users">, id: 6, inserted_at: ~N[2016-12-13
16:16:35.983000], name: "Bill", posts:
#Ecto.Association.NotLoaded<association :posts is not
loaded>, reputation: 10, updated_at: ~N[2016-12-13
16:16:36.001000]}
Schema
# Get the user back
iex> newuser = Blog.Repo.get(Blog.User, 6)
iex> newuser.id
6
# Delete it
iex> Blog.Repo.delete(newuser)
{:ok, %Blog.User{…, id: 6,…}}
Schema
We can use pattern matching on Structs created with Schemas:
iex> %{name: name, reputation: reputation} =
...> Blog.Repo.get(Blog.User, 1)
iex> name
"Alex"
iex> reputation
144
Changesets
We can add changesets to our schemas to validate changes before we
apply them to the data (libbloguser.ex):
def changeset(user, params  %{}) do
user
|> cast(params, [:name, :reputation])
|> validate_required([:name, :reputation])
|> validate_inclusion(:reputation, -999..999)
end
Changesets
iex> alina = %Blog.User{name: "Alina"}
iex> correct_changeset = Blog.User.changeset(alina, %{reputation: 55})
#Ecto.Changeset<action: nil, changes: %{reputation: 55}, errors: [],
data: #Blog.User<>, valid?: true>
iex> invalid_changeset = Blog.User.changeset(alina, %{reputation: 1055})
#Ecto.Changeset<action: nil, changes: %{reputation: 1055}, errors:
[reputation: {"is invalid", [validation: :inclusion]}], data:
#Blog.User<>, valid?: false>
Changeset with Repository functions
iex> valid_changeset.valid?
true
iex> Blog.Repo.insert(valid_changeset)
{:ok, %Blog.User{…, id: 7, …}}
Changeset with Repository functions
iex> invalid_changeset.valid?
false
iex> Blog.Repo.insert(invalid_changeset)
{:error, #Ecto.Changeset<action: :insert, changes:
%{reputation: 1055}, errors: [reputation: {"is
invalid", [validation: :inclusion]}], data:
#Blog.User<>, valid?: false>}
Changeset with Repository functions
case Blog.Repo.update(changeset) do
{:ok, user} ->
# user updated
{:error, changeset} ->
# an error occurred
end
We can provide different changeset functions
for different use cases
def registration_changeset(user, params) do
# Changeset on create
end
def update_changeset(user, params) do
# Changeset on update
end
Query
Ecto allows you to write queries in Elixir and send them to the
repository, which translates them to the underlying database.
Query using predefined Schema
# Query using predefined Schema
query = from u in User,
where: u.reputation > 35,
select: u
# Returns %User{} structs matching the query
Repo.all(query)
[%Blog.User{…, id: 2, …, name: "Bender", …, reputation: 42, …},
%Blog.User{…, id: 1, …, name: "Alex", …, reputation: 144, …}]
Directly querying the “users” table
# Directly querying the “users” table
query = from u in "users",
where: u.reputation > 30,
select: %{name: u.name, reputation: u.reputation}
# Returns maps as defined in select
Repo.all(query)
[%{name: "Bender", reputation: 42}, %{name: "Alex", reputation: 144}]
External values in Queries
# ^ operator
min = 33
query = from u in "users",
where: u.reputation > ^min,
select: u.name
# casting
mins = "33"
query = from u in "users",
where: u.reputation > type(^mins, :integer),
select: u.name
External values in Queries
If the query is made against Schema than Ecto will
automatically cast external value
min = "35"
Repo.all(from u in User, where: u.reputation > ^min)
You can also skip Select to retrieve all fields specified in the Schema

More Related Content

What's hot

Unix Programming with Perl 2
Unix Programming with Perl 2Unix Programming with Perl 2
Unix Programming with Perl 2Kazuho Oku
 
Magic Clusters and Where to Find Them - Eugene Pirogov
Magic Clusters and Where to Find Them - Eugene PirogovMagic Clusters and Where to Find Them - Eugene Pirogov
Magic Clusters and Where to Find Them - Eugene PirogovElixir Club
 
"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014Henning Jacobs
 
งานย่อยที่ 7
งานย่อยที่ 7งานย่อยที่ 7
งานย่อยที่ 7Little Aiiry
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful weddingStéphane Wirtel
 
Node child process
Node child processNode child process
Node child processLearningTech
 
ng-conf 2017: Angular Mischief Maker Slides
ng-conf 2017: Angular Mischief Maker Slidesng-conf 2017: Angular Mischief Maker Slides
ng-conf 2017: Angular Mischief Maker SlidesLukas Ruebbelke
 
7 strace examples to debug the execution of a program in linux
7 strace examples to debug the execution of a program in linux7 strace examples to debug the execution of a program in linux
7 strace examples to debug the execution of a program in linuxchinkshady
 
Owasp orlando, april 13, 2016
Owasp orlando, april 13, 2016Owasp orlando, april 13, 2016
Owasp orlando, april 13, 2016Mikhail Sosonkin
 
Operation Flow @ ChicagoRoboto
Operation Flow @ ChicagoRobotoOperation Flow @ ChicagoRoboto
Operation Flow @ ChicagoRobotoSeyed Jafari
 
Remote Notifications
Remote NotificationsRemote Notifications
Remote NotificationsJosef Cacek
 
[D2 Campus] Tech meetup (주제: Android) 모바일 머신러닝 [열일한 내 거북ᄆ...
[D2 Campus] Tech meetup (주제: Android) 모바일 머신러닝 [열일한 내 거북ᄆ...[D2 Campus] Tech meetup (주제: Android) 모바일 머신러닝 [열일한 내 거북ᄆ...
[D2 Campus] Tech meetup (주제: Android) 모바일 머신러닝 [열일한 내 거북ᄆ...Jeongah Shin
 
6 new ES6 features
6 new ES6 features6 new ES6 features
6 new ES6 featuresKyle Dorman
 
Shell scripting - By Vu Duy Tu from eXo Platform SEA
Shell scripting - By Vu Duy Tu from eXo Platform SEAShell scripting - By Vu Duy Tu from eXo Platform SEA
Shell scripting - By Vu Duy Tu from eXo Platform SEAThuy_Dang
 

What's hot (20)

Unix Programming with Perl 2
Unix Programming with Perl 2Unix Programming with Perl 2
Unix Programming with Perl 2
 
Magic Clusters and Where to Find Them - Eugene Pirogov
Magic Clusters and Where to Find Them - Eugene PirogovMagic Clusters and Where to Find Them - Eugene Pirogov
Magic Clusters and Where to Find Them - Eugene Pirogov
 
"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014
 
งานย่อยที่ 7
งานย่อยที่ 7งานย่อยที่ 7
งานย่อยที่ 7
 
Backdoor coding
Backdoor codingBackdoor coding
Backdoor coding
 
Python modulesfinal
Python modulesfinalPython modulesfinal
Python modulesfinal
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
 
Node child process
Node child processNode child process
Node child process
 
Posfix
PosfixPosfix
Posfix
 
ng-conf 2017: Angular Mischief Maker Slides
ng-conf 2017: Angular Mischief Maker Slidesng-conf 2017: Angular Mischief Maker Slides
ng-conf 2017: Angular Mischief Maker Slides
 
7 strace examples to debug the execution of a program in linux
7 strace examples to debug the execution of a program in linux7 strace examples to debug the execution of a program in linux
7 strace examples to debug the execution of a program in linux
 
Owasp orlando, april 13, 2016
Owasp orlando, april 13, 2016Owasp orlando, april 13, 2016
Owasp orlando, april 13, 2016
 
Slink into Elixir
Slink into ElixirSlink into Elixir
Slink into Elixir
 
Operation Flow @ ChicagoRoboto
Operation Flow @ ChicagoRobotoOperation Flow @ ChicagoRoboto
Operation Flow @ ChicagoRoboto
 
Python Async IO Horizon
Python Async IO HorizonPython Async IO Horizon
Python Async IO Horizon
 
clonehd01
clonehd01clonehd01
clonehd01
 
Remote Notifications
Remote NotificationsRemote Notifications
Remote Notifications
 
[D2 Campus] Tech meetup (주제: Android) 모바일 머신러닝 [열일한 내 거북ᄆ...
[D2 Campus] Tech meetup (주제: Android) 모바일 머신러닝 [열일한 내 거북ᄆ...[D2 Campus] Tech meetup (주제: Android) 모바일 머신러닝 [열일한 내 거북ᄆ...
[D2 Campus] Tech meetup (주제: Android) 모바일 머신러닝 [열일한 내 거북ᄆ...
 
6 new ES6 features
6 new ES6 features6 new ES6 features
6 new ES6 features
 
Shell scripting - By Vu Duy Tu from eXo Platform SEA
Shell scripting - By Vu Duy Tu from eXo Platform SEAShell scripting - By Vu Duy Tu from eXo Platform SEA
Shell scripting - By Vu Duy Tu from eXo Platform SEA
 

Viewers also liked

Yurii Bodarev - OTP, Phoenix & Ecto: Three Pillars of Elixir
Yurii Bodarev - OTP, Phoenix & Ecto: Three Pillars of ElixirYurii Bodarev - OTP, Phoenix & Ecto: Three Pillars of Elixir
Yurii Bodarev - OTP, Phoenix & Ecto: Three Pillars of ElixirElixir Club
 
diagramme d'activité
diagramme d'activitédiagramme d'activité
diagramme d'activitémarwa baich
 
консультация для воспитателя
консультация для воспитателяконсультация для воспитателя
консультация для воспитателяvirtualtaganrog
 
Composable Queries with Ecto
Composable Queries with EctoComposable Queries with Ecto
Composable Queries with Ectodrewolson
 
Maria eddy contreras cuadro_app movil
Maria eddy contreras cuadro_app movilMaria eddy contreras cuadro_app movil
Maria eddy contreras cuadro_app movilMARIAEDDY515
 
EL CINE Y LA GUERRA CIVIL EN BENIFAIRÓ DE LES VALLS - Mª Vicenta Pérez
EL CINE Y LA GUERRA CIVIL EN BENIFAIRÓ DE LES VALLS - Mª Vicenta PérezEL CINE Y LA GUERRA CIVIL EN BENIFAIRÓ DE LES VALLS - Mª Vicenta Pérez
EL CINE Y LA GUERRA CIVIL EN BENIFAIRÓ DE LES VALLS - Mª Vicenta PérezLa Finestra del Rey
 
Fallo tutela gloria patricia mayorga ariza. supuesto periodista aldemar
Fallo tutela  gloria  patricia mayorga ariza. supuesto periodista aldemarFallo tutela  gloria  patricia mayorga ariza. supuesto periodista aldemar
Fallo tutela gloria patricia mayorga ariza. supuesto periodista aldemargloriapatriciamayorga
 

Viewers also liked (10)

Yurii Bodarev - OTP, Phoenix & Ecto: Three Pillars of Elixir
Yurii Bodarev - OTP, Phoenix & Ecto: Three Pillars of ElixirYurii Bodarev - OTP, Phoenix & Ecto: Three Pillars of Elixir
Yurii Bodarev - OTP, Phoenix & Ecto: Three Pillars of Elixir
 
Sunk cost
Sunk costSunk cost
Sunk cost
 
Informatica
InformaticaInformatica
Informatica
 
diagramme d'activité
diagramme d'activitédiagramme d'activité
diagramme d'activité
 
консультация для воспитателя
консультация для воспитателяконсультация для воспитателя
консультация для воспитателя
 
Owl
OwlOwl
Owl
 
Composable Queries with Ecto
Composable Queries with EctoComposable Queries with Ecto
Composable Queries with Ecto
 
Maria eddy contreras cuadro_app movil
Maria eddy contreras cuadro_app movilMaria eddy contreras cuadro_app movil
Maria eddy contreras cuadro_app movil
 
EL CINE Y LA GUERRA CIVIL EN BENIFAIRÓ DE LES VALLS - Mª Vicenta Pérez
EL CINE Y LA GUERRA CIVIL EN BENIFAIRÓ DE LES VALLS - Mª Vicenta PérezEL CINE Y LA GUERRA CIVIL EN BENIFAIRÓ DE LES VALLS - Mª Vicenta Pérez
EL CINE Y LA GUERRA CIVIL EN BENIFAIRÓ DE LES VALLS - Mª Vicenta Pérez
 
Fallo tutela gloria patricia mayorga ariza. supuesto periodista aldemar
Fallo tutela  gloria  patricia mayorga ariza. supuesto periodista aldemarFallo tutela  gloria  patricia mayorga ariza. supuesto periodista aldemar
Fallo tutela gloria patricia mayorga ariza. supuesto periodista aldemar
 

Similar to Ecto DSL for Elixir Database Queries

Introducción a Elixir
Introducción a ElixirIntroducción a Elixir
Introducción a ElixirSvet Ivantchev
 
Python Programming: Lists, Modules, Exceptions
Python Programming: Lists, Modules, ExceptionsPython Programming: Lists, Modules, Exceptions
Python Programming: Lists, Modules, ExceptionsSreedhar Chowdam
 
Elixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental ConceptsElixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental ConceptsHéla Ben Khalfallah
 
Introduction to Elixir
Introduction to ElixirIntroduction to Elixir
Introduction to Elixirbrien_wankel
 
Arrays and function basic c programming notes
Arrays and function basic c programming notesArrays and function basic c programming notes
Arrays and function basic c programming notesGOKULKANNANMMECLECTC
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsEleanor McHugh
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7decoupled
 
Matlab solved problems
Matlab solved problemsMatlab solved problems
Matlab solved problemsMake Mannan
 
Introduction to python programming 1
Introduction to python programming   1Introduction to python programming   1
Introduction to python programming 1Giovanni Della Lunga
 
Basic R Data Manipulation
Basic R Data ManipulationBasic R Data Manipulation
Basic R Data ManipulationChu An
 
Introduction to Elixir
Introduction to ElixirIntroduction to Elixir
Introduction to ElixirDiacode
 
Using-Python-Libraries.9485146.powerpoint.pptx
Using-Python-Libraries.9485146.powerpoint.pptxUsing-Python-Libraries.9485146.powerpoint.pptx
Using-Python-Libraries.9485146.powerpoint.pptxUadAccount
 
Python Interview Questions | Python Interview Questions And Answers | Python ...
Python Interview Questions | Python Interview Questions And Answers | Python ...Python Interview Questions | Python Interview Questions And Answers | Python ...
Python Interview Questions | Python Interview Questions And Answers | Python ...Simplilearn
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixirKent Ohashi
 
C++ process new
C++ process newC++ process new
C++ process new敬倫 林
 

Similar to Ecto DSL for Elixir Database Queries (20)

Introducción a Elixir
Introducción a ElixirIntroducción a Elixir
Introducción a Elixir
 
Python Programming: Lists, Modules, Exceptions
Python Programming: Lists, Modules, ExceptionsPython Programming: Lists, Modules, Exceptions
Python Programming: Lists, Modules, Exceptions
 
Elixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental ConceptsElixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental Concepts
 
Introduction to Elixir
Introduction to ElixirIntroduction to Elixir
Introduction to Elixir
 
Arrays and function basic c programming notes
Arrays and function basic c programming notesArrays and function basic c programming notes
Arrays and function basic c programming notes
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord Migrations
 
MATLAB Programming
MATLAB Programming MATLAB Programming
MATLAB Programming
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
Matlab solved problems
Matlab solved problemsMatlab solved problems
Matlab solved problems
 
Introduction to python programming 1
Introduction to python programming   1Introduction to python programming   1
Introduction to python programming 1
 
Matlab-1.pptx
Matlab-1.pptxMatlab-1.pptx
Matlab-1.pptx
 
Basic R Data Manipulation
Basic R Data ManipulationBasic R Data Manipulation
Basic R Data Manipulation
 
Introduction to Elixir
Introduction to ElixirIntroduction to Elixir
Introduction to Elixir
 
Using-Python-Libraries.9485146.powerpoint.pptx
Using-Python-Libraries.9485146.powerpoint.pptxUsing-Python-Libraries.9485146.powerpoint.pptx
Using-Python-Libraries.9485146.powerpoint.pptx
 
Python Interview Questions | Python Interview Questions And Answers | Python ...
Python Interview Questions | Python Interview Questions And Answers | Python ...Python Interview Questions | Python Interview Questions And Answers | Python ...
Python Interview Questions | Python Interview Questions And Answers | Python ...
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixir
 
R workshop
R workshopR workshop
R workshop
 
C++ process new
C++ process newC++ process new
C++ process new
 
scripting in Python
scripting in Pythonscripting in Python
scripting in Python
 

More from Elixir Club

Kubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club Ukraine
Kubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club UkraineKubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club Ukraine
Kubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club UkraineElixir Club
 
Integrating 3rd parties with Ecto - Eduardo Aguilera | Elixir Club Ukraine
Integrating 3rd parties with Ecto -  Eduardo Aguilera | Elixir Club UkraineIntegrating 3rd parties with Ecto -  Eduardo Aguilera | Elixir Club Ukraine
Integrating 3rd parties with Ecto - Eduardo Aguilera | Elixir Club UkraineElixir Club
 
— An async template - Oleksandr Khokhlov | Elixir Club Ukraine
— An async template  -  Oleksandr Khokhlov | Elixir Club Ukraine— An async template  -  Oleksandr Khokhlov | Elixir Club Ukraine
— An async template - Oleksandr Khokhlov | Elixir Club UkraineElixir Club
 
BEAM architecture handbook - Andrea Leopardi | Elixir Club Ukraine
BEAM architecture handbook - Andrea Leopardi  | Elixir Club UkraineBEAM architecture handbook - Andrea Leopardi  | Elixir Club Ukraine
BEAM architecture handbook - Andrea Leopardi | Elixir Club UkraineElixir Club
 
You ain't gonna need write a GenServer - Ulisses Almeida | Elixir Club Ukraine
You ain't gonna need write a GenServer - Ulisses Almeida  | Elixir Club UkraineYou ain't gonna need write a GenServer - Ulisses Almeida  | Elixir Club Ukraine
You ain't gonna need write a GenServer - Ulisses Almeida | Elixir Club UkraineElixir Club
 
— Knock, knock — An async templates — Who’s there? - Alexander Khokhlov | ...
 — Knock, knock — An async templates — Who’s there? - Alexander Khokhlov  |  ... — Knock, knock — An async templates — Who’s there? - Alexander Khokhlov  |  ...
— Knock, knock — An async templates — Who’s there? - Alexander Khokhlov | ...Elixir Club
 
Performance measurement methodology — Maksym Pugach | Elixir Evening Club 3
Performance measurement methodology — Maksym Pugach | Elixir Evening Club 3Performance measurement methodology — Maksym Pugach | Elixir Evening Club 3
Performance measurement methodology — Maksym Pugach | Elixir Evening Club 3Elixir Club
 
Erlang cluster. How is it? Production experience. — Valerii Vasylkov | Elixi...
Erlang cluster. How is it? Production experience. —  Valerii Vasylkov | Elixi...Erlang cluster. How is it? Production experience. —  Valerii Vasylkov | Elixi...
Erlang cluster. How is it? Production experience. — Valerii Vasylkov | Elixi...Elixir Club
 
Promo Phx4RailsDevs - Volodya Sveredyuk
Promo Phx4RailsDevs - Volodya SveredyukPromo Phx4RailsDevs - Volodya Sveredyuk
Promo Phx4RailsDevs - Volodya SveredyukElixir Club
 
Web of today — Alexander Khokhlov
Web of today —  Alexander KhokhlovWeb of today —  Alexander Khokhlov
Web of today — Alexander KhokhlovElixir Club
 
ElixirConf Eu 2018, what was it like? – Eugene Pirogov
ElixirConf Eu 2018, what was it like? – Eugene PirogovElixirConf Eu 2018, what was it like? – Eugene Pirogov
ElixirConf Eu 2018, what was it like? – Eugene PirogovElixir Club
 
Implementing GraphQL API in Elixir – Victor Deryagin
Implementing GraphQL API in Elixir – Victor DeryaginImplementing GraphQL API in Elixir – Victor Deryagin
Implementing GraphQL API in Elixir – Victor DeryaginElixir Club
 
WebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerWebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerElixir Club
 
GenServer in Action – Yurii Bodarev
GenServer in Action – Yurii Bodarev   GenServer in Action – Yurii Bodarev
GenServer in Action – Yurii Bodarev Elixir Club
 
Russian Doll Paradox: Elixir Web without Phoenix - Alex Rozumii
Russian Doll Paradox: Elixir Web without Phoenix - Alex RozumiiRussian Doll Paradox: Elixir Web without Phoenix - Alex Rozumii
Russian Doll Paradox: Elixir Web without Phoenix - Alex RozumiiElixir Club
 
Practical Fault Tolerance in Elixir - Alexei Sholik
Practical Fault Tolerance in Elixir - Alexei SholikPractical Fault Tolerance in Elixir - Alexei Sholik
Practical Fault Tolerance in Elixir - Alexei SholikElixir Club
 
Phoenix and beyond: Things we do with Elixir - Alexander Khokhlov
Phoenix and beyond: Things we do with Elixir - Alexander KhokhlovPhoenix and beyond: Things we do with Elixir - Alexander Khokhlov
Phoenix and beyond: Things we do with Elixir - Alexander KhokhlovElixir Club
 
Monads are just monoids in the category of endofunctors - Ike Kurghinyan
Monads are just monoids in the category of endofunctors - Ike KurghinyanMonads are just monoids in the category of endofunctors - Ike Kurghinyan
Monads are just monoids in the category of endofunctors - Ike KurghinyanElixir Club
 
Craft effective API with GraphQL and Absinthe - Ihor Katkov
Craft effective API with GraphQL and Absinthe - Ihor KatkovCraft effective API with GraphQL and Absinthe - Ihor Katkov
Craft effective API with GraphQL and Absinthe - Ihor KatkovElixir Club
 
Elixir in a service of government - Alex Troush
Elixir in a service of government - Alex TroushElixir in a service of government - Alex Troush
Elixir in a service of government - Alex TroushElixir Club
 

More from Elixir Club (20)

Kubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club Ukraine
Kubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club UkraineKubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club Ukraine
Kubernetes + Docker + Elixir - Alexei Sholik, Andrew Dryga | Elixir Club Ukraine
 
Integrating 3rd parties with Ecto - Eduardo Aguilera | Elixir Club Ukraine
Integrating 3rd parties with Ecto -  Eduardo Aguilera | Elixir Club UkraineIntegrating 3rd parties with Ecto -  Eduardo Aguilera | Elixir Club Ukraine
Integrating 3rd parties with Ecto - Eduardo Aguilera | Elixir Club Ukraine
 
— An async template - Oleksandr Khokhlov | Elixir Club Ukraine
— An async template  -  Oleksandr Khokhlov | Elixir Club Ukraine— An async template  -  Oleksandr Khokhlov | Elixir Club Ukraine
— An async template - Oleksandr Khokhlov | Elixir Club Ukraine
 
BEAM architecture handbook - Andrea Leopardi | Elixir Club Ukraine
BEAM architecture handbook - Andrea Leopardi  | Elixir Club UkraineBEAM architecture handbook - Andrea Leopardi  | Elixir Club Ukraine
BEAM architecture handbook - Andrea Leopardi | Elixir Club Ukraine
 
You ain't gonna need write a GenServer - Ulisses Almeida | Elixir Club Ukraine
You ain't gonna need write a GenServer - Ulisses Almeida  | Elixir Club UkraineYou ain't gonna need write a GenServer - Ulisses Almeida  | Elixir Club Ukraine
You ain't gonna need write a GenServer - Ulisses Almeida | Elixir Club Ukraine
 
— Knock, knock — An async templates — Who’s there? - Alexander Khokhlov | ...
 — Knock, knock — An async templates — Who’s there? - Alexander Khokhlov  |  ... — Knock, knock — An async templates — Who’s there? - Alexander Khokhlov  |  ...
— Knock, knock — An async templates — Who’s there? - Alexander Khokhlov | ...
 
Performance measurement methodology — Maksym Pugach | Elixir Evening Club 3
Performance measurement methodology — Maksym Pugach | Elixir Evening Club 3Performance measurement methodology — Maksym Pugach | Elixir Evening Club 3
Performance measurement methodology — Maksym Pugach | Elixir Evening Club 3
 
Erlang cluster. How is it? Production experience. — Valerii Vasylkov | Elixi...
Erlang cluster. How is it? Production experience. —  Valerii Vasylkov | Elixi...Erlang cluster. How is it? Production experience. —  Valerii Vasylkov | Elixi...
Erlang cluster. How is it? Production experience. — Valerii Vasylkov | Elixi...
 
Promo Phx4RailsDevs - Volodya Sveredyuk
Promo Phx4RailsDevs - Volodya SveredyukPromo Phx4RailsDevs - Volodya Sveredyuk
Promo Phx4RailsDevs - Volodya Sveredyuk
 
Web of today — Alexander Khokhlov
Web of today —  Alexander KhokhlovWeb of today —  Alexander Khokhlov
Web of today — Alexander Khokhlov
 
ElixirConf Eu 2018, what was it like? – Eugene Pirogov
ElixirConf Eu 2018, what was it like? – Eugene PirogovElixirConf Eu 2018, what was it like? – Eugene Pirogov
ElixirConf Eu 2018, what was it like? – Eugene Pirogov
 
Implementing GraphQL API in Elixir – Victor Deryagin
Implementing GraphQL API in Elixir – Victor DeryaginImplementing GraphQL API in Elixir – Victor Deryagin
Implementing GraphQL API in Elixir – Victor Deryagin
 
WebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerWebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan Wintermeyer
 
GenServer in Action – Yurii Bodarev
GenServer in Action – Yurii Bodarev   GenServer in Action – Yurii Bodarev
GenServer in Action – Yurii Bodarev
 
Russian Doll Paradox: Elixir Web without Phoenix - Alex Rozumii
Russian Doll Paradox: Elixir Web without Phoenix - Alex RozumiiRussian Doll Paradox: Elixir Web without Phoenix - Alex Rozumii
Russian Doll Paradox: Elixir Web without Phoenix - Alex Rozumii
 
Practical Fault Tolerance in Elixir - Alexei Sholik
Practical Fault Tolerance in Elixir - Alexei SholikPractical Fault Tolerance in Elixir - Alexei Sholik
Practical Fault Tolerance in Elixir - Alexei Sholik
 
Phoenix and beyond: Things we do with Elixir - Alexander Khokhlov
Phoenix and beyond: Things we do with Elixir - Alexander KhokhlovPhoenix and beyond: Things we do with Elixir - Alexander Khokhlov
Phoenix and beyond: Things we do with Elixir - Alexander Khokhlov
 
Monads are just monoids in the category of endofunctors - Ike Kurghinyan
Monads are just monoids in the category of endofunctors - Ike KurghinyanMonads are just monoids in the category of endofunctors - Ike Kurghinyan
Monads are just monoids in the category of endofunctors - Ike Kurghinyan
 
Craft effective API with GraphQL and Absinthe - Ihor Katkov
Craft effective API with GraphQL and Absinthe - Ihor KatkovCraft effective API with GraphQL and Absinthe - Ihor Katkov
Craft effective API with GraphQL and Absinthe - Ihor Katkov
 
Elixir in a service of government - Alex Troush
Elixir in a service of government - Alex TroushElixir in a service of government - Alex Troush
Elixir in a service of government - Alex Troush
 

Recently uploaded

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 

Recently uploaded (20)

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 

Ecto DSL for Elixir Database Queries

  • 1. Ecto DSL Domain specific language for writing queries and interacting with databases in Elixir.
  • 2. Yurii Bodarev Back-end software developer twitter.com/bodarev_yurii github.com/yuriibodarev
  • 4. Brief contents • Elixir Data Structures • Basic data types and structures • Associative data structures • Structs • Pattern Matching • Ecto • Ecto.Repo • Ecto.Schema • Ecto.Changeset • Ecto.Query
  • 5. Basic data types and structures • Atoms • Lists • Tuples
  • 6. Atoms Atoms are constants where their name is their own value. iex> :hello :hello iex> :hello == :world false iex> true == :true true
  • 7. Lists (Linked) Lists are used to manage dynamic, variable-sized collections of data of any type. iex> [1, "abc", true, 3] [1, "abc", true, 3] iex> length([1, 2, 3]) 3
  • 8. List - recursive structure [head | tail] iex> [1 | [2, 3, 4]] [1, 2, 3, 4] [head | [head | [head | tail…]]] iex> [1 | [2 | [3 | [4 | []]]]] [1, 2, 3, 4]
  • 9. List - recursive structure iex> hd([1, 2, 3, 4]) 1 iex> tl([1, 2, 3, 4]) [2, 3, 4] iex> tl([2, 3, 4]) [3, 4] iex> tl([4]) []
  • 10. Tuples Tuples are untyped structures often used to group a fixed number of elements together. iex> tuple = {:ok, "hello"} {:ok, "hello"} iex> elem(tuple, 1) "hello" iex> tuple_size(tuple) 2
  • 11. Associative data structures • Keyword lists • Maps
  • 12. List as key-value data structure It is common to use a list of 2-item tuples as the representation of a key-value data structure iex> list = [{"a", 1}, {"b", 2}, {"c", 3}] [{"a", 1}, {"b", 2}, {"c", 3}] iex> List.keyfind(list, "b", 0) {"b", 2}
  • 13. Keyword lists When we have a list of tuples and the first item of the tuple (i.e. the key) is an atom, we call it a keyword list. iex> [{:a, 1}, {:b, 2}, {:c, 3}] [a: 1, b: 2, c: 3]
  • 14. Keyword lists Elixir supports a special syntax for defining such lists: [key: value] iex> [a: 1, b: 2, c: 3] == [{:a, 1}, {:b, 2}, {:c, 3}] true • Keys must be atoms. • Keys are ordered, as specified by the developer. • Keys can be given more than once.
  • 15. We can use all operations available to lists on keyword lists iex> list = [a: 1, c: 3, b: 2] [a: 1, c: 3, b: 2] iex> hd(list) {:a, 1} iex> tl(list) [c: 3, b: 2] iex> list[:a] 1 iex> newlist = [a: 0] ++ list [a: 0, a: 1, c: 3, b: 2] iex> newlist[:a] 0 iex> list[:d] nil
  • 16. Keyword lists - default mechanism for passing options to functions in Elixir iex> if true, do: "THIS" "THIS" iex> if false, do: "THIS", else: "THAT" "THAT" iex> if(false, [do: "THIS", else: "THAT"]) "THAT" When the keyword list is the last argument of a function, the square brackets are optional.
  • 17. Example of the Ecto query query = from w in Weather, where: w.prcp > 0, where: w.temp < 20, select: w
  • 18. Maps A map is a key-value store, where keys and values can be any term. A map is created using the %{} syntax. Maps’ keys do not follow developer ordering. iex> map = %{:a => 1, 2 => "b", "c" => 3} %{2 => "b", :a => 1, "c" => 3} iex> map[:a] 1 iex> map[2] "b" iex> map["d"] nil
  • 19. Maps When all the keys in a map are atoms, you can use the keyword syntax. iex> map = %{a: 1, b: 2, c: 3} %{a: 1, b: 2, c: 3} iex> map.a 1 iex> map.d ** (KeyError) key :d not found in: %{a: 1, b: 2, c: 3} iex> %{map | c: 5} %{a: 1, b: 2, c: 5} iex> %{map | d: 0} ** (KeyError) key :d not found in: %{a: 1, b: 2, c: 3}
  • 20. Structs Structs are extensions built on top of maps that provide compile-time checks and default values. iex> defmodule User do ...> defstruct name: "Ivan", age: 25 ...> end iex> %User{} %User{age: 25, name: "Ivan"}
  • 21. Structs iex> %User{name: "Maria"} %User{age: 25, name: "Maria"} iex> %User{other: "Something"} ** (KeyError) key :other not found in: %User{age: 25, name: "Ivan"}
  • 22. Structs are bare maps underneath, but none of the protocols implemented for maps are available for structs iex> ivan = %User{} %User{age: 25, name: "Ivan"} iex> is_map(ivan) true iex> Map.keys(ivan) [:__struct__, :age, :name] iex> ivan.__struct__ User iex> ivan[:age] ** (UndefinedFunctionError) function User.fetch/2 is undefined (User does not implement the Access behaviour)
  • 23. Pattern matching iex> {a, b, c} = {:hello, "world", 42} {:hello, "world", 42} iex> a :hello iex> b "world" iex> c 42
  • 24. A pattern match will error if the sides can’t be matched iex> {a, b, c} = {:hello, "world"} ** (MatchError) no match of right hand side value: {:hello, "world"} iex> {a, b, c} = [:hello, "world", 42] ** (MatchError) no match of right hand side value: [:hello, "world", 42]
  • 25. We can match on specific values iex> {:ok, result} = {:ok, 13} {:ok, 13} iex> result 13 iex> {:ok, result} = {:error, "Not Found!"} ** (MatchError) no match of right hand side value: {:error, "Not Found!"}
  • 26. We can match on specific values post = Repo.get!(Post, 42) case Repo.delete post do {:ok, struct} -> # Deleted with success {:error, changeset} -> # Something went wrong end
  • 27. Pattern match on lists iex> [a, b, c] = [1, 2, 3] [1, 2, 3] iex> b 2 iex> [head | tail] = [1, 2, 3] [1, 2, 3] iex> head 1 iex> tail [2, 3] iex> [] = [1, 2, 3] ** (MatchError) no match of right hand side value: [1, 2, 3]
  • 28. Pattern match on keyword lists iex> [a: a] = [a: 1] [a: 1] iex> [a: a] = [a: 1, b: 2] ** (MatchError) no match of right hand side value: [a: 1, b: 2] iex> [b: b, a: a] = [a: 1, b: 2] ** (MatchError) no match of right hand side value: [a: 1, b: 2]
  • 29. Pattern match on maps iex> %{} = %{a: 1, b: 2} %{a: 1, b: 2} iex> %{b: b} = %{a: 1, b: 2} %{a: 1, b: 2} iex> b 2 iex> %{c: c} = %{a: 1, b: 2} ** (MatchError) no match of right hand side value: %{a: 1, b: 2}
  • 30. The pin ^ operator and _ iex> x = 2 2 iex> {1, ^x} = {1, 2} {1, 2} iex> {a, _} = {1, 2} {1, 2} iex> a 1
  • 31. Ecto Ecto is split into 4 main components: • Ecto.Repo - repositories are wrappers around the data store. • Ecto.Schema - schemas are used to map any data source into an Elixir struct. • Ecto.Changeset - allow developers to filter, cast, and validate changes before we apply them to the data. • Ecto.Query - written in Elixir syntax, queries are used to retrieve information from a given repository.
  • 32. Ecto playground Ecto in not an ORM github.com/yuriibodarev/Ecto_not_ORM Requires: PostgreSQL Run within IEx console: iex -S mix
  • 33. Repositories Via the repository, we can create, update, destroy and query existing database entries.
  • 34. Repositories Ecto.Repo is a wrapper around the database. We can define a repository as follows (libblogrepo.ex): defmodule Blog.Repo do use Ecto.Repo, otp_app: :blog end
  • 35. Repositories A repository needs an adapter and credentials to communicate to the database. Configuration for the Repo usually defined in your config/config.exs: config :blog, Blog.Repo, adapter: Ecto.Adapters.Postgres, database: "blog_repo", username: "postgres", password: "postgres", hostname: "localhost"
  • 36. Repositories Each repository in Ecto defines a start_link/0. Usually this function is invoked as part of your application supervision tree (libblog.ex): def start(_type, _args) do import Supervisor.Spec, warn: false children = [ worker(Blog.Repo, []), ] opts = [strategy: :one_for_one, name: Blog.Supervisor] Supervisor.start_link(children, opts) end
  • 37. Schema Schemas allows developers to define the shape of their data. (libbloguser.ex) defmodule Blog.User do use Ecto.Schema schema "users" do field :name, :string field :reputation, :integer, default: 0 has_many :posts, Blog.Post, on_delete: :delete_all timestamps end end
  • 38. Schema By defining a schema, Ecto automatically defines a struct: iex> user = %Blog.User{name: "Bill"} %Blog.User{__meta__: #Ecto.Schema.Metadata<:built, "users">, id: nil, inserted_at: nil, name: "Bill"}, posts: #Ecto.Association.NotLoaded<association :posts is not loaded>, reputation: 0, updated_at: nil}
  • 39. Schema Using Schema we can interact with a repository: iex> user = %Blog.User{name: "Bill", reputation: 10} %Blog.User{…} iex> Blog.Repo.insert!(user) %Blog.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: 6, inserted_at: ~N[2016-12-13 16:16:35.983000], name: "Bill", posts: #Ecto.Association.NotLoaded<association :posts is not loaded>, reputation: 10, updated_at: ~N[2016-12-13 16:16:36.001000]}
  • 40. Schema # Get the user back iex> newuser = Blog.Repo.get(Blog.User, 6) iex> newuser.id 6 # Delete it iex> Blog.Repo.delete(newuser) {:ok, %Blog.User{…, id: 6,…}}
  • 41. Schema We can use pattern matching on Structs created with Schemas: iex> %{name: name, reputation: reputation} = ...> Blog.Repo.get(Blog.User, 1) iex> name "Alex" iex> reputation 144
  • 42. Changesets We can add changesets to our schemas to validate changes before we apply them to the data (libbloguser.ex): def changeset(user, params %{}) do user |> cast(params, [:name, :reputation]) |> validate_required([:name, :reputation]) |> validate_inclusion(:reputation, -999..999) end
  • 43. Changesets iex> alina = %Blog.User{name: "Alina"} iex> correct_changeset = Blog.User.changeset(alina, %{reputation: 55}) #Ecto.Changeset<action: nil, changes: %{reputation: 55}, errors: [], data: #Blog.User<>, valid?: true> iex> invalid_changeset = Blog.User.changeset(alina, %{reputation: 1055}) #Ecto.Changeset<action: nil, changes: %{reputation: 1055}, errors: [reputation: {"is invalid", [validation: :inclusion]}], data: #Blog.User<>, valid?: false>
  • 44. Changeset with Repository functions iex> valid_changeset.valid? true iex> Blog.Repo.insert(valid_changeset) {:ok, %Blog.User{…, id: 7, …}}
  • 45. Changeset with Repository functions iex> invalid_changeset.valid? false iex> Blog.Repo.insert(invalid_changeset) {:error, #Ecto.Changeset<action: :insert, changes: %{reputation: 1055}, errors: [reputation: {"is invalid", [validation: :inclusion]}], data: #Blog.User<>, valid?: false>}
  • 46. Changeset with Repository functions case Blog.Repo.update(changeset) do {:ok, user} -> # user updated {:error, changeset} -> # an error occurred end
  • 47. We can provide different changeset functions for different use cases def registration_changeset(user, params) do # Changeset on create end def update_changeset(user, params) do # Changeset on update end
  • 48. Query Ecto allows you to write queries in Elixir and send them to the repository, which translates them to the underlying database.
  • 49. Query using predefined Schema # Query using predefined Schema query = from u in User, where: u.reputation > 35, select: u # Returns %User{} structs matching the query Repo.all(query) [%Blog.User{…, id: 2, …, name: "Bender", …, reputation: 42, …}, %Blog.User{…, id: 1, …, name: "Alex", …, reputation: 144, …}]
  • 50. Directly querying the “users” table # Directly querying the “users” table query = from u in "users", where: u.reputation > 30, select: %{name: u.name, reputation: u.reputation} # Returns maps as defined in select Repo.all(query) [%{name: "Bender", reputation: 42}, %{name: "Alex", reputation: 144}]
  • 51. External values in Queries # ^ operator min = 33 query = from u in "users", where: u.reputation > ^min, select: u.name # casting mins = "33" query = from u in "users", where: u.reputation > type(^mins, :integer), select: u.name
  • 52. External values in Queries If the query is made against Schema than Ecto will automatically cast external value min = "35" Repo.all(from u in User, where: u.reputation > ^min) You can also skip Select to retrieve all fields specified in the Schema