mini_sql 0.1.5 → 0.1.6

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
  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