simple-sql 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ebc8a4a49401550f8549ea98b802f8eb523d9ef4
4
- data.tar.gz: d8f4339ec84a7dc8fb03088db8f38ee802072a42
3
+ metadata.gz: c2aa68ab4036da8b4bc0eae03f6e4245bd4e8620
4
+ data.tar.gz: 02eef57ff0d00d3a1d35ef861d1efc88976c1e74
5
5
  SHA512:
6
- metadata.gz: 67886aafa505ee2ffe6146742a671b5cae23f4a38641fd536e24821383a30a852221e104b512041aadfd01e867c3def28654603a9b2ac19aa591ef7d3867119c
7
- data.tar.gz: c858be8d0075d5b0bf448313ec1ce47ef6167d1206cc684cfc8dcea61569ad04cbe8a43eef7de5efc19e2d6382a952673fff85d90065f7812786b1e70c0776d5
6
+ metadata.gz: 1262f806ebf0db280660ead752521fd3890f9c9472a8ba62f21ab87aa263c369319dab4a300035dabe8288997b68fa1e250c202ba5021b33af438c536c46d63f
7
+ data.tar.gz: 895728b860f7861b0a7e8f46507abcbe07b70d03ec36520893c507d3939c4848e838f7b0d0804467409daa611485003c66e180c4634b1d0443ace09e3d31798c
@@ -10,7 +10,7 @@ AllCops:
10
10
  - 'Rakefile'
11
11
 
12
12
  Metrics/LineLength:
13
- Max: 115
13
+ Max: 120
14
14
 
15
15
  Style/SpecialGlobalVars:
16
16
  Enabled: false
@@ -57,3 +57,6 @@ Style/NumericPredicate:
57
57
 
58
58
  Style/RegexpLiteral:
59
59
  Enabled: false
60
+
61
+ Style/ClassVars:
62
+ Enabled: false
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- simple-sql (0.3.7)
4
+ simple-sql (0.4.0)
5
5
  pg (~> 0.20)
6
6
  pg_array_parser (~> 0)
7
7
 
@@ -6,132 +6,50 @@ require_relative "sql/decoder.rb"
6
6
  require_relative "sql/encoder.rb"
7
7
  require_relative "sql/config.rb"
8
8
  require_relative "sql/logging.rb"
9
+ require_relative "sql/simple_transactions.rb"
10
+ require_relative "sql/connection_adapter.rb"
9
11
  require_relative "sql/connection.rb"
10
12
  require_relative "sql/reflection.rb"
11
13
  require_relative "sql/insert.rb"
12
14
  require_relative "sql/duplicate.rb"
13
15
 
14
- # rubocop:disable Metrics/MethodLength
15
-
16
16
  module Simple
17
17
  # The Simple::SQL module
18
18
  module SQL
19
19
  extend self
