Skip to content

Instantly share code, notes, and snippets.

@pufe
Forked from romul/README.md
Last active December 23, 2016 16:20
Show Gist options
  • Save pufe/688ae59881a8f9845549e0c3d5958ecf to your computer and use it in GitHub Desktop.
Save pufe/688ae59881a8f9845549e0c3d5958ecf to your computer and use it in GitHub Desktop.
Using Postres hstore with Elixir, Ecto & Postgrex

To use hstore in Ecto schemas you have to create own Ecto type. To do this, follow these steps:

  1. Create files hstore.ex & hstore_extension.ex inside your lib folder
  2. Open your database settings and add the following line

extensions: [{MyApp.HStoreExtension, nil}],, for example

config :my_app, MyApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: "",
  database: "database_name",
  extensions: [{MyApp.HStoreExtension, nil}],
  size: 100
  • On postgrex 0.10 onwards, postgrex split the Binary extension across multiple files, so this fork uses the Postgrex.Extensions.HStore instead of the Postgrex.Extensions.Binary
  • Tested with Ecto 2.0.0-rc.6, Postgrex 0.11.2 and PostgreSQL 9.3.5
defmodule MyApp.HStore do
@behaviour Ecto.Type
def type, do: :hstore
def cast(value), do: {:ok, value}
def blank?(_), do: false
def load(value) do
{:ok, value}
end
def dump(value) do
{:ok, value}
end
end
defmodule MyApp.HStoreExtension do
alias Postgrex.TypeInfo
alias Postgrex.Extensions.HStore
@behaviour Postgrex.Extension
def init(_parameters, _opts), do: []
def matching(_), do: [type: "hstore"]
def format(_), do: :binary
def decode(info = %TypeInfo{type: "hstore"}, bin, types, _opts) do
HStore.decode %TypeInfo{info | send: "hstore_send"}, bin, types, :reference # can also use :copy
end
def encode(info = %TypeInfo{type: "hstore"}, map, types, opts) do
HStore.encode %TypeInfo{info | send: "hstore_send"}, map, types, opts
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment