defmodule QuackDB.Query do @moduledoc """ Query metadata used by the DBConnection driver. """ @type t :: %__MODULE__{ statement: iodata(), columns: [String.t()] | nil, result_types: [term()] | nil, result_uuid: integer() | nil, operation: term() | nil } defstruct [:statement, :columns, :result_types, :result_uuid, :operation] end defimpl DBConnection.Query, for: QuackDB.Query do def parse(%QuackDB.Query{operation: nil} = query, _options) do %{query | statement: IO.iodata_to_binary(query.statement)} end def parse(%QuackDB.Query{} = query, _options), do: query def describe(%QuackDB.Query{} = query, _options), do: query def encode(_query, params, _options), do: params def decode(_query, %QuackDB.Result{rows: nil} = result, _options), do: result def decode(_query, %QuackDB.Result{rows: rows} = result, options) do %{result | rows: decode_rows(rows, Keyword.get(options, :decode_mapper))} end defp decode_rows(rows, nil), do: rows defp decode_rows(rows, mapper), do: Enum.map(rows, mapper) end defimpl Inspect, for: QuackDB.Query do import Inspect.Algebra def inspect(query, opts) do fields = [ statement: QuackDB.Inspect.truncate(query.statement), columns: query.columns, result_uuid: query.result_uuid ] concat(QuackDB.Inspect.container("QuackDB.Query", fields, opts)) end end defimpl String.Chars, for: QuackDB.Query do def to_string(%QuackDB.Query{statement: statement}) do IO.iodata_to_binary(statement) end end