Ecto v1.1.0 Ecto.Repo behaviour

Defines a repository.

A repository maps to an underlying data store, controlled by the adapter. For example, Ecto ships with a Postgres adapter that stores data into a PostgreSQL database.

When used, the repository expects the :otp_app as option. The :otp_app should point to an OTP application that has the repository configuration. For example, the repository:

defmodule Repo do
  use Ecto.Repo, otp_app: :my_app
end

Could be configured with:

config :my_app, Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "ecto_simple",
  username: "postgres",
  password: "postgres",
  hostname: "localhost"

Most of the configuration that goes into the config is specific to the adapter, so check Ecto.Adapters.Postgres documentation for more information. However, some configuration is shared across all adapters, they are:

  • :priv - the directory where to keep repository data, like migrations, schema and more. Defaults to “priv/YOUR_REPO”

  • :url - an URL that specifies storage information. Read below for more information

URLs

Repositories by default support URLs. For example, the configuration above could be rewriten to:

config :my_app, Repo,
  url: "ecto://postgres:postgres@localhost/ecto_simple"

The schema can be of any value. The path represents the database name while options are simply merged in.

URLs also support {:system, "KEY"} to be given, telling Ecto to load the configuration from the system environment instead:

config :my_app, Repo,
  url: {:system, "DATABASE_URL"}

Summary

Callbacks

Returns the adapter tied to the repository

Returns the pool information this repository should run under

Returns the name of the ETS table used for query caching

Simply returns true to mark this module as a repository

Fetches all entries from the data store matching the given query

Returns the adapter configuration stored in the :otp_app environment

Deletes a model using its primary key

Same as delete/2 but returns the model or raises if the changeset is invalid

Deletes all entries matching the given query

Fetches a single model from the data store where the primary key matches the given id

Similar to get/3 but raises Ecto.NoResultsError if no record was found

Fetches a single result from the query

Similar to get_by/3 but raises Ecto.NoResultsError if no record was found

Inserts a model or a changeset

Same as insert/2 but returns the model or raises if the changeset is invalid

Inserts or updates a changeset depending on whether the model is persisted or not

Same as insert_or_update/2 but returns the model or raises if the changeset is invalid

Enables logging of adapter actions such as sending queries to the database

Fetches a single result from the query

Similar to one/2 but raises Ecto.NoResultsError if no record was found

Preloads all associations on the given model or models

Rolls back the current transaction

Starts any connection pooling or supervision and return {:ok, pid} or just :ok if nothing needs to be done

Shuts down the repository represented by the given pid

Runs the given function inside a transaction

Updates a model or changeset using its primary key

Same as update/2 but returns the model or raises if the changeset is invalid

Updates all entries matching the given query with the given values

Types

t :: module

Callbacks

__adapter__()

Specs

__adapter__ :: Ecto.Adapter.t

Returns the adapter tied to the repository.

__pool__()

Specs

__pool__ :: {pool :: module, name :: atom, pool_timeout :: timeout, op_timeout :: timeout}

Returns the pool information this repository should run under.

__query_cache__()

Specs

__query_cache__ :: atom

Returns the name of the ETS table used for query caching.

The name can be configured with the :query_cache option.

__repo__()

Specs

__repo__ :: true

Simply returns true to mark this module as a repository.

all(arg0, arg1)

Specs

all(Ecto.Query.t, Keyword.t) ::
  [Ecto.Schema.t] |
  no_return

Fetches all entries from the data store matching the given query.

May raise Ecto.QueryError if query validation fails.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query

Example

# Fetch all post titles
query = from p in Post,
     select: p.title
MyRepo.all(query)
config()

Specs

config :: Keyword.t

Returns the adapter configuration stored in the :otp_app environment.

delete(arg0, arg1)

Specs

delete(Ecto.Schema.t, Keyword.t) ::
  {:ok, Ecto.Schema.t} |
  {:error, Ecto.Changeset.t}

Deletes a model using its primary key.

If any before_delete or after_delete callback are registered in the given model, they will be invoked with the changeset.

If the model has no primary key, Ecto.NoPrimaryKeyFieldError will be raised.

It returns {:ok, model} if the model has been successfully deleted or {:error, changeset} if there was a validation or a known constraint error.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query

Example

[post] = MyRepo.all(from(p in Post, where: p.id == 42))
case MyRepo.delete post do
  {:ok, model}        -> # Deleted with success
  {:error, changeset} -> # Something went wrong
end
delete!(arg0, arg1)

Specs

delete!(Ecto.Schema.t, Keyword.t) ::
  Ecto.Schema.t |
  no_return

Same as delete/2 but returns the model or raises if the changeset is invalid.

delete_all(arg0, arg1)

Specs

delete_all(Ecto.Queryable.t, Keyword.t) ::
  {integer, nil} |
  no_return

Deletes all entries matching the given query.

It returns a tuple containing the number of entries and any returned result as second element. If the database does not support RETURNING in DELETE statements or no return result was selected, the second element will be nil.