20
-
21
- def logger
22
- @logger ||= default_logger
23
- end
24
-
25
- def logger=(logger)
26
- @logger = logger
27
- end
28
-
29
- def default_logger
30
- logger = ActiveRecord::Base.logger if defined?(ActiveRecord)
31
- return logger if logger
32
-
33
- logger = Logger.new(STDERR)
34
- logger.level = Logger::INFO
35
- logger
36
- end
37
-
38
- # execute one or more sql statements. This method does not allow to pass in
39
- # arguments - since the pg client does not support this - but it allows to
40
- # run multiple sql statements separated by ";"
41
- def exec(sql)
42
- Logging.yield_logged sql do
43
- connection.exec sql
44
- end
45
- end
46
-
47
- # Runs a query, with optional arguments, and returns the result. If the SQL
48
- # query returns rows with one column, this method returns an array of these
49
- # values. Otherwise it returns an array of arrays.
50
- #
51
- # Example:
52
- #
53
- # - <tt>Simple::SQL.all("SELECT id FROM users")</tt> returns an array of id values
54
- # - <tt>Simple::SQL.all("SELECT id, email FROM users")</tt> returns an array of
55
- # arrays `[ <id>, <email> ]`.
56
- #
57
- # Simple::SQL.all "SELECT id, email FROM users" do |id, email|
58
- # # do something
59
- # end
60
-
61
- def all(sql, *args, into: nil, &block)
62
- result = exec_logged(sql, *args)
63
- enumerate(result, into: into, &block)
64
- end
65
-
66
- # Runs a query and returns the first result row of a query.
67
- #
68
- # Examples:
69
- #
70
- # - <tt>Simple::SQL.ask "SELECT id FROM users WHERE email=$?", "foo@local"</tt>
71
- # returns a number (or +nil+)
72
- # - <tt>Simple::SQL.ask "SELECT id, email FROM users WHERE email=$?", "foo@local"</tt>
73
- # returns an array <tt>[ <id>, <email> ]</tt> (or +nil+)
74
- def ask(sql, *args, into: nil)
75
- catch(:ok) do
76
- all(sql, *args, into: into) { |row| throw :ok, row }
77
- nil
78
- end
79
- end
80
-
81
- # [Deprecated] Runs a query, with optional arguments, and returns the
82
- # result as an array of Hashes.
83
- def records(sql, *args, into: Hash, &block)
84
- all sql, *args, into: (into || Hash), &block
85
- end
86
-
87
- # [Deprecated] Runs a query and returns the first result row of a query
88
- # as a Hash.
89
- def record(sql, *args, into: Hash)
90
- ask sql, *args, into: (into || Hash)
91
- end
92
-
93
20
  extend Forwardable
21
+ delegate [:ask, :all, :each] => :connection
94
22
  delegate [:transaction, :wait_for_notify] => :connection
95
23
 
96
- private
24
+ delegate [:logger, :logger=] => ::Simple::SQL::Logging
97
25
 
98
- def exec_logged(sql, *args)
99
- Logging.yield_logged sql, *args do
100
- connection.exec_params(sql, Encoder.encode_args(args))
101
- end
102
- end
103
-
104
- def enumerate(result, into:, &block)
105
- decoder = Decoder.new(result, into: into)
106
-
107
- if block
108
- result.each_row do |row|
109
- yield decoder.decode(row)
110
- end
111
- self
112
- else
113
- ary = []
114
- result.each_row { |row| ary << decoder.decode(row) }
115
- ary
116
- end
117
- end
118
-
119
- def resolve_type(ftype, fmod)
120
- @resolved_types ||= {}
121
- @resolved_types[[ftype, fmod]] ||= connection.exec("SELECT format_type($1,$2)", [ftype, fmod]).getvalue(0, 0)
122
- end
26
+ private
123
27
 
124
28
  def connection
125
- @connector.call
29
+ connector.call
126
30
  end
127
31
 
32
+ # The connector attribute returns a lambda, which, when called, returns a connection
33
+ # object.
34
+ #
35
+ # If this seems weird: this is for interacting with ActiveRecord. To be in sync how
36
+ # Rails handles ActiveRecord connections (it checks it out of a connection pool when
37
+ # needed for the first time in a request cycle, and checks it in afterwards) we need
38
+ # to make sure not to keep a reference to the actual connection object around. Instead
39
+ # we need to be able to call a function (in that case ActiveRecord::Base.connection).
40
+ #
41
+ # In non-Rails mode the connector really is a lambda which just returns an object.
42
+ #
43
+ # In any case the connector is stored in a thread-safe fashion. This is not necessary
44
+ # in Rails mode (because AR::B.connection itself is thread-safe already), but in non-
45
+ # Rails-mode we make sure to manage one connection per thread.
128
46
  def connector=(connector)
129
- @connector = connector
47
+ Thread.current[:"Simple::SQL.connector"] = connector
130
48
  end
131
49
 
132
- self.connector = lambda {
133
- connect_to_active_record
134
- }
50
+ def connector
51
+ Thread.current[:"Simple::SQL.connector"] ||= lambda { connect_to_active_record }
52
+ end
135
53
 
136
54
  def connect_to_active_record
137
55
  return Connection.active_record_connection if defined?(ActiveRecord)
