mini_sql 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fc60087b4254ce21f8cbe17e3ecbfd980f93a95bbe258f9a7a4d78d7a057d7b
4
- data.tar.gz: e2f13c9b9c8f4e3f91570d405a59ba3cfc9c742dd8ecbaeebd75a3b4190fe085
3
+ metadata.gz: 5fe7bfcf37c73b216a8532cd6b17957733213610c73924e241ba36619ae4ce04
4
+ data.tar.gz: 21e2f615add1039d3cd6363ce1bdea501dc2b9bc08d17565cb8b6378a508e04e
5
5
  SHA512:
6
- metadata.gz: 41fb7cdb0ea9365a733629fb1f1c863e3153c077d03754c123249cea1da8edf5ce3e8fd19b95f5922b61cfd4742d87f1431b92b25c974b6a438fa4b449a8b915
7
- data.tar.gz: 0e0b2b47a5ed734a4d1bf3d54ce827f27df9a59c886e83913c2eb20abefa8fc88528ee25988ee69042f996a52fd54259160914fb6c56e57f44456b39e6fc361e
6
+ metadata.gz: 5c8de4d35f5d332dd53925502b3d696782a90862b47e75b28e7402b85f7735c675c64ffd6027e419328396114dd9e1d8fcd62760ceda42e58576f52727da0411
7
+ data.tar.gz: 23e73177710c4ac500bf2a6d96de4c0b9d191526c9e68cd7fcd29d39a3fd686e39a59ade520bc35f60279b3daf78bd3365b1be06b33642f42ee932946734ed98
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ Gemfile.lock
data/README.md CHANGED
@@ -27,19 +27,40 @@ conn = MiniSql::Connection.new(pg_conn)
27
27
  puts conn.exec('update table set column = 1 where id in (1,2)')
28
28
  # returns 2 if 2 rows changed
29
29
 
30
- conn.query("select 1 id, 'bob' name") do |user|
30
+ conn.query("select 1 id, 'bob' name").each do |user|
31
31
  puts user.name # bob
32
32
  puts user.id # 1
33
33
  end
34
34
 
35
- puts conn.query_single('select 1 union select 2')
35
+ p conn.query_single('select 1 union select 2')
36
36
  # [1,2]
37
37
 
38
+ p conn.query_hash('select 1 as a, 2 as b union select 3, 4')
39
+ # [{"a" => 1, "b"=> 1},{"a" => 3, "b" => 4}
40
+ ```
41
+
42
+ ## The query builder
43
+
44
+ You can use the simple query builder interface to compose queries.
45
+
46
+ ```ruby
47
+ builder = conn.build("select * from topics /*where*/ /*limit*/")
48
+
49
+ if look_for_something
50
+ builder.where("title = :title", title: 'something')
51
+ end
52
+
53
+ builder.limit(20)
54
+
55
+ builder.query.each do |t|
56
+ puts t.id
57
+ puts t.title
58
+ end
38
59
  ```
39
60
 
40
61
  ## Is it fast?
41
62
 
42
- Yes, it is very fast, see benchmarks [the bench directory](https://github.com/discourse/mini_sql/tree/master/bench)
63
+ Yes, it is very fast. See benchmarks in [the bench directory](https://github.com/discourse/mini_sql/tree/master/bench).
43
64
 
44
65
  As a rule it will outperform similar naive PG code while remaining safe.
45
66
 
@@ -47,14 +68,18 @@ As a rule it will outperform similar naive PG code while remaining safe.
47
68
  pg_conn = PG.connect(db_name: 'my_db')
48
69
 
49
70
  # this is slower, and less safe
50
- pg_conn.async_exec('select * from table') do |r|
71
+ result = pg_conn.async_exec('select * from table')
72
+ result.each do |r|
51
73
  name = r['name']
52
74
  end
75
+ # ideally you want to remember to run r.clear here
53
76
 
54
77
  # this is faster and safer
55
78
  conn = MiniSql::Connection.new(pg_conn)
56
- conn.query('select * from table') do |r|
57
- name = r.name
79
+ r = conn.query('select * from table')
80
+
81
+ r.each do |row|
82
+ name = row.name
58
83
  end
59
84
  ```
60
85
 
@@ -79,4 +104,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
79
104
 
80
105
  ## Code of Conduct
81
106
 
82
- Everyone interacting in the MiniSql project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/SamSaffron/mini_sql/blob/master/CODE_OF_CONDUCT.md).
107
+ Everyone interacting in the MiniSql project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/discourse/mini_sql/blob/master/CODE_OF_CONDUCT.md).
data/bench/topic_perf.rb CHANGED
@@ -168,7 +168,28 @@ def sequel_pluck_title_id
168
168
  s
169
169
  end
170
170
 
171
- results = [ar_title_id, ar_title_id_pluck, pg_title_id, mini_sql_title_id, sequel_pluck_title_id, sequel_select_title_id]
171
+ # usage is not really recommended but just to compare to pluck lets have it
172
+ def mini_sql_title_id_query_single
173
+ s = +""
174
+ i = 0
175
+ r = $mini_sql.query_single(-"select id, title from topics order by id limit 1000")
176
+ while i < r.length
177
+ s << r[i].to_s
178
+ s << r[i+1]
179
+ i += 2
180
+ end
181
+ s
182
+ end
183
+
184
+ results = [
185
+ ar_title_id,
186
+ ar_title_id_pluck,
187
+ pg_title_id,
188
+ mini_sql_title_id,
189
+ sequel_pluck_title_id,
190
+ sequel_select_title_id,
191
+ mini_sql_title_id_query_single
192
+ ]
172
193
 
173
194
  exit(-1) unless results.uniq.length == 1
174
195
 
@@ -241,12 +262,6 @@ Benchmark.ips do |r|
241
262
  n -= 1
242
263
  end
243
264
  end
244
- r.report("sequel title id pluck") do |n|
245
- while n > 0
246
- sequel_pluck_title_id
247
- n -= 1
248
- end
249
- end
250
265
  r.report("pg select title id") do |n|
251
266
  while n > 0
252
267
  pg_title_id
@@ -259,30 +274,58 @@ Benchmark.ips do |r|
259
274
  n -= 1
260
275
  end
261
276
  end
277
+ r.report("sequel title id pluck") do |n|
278
+ while n > 0
279
+ sequel_pluck_title_id
280
+ n -= 1
281
+ end
282
+ end
283
+ r.report("mini_sql query_single title id") do |n|
284
+ while n > 0
285
+ mini_sql_title_id_query_single
286
+ n -= 1
287
+ end
288
+ end
262
289
  r.compare!
263
290
  end
264
291
 
265
292
 
266
293
  # Calculating -------------------------------------
267
- # ar select title id 144.043 1.4%) i/s - 728.000 in 5.055454s
294
+ # wide topic ar 2.383k4.9%) i/s - 12.005k in 5.050490s
295
+ # wide topic sequel 3.449k (± 3.2%) i/s - 17.591k in 5.104951s
296
+ # wide topic pg 7.345k (± 1.2%) i/s - 37.352k in 5.086015s
297
+ # wide topic mini sql 7.536k (± 1.4%) i/s - 38.220k in 5.072834s
298
+ #
299
+ # Comparison:
300
+ # wide topic mini sql: 7535.8 i/s
301
+ # wide topic pg: 7345.1 i/s - same-ish: difference falls within error
302
+ # wide topic sequel: 3449.4 i/s - 2.18x slower
303
+ # wide topic ar: 2382.9 i/s - 3.16x slower
304
+ #
305
+ # Calculating -------------------------------------
306
+ # ar select title id 131.572 (± 3.8%) i/s - 658.000 in 5.008231s
268
307
  # ar select title id pluck
269
- # 712.8181.5%) i/s - 3.570k in 5.009412s
308
+ # 696.2333.7%) i/s - 3.519k in 5.061335s
270
309
  # sequel title id select
271
- # 927.0111.8%) i/s - 4.655k in 5.023228s
272
- # sequel title id pluck
273
- # 1.183k (± 3.2%) i/s - 5.967k in 5.048635s
274
- # pg select title id 1.040k (± 1.4%) i/s - 5.253k in 5.051679s
310
+ # 916.8413.7%) i/s - 4.655k in 5.084499s
311
+ # pg select title id 1.002k (± 4.0%) i/s - 5.044k in 5.040584s
275
312
  # mini_sql select title id
276
- # 1.139k (± 2.5%) i/s - 5.712k in 5.016383s
313
+ # 1.106k (± 2.4%) i/s - 5.618k in 5.084423s
314
+ # sequel title id pluck
315
+ # 1.181k (± 3.5%) i/s - 5.980k in 5.069815s
316
+ # mini_sql query_single title id
317
+ # 1.171k (± 3.1%) i/s - 5.880k in 5.025793s
277
318
  #
278
319
  # Comparison:
279
- # sequel title id pluck: 1183.1 i/s
280
- # mini_sql select title id: 1139.3 i/s - same-ish: difference falls within error
281
- # pg select title id: 1040.1 i/s - 1.14x slower
282
- # sequel title id select: 927.0 i/s - 1.28x slower
283
- # ar select title id pluck: 712.8 i/s - 1.66x slower
284
- # ar select title id: 144.0 i/s - 8.21x slower
320
+ # sequel title id pluck: 1181.0 i/s
321
+ # mini_sql query_single title id: 1171.1 i/s - same-ish: difference falls within error
322
+ # mini_sql select title id: 1105.6 i/s - 1.07x slower
323
+ # pg select title id: 1002.2 i/s - 1.18x slower
324
+ # sequel title id select: 916.8 i/s - 1.29x slower
325
+ # ar select title id pluck: 696.2 i/s - 1.70x slower
326
+ # ar select title id: 131.6 i/s - 8.98x slower
285
327
  #
328
+
286
329
  # to run deep analysis run
287
330
  # MemoryProfiler.report do
288
331
  # ar
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class MiniSql::Builder
2
4
 
3
5
  def initialize(connection, template)
@@ -8,9 +10,13 @@ class MiniSql::Builder
8
10
  end
9
11
 
10
12
  [:set, :where2, :where, :order_by, :limit, :left_join, :join, :offset, :select].each do |k|
11
- define_method k do |data, args = {}|
13
+ define_method k do |data, *args|
12
14
  @args ||= {}
13
- @args.merge!(args)
15
+ if Hash === args
16
+ @args.merge!(args)
17
+ elsif args && args.length > 0
18
+ data = @connection.param_encoder.encode(data, *args)
19
+ end
14
20
  @sections[k] ||= []
15
21
  @sections[k] << data
16
22
  self
@@ -24,21 +30,21 @@ class MiniSql::Builder
24
30
  joined = nil
25
31
  case k
26
32
  when :select
27
- joined = "SELECT " << v.join(" , ")
33
+ joined = (+"SELECT ") << v.join(" , ")
28
34
  when :where, :where2
29
- joined = "WHERE " << v.map { |c| "(" << c << ")" }.join(" AND ")
35
+ joined = (+"WHERE ") << v.map { |c| (+"(") << c << ")" }.join(" AND ")
30
36
  when :join
31
- joined = v.map { |item| "JOIN " << item }.join("\n")
37
+ joined = v.map { |item| (+"JOIN ") << item }.join("\n")
32
38
  when :left_join
33
- joined = v.map { |item| "LEFT JOIN " << item }.join("\n")
39
+ joined = v.map { |item| (+"LEFT JOIN ") << item }.join("\n")
34
40
  when :limit
35
- joined = "LIMIT " << v.last.to_s
41
+ joined = (+"LIMIT ") << v.last.to_i.to_s
36
42
  when :offset
37
- joined = "OFFSET " << v.last.to_s
43
+ joined = (+"OFFSET ") << v.last.to_i.to_s
38
44
  when :order_by
39
- joined = "ORDER BY " << v.join(" , ")
45
+ joined = (+"ORDER BY ") << v.join(" , ")
40
46
  when :set
41
- joined = "SET " << v.join(" , ")
47
+ joined = (+"SET ") << v.join(" , ")
42
48
  end
43
49
 
44
50
  sql.sub!("/*#{k}*/", joined)
@@ -46,20 +52,13 @@ class MiniSql::Builder
46
52
  sql
47
53
  end
48
54
 
49
- def query(args = nil)
50
- if args
51
- @args.merge!(args)
52
- end
53
- sql = to_sql
54
- @connection.query(sql, @args)
55
- end
56
-
57
- def exec(args = nil)
58
- if args
59
- @args.merge!(args)
60
- end
61
- sql = to_sql
62
- @connection.exec(sql, @args)
55
+ [:query, :query_single, :query_hash, :exec].each do |m|
56
+ class_eval <<~RUBY
57
+ def #{m}(hash_args = nil)
58
+ hash_args = @args.merge(hash_args) if hash_args
59
+ @connection.#{m}(to_sql, hash_args || @args)
60
+ end
61
+ RUBY
63
62
  end
64
63
 
65
64
  end
@@ -2,8 +2,7 @@
2
2
 
3
3
  module MiniSql
4
4
  class Connection
5
- attr_reader :raw_connection
6
- attr_reader :type_map
5
+ attr_reader :raw_connection, :type_map, :param_encoder
7
6
 
8
7
  def self.default_deserializer_cache
9
8
  @deserializer_cache ||= DeserializerCache.new
@@ -100,7 +99,7 @@ module MiniSql
100
99
 
101
100
  def run(sql, params)
102
101
  if params && params.length > 0
103
- sql = @param_encoder.encode(sql, *params)
102
+ sql = param_encoder.encode(sql, *params)
104
103
  end
105
104
  raw_connection.async_exec(sql)
106
105
  end
@@ -1,3 +1,3 @@
1
1
  module MiniSql
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-19 00:00:00.000000000 Z
11
+ date: 2018-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -119,7 +119,6 @@ files:
119
119
  - ".travis.yml"
120
120
  - CODE_OF_CONDUCT.md
121
121
  - Gemfile
122
- - Gemfile.lock
123
122
  - Guardfile
124
123
  - LICENSE.txt
125
124
  - README.md
data/Gemfile.lock DELETED
@@ -1,73 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- mini_sql (0.1.5)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activesupport (5.2.0)
10
- concurrent-ruby (~> 1.0, >= 1.0.2)
11
- i18n (>= 0.7, < 2)
12
- minitest (~> 5.1)
13
- tzinfo (~> 1.1)
14
- coderay (1.1.2)
15
- concurrent-ruby (1.0.5)
16
- ffi (1.9.25)
17
- formatador (0.2.5)
18
- guard (2.14.2)
19
- formatador (>= 0.2.4)
20
- listen (>= 2.7, < 4.0)
21
- lumberjack (>= 1.0.12, < 2.0)
22
- nenv (~> 0.1)
23
- notiffany (~> 0.0)
24
- pry (>= 0.9.12)
25
- shellany (~> 0.0)
26
- thor (>= 0.18.1)
27
- guard-compat (1.2.1)
28
- guard-minitest (2.4.6)
29
- guard-compat (~> 1.2)
30
- minitest (>= 3.0)
31
- i18n (1.0.1)
32
- concurrent-ruby (~> 1.0)
33
- listen (3.1.5)
34
- rb-fsevent (~> 0.9, >= 0.9.4)
35
- rb-inotify (~> 0.9, >= 0.9.7)
36
- ruby_dep (~> 1.2)
37
- lumberjack (1.0.13)
38
- method_source (0.9.0)
39
- minitest (5.11.3)
40
- nenv (0.3.0)
41
- notiffany (0.1.1)
42
- nenv (~> 0.1)
43
- shellany (~> 0.0)
44
- pg (1.0.0)
45
- pry (0.11.3)
46
- coderay (~> 1.1.0)
47
- method_source (~> 0.9.0)
48
- rake (10.5.0)
49
- rb-fsevent (0.10.3)
50
- rb-inotify (0.9.10)
51
- ffi (>= 0.5.0, < 2)
52
- ruby_dep (1.5.0)
53
- shellany (0.0.1)
54
- thor (0.20.0)
55
- thread_safe (0.3.6)
56
- tzinfo (1.2.5)
57
- thread_safe (~> 0.1)
58
-
59
- PLATFORMS
60
- ruby
61
-
62
- DEPENDENCIES
63
- activesupport (~> 5.2)
64
- bundler (~> 1.16)
65
- guard (~> 2.14)
66
- guard-minitest (~> 2.4)
67
- mini_sql!
68
- minitest (~> 5.0)
69
- pg (~> 1.0.0)
70
- rake (~> 10.0)
71
-
72
- BUNDLED WITH
73
- 1.16.2