Created
February 5, 2022 03:39
-
-
Save karlseguin/f00417db62d1e4b45d6b37925abc1142 to your computer and use it in GitHub Desktop.
Elixir without Ecto, A thin Postgrex wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the code, great article, I was looking for exactly something like this.