@@ -161,12 +79,17 @@ module Simple
161
79
  def connect!(database_url = :auto)
162
80
  database_url = Config.determine_url if database_url == :auto
163
81
 
164
- logger.info "Connecting to #{database_url}"
82
+ Logging.info "Connecting to #{database_url}"
165
83
  config = Config.parse_url(database_url)
166
84
 
167
85
  require "pg"
168
86
  connection = Connection.pg_connection(PG::Connection.new(config))
169
87
  self.connector = lambda { connection }
170
88
  end
89
+
90
+ # disconnects the current connection.
91
+ def disconnect!
92
+ self.connector = nil
93
+ end
171
94
  end
172
95
  end
@@ -1,6 +1,3 @@
1
- # rubocop:disable Metrics/MethodLength
2
- # rubocop:disable Style/IfUnlessModifier
3
-
4
1
  # private
5
2
  module Simple::SQL::Connection
6
3
  def self.active_record_connection
@@ -11,60 +8,34 @@ module Simple::SQL::Connection
11
8
  PgConnection.new(connection)
12
9
  end
13
10
 
11
+ # A PgConnection object is built around a raw connection. It includes
12
+ # the ConnectionAdapter, which implements ask, all, + friends, and also
13
+ # includes a quiet simplistic Transaction implementation
14
14
  class PgConnection
15
- extend Forwardable
16
- delegate %w(exec_params exec escape wait_for_notify) => :@raw_connection
15
+ attr_reader :raw_connection
17
16
 
18
17
  def initialize(raw_connection)
19
18
  @raw_connection = raw_connection
20
- @tx_nesting_level = 0
21
19
  end
22
20
 
23
- private
24
-
25
- def transaction(&_block)
26
- # Notes: by using "ensure" (as opposed to rescue) we are rolling back
27
- # both when an exception was raised and when a value was thrown. This
28
- # also means we have to track whether or not to rollback. i.e. do roll
29
- # back when we yielded to &block but not otherwise.
30
- #
31
- # Also the transaction support is a bit limited: you cannot rollback.
32
- # Rolling back from inside a nested transaction would require SAVEPOINT
33
- # support; without the code is simpler at least :)
34
-
35
- if @tx_nesting_level == 0
36
- exec "BEGIN"
37
- tx_started = true
38
- end
39
-
40
- @tx_nesting_level += 1
21
+ include ::Simple::SQL::ConnectionAdapter # all, ask, first, etc.
22
+ include ::Simple::SQL::SimpleTransactions # transactions
41
23
 
42
- return_value = yield
43
-
44
- # Only commit if we started a transaction here.
45
- if tx_started
46
- exec "COMMIT"
47
- tx_committed = true
48
- end
49
-
50
- return_value
51
- ensure
52
- @tx_nesting_level -= 1
53
- if tx_started && !tx_committed
54
- exec "ROLLBACK"
55
- end
56
- end
24
+ extend Forwardable
25
+ delegate [:wait_for_notify] => :raw_connection # wait_for_notify
57
26
  end
58
27
 
59
28
  module ActiveRecordConnection
60
29
  extend self
61
30
 
31
+ extend ::Simple::SQL::ConnectionAdapter # all, ask, first, etc.
32
+
62
33
  extend Forwardable
63
- delegate %w(exec_params exec escape wait_for_notify) => :raw_connection
64
- delegate [:transaction] => :connection
34
+ delegate [:transaction] => :connection # transactions
35
+ delegate [:wait_for_notify] => :connection # wait_for_notify
65
36
 
66
37
  def raw_connection
67
- connection.raw_connection
38
+ ActiveRecord::Base.connection.raw_connection
68
39
  end
69
40
 
70
41
  def connection
