query.ex (3215B)
1 defmodule Postgrex.Query do 2 @moduledoc """ 3 Query struct returned from a successfully prepared query. 4 5 Its public fields are: 6 7 * `name` - The name of the prepared statement; 8 * `statement` - The prepared statement; 9 * `columns` - The column names; 10 * `ref` - A reference used to identify prepared queries; 11 12 ## Prepared queries 13 14 Once a query is prepared with `Postgrex.prepare/4`, the 15 returned query will have its `ref` field set to a reference. 16 When `Postgrex.execute/4` is called with the prepared query, 17 it always returns a query. If the `ref` field in the query 18 given to `execute` and the one returned are the same, it 19 means the cached prepared query was used. If the `ref` field 20 is not the same, it means the query had to be re-prepared. 21 """ 22 23 @type t :: %__MODULE__{ 24 cache: :reference | :statement, 25 ref: reference | nil, 26 name: iodata, 27 statement: iodata, 28 param_oids: [Postgrex.Types.oid()] | nil, 29 param_formats: [:binary | :text] | nil, 30 param_types: [Postgrex.Types.type()] | nil, 31 columns: [String.t()] | nil, 32 result_oids: [Postgrex.Types.oid()] | nil, 33 result_formats: [:binary | :text] | nil, 34 result_types: [Postgrex.Types.type()] | nil, 35 types: Postgrex.Types.state() | nil 36 } 37 38 defstruct [ 39 :ref, 40 :name, 41 :statement, 42 :param_oids, 43 :param_formats, 44 :param_types, 45 :columns, 46 :result_oids, 47 :result_formats, 48 :result_types, 49 :types, 50 cache: :reference 51 ] 52 end 53 54 defimpl DBConnection.Query, for: Postgrex.Query do 55 require Postgrex.Messages 56 57 def parse(%{types: nil, name: name} = query, _) do 58 # for query table to match names must be equal 59 %{query | name: IO.iodata_to_binary(name)} 60 end 61 62 def parse(query, _) do 63 raise ArgumentError, "query #{inspect(query)} has already been prepared" 64 end 65 66 def describe(query, _), do: query 67 68 def encode(%{types: nil} = query, _params, _) do 69 raise ArgumentError, "query #{inspect(query)} has not been prepared" 70 end 71 72 def encode(query, params, _) do 73 %{param_types: param_types, types: types} = query 74 75 case Postgrex.Types.encode_params(params, param_types, types) do 76 encoded when is_list(encoded) -> 77 encoded 78 79 :error -> 80 raise ArgumentError, 81 "parameters must be of length #{length(param_types)} for query #{inspect(query)}" 82 end 83 end 84 85 def decode(_, %Postgrex.Result{rows: nil} = res, _opts) do 86 res 87 end 88 89 def decode(_, %Postgrex.Result{rows: rows} = res, opts) do 90 %Postgrex.Result{res | rows: decode_map(rows, opts)} 91 end 92 93 def decode(_, %Postgrex.Copy{} = copy, _opts) do 94 copy 95 end 96 97 ## Helpers 98 99 defp decode_map(data, opts) do 100 case opts[:decode_mapper] do 101 nil -> Enum.reverse(data) 102 mapper -> decode_map(data, mapper, []) 103 end 104 end 105 106 defp decode_map([row | data], mapper, decoded) do 107 decode_map(data, mapper, [mapper.(row) | decoded]) 108 end 109 110 defp decode_map([], _, decoded) do 111 decoded 112 end 113 end 114 115 defimpl String.Chars, for: Postgrex.Query do 116 def to_string(%Postgrex.Query{statement: statement}) do 117 IO.iodata_to_binary(statement) 118 end 119 end