mini_sql 0.2.1 → 0.3
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 +4 -4
- data/.gitignore +1 -0
- data/.rubocop-https---raw-githubusercontent-com-discourse-discourse-master--rubocop-yml +355 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +8 -1
- data/CHANGELOG +20 -0
- data/Gemfile +3 -1
- data/Guardfile +2 -0
- data/README.md +90 -2
- data/Rakefile +10 -2
- data/bench/timestamp_perf.rb +22 -21
- data/bench/topic_mysql_perf.rb +304 -0
- data/bench/topic_perf.rb +175 -11
- data/bin/console +1 -0
- data/lib/mini_sql.rb +20 -8
- data/lib/mini_sql/builder.rb +0 -2
- data/lib/mini_sql/connection.rb +18 -2
- data/lib/mini_sql/deserializer_cache.rb +2 -0
- data/lib/mini_sql/inline_param_encoder.rb +9 -9
- data/lib/mini_sql/mysql/connection.rb +69 -0
- data/lib/mini_sql/mysql/deserializer_cache.rb +63 -0
- data/lib/mini_sql/postgres/coders.rb +2 -0
- data/lib/mini_sql/postgres/connection.rb +83 -0
- data/lib/mini_sql/postgres/deserializer_cache.rb +29 -3
- data/lib/mini_sql/postgres_jdbc/connection.rb +102 -0
- data/lib/mini_sql/postgres_jdbc/deserializer_cache.rb +71 -0
- data/lib/mini_sql/sqlite/connection.rb +11 -1
- data/lib/mini_sql/sqlite/deserializer_cache.rb +7 -3
- data/lib/mini_sql/version.rb +2 -1
- data/mini_sql.gemspec +23 -5
- metadata +78 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ea4564f53848c314c76c45db0c2af652c1e128ebfc1ba52d6ae11b3799149f4
|
4
|
+
data.tar.gz: ecdfdc07fdf11e60338bc2ceb0415cbcc027720c5bba645281217a51befc2402
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76a040187f4932dc9fbc80ae3323633a38462753caec47233dbfad3e276e90d8eeb0fbddcbfe974ade3b0b99c18a487d5ef865ebdb1effc67048352ecd35d99d
|
7
|
+
data.tar.gz: 73c3519bf51a7934af89827830e3e7c45366eec01b1d65dc0c61afb2b87c12b093e9f3db99b1c4db081e6a6a1e983fd24d88db3aa13f63b9e546af0dce36beae
|
data/.gitignore
CHANGED
@@ -0,0 +1,355 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-discourse
|
3
|
+
- rubocop-rspec
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
TargetRubyVersion: 2.6
|
7
|
+
DisabledByDefault: true
|
8
|
+
Exclude:
|
9
|
+
- "db/schema.rb"
|
10
|
+
- "bundle/**/*"
|
11
|
+
- "vendor/**/*"
|
12
|
+
- "node_modules/**/*"
|
13
|
+
- "public/**/*"
|
14
|
+
- "plugins/**/gems/**/*"
|
15
|
+
|
16
|
+
Discourse:
|
17
|
+
Enabled: true
|
18
|
+
|
19
|
+
Discourse/NoChdir:
|
20
|
+
Exclude:
|
21
|
+
- 'spec/**/*' # Specs are run sequentially, so chdir can be used
|
22
|
+
- 'plugins/*/spec/**/*'
|
23
|
+
|
24
|
+
# Prefer &&/|| over and/or.
|
25
|
+
Style/AndOr:
|
26
|
+
Enabled: true
|
27
|
+
|
28
|
+
Style/FrozenStringLiteralComment:
|
29
|
+
Enabled: true
|
30
|
+
|
31
|
+
# Align `when` with `case`.
|
32
|
+
Layout/CaseIndentation:
|
33
|
+
Enabled: true
|
34
|
+
|
35
|
+
# Align comments with method definitions.
|
36
|
+
Layout/CommentIndentation:
|
37
|
+
Enabled: true
|
38
|
+
|
39
|
+
# No extra empty lines.
|
40
|
+
Layout/EmptyLines:
|
41
|
+
Enabled: true
|
42
|
+
|
43
|
+
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
|
44
|
+
Style/HashSyntax:
|
45
|
+
Enabled: true
|
46
|
+
|
47
|
+
# Two spaces, no tabs (for indentation).
|
48
|
+
Layout/IndentationWidth:
|
49
|
+
Enabled: true
|
50
|
+
|
51
|
+
Layout/SpaceAfterColon:
|
52
|
+
Enabled: true
|
53
|
+
|
54
|
+
Layout/SpaceAfterComma:
|
55
|
+
Enabled: true
|
56
|
+
|
57
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
58
|
+
Enabled: true
|
59
|
+
|
60
|
+
Layout/SpaceAroundKeyword:
|
61
|
+
Enabled: true
|
62
|
+
|
63
|
+
Layout/SpaceAroundOperators:
|
64
|
+
Enabled: true
|
65
|
+
|
66
|
+
Layout/SpaceBeforeFirstArg:
|
67
|
+
Enabled: true
|
68
|
+
|
69
|
+
# Defining a method with parameters needs parentheses.
|
70
|
+
Style/MethodDefParentheses:
|
71
|
+
Enabled: true
|
72
|
+
|
73
|
+
# Use `foo {}` not `foo{}`.
|
74
|
+
Layout/SpaceBeforeBlockBraces:
|
75
|
+
Enabled: true
|
76
|
+
|
77
|
+
# Use `foo { bar }` not `foo {bar}`.
|
78
|
+
Layout/SpaceInsideBlockBraces:
|
79
|
+
Enabled: true
|
80
|
+
|
81
|
+
# Use `{ a: 1 }` not `{a:1}`.
|
82
|
+
Layout/SpaceInsideHashLiteralBraces:
|
83
|
+
Enabled: true
|
84
|
+
|
85
|
+
Layout/SpaceInsideParens:
|
86
|
+
Enabled: true
|
87
|
+
|
88
|
+
# Detect hard tabs, no hard tabs.
|
89
|
+
Layout/Tab:
|
90
|
+
Enabled: true
|
91
|
+
|
92
|
+
# Blank lines should not have any spaces.
|
93
|
+
Layout/TrailingEmptyLines:
|
94
|
+
Enabled: true
|
95
|
+
|
96
|
+
# No trailing whitespace.
|
97
|
+
Layout/TrailingWhitespace:
|
98
|
+
Enabled: true
|
99
|
+
|
100
|
+
Lint/Debugger:
|
101
|
+
Enabled: true
|
102
|
+
|
103
|
+
Layout/BlockAlignment:
|
104
|
+
Enabled: true
|
105
|
+
|
106
|
+
# Align `end` with the matching keyword or starting expression except for
|
107
|
+
# assignments, where it should be aligned with the LHS.
|
108
|
+
Layout/EndAlignment:
|
109
|
+
Enabled: true
|
110
|
+
EnforcedStyleAlignWith: variable
|
111
|
+
|
112
|
+
# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
|
113
|
+
Lint/RequireParentheses:
|
114
|
+
Enabled: true
|
115
|
+
|
116
|
+
Lint/ShadowingOuterLocalVariable:
|
117
|
+
Enabled: true
|
118
|
+
|
119
|
+
Layout/MultilineMethodCallIndentation:
|
120
|
+
Enabled: true
|
121
|
+
EnforcedStyle: indented
|
122
|
+
|
123
|
+
Layout/HashAlignment:
|
124
|
+
Enabled: true
|
125
|
+
|
126
|
+
Bundler/OrderedGems:
|
127
|
+
Enabled: false
|
128
|
+
|
129
|
+
Style/SingleLineMethods:
|
130
|
+
Enabled: true
|
131
|
+
|
132
|
+
Style/Semicolon:
|
133
|
+
Enabled: true
|
134
|
+
AllowAsExpressionSeparator: true
|
135
|
+
|
136
|
+
Style/RedundantReturn:
|
137
|
+
Enabled: true
|
138
|
+
|
139
|
+
Style/GlobalVars:
|
140
|
+
Enabled: true
|
141
|
+
Severity: warning
|
142
|
+
Exclude:
|
143
|
+
- 'lib/tasks/**/*'
|
144
|
+
- 'script/**/*'
|
145
|
+
- 'spec/**/*.rb'
|
146
|
+
- 'plugins/*/spec/**/*'
|
147
|
+
|
148
|
+
# Specs
|
149
|
+
|
150
|
+
RSpec/AnyInstance:
|
151
|
+
Enabled: false # To be decided
|
152
|
+
|
153
|
+
RSpec/AroundBlock:
|
154
|
+
Enabled: true
|
155
|
+
|
156
|
+
RSpec/BeforeAfterAll:
|
157
|
+
Enabled: false # To be decided
|
158
|
+
|
159
|
+
RSpec/ContextMethod:
|
160
|
+
Enabled: false # TODO
|
161
|
+
|
162
|
+
RSpec/ContextWording:
|
163
|
+
Enabled: false # To be decided
|
164
|
+
|
165
|
+
RSpec/DescribeClass:
|
166
|
+
Enabled: false # To be decided
|
167
|
+
|
168
|
+
RSpec/DescribeMethod:
|
169
|
+
Enabled: true
|
170
|
+
|
171
|
+
RSpec/DescribeSymbol:
|
172
|
+
Enabled: false # To be decided
|
173
|
+
|
174
|
+
RSpec/DescribedClass:
|
175
|
+
Enabled: false # To be decided
|
176
|
+
|
177
|
+
RSpec/DescribedClassModuleWrapping:
|
178
|
+
Enabled: false # To be decided
|
179
|
+
|
180
|
+
RSpec/EmptyExampleGroup:
|
181
|
+
Enabled: true
|
182
|
+
|
183
|
+
RSpec/EmptyLineAfterExample:
|
184
|
+
Enabled: false # TODO
|
185
|
+
|
186
|
+
RSpec/EmptyLineAfterExampleGroup:
|
187
|
+
Enabled: false # TODO
|
188
|
+
|
189
|
+
RSpec/EmptyLineAfterFinalLet:
|
190
|
+
Enabled: false # TODO
|
191
|
+
|
192
|
+
RSpec/EmptyLineAfterHook:
|
193
|
+
Enabled: false # TODO
|
194
|
+
|
195
|
+
RSpec/EmptyLineAfterSubject:
|
196
|
+
Enabled: false # TODO
|
197
|
+
|
198
|
+
RSpec/ExampleLength:
|
199
|
+
Enabled: false # To be decided
|
200
|
+
|
201
|
+
RSpec/ExampleWithoutDescription:
|
202
|
+
Enabled: true
|
203
|
+
|
204
|
+
RSpec/ExampleWording:
|
205
|
+
Enabled: false # TODO
|
206
|
+
|
207
|
+
RSpec/ExpectActual:
|
208
|
+
Enabled: true
|
209
|
+
|
210
|
+
RSpec/ExpectChange:
|
211
|
+
Enabled: false # To be decided
|
212
|
+
|
213
|
+
RSpec/ExpectInHook:
|
214
|
+
Enabled: false # To be decided
|
215
|
+
|
216
|
+
RSpec/ExpectOutput:
|
217
|
+
Enabled: true
|
218
|
+
|
219
|
+
RSpec/FilePath:
|
220
|
+
Enabled: false # To be decided
|
221
|
+
|
222
|
+
RSpec/Focus:
|
223
|
+
Enabled: true
|
224
|
+
|
225
|
+
RSpec/HookArgument:
|
226
|
+
Enabled: false # TODO
|
227
|
+
|
228
|
+
RSpec/HooksBeforeExamples:
|
229
|
+
Enabled: false # TODO
|
230
|
+
|
231
|
+
RSpec/ImplicitBlockExpectation:
|
232
|
+
Enabled: true
|
233
|
+
|
234
|
+
RSpec/ImplicitExpect:
|
235
|
+
Enabled: false # To be decided
|
236
|
+
|
237
|
+
RSpec/ImplicitSubject:
|
238
|
+
Enabled: false # To be decided
|
239
|
+
|
240
|
+
RSpec/InstanceSpy:
|
241
|
+
Enabled: true
|
242
|
+
|
243
|
+
RSpec/InstanceVariable:
|
244
|
+
Enabled: false # TODO
|
245
|
+
|
246
|
+
RSpec/InvalidPredicateMatcher:
|
247
|
+
Enabled: true
|
248
|
+
|
249
|
+
RSpec/ItBehavesLike:
|
250
|
+
Enabled: true
|
251
|
+
|
252
|
+
RSpec/IteratedExpectation:
|
253
|
+
Enabled: false # To be decided
|
254
|
+
|
255
|
+
RSpec/LeadingSubject:
|
256
|
+
Enabled: false # TODO
|
257
|
+
|
258
|
+
RSpec/LeakyConstantDeclaration:
|
259
|
+
Enabled: false # To be decided
|
260
|
+
|
261
|
+
RSpec/LetBeforeExamples:
|
262
|
+
Enabled: false # TODO
|
263
|
+
|
264
|
+
RSpec/LetSetup:
|
265
|
+
Enabled: false # TODO
|
266
|
+
|
267
|
+
RSpec/MessageChain:
|
268
|
+
Enabled: true
|
269
|
+
|
270
|
+
RSpec/MessageSpies:
|
271
|
+
Enabled: true
|
272
|
+
|
273
|
+
RSpec/MissingExampleGroupArgument:
|
274
|
+
Enabled: true
|
275
|
+
|
276
|
+
RSpec/MultipleDescribes:
|
277
|
+
Enabled: false # TODO
|
278
|
+
|
279
|
+
RSpec/MultipleSubjects:
|
280
|
+
Enabled: true
|
281
|
+
|
282
|
+
RSpec/NamedSubject:
|
283
|
+
Enabled: false # To be decided
|
284
|
+
|
285
|
+
RSpec/NestedGroups:
|
286
|
+
Enabled: false # To be decided
|
287
|
+
|
288
|
+
RSpec/OverwritingSetup:
|
289
|
+
Enabled: true
|
290
|
+
|
291
|
+
RSpec/ReceiveCounts:
|
292
|
+
Enabled: true
|
293
|
+
|
294
|
+
RSpec/ReceiveNever:
|
295
|
+
Enabled: true
|
296
|
+
|
297
|
+
RSpec/RepeatedDescription:
|
298
|
+
Enabled: false # TODO
|
299
|
+
|
300
|
+
RSpec/RepeatedExample:
|
301
|
+
Enabled: false # TODO
|
302
|
+
|
303
|
+
RSpec/RepeatedExampleGroupBody:
|
304
|
+
Enabled: false # TODO
|
305
|
+
|
306
|
+
RSpec/RepeatedExampleGroupDescription:
|
307
|
+
Enabled: false # TODO
|
308
|
+
|
309
|
+
RSpec/ReturnFromStub:
|
310
|
+
Enabled: true
|
311
|
+
|
312
|
+
RSpec/ScatteredSetup:
|
313
|
+
Enabled: false # TODO
|
314
|
+
|
315
|
+
RSpec/SharedContext:
|
316
|
+
Enabled: true
|
317
|
+
|
318
|
+
RSpec/SharedExamples:
|
319
|
+
Enabled: true
|
320
|
+
|
321
|
+
RSpec/SingleArgumentMessageChain:
|
322
|
+
Enabled: true
|
323
|
+
|
324
|
+
RSpec/SubjectStub:
|
325
|
+
Enabled: true
|
326
|
+
|
327
|
+
RSpec/UnspecifiedException:
|
328
|
+
Enabled: true
|
329
|
+
|
330
|
+
RSpec/VerifiedDoubles:
|
331
|
+
Enabled: true
|
332
|
+
|
333
|
+
RSpec/VoidExpect:
|
334
|
+
Enabled: true
|
335
|
+
|
336
|
+
RSpec/Yield:
|
337
|
+
Enabled: true
|
338
|
+
|
339
|
+
Capybara/CurrentPathExpectation:
|
340
|
+
Enabled: true
|
341
|
+
|
342
|
+
Capybara/FeatureMethods:
|
343
|
+
Enabled: true
|
344
|
+
|
345
|
+
FactoryBot/AttributeDefinedStatically:
|
346
|
+
Enabled: true
|
347
|
+
|
348
|
+
FactoryBot/CreateList:
|
349
|
+
Enabled: true
|
350
|
+
|
351
|
+
FactoryBot/FactoryClassName:
|
352
|
+
Enabled: true
|
353
|
+
|
354
|
+
Rails/HttpStatus:
|
355
|
+
Enabled: true
|
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.5
|
3
|
+
- 2.5
|
4
|
+
- 2.6
|
5
|
+
- 2.7
|
4
6
|
- ruby-head
|
5
7
|
|
6
8
|
before_install:
|
@@ -9,11 +11,16 @@ before_install:
|
|
9
11
|
cache: bundler
|
10
12
|
sudo: false
|
11
13
|
|
14
|
+
services:
|
15
|
+
- mysql
|
16
|
+
|
12
17
|
addons:
|
13
18
|
postgresql: 9.6
|
19
|
+
mysql: 5.7
|
14
20
|
|
15
21
|
install:
|
16
22
|
- createdb test_mini_sql
|
23
|
+
- mysql -e 'CREATE DATABASE test_mini_sql;'
|
17
24
|
- bundle install
|
18
25
|
|
19
26
|
matrix:
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
2020-06-25 - 0.3
|
2
|
+
|
3
|
+
- Added support for query_each and query_each_hash, which lazily queries rows and enables selecting large result sets by streaming
|
4
|
+
|
5
|
+
2020-04-07 - 0.2.5
|
6
|
+
|
7
|
+
- Added support for custom type maps with Postgres connections
|
8
|
+
|
9
|
+
2019-01-16 - 0.2.4
|
10
|
+
|
11
|
+
- Fixed symbol param encoder
|
12
|
+
|
13
|
+
2019-12-20 - 0.2.3
|
14
|
+
|
15
|
+
- Added support for MySQL
|
16
|
+
|
17
|
+
2019-11-04 - 0.2.2
|
18
|
+
|
19
|
+
- Added adapters for JRuby postgres support thanks to @enebo
|
20
|
+
|
1
21
|
2019-02-25 - 0.2.1
|
2
22
|
|
3
23
|
- Handle `BigDecimal.new` deprecation by using `BigDecimal()` instead
|
data/Gemfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
|
-
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
6
|
|
5
7
|
# Specify your gem's dependencies in mini_sql.gemspec
|
6
8
|
gemspec
|
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -32,11 +32,28 @@ conn.query("select 1 id, 'bob' name").each do |user|
|
|
32
32
|
puts user.id # 1
|
33
33
|
end
|
34
34
|
|
35
|
+
# extend result objects with additional method
|
36
|
+
module ProductDecorator
|
37
|
+
def amount_price
|
38
|
+
price * quantity
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
conn.query_decorator(ProductDecorator, "select 20 price, 3 quantity").each do |user|
|
43
|
+
puts user.amount_price # 60
|
44
|
+
end
|
45
|
+
|
35
46
|
p conn.query_single('select 1 union select 2')
|
36
47
|
# [1,2]
|
37
48
|
|
38
49
|
p conn.query_hash('select 1 as a, 2 as b union select 3, 4')
|
39
50
|
# [{"a" => 1, "b"=> 1},{"a" => 3, "b" => 4}
|
51
|
+
|
52
|
+
p conn.query_array("select 1 as a, '2' as b union select 3, 'e'")
|
53
|
+
# [[1, '2'], [3, 'e']]
|
54
|
+
|
55
|
+
p conn.query_array("select 1 as a, '2' as b union select 3, 'e'").to_h
|
56
|
+
# {1 => '2', 3 => 'e'}
|
40
57
|
```
|
41
58
|
|
42
59
|
## The query builder
|
@@ -63,9 +80,18 @@ end
|
|
63
80
|
The builder allows for `order_by`, `where`, `select`, `set`, `limit`, `join`, `left_join` and `offset`.
|
64
81
|
|
65
82
|
## Is it fast?
|
66
|
-
|
67
83
|
Yes, it is very fast. See benchmarks in [the bench directory](https://github.com/discourse/mini_sql/tree/master/bench).
|
68
84
|
|
85
|
+
**Comparison mini_sql methods**
|
86
|
+
```
|
87
|
+
query_array 1351.6 i/s
|
88
|
+
query 963.8 i/s - 1.40x slower
|
89
|
+
query_hash 787.4 i/s - 1.72x slower
|
90
|
+
|
91
|
+
query_single('select id from topics limit 1000') 2368.9 i/s
|
92
|
+
query_array('select id from topics limit 1000').flatten 1350.1 i/s - 1.75x slower
|
93
|
+
```
|
94
|
+
|
69
95
|
As a rule it will outperform similar naive PG code while remaining safe.
|
70
96
|
|
71
97
|
```ruby
|
@@ -98,6 +124,68 @@ MiniSql is careful to always clear results as soon as possible.
|
|
98
124
|
|
99
125
|
MiniSql's default type mapper prefers treating `timestamp without time zone` columns as utc. This is done to ensure widest amount of compatability and is a departure from the default in the PG 1.0 gem. If you wish to amend behavior feel free to pass in a custom type_map.
|
100
126
|
|
127
|
+
## Custom type maps
|
128
|
+
|
129
|
+
When using Postgres, native type mapping implementation is used. This is roughly
|
130
|
+
implemented as:
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
type_map ||= PG::BasicTypeMapForResults.new(conn)
|
134
|
+
# additional specific decoders
|
135
|
+
```
|
136
|
+
|
137
|
+
The type mapper instansitated once on-demand at boot and reused by all mini_sql connections.
|
138
|
+
|
139
|
+
Initializing the basic type map for Postgres can be a costly operation. You may
|
140
|
+
wish to amend the type mapper so for example you only return strings:
|
141
|
+
|
142
|
+
```
|
143
|
+
# maybe you do not want Integer
|
144
|
+
p cnn.query("select a 1").first.a
|
145
|
+
"1"
|
146
|
+
```
|
147
|
+
|
148
|
+
To specify a different type mapper for your results use:
|
149
|
+
|
150
|
+
```
|
151
|
+
MiniSql::Connections.get(pg_connection, type_map: custom_type_map)
|
152
|
+
```
|
153
|
+
|
154
|
+
In the case of Rails you can opt to use the type mapper Rails uses with:
|
155
|
+
|
156
|
+
```
|
157
|
+
pg_cnn = ActiveRecord::Base.connection.raw_connection
|
158
|
+
mini_sql_cnn = MiniSql::Connection.get(pg_cnn, type_map: pg_cnn.type_map_for_results)
|
159
|
+
```
|
160
|
+
|
161
|
+
Note the type mapper for Rails may miss some of the mapping MiniSql ships with such as `IPAddr`, MiniSql is also careful to use the very efficient TimestampUtc decoders where available.
|
162
|
+
|
163
|
+
## Streaming support
|
164
|
+
|
165
|
+
In some exceptional cases you may want to stream results directly from the database. This enables selection of 100s of thousands of rows with limited memory impact.
|
166
|
+
|
167
|
+
Two interfaces exists for this:
|
168
|
+
|
169
|
+
`query_each` : which can be used to get materialized objects
|
170
|
+
`query_each_hash` : which can be used to iterate through Hash objects
|
171
|
+
|
172
|
+
Usage:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
mini_sql_cnn.query_each("SELECT * FROM tons_of_cows limit :limit", limit: 1_000_000) do |row|
|
176
|
+
puts row.cow_name
|
177
|
+
puts row.cow_age
|
178
|
+
end
|
179
|
+
|
180
|
+
mini_sql_cnn.query_each_hash("SELECT * FROM one_million_cows") do |row|
|
181
|
+
puts row["cow_name"]
|
182
|
+
puts row["cow_age"]
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
Note, in Postgres streaming is going to be slower than non-streaming options due to internal implementation in the pq gem, each row gets a full result object and additional bookkeeping is needed. Only use it if you need to optimize memory usage.
|
187
|
+
|
188
|
+
Streaming support is only implemented in the postgres backend at the moment, PRs welcome to add to other backends.
|
101
189
|
|
102
190
|
## I want more features!
|
103
191
|
|
@@ -109,7 +197,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
109
197
|
|
110
198
|
## Contributing
|
111
199
|
|
112
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
200
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/discourse/mini_sql. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
113
201
|
|
114
202
|
## License
|
115
203
|
|