@@ -0,0 +1,81 @@
1
+ # rubocop:disable Metrics/MethodLength
2
+
3
+ # This module implements an adapter between the Simple::SQL interface
4
+ # (i.e. ask, all, first, transaction) and a raw connection.
5
+ #
6
+ # This module can be mixed onto objects that implement a raw_connection
7
+ # method, which must return a Pg::Connection.
8
+ module Simple::SQL::ConnectionAdapter
9
+ Logging = Simple::SQL::Logging
10
+ Encoder = Simple::SQL::Encoder
11
+ Decoder = Simple::SQL::Decoder
12
+
13
+ # execute one or more sql statements. This method does not allow to pass in
14
+ # arguments - since the pg client does not support this - but it allows to
15
+ # run multiple sql statements separated by ";"
16
+ def exec(sql)
17
+ Logging.yield_logged sql do
18
+ raw_connection.exec sql
19
+ end
20
+ end
21
+
22
+ # Runs a query, with optional arguments, and returns the result. If the SQL
23
+ # query returns rows with one column, this method returns an array of these
24
+ # values. Otherwise it returns an array of arrays.
25
+ #
26
+ # Example:
27
+ #
28
+ # - <tt>Simple::SQL.all("SELECT id FROM users")</tt> returns an array of id values
29
+ # - <tt>Simple::SQL.all("SELECT id, email FROM users")</tt> returns an array of
30
+ # arrays `[ <id>, <email> ]`.
31
+ #
32
+ # Simple::SQL.all "SELECT id, email FROM users" do |id, email|
33
+ # # do something
34
+ # end
35
+
36
+ def all(sql, *args, into: nil, &block)
37
+ result = exec_logged(sql, *args)
38
+ enumerate(result, into: into, &block)
39
+ end
40
+
41
+ # Runs a query and returns the first result row of a query.
42
+ #
43
+ # Examples:
44
+ #
45
+ # - <tt>Simple::SQL.ask "SELECT id FROM users WHERE email=$?", "foo@local"</tt>
46
+ # returns a number (or +nil+)
47
+ # - <tt>Simple::SQL.ask "SELECT id, email FROM users WHERE email=$?", "foo@local"</tt>
48
+ # returns an array <tt>[ <id>, <email> ]</tt> (or +nil+)
49
+ def ask(sql, *args, into: nil)
50
+ catch(:ok) do
51
+ all(sql, *args, into: into) { |row| throw :ok, row }
52
+ nil
53
+ end
54
+ end
55
+
56
+ def exec_logged(sql, *args)
57
+ Logging.yield_logged sql, *args do
58
+ raw_connection.exec_params(sql, Encoder.encode_args(raw_connection, args))
59
+ end
60
+ end
61
+
62
+ def enumerate(result, into:, &block)
63
+ decoder = Decoder.new(self, result, into: into)
64
+
65
+ if block
66
+ result.each_row do |row|
67
+ yield decoder.decode(row)
68
+ end
69
+ self
70
+ else
71
+ ary = []
72
+ result.each_row { |row| ary << decoder.decode(row) }
73
+ ary
74
+ end
75
+ end
76
+
77
+ def resolve_type(ftype, fmod)
78
+ @resolved_types ||= {}
79
+ @resolved_types[[ftype, fmod]] ||= raw_connection.exec("SELECT format_type($1,$2)", [ftype, fmod]).getvalue(0, 0)
80
+ end
81
+ end
@@ -4,12 +4,12 @@ require "time"
4
4
  module Simple::SQL::Decoder
5
5
  extend self
6
6
 
7
- def new(result, into:)
8
- if into == Hash then HashRecord.new(result)
9
- elsif into == :struct then StructRecord.new(result)
10
- elsif into then Record.new(result, into: into)
11
- elsif result.nfields == 1 then SingleColumn.new(result)
12
- else MultiColumns.new(result)
7
+ def new(connection, result, into:)
8
+ if into == Hash then HashRecord.new(connection, result)
9
+ elsif into == :struct then StructRecord.new(connection, result)
10
+ elsif into then Record.new(connection, result, into: into)
11
+ elsif result.nfields == 1 then SingleColumn.new(connection, result)
12
+ else MultiColumns.new(connection, result)
13
13
  end
14
14
  end
15
15
 
@@ -82,8 +82,8 @@ module Simple::SQL::Decoder
82
82
  end
83
83
 
84
84
  class Simple::SQL::Decoder::SingleColumn
85
- def initialize(result)
86
- typename = ::Simple::SQL.send(:resolve_type, result.ftype(0), result.fmod(0))
85
+ def initialize(connection, result)
86
+ typename = connection.resolve_type(result.ftype(0), result.fmod(0))
87
87
  @field_type = typename.to_sym
88
88
  end
89
89
 
@@ -94,9 +94,9 @@ class Simple::SQL::Decoder::SingleColumn
94
94
  end
95
95
 
96
96
  class Simple::SQL::Decoder::MultiColumns
97
- def initialize(result)
97
+ def initialize(connection, result)
98
98
  @field_types = 0.upto(result.fields.length - 1).map do |idx|
99
- typename = ::Simple::SQL.send(:resolve_type, result.ftype(idx), result.fmod(idx))
99
+ typename = connection.resolve_type(result.ftype(idx), result.fmod(idx))
100
100
  typename.to_sym
101
101
  end
102
102
  end
@@ -109,8 +109,8 @@ class Simple::SQL::Decoder::MultiColumns
109
109
  end
110
110
 
111
111
  class Simple::SQL::Decoder::HashRecord < Simple::SQL::Decoder::MultiColumns
112
- def initialize(result)
113
- super(result)
112
+ def initialize(connection, result)
113
+ super(connection, result)
114
114
  @field_names = result.fields.map(&:to_sym)
115
115
  end
116
116
 
@@ -121,8 +121,8 @@ class Simple::SQL::Decoder::HashRecord < Simple::SQL::Decoder::MultiColumns
121
121
  end
122
122
 
123
123
  class Simple::SQL::Decoder::Record < Simple::SQL::Decoder::HashRecord
124
- def initialize(result, into:)
125
- super(result)
124
+ def initialize(connection, result, into:)
125
+ super(connection, result)
126
126
  @into = into
127
127
  end
128
128
 
@@ -134,8 +134,8 @@ end
134
134
  class Simple::SQL::Decoder::StructRecord < Simple::SQL::Decoder::MultiColumns
135
135
  @@struct_cache = {}
136
136
 
137
- def initialize(result)
138
- super(result)
137
+ def initialize(connection, result)
138
+ super(connection, result)
139
139
 
140
140
  field_names = result.fields.map(&:to_sym)
141
141
  @into = @@struct_cache[field_names] ||= Struct.new(*field_names)
@@ -1,15 +1,12 @@
1
1
  # private
2
2
  module Simple::SQL::Encoder
3
3
  extend self
4
- extend Forwardable
5
4
 
6
- delegate connection: ::Simple::SQL
7
-
8
- def encode_args(args)
9
- args.map { |arg| encode_arg(arg) }
5
+ def encode_args(connection, args)
6
+ args.map { |arg| encode_arg(connection, arg) }
10
7
  end
11
8
 
12
- def encode_arg(arg)
9
+ def encode_arg(connection, arg)
13
10
  return arg unless arg.is_a?(Array)
14
11
 
15
12
  if arg.first.is_a?(String)
@@ -1,4 +1,3 @@
1
- # rubocop:disable Style/ClassVars
2
1
  # rubocop:disable Metrics/AbcSize
3
2
  # rubocop:disable Metrics/LineLength
4
3
  module Simple
@@ -1,20 +1,52 @@
1
- # rubocop:disable Metrics/AbcSize
2
- # rubocop:disable Metrics/LineLength
3
-
4
1
  module Simple
5
2
  module SQL
6
3
  module Logging
7
4
  extend self
8
5
 
