Module: Simple::SQL::ConnectionAdapter
- Defined in:
- lib/simple/sql/connection_adapter.rb
Overview
This module implements an adapter between the Simple::SQL interface (i.e. ask, all, first, transaction) and a raw connection.
This module can be mixed onto objects that implement a raw_connection method, which must return a Pg::Connection.
Constant Summary collapse
- Logging =
::Simple::SQL::Logging
- Encoder =
::Simple::SQL::Encoder
- Decoder =
::Simple::SQL::Decoder
- Scope =
::Simple::SQL::Scope
Instance Method Summary collapse
- #add_page_info(scope, results) ⇒ Object
-
#all(sql, *args, into: nil, &block) ⇒ Object
Runs a query, with optional arguments, and returns the result.
-
#ask(sql, *args, into: nil) ⇒ Object
Runs a query and returns the first result row of a query.
- #enumerate(result, into:, &block) ⇒ Object
-
#exec(sql) ⇒ Object
execute one or more sql statements.
- #exec_logged(sql_or_scope, *args) ⇒ Object
- #resolve_type(ftype, fmod) ⇒ Object
Instance Method Details
#add_page_info(scope, results) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/simple/sql/connection_adapter.rb', line 63 def add_page_info(scope, results) raise ArgumentError, "expect Array but get a #{results.class.name}" unless results.is_a?(Array) raise ArgumentError, "per must be > 0" unless scope.per > 0 # optimization: add empty case (page <= 1 && results.empty?) if scope.page <= 1 && results.empty? Scope::PageInfo.attach(results, total_count: 0, per: scope.per, page: scope.page) else sql = "SELECT COUNT(*) FROM (#{scope.to_sql(pagination: false)}) simple_sql_count" total_count = ask(sql, *scope.args) Scope::PageInfo.attach(results, total_count: total_count, per: scope.per, page: scope.page) end end |
#all(sql, *args, into: nil, &block) ⇒ Object
Runs a query, with optional arguments, and returns the result. If the SQL query returns rows with one column, this method returns an array of these values. Otherwise it returns an array of arrays.
Example:
-
Simple::SQL.all("SELECT id FROM users")returns an array of id values -
Simple::SQL.all("SELECT id, email FROM users")returns an array ofarrays `[ <id>, <email> ]`.
Simple::SQL.all “SELECT id, email FROM users” do |id, email|
# do something
end
39 40 41 42 43 44 45 46 |
# File 'lib/simple/sql/connection_adapter.rb', line 39 def all(sql, *args, into: nil, &block) result = exec_logged(sql, *args) result = enumerate(result, into: into, &block) if sql.is_a?(Scope) && sql.paginated? add_page_info(sql, result) end result end |
#ask(sql, *args, into: nil) ⇒ Object
Runs a query and returns the first result row of a query.
Examples:
-
Simple::SQL.ask "SELECT id FROM users WHERE email=$?", "foo@local"returns a number (ornil) -
Simple::SQL.ask "SELECT id, email FROM users WHERE email=$?", "foo@local"returns an array[ <id>, <email> ](ornil)
56 57 58 59 60 61 |
# File 'lib/simple/sql/connection_adapter.rb', line 56 def ask(sql, *args, into: nil) catch(:ok) do all(sql, *args, into: into) { |row| throw :ok, row } nil end end |
#enumerate(result, into:, &block) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/simple/sql/connection_adapter.rb', line 92 def enumerate(result, into:, &block) decoder = Decoder.new(self, result, into: into) if block result.each_row do |row| yield decoder.decode(row) end self else ary = [] result.each_row { |row| ary << decoder.decode(row) } ary end end |
#exec(sql) ⇒ Object
execute one or more sql statements. This method does not allow to pass in arguments - since the pg client does not support this - but it allows to run multiple sql statements separated by “;”
19 20 21 22 23 |
# File 'lib/simple/sql/connection_adapter.rb', line 19 def exec(sql) Logging.yield_logged sql do raw_connection.exec sql end end |
#exec_logged(sql_or_scope, *args) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/simple/sql/connection_adapter.rb', line 77 def exec_logged(sql_or_scope, *args) if sql_or_scope.is_a?(Scope) raise ArgumentError, "You cannot call .all with a scope and additional arguments" unless args.empty? sql = sql_or_scope.to_sql args = sql_or_scope.args else sql = sql_or_scope end Logging.yield_logged sql, *args do raw_connection.exec_params(sql, Encoder.encode_args(raw_connection, args)) end end |
#resolve_type(ftype, fmod) ⇒ Object
107 108 109 110 |
# File 'lib/simple/sql/connection_adapter.rb', line 107 def resolve_type(ftype, fmod) @resolved_types ||= {} @resolved_types[[ftype, fmod]] ||= raw_connection.exec("SELECT format_type($1,$2)", [ftype, fmod]).getvalue(0, 0) end |