This operation does not run the model before_delete and after_delete callbacks.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query

Examples

MyRepo.delete_all(Post)

from(p in Post, where: p.id < 10) |> MyRepo.delete_all
get(arg0, term, arg2)

Specs

get(Ecto.Queryable.t, term, Keyword.t) ::
  Ecto.Schema.t |
  nil |
  no_return

Fetches a single model from the data store where the primary key matches the given id.

Returns nil if no result was found. If the model in the queryable has no primary key Ecto.NoPrimaryKeyFieldError will be raised.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query
get!(arg0, term, arg2)

Specs

get!(Ecto.Queryable.t, term, Keyword.t) ::
  Ecto.Schema.t |
  nil |
  no_return

Similar to get/3 but raises Ecto.NoResultsError if no record was found.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query
get_by(arg0, arg1, arg2)

Specs

get_by(Ecto.Queryable.t, Keyword.t | Map.t, Keyword.t) ::
  Ecto.Schema.t |
  nil |
  no_return

Fetches a single result from the query.

Returns nil if no result was found.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query

Example

MyRepo.get_by(Post, title: "My post")
get_by!(arg0, arg1, arg2)

Specs

get_by!(Ecto.Queryable.t, Keyword.t | Map.t, Keyword.t) ::
  Ecto.Schema.t |
  nil |
  no_return

Similar to get_by/3 but raises Ecto.NoResultsError if no record was found.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query

Example

MyRepo.get_by!(Post, title: "My post")
insert(arg0, arg1)

Specs

Inserts a model or a changeset.

In case a model is given, the model is converted into a changeset with all model non-virtual fields as part of the changeset. This conversion is done by calling Ecto.Changeset.change/2 directly.

In case a changeset is given, the changes in the changeset are merged with the model fields, and all of them are sent to the database.

If any before_insert or after_insert callback is registered in the given model, they will be invoked with the changeset.

It returns {:ok, model} if the model has been successfully inserted or {:error, changeset} if there was a validation or a known constraint error.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query

Example

case MyRepo.insert %Post{title: "Ecto is great"} do
  {:ok, model}        -> # Inserted with success
  {:error, changeset} -> # Something went wrong
end
insert!(arg0, arg1)

Specs

insert!(Ecto.Schema.t, Keyword.t) ::
  Ecto.Schema.t |
  no_return

Same as insert/2 but returns the model or raises if the changeset is invalid.

insert_or_update(arg0, arg1)

Specs

insert_or_update(Ecto.Changeset.t, Keyword.t) ::
  {:ok, Ecto.Schema.t} |
  {:error, Ecto.Changeset.t}

Inserts or updates a changeset depending on whether the model is persisted or not.

The distinction whether to insert or update will be made on the Ecto.Schema.Metadata field :state. The :state is automatically set by Ecto when loading or building a schema.

Please note that for this to work, you will have to load existing models from the database. So even if the model exists, this won’t work:

model = %Post{id: 'existing_id', ...}
MyRepo.insert_or_update changeset
# => {:error, "id already exists"}

Example

result =
  case MyRepo.get(Post, id) do
    nil  -> %Post{id: id} # Post not found, we build one
    post -> post          # Post exists, let's use it
  end
  |> Post.changeset(changes)
  |> MyRepo.insert_or_update

case result do
  {:ok, model}        -> # Inserted or updated with success
  {:error, changeset} -> # Something went wrong
end
insert_or_update!(arg0, arg1)

Specs

insert_or_update!(Ecto.Changeset.t, Keyword.t) ::
  Ecto.Schema.t |
  no_return

Same as insert_or_update/2 but returns the model or raises if the changeset is invalid.

log(arg0)

Specs

log(Ecto.LogEntry.t) :: any

Enables logging of adapter actions such as sending queries to the database.

By default writes to Logger but can be overriden to customize behaviour.

Examples

The default implementation of the log/1 function is shown below:

def log(entry) do
  Logger.debug(fn ->
    {_entry, iodata} = Ecto.LogEntry.to_iodata(entry)
    iodata
  end, ecto_conn_pid: entry.connection_pid)
end
one(arg0, arg1)

Specs

one(Ecto.Queryable.t, Keyword.t) ::
  Ecto.Schema.t |
  nil |
  no_return

Fetches a single result from the query.

Returns nil if no result was found.

Options

  • :timeout - The time in milliseconds to wait for the call to finish, :infinity will wait indefinitely (default: 5000);;
  • :log - When false, does not log the query
one!(arg0, arg1)

Specs

one!(Ecto.Queryable.t, Keyword.t) ::
  Ecto.Schema.t |
  nil |
  no_return

Similar to one/2 but raises Ecto.NoResultsError if no record was found.

Options

  • :timeout - The time in milliseconds to wait for the call to finish, :infinity will wait indefinitely (default: 5000);;
  • :log - When false, does not log the query
preload(arg0, preloads)

Specs

preload([Ecto.Schema.t] | Ecto.Schema.t, preloads :: term) ::
  [Ecto.Schema.t] |
  Ecto.Schema.t

Preloads all associations on the given model or models.

This is similar to Ecto.Query.preload/3 except it allows you to preload models after they have been fetched from the database.

In case the association was already loaded, preload won’t attempt to reload it.

Examples

posts = Repo.preload posts, :comments
posts = Repo.preload posts, comments: :permalinks
posts = Repo.preload posts, comments: from(c in Comment, order_by: c.published_at)
rollback(any)

Specs

rollback(any) :: no_return

Rolls back the current transaction.

The transaction will return the value given as {:error, value}.

start_link()

Specs

start_link ::
  {:ok, pid} |
  {:error, {:already_started, pid}} |
  {:error, term}

Starts any connection pooling or supervision and return {:ok, pid} or just :ok if nothing needs to be done.

Returns {:error, {:already_started, pid}} if the repo already started or {:error, term} in case anything else goes wrong.

stop(pid, timeout)

Specs

stop(pid, timeout) :: :ok

Shuts down the repository represented by the given pid.

This callback must be called by the process that called start_link/2. Therefore, it is useful for scripts.

transaction(arg0, list)

Specs

transaction(Keyword.t, (... -> any)) ::
  {:ok, any} |
  {:error, any}

Runs the given function inside a transaction.

If an unhandled error occurs the transaction will be rolled back and the error will bubble up from the transaction function. If no error occurred the transaction will be commited when the function returns. A transaction can be explicitly rolled back by calling rollback/1, this will immediately leave the function and return the value given to rollback as {:error, value}.

A successful transaction returns the value returned by the function wrapped in a tuple as {:ok, value}.

If transaction/2 is called inside another transaction, the function is simply executed, without wrapping the new transaction call in any way. If there is an error in the inner transaction and the error is rescued, or the inner transaction is rolled back, the whole outer transaction is marked as tainted, guaranteeing nothing will be comitted.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log begin/commit/rollback queries

Examples

MyRepo.transaction(fn ->
  MyRepo.update!(%{alice | balance: alice.balance - 10})
  MyRepo.update!(%{bob | balance: bob.balance + 10})
end)

# Roll back a transaction explicitly
MyRepo.transaction(fn ->
  p = MyRepo.insert!(%Post{})
  if not Editor.post_allowed?(p) do
    MyRepo.rollback(:posting_not_allowed)
  end
end)
update(arg0, arg1)

Specs

update(Ecto.Changeset.t, Keyword.t) ::
  {:ok, Ecto.Schema.t} |
  {:error, Ecto.Changeset.t}

Updates a model or changeset using its primary key.

In case a model is given, the model is converted into a changeset with all model non-virtual fields as part of the changeset. This conversion is done by calling Ecto.Changeset.change/2 directly. For this reason, it is preferred to use changesets when performing updates as they perform dirty tracking and avoid sending data that did not change to the database over and over. In case there are no changes in the changeset, no data is sent to the database at all.

In case a changeset is given, only the changes in the changeset will be updated, leaving all the other model fields intact.

If any before_update or after_update callback are registered in the given model, they will be invoked with the changeset.

If the model has no primary key, Ecto.NoPrimaryKeyFieldError will be raised.

It returns {:ok, model} if the model has been successfully updated or {:error, changeset} if there was a validation or a known constraint error.

Options

  • :force - By default, if there are no changes in the changeset, update!/2 is a no-op. By setting this option to true, update callbacks will always be executed, even if there are no changes (including timestamps).
  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query

Example

post = MyRepo.get!(Post, 42)
post = Ecto.Changeset.change post, title: "New title"
case MyRepo.update post do
  {:ok, model}        -> # Updated with success
  {:error, changeset} -> # Something went wrong
end
update!(arg0, arg1)

Specs

update!(Ecto.Schema.t, Keyword.t) ::
  Ecto.Schema.t |
  no_return

Same as update/2 but returns the model or raises if the changeset is invalid.

update_all(arg0, arg1, arg2)

Specs

update_all(Macro.t, Keyword.t, Keyword.t) ::
  {integer, nil} |
  no_return

Updates all entries matching the given query with the given values.

It returns a tuple containing the number of entries and any returned result as second element. If the database does not support RETURNING in UPDATE statements or no return result was selected, the second element will be nil.

See Ecto.Query.update/3 for update operations that can be performed on fields.

This operation does not run the model before_update and after_update callbacks.

Options

  • :timeout - The time in milliseconds to wait for the query call to finish, :infinity will wait indefinitely (default: 15000);
  • :pool_timeout - The time in milliseconds to wait for calls to the pool to finish, :infinity will wait indefinitely (default: 5000);
  • :log - When false, does not log the query

Examples

MyRepo.update_all(Post, set: [title: "New title"])

MyRepo.update_all(Post, inc: [visits: 1])

from(p in Post, where: p.id < 10)
|> MyRepo.update_all(set: [title: "New title"])

from(p in Post, where: p.id < 10, update: [set: [title: "New title"]])
|> MyRepo.update_all([])