This library combines abacus and ecto.
Pipe user-supplied abacus terms into queries like this:
from(b in BlogPost)
|> AbacusSql.where(~S[title == "abacus"])
|> AbacusSql.select("author", "author.name")
and you'll get a query that will not only filter for the posts title, but also automatically joins to the users table, adding the name of the author to the select list:
#Ecto.Query<from b in AbacusSqlTest.BlogPost, left_join: a in assoc(b, :author),
where: b.title == ^"abacus", select: %{"author" => a.name}>
Allow additional type casts as such:
config :abacus_sql, :allowed_casts, [
:unit, :my_custom_type
]
These casts will be available as function calls: unit("30 m")
and will be converted into a cast expression: fragment("(?)::text::unit", type(^"30 m", :string))
.
Allow additional SQL functions:
config :abacus_sql, :allowed_function_calls, [
:extract, :coalesce, :st_buffer
]
These SQL functions will be available as normal function calls.
To add your own convert_ast clauses, configure a macro_module
:
config :abacus_sql, :macro_module, MyApp.MacroModule
defmodule MyApp.MacroModule do
import AbacusSql.Term
@spec convert_ast(any, Ecto.Query.t, list, integer) :: {any, Ecto.Query.t, list}
# don't add a catch-all here, a FunctionClauseError on this function will automatically be handled gracefully
def convert_ast({{"my_macro", _, nil}, ctx, args}, query, params, root_id) do
{[arg0 | _rest], query, params} = reduce_args(args, query, params, root_id)
ast = {:frament, ctx, [
raw: "MY MACRO IS ",
expr: arg0,
raw: " YEAH"
]}
{ast, query, params}
end
end
If available in Hex, the package can be installed
by adding abacus_sql
to your list of dependencies in mix.exs
:
def deps do
[
{:abacus_sql, "~> 0.1.0"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/abacus_sql.