6
+ # The logger object.
7
+ #
8
+ # If no logger was set via <tt>Simple::SQL::Logging.logger = <foo></tt>
9
+ # this returns a default logger.
10
+ def logger
11
+ @logger ||= default_logger
12
+ end
13
+
14
+ # The logger object.
15
+ def logger=(logger)
16
+ @logger = logger
17
+ end
18
+
19
+ private
20
+
21
+ def default_logger
22
+ # return the ActiveRecord logger, if it exists.
23
+ if defined?(ActiveRecord)
24
+ logger = ActiveRecord::Base.logger
25
+ return logger if logger
26
+ end
27
+
28
+ # returns a stderr_logger
29
+ @stderr_logger ||= begin
30
+ logger = Logger.new(STDERR)
31
+ logger.level = Logger::INFO
32
+ logger
33
+ end
34
+ end
35
+
36
+ public
37
+
38
+ extend Forwardable
39
+ delegate [:debug, :info, :warn, :error, :fatal] => :logger
40
+
9
41
  def yield_logged(sql, *args, &_block)
10
42
  r0 = Time.now
11
43
  rv = yield
12
44
  realtime = Time.now - r0
13
- ::Simple::SQL.logger.debug "[sql] %.3f secs: %s" % [realtime, format_query(sql, *args)]
45
+ debug "[sql] %.3f secs: %s" % [realtime, format_query(sql, *args)]
14
46
  rv
15
47
  rescue StandardError => e
16
48
  realtime = Time.now - r0
17
- ::Simple::SQL.logger.warn "[sql] %.3f secs: %s:\n\tfailed with error %s" % [realtime, format_query(sql, *args), e.message]
49
+ warn "[sql] %.3f secs: %s:\n\tfailed with error %s" % [realtime, format_query(sql, *args), e.message]
18
50
  raise
19
51
  end
20
52
 
@@ -47,7 +47,7 @@ module Simple
47
47
  "table_schema || '.' || table_name AS name, *"
48
48
  end
49
49
 
50
- recs = records <<~SQL, schema
50
+ recs = all <<~SQL, schema, into: Hash
51
51
  SELECT #{columns}
52
52
  FROM information_schema.tables
53
53
  WHERE table_schema=$1
@@ -57,7 +57,7 @@ module Simple
57
57
 
58
58
  def column_info(table_name)
59
59
  schema, table_name = parse_table_name(table_name)
60
- recs = records <<~SQL, schema, table_name
60
+ recs = all <<~SQL, schema, table_name, into: Hash
61
61
  SELECT
62
62
  column_name AS name,
63
63
  *
@@ -0,0 +1,46 @@
1
+ # rubocop:disable Metrics/MethodLength
2
+ # rubocop:disable Style/IfUnlessModifier
3
+
4
+ # private
5
+ module Simple::SQL::SimpleTransactions
6
+ def tx_nesting_level
7
+ @tx_nesting_level ||= 0
8
+ end
9
+
10
+ def tx_nesting_level=(tx_nesting_level)
11
+ @tx_nesting_level = tx_nesting_level
12
+ end
13
+
14
+ def transaction(&_block)
15
+ # Notes: by using "ensure" (as opposed to rescue) we are rolling back
16
+ # both when an exception was raised and when a value was thrown. This
17
+ # also means we have to track whether or not to rollback. i.e. do roll
18
+ # back when we yielded to &block but not otherwise.
19
+ #
20
+ # Also the transaction support is a bit limited: you cannot rollback.
21
+ # Rolling back from inside a nested transaction would require SAVEPOINT
22
+ # support; without the code is simpler at least :)
23
+
24
+ if tx_nesting_level == 0
25
+ exec "BEGIN"
26
+ tx_started = true
27
+ end
28
+
29
+ self.tx_nesting_level += 1
30
+
31
+ return_value = yield
32
+
33
+ # Only commit if we started a transaction here.
34
+ if tx_started
35
+ exec "COMMIT"
36
+ tx_committed = true
37
+ end
38
+
39
+ return_value
40
+ ensure
41
+ self.tx_nesting_level -= 1
42
+ if tx_started && !tx_committed
43
+ exec "ROLLBACK"
44
+ end
45
+ end
46
+ end
@@ -1,5 +1,5 @@
1
1
  module Simple
2
2
  module SQL
3
- VERSION = "0.3.7"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ watchr lib,spec rspec
@@ -11,7 +11,7 @@ describe "Simple::SQL.insert" do
11
11
  expect(initial_ids).not_to include(id)
12
12
  expect(SQL.ask("SELECT count(*) FROM users")).to eq(USER_COUNT+1)
13
13
 
14
- user = SQL.record("SELECT * FROM users WHERE id=$1", id, into: OpenStruct)
14
+ user = SQL.ask("SELECT * FROM users WHERE id=$1", id, into: OpenStruct)
15
15
  expect(user.first_name).to eq("foo")
16
16
  expect(user.last_name).to eq("bar")
17
17
  expect(user.created_at).to be_a(Time)
@@ -29,5 +29,5 @@ end
29
29
  def create(table)
30
30
  table_name = table.to_s.pluralize
31
31
  id = Simple::SQL.insert(table_name, attrs(table))
32
- Simple::SQL.record("SELECT * FROM #{table_name} WHERE id=$1", id, into: OpenStruct)
32
+ Simple::SQL.ask("SELECT * FROM #{table_name} WHERE id=$1", id, into: OpenStruct)
33
33
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple-sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - radiospiel
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-04-04 00:00:00.000000000 Z
12
+ date: 2018-04-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pg_array_parser
@@ -170,14 +170,17 @@ files:
170
170
  - lib/simple/sql.rb
171
171
  - lib/simple/sql/config.rb
172
172
  - lib/simple/sql/connection.rb
173
+ - lib/simple/sql/connection_adapter.rb
173
174
  - lib/simple/sql/decoder.rb
174
175
  - lib/simple/sql/duplicate.rb
175
176
  - lib/simple/sql/encoder.rb
176
177
  - lib/simple/sql/insert.rb
177
178
  - lib/simple/sql/logging.rb
178
179
  - lib/simple/sql/reflection.rb
180
+ - lib/simple/sql/simple_transactions.rb
179
181
  - lib/simple/sql/version.rb
180
182
  - log/.gitkeep
183
+ - scripts/watch
181
184
  - simple-sql.gemspec
182
185
  - spec/simple/sql/version_spec.rb
183
186
  - spec/simple/sql_all_into_spec.rb
@@ -189,7 +192,6 @@ files:
189
192
  - spec/simple/sql_duplicate_spec.rb
190
193
  - spec/simple/sql_duplicate_unique_spec.rb
191
194
  - spec/simple/sql_insert_spec.rb
192
- - spec/simple/sql_record_spec.rb
193
195
  - spec/simple/sql_reflection_spec.rb
194
196
  - spec/spec_helper.rb
195
197
  - spec/support/001_database.rb
@@ -232,7 +234,6 @@ test_files:
232
234
  - spec/simple/sql_duplicate_spec.rb
233
235
  - spec/simple/sql_duplicate_unique_spec.rb
234
236
  - spec/simple/sql_insert_spec.rb
235
- - spec/simple/sql_record_spec.rb
236
237
  - spec/simple/sql_reflection_spec.rb
237
238
  - spec/spec_helper.rb
238
239
  - spec/support/001_database.rb
@@ -1,27 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Simple::SQL.record" do
4
- let!(:users) { 1.upto(USER_COUNT).map { create(:user) } }
5
-
6
- it "calls the database" do
7
- r = SQL.record("SELECT COUNT(*) AS count FROM users")
8
- expect(r).to eq({count: 2})
9
- end
10
-
11
- it "returns nil when there is no record" do
12
- r = SQL.record("SELECT * FROM users WHERE FALSE", into: OpenStruct)
13
- expect(r).to be_nil
14
- end
15
-
16
- it "supports the into: option" do
17
- r = SQL.record("SELECT COUNT(*) AS count FROM users", into: OpenStruct)
18
- expect(r).to be_a(OpenStruct)
19
- expect(r).to eq(OpenStruct.new(count: 2))
20
- end
21
-
22
- it "supports the into: option even with parameters" do
23
- r = SQL.record("SELECT $1::integer AS count FROM users", 2, into: OpenStruct)
24
- expect(r).to be_a(OpenStruct)
25
- expect(r).to eq(OpenStruct.new(count: 2))
26
- end
27
- end