Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@karlseguin
Created February 5, 2022 03:39
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save karlseguin/f00417db62d1e4b45d6b37925abc1142 to your computer and use it in GitHub Desktop.
Save karlseguin/f00417db62d1e4b45d6b37925abc1142 to your computer and use it in GitHub Desktop.
Elixir without Ecto, A thin Postgrex wrapper
# see https://www.openmymind.net/Elixir-Without-Ecto/
defmodule A.DB do
defmacro __using__(_) do
quote location: :keep do
@name __MODULE__
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, opts}
}
end
def start_link(config) do
defaults = [name: @name, pool_size: 5]
config = Keyword.merge(defaults, config)
Postgrex.start_link(config)
end
def ok!(sql, values), do: ok!(@name, sql, values, [])
def ok!(conn, sql, values, opts \\ []) do
query!(conn, sql, values, opts)
:ok
end
def affected!(sql, values), do: affected!(@name, sql, values, [])
def affected!(conn, sql, values, opts) do
query!(conn, sql, values, opts).num_rows
end
def scalar!(sql, values), do: scalar!(@name, sql, values, [])
def scalar!(conn, sql, values, opts \\ []) do
case query!(conn, sql, values, opts) do
%{rows: []} -> nil
%{rows: [[value]]} -> value
_ -> raise "scalar returned multiple columns and/or rows"
end
end
def row!(sql, values), do: row!(@name, sql, values, [])
def row!(conn, sql, values, opts \\ []) do
case query!(conn, sql, values, opts) do
%{rows: []} -> nil
%{rows: [row]} -> row
_ -> raise "row! returned multiple rows"
end
end
def map!(sql, values), do: map!(@name, sql, values, [])
def map!(conn, sql, values, opts \\ []) do
r = query!(conn, sql, values, opts)
case r.rows do
[] -> nil
[row] -> A.DB.mapify(r.columns, row)
_ -> raise "map returned multiple rows"
end
end
def maps!(sql, values), do: maps!(@name, sql, values, [])
def maps!(conn, sql, values, opts \\ []) do
case query!(sql, values) do
%{rows: []} -> nil
%{rows: rows, columns: columns} ->
Enum.map(rows, fn row -> A.DB.mapify(columns, row) end)
_ -> raise "maps! returned multiple rows"
end
end
def rows!(sql, values), do: rows!(@name, sql, values, [])
def rows!(conn, sql, values, opts \\ []) do
query!(conn, sql, values, opts).rows
end
def transaction!(fun, opts \\ []) do
case Postgrex.transaction(@name, fun, opts) do
{:ok, res} -> res
{:error, :rollback} -> raise "transaction! rollback"
err -> err
end
end
def query!(sql, values), do: query!(@name, sql, values, [])
def query!(conn, sql, values, opts \\ []) do
Postgrex.query!(conn, sql, values, opts)
end
end
end
def mapify(columns, row) do
columns
|> Enum.zip(row)
|> Map.new()
end
end
@csangonzo
Copy link

Thanks for the code, great article, I was looking for exactly something like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment