mini_sql 0.3 → 1.1.2

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +66 -0
  3. data/.rubocop.yml +5 -2
  4. data/CHANGELOG +22 -0
  5. data/README.md +36 -0
  6. data/bench/builder_perf.rb +138 -0
  7. data/bench/decorator_perf.rb +143 -0
  8. data/bench/mini_sql_methods_perf.rb +80 -0
  9. data/bench/prepared_perf.rb +59 -0
  10. data/bench/shared/generate_data.rb +133 -0
  11. data/bench/topic_perf.rb +21 -327
  12. data/bench/topic_wide_perf.rb +92 -0
  13. data/lib/mini_sql.rb +20 -8
  14. data/lib/mini_sql/abstract/prepared_binds.rb +74 -0
  15. data/lib/mini_sql/abstract/prepared_cache.rb +45 -0
  16. data/lib/mini_sql/builder.rb +66 -23
  17. data/lib/mini_sql/decoratable.rb +22 -0
  18. data/lib/mini_sql/inline_param_encoder.rb +4 -5
  19. data/lib/mini_sql/mysql/connection.rb +8 -0
  20. data/lib/mini_sql/mysql/deserializer_cache.rb +9 -15
  21. data/lib/mini_sql/mysql/prepared_binds.rb +15 -0
  22. data/lib/mini_sql/mysql/prepared_cache.rb +21 -0
  23. data/lib/mini_sql/mysql/prepared_connection.rb +44 -0
  24. data/lib/mini_sql/postgres/connection.rb +10 -2
  25. data/lib/mini_sql/postgres/deserializer_cache.rb +11 -17
  26. data/lib/mini_sql/postgres/prepared_binds.rb +15 -0
  27. data/lib/mini_sql/postgres/prepared_cache.rb +25 -0
  28. data/lib/mini_sql/postgres/prepared_connection.rb +36 -0
  29. data/lib/mini_sql/postgres_jdbc/connection.rb +3 -1
  30. data/lib/mini_sql/postgres_jdbc/deserializer_cache.rb +10 -14
  31. data/lib/mini_sql/result.rb +30 -0
  32. data/lib/mini_sql/serializer.rb +84 -0
  33. data/lib/mini_sql/sqlite/connection.rb +11 -1
  34. data/lib/mini_sql/sqlite/deserializer_cache.rb +9 -15
  35. data/lib/mini_sql/sqlite/prepared_binds.rb +15 -0
  36. data/lib/mini_sql/sqlite/prepared_cache.rb +21 -0
  37. data/lib/mini_sql/sqlite/prepared_connection.rb +40 -0
  38. data/lib/mini_sql/version.rb +1 -1
  39. data/mini_sql.gemspec +5 -4
  40. metadata +42 -8
  41. data/.travis.yml +0 -28
@@ -11,6 +11,14 @@ module MiniSql
11
11
  @deserializer_cache = (args && args[:deserializer_cache]) || DeserializerCache.new
12
12
  end
13
13
 
14
+ def prepared(condition = true)
15
+ if condition
16
+ @prepared ||= PreparedConnection.new(self, @deserializer_cache)
17
+ else
18
+ self
19
+ end
20
+ end
21
+
14
22
  def query_single(sql, *params)
15
23
  # a bit lazy can be optimized
16
24
  run(sql, *params).flatten!
@@ -68,7 +76,9 @@ module MiniSql
68
76
  end
69
77
  if block_given?
70
78
  stmt = SQLite3::Statement.new(raw_connection, sql)
71
- yield stmt.execute
79
+ result = yield stmt.execute
80
+ stmt.close
81
+ result
72
82
  else
73
83
  raw_connection.execute(sql)
74
84
  end
@@ -13,18 +13,20 @@ module MiniSql
13
13
 
14
14
  def materialize(result, decorator_module = nil)
15
15
 
16
- key = result.columns
16
+ key = result.columns.join(',')
17
17
 
18
18
  # trivial fast LRU implementation
19
19
  materializer = @cache.delete(key)
20
20
  if materializer
21
21
  @cache[key] = materializer
22
22
  else
23
- materializer = @cache[key] = new_row_matrializer(result)
23
+ materializer = @cache[key] = new_row_materializer(result)
24
24
  @cache.shift if @cache.length > @max_size
25
25
  end
26
26
 
27
- materializer.include(decorator_module) if decorator_module
27
+ if decorator_module
28
+ materializer = materializer.decorated(decorator_module)
29
+ end
28
30
 
29
31
  r = []
30
32
  # quicker loop
@@ -39,22 +41,14 @@ module MiniSql
39
41
 
40
42
  private
41
43
 
42
- def new_row_matrializer(result)
44
+ def new_row_materializer(result)
43
45
  fields = result.columns
44
46
 
45
47
  Class.new do
46
- attr_accessor(*fields)
47
-
48
- # AM serializer support
49
- alias :read_attribute_for_serialization :send
48
+ extend MiniSql::Decoratable
49
+ include MiniSql::Result
50
50
 
51
- def to_h
52
- r = {}
53
- instance_variables.each do |f|
54
- r[f.to_s.sub('@', '').to_sym] = instance_variable_get(f)
55
- end
56
- r
57
- end
51
+ attr_accessor(*fields)
58
52
 
59
53
  instance_eval <<~RUBY
60
54
  def materialize(data)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mini_sql/abstract/prepared_binds"
4
+
5
+ module MiniSql
6
+ module Sqlite
7
+ class PreparedBinds < ::MiniSql::Abstract::PreparedBinds
8
+
9
+ def bind_output(i)
10
+ '?'
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mini_sql/abstract/prepared_cache"
4
+
5
+ module MiniSql
6
+ module Sqlite
7
+ class PreparedCache < MiniSql::Abstract::PreparedCache
8
+
9
+ private
10
+
11
+ def alloc(sql)
12
+ @connection.prepare(sql)
13
+ end
14
+
15
+ def dealloc(statement)
16
+ statement.close unless statement.closed?
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MiniSql
4
+ module Sqlite
5
+ class PreparedConnection < Connection
6
+
7
+ attr_reader :unprepared
8
+
9
+ def initialize(unprepared_connection, deserializer_cache)
10
+ @unprepared = unprepared_connection
11
+ @raw_connection = unprepared_connection.raw_connection
12
+ @deserializer_cache = deserializer_cache
13
+ @param_encoder = unprepared_connection.param_encoder
14
+
15
+ @prepared_cache = PreparedCache.new(@raw_connection)
16
+ @param_binder = PreparedBinds.new
17
+ end
18
+
19
+ def build(_)
20
+ raise 'Builder can not be called on prepared connections, instead of `::MINI_SQL.prepared.build(sql).query` use `::MINI_SQL.build(sql).prepared.query`'
21
+ end
22
+
23
+ def prepared(condition = true)
24
+ condition ? self : @unprepared
25
+ end
26
+
27
+ private def run(sql, params)
28
+ prepared_sql, binds, _bind_names = @param_binder.bind(sql, params)
29
+ statement = @prepared_cache.prepare_statement(prepared_sql)
30
+ statement.bind_params(binds)
31
+ if block_given?
32
+ yield statement.execute
33
+ else
34
+ statement.execute.to_a
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module MiniSql
3
- VERSION = "0.3"
3
+ VERSION = "1.1.2"
4
4
  end
data/mini_sql.gemspec CHANGED
@@ -25,11 +25,11 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  # Specify which files should be added to the gem when it is released.
27
27
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
- # rubocop:disable DiscoruseCops/NoChdir
28
+ # rubocop:disable Discourse/NoChdir
29
29
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
30
30
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
31
31
  end
32
- # rubocop:enable DiscoruseCops/NoChdir
32
+ # rubocop:enable Discourse/NoChdir
33
33
  spec.require_paths = ["lib"]
34
34
 
35
35
  spec.add_development_dependency "bundler", "> 1.16"
@@ -38,8 +38,9 @@ Gem::Specification.new do |spec|
38
38
  spec.add_development_dependency "guard", "~> 2.14"
39
39
  spec.add_development_dependency "guard-minitest", "~> 2.4"
40
40
  spec.add_development_dependency "activesupport", "~> 5.2"
41
- spec.add_development_dependency 'rubocop', '~> 0.79.0'
42
- spec.add_development_dependency 'rubocop-discourse', '~> 1.0.2'
41
+ spec.add_development_dependency 'rubocop', '~> 1.4.0'
42
+ spec.add_development_dependency 'rubocop-discourse', '~> 2.4.1'
43
+ spec.add_development_dependency 'm', '~> 1.5.1'
43
44
 
44
45
  if RUBY_ENGINE == 'jruby'
45
46
  spec.add_development_dependency "activerecord-jdbcpostgresql-adapter", "~> 52.2"
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.3'
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-25 00:00:00.000000000 Z
11
+ date: 2021-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,28 +100,42 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.79.0
103
+ version: 1.4.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.79.0
110
+ version: 1.4.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rubocop-discourse
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 1.0.2
117
+ version: 2.4.1
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 1.0.2
124
+ version: 2.4.1
125
+ - !ruby/object:Gem::Dependency
126
+ name: m
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 1.5.1
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.5.1
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: pg
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -171,10 +185,10 @@ executables: []
171
185
  extensions: []
172
186
  extra_rdoc_files: []
173
187
  files:
188
+ - ".github/workflows/ci.yml"
174
189
  - ".gitignore"
175
190
  - ".rubocop-https---raw-githubusercontent-com-discourse-discourse-master--rubocop-yml"
176
191
  - ".rubocop.yml"
177
- - ".travis.yml"
178
192
  - CHANGELOG
179
193
  - CODE_OF_CONDUCT.md
180
194
  - Gemfile
@@ -182,25 +196,45 @@ files:
182
196
  - LICENSE.txt
183
197
  - README.md
184
198
  - Rakefile
199
+ - bench/builder_perf.rb
200
+ - bench/decorator_perf.rb
201
+ - bench/mini_sql_methods_perf.rb
202
+ - bench/prepared_perf.rb
203
+ - bench/shared/generate_data.rb
185
204
  - bench/timestamp_perf.rb
186
205
  - bench/topic_mysql_perf.rb
187
206
  - bench/topic_perf.rb
207
+ - bench/topic_wide_perf.rb
188
208
  - bin/console
189
209
  - bin/setup
190
210
  - lib/mini_sql.rb
211
+ - lib/mini_sql/abstract/prepared_binds.rb
212
+ - lib/mini_sql/abstract/prepared_cache.rb
191
213
  - lib/mini_sql/builder.rb
192
214
  - lib/mini_sql/connection.rb
215
+ - lib/mini_sql/decoratable.rb
193
216
  - lib/mini_sql/deserializer_cache.rb
194
217
  - lib/mini_sql/inline_param_encoder.rb
195
218
  - lib/mini_sql/mysql/connection.rb
196
219
  - lib/mini_sql/mysql/deserializer_cache.rb
220
+ - lib/mini_sql/mysql/prepared_binds.rb
221
+ - lib/mini_sql/mysql/prepared_cache.rb
222
+ - lib/mini_sql/mysql/prepared_connection.rb
197
223
  - lib/mini_sql/postgres/coders.rb
198
224
  - lib/mini_sql/postgres/connection.rb
199
225
  - lib/mini_sql/postgres/deserializer_cache.rb
226
+ - lib/mini_sql/postgres/prepared_binds.rb
227
+ - lib/mini_sql/postgres/prepared_cache.rb
228
+ - lib/mini_sql/postgres/prepared_connection.rb
200
229
  - lib/mini_sql/postgres_jdbc/connection.rb
201
230
  - lib/mini_sql/postgres_jdbc/deserializer_cache.rb
231
+ - lib/mini_sql/result.rb
232
+ - lib/mini_sql/serializer.rb
202
233
  - lib/mini_sql/sqlite/connection.rb
203
234
  - lib/mini_sql/sqlite/deserializer_cache.rb
235
+ - lib/mini_sql/sqlite/prepared_binds.rb
236
+ - lib/mini_sql/sqlite/prepared_cache.rb
237
+ - lib/mini_sql/sqlite/prepared_connection.rb
204
238
  - lib/mini_sql/version.rb
205
239
  - mini_sql.gemspec
206
240
  homepage: https://github.com/discourse/mini_sql
@@ -225,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
259
  - !ruby/object:Gem::Version
226
260
  version: '0'
227
261
  requirements: []
228
- rubygems_version: 3.0.3
262
+ rubygems_version: 3.2.2
229
263
  signing_key:
230
264
  specification_version: 4
231
265
  summary: A fast, safe, simple direct SQL executor
data/.travis.yml DELETED
@@ -1,28 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.5
4
- - 2.6
5
- - 2.7
6
- - ruby-head
7
-
8
- before_install:
9
- - gem install bundler
10
-
11
- cache: bundler
12
- sudo: false
13
-
14
- services:
15
- - mysql
16
-
17
- addons:
18
- postgresql: 9.6
19
- mysql: 5.7
20
-
21
- install:
22
- - createdb test_mini_sql
23
- - mysql -e 'CREATE DATABASE test_mini_sql;'
24
- - bundle install
25
-
26
- matrix:
27
- allow_failures:
28
- - rvm: ruby-head