occams-record 1.1.3 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -3
- data/lib/occams-record/batches.rb +25 -9
- data/lib/occams-record/eager_loaders/belongs_to.rb +2 -1
- data/lib/occams-record/eager_loaders/has_one.rb +1 -0
- data/lib/occams-record/eager_loaders/polymorphic_belongs_to.rb +1 -0
- data/lib/occams-record/raw_query.rb +1 -1
- data/lib/occams-record/results/row.rb +1 -1
- data/lib/occams-record/version.rb +1 -1
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ceea75487deeadf930b9236a44980882ac539042e9d86b6ce5612da9c58642c
|
4
|
+
data.tar.gz: 190dab76b6f35d430f97a4be25ccf3fe56b652edb9722c83de844cd5c9d1715e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 384fcddbac59eb4663a0e4d8f3f7c0286f8ff348c5b37e74c5f052fca5138011f06a107a5b305d57df1391bf581b35605346ee11a9e5d6542af0e2298e3e0273
|
7
|
+
data.tar.gz: 49e71a3dd7eb5bd78180b17ba01550e7105450fdeee2ff6bbbae255fbb3f11eac1182bc233caff5567449723b45c24ed8e465a2bee0b28523ebcc74904280956
|
data/README.md
CHANGED
@@ -12,14 +12,14 @@ OccamsRecord is a high-efficiency, advanced query library for use alongside Acti
|
|
12
12
|
|
13
13
|
### 2) Supercharged querying & eager loading
|
14
14
|
|
15
|
-
Continue using ActiveRecord's query builder, but let Occams take over eager loading and raw SQL calls. None of the examples below are possible with ActiveRecord, but OccamsRecord
|
15
|
+
Continue using ActiveRecord's query builder, but let Occams take over running them, eager loading, and raw SQL calls. None of the examples below are possible with ActiveRecord, but OccamsRecord makes them trivial. (More complete examples are shown later, but these should whet your appetite.)
|
16
16
|
|
17
17
|
**Customize the SQL used to eager load associations**
|
18
18
|
|
19
19
|
```ruby
|
20
20
|
OccamsRecord.
|
21
21
|
query(User.active).
|
22
|
-
eager_load(:orders, ->(q) { q.where("created_at >= ?", date })
|
22
|
+
eager_load(:orders, ->(q) { q.where("created_at >= ?", date).order("created_at DESC") })
|
23
23
|
```
|
24
24
|
|
25
25
|
**Use `ORDER BY` with `find_each`/`find_in_batches`**
|
@@ -297,15 +297,25 @@ bundle install
|
|
297
297
|
bundle exec rake test
|
298
298
|
```
|
299
299
|
|
300
|
+
**Specify ActiveRecord version**
|
301
|
+
|
300
302
|
By default, bundler will install the latest (supported) version of ActiveRecord. To specify a version to test against, run:
|
301
303
|
|
302
304
|
```bash
|
303
305
|
AR=5.2 bundle update activerecord
|
304
|
-
bundle exec rake test
|
306
|
+
AR=5.2 bundle exec rake test
|
305
307
|
```
|
306
308
|
|
307
309
|
Look inside `Gemfile` to see all testable versions.
|
308
310
|
|
311
|
+
**Run against Postgres**
|
312
|
+
|
313
|
+
By default the tests run against an in-memory Sqlite3 database. Use the following env var to force running against a Postgres database:
|
314
|
+
|
315
|
+
```bash
|
316
|
+
TEST_DATABASE_URL=postgres://postgres@localhost:5432/occams_record bundle exec rake test
|
317
|
+
```
|
318
|
+
|
309
319
|
# License
|
310
320
|
|
311
321
|
MIT License. See LICENSE for details.
|
@@ -13,12 +13,13 @@ module OccamsRecord
|
|
13
13
|
#
|
14
14
|
# @param batch_size [Integer]
|
15
15
|
# @param use_transaction [Boolean] Ensure it runs inside of a database transaction
|
16
|
+
# @param append_order_by [String] Append this column to ORDER BY to ensure consistent results. Defaults to the primary key. Pass false to disable.
|
16
17
|
# @yield [OccamsRecord::Results::Row]
|
17
18
|
# @return [Enumerator] will yield each record
|
18
19
|
#
|
19
|
-
def find_each(batch_size: 1000, use_transaction: true)
|
20
|
+
def find_each(batch_size: 1000, use_transaction: true, append_order_by: nil)
|
20
21
|
enum = Enumerator.new { |y|
|
21
|
-
batches(of: batch_size, use_transaction: use_transaction).each { |batch|
|
22
|
+
batches(of: batch_size, use_transaction: use_transaction, append_order_by: append_order_by).each { |batch|
|
22
23
|
batch.each { |record| y.yield record }
|
23
24
|
}
|
24
25
|
}
|
@@ -39,11 +40,12 @@ module OccamsRecord
|
|
39
40
|
#
|
40
41
|
# @param batch_size [Integer]
|
41
42
|
# @param use_transaction [Boolean] Ensure it runs inside of a database transaction
|
43
|
+
# @param append_order_by [String] Append this column to ORDER BY to ensure consistent results. Defaults to the primary key. Pass false to disable.
|
42
44
|
# @yield [OccamsRecord::Results::Row]
|
43
45
|
# @return [Enumerator] will yield each batch
|
44
46
|
#
|
45
|
-
def find_in_batches(batch_size: 1000, use_transaction: true)
|
46
|
-
enum = batches(of: batch_size, use_transaction: use_transaction)
|
47
|
+
def find_in_batches(batch_size: 1000, use_transaction: true, append_order_by: nil)
|
48
|
+
enum = batches(of: batch_size, use_transaction: use_transaction, append_order_by: append_order_by)
|
47
49
|
if block_given?
|
48
50
|
enum.each { |batch| yield batch }
|
49
51
|
else
|
@@ -61,30 +63,44 @@ module OccamsRecord
|
|
61
63
|
#
|
62
64
|
# @param of [Integer] batch size
|
63
65
|
# @param use_transaction [Boolean] Ensure it runs inside of a database transaction
|
66
|
+
# @param append_order_by [String] Append this column to ORDER BY to ensure consistent results. Defaults to the primary key. Pass false to disable.
|
64
67
|
# @return [Enumerator] yields batches
|
65
68
|
#
|
66
|
-
def batches(of:, use_transaction: true)
|
69
|
+
def batches(of:, use_transaction: true, append_order_by: nil)
|
70
|
+
append_order =
|
71
|
+
case append_order_by
|
72
|
+
when false then nil
|
73
|
+
when nil then model.primary_key
|
74
|
+
else append_order_by
|
75
|
+
end
|
76
|
+
|
67
77
|
Enumerator.new do |y|
|
68
78
|
if use_transaction and model.connection.open_transactions == 0
|
69
79
|
model.connection.transaction {
|
70
|
-
run_batches y, of
|
80
|
+
run_batches y, of, append_order
|
71
81
|
}
|
72
82
|
else
|
73
|
-
run_batches y, of
|
83
|
+
run_batches y, of, append_order
|
74
84
|
end
|
75
85
|
end
|
76
86
|
end
|
77
87
|
|
78
|
-
def run_batches(y, of)
|
88
|
+
def run_batches(y, of, append_order_by = nil)
|
79
89
|
limit = scope.limit_value
|
80
90
|
batch_size = limit && limit < of ? limit : of
|
81
91
|
|
82
92
|
offset = scope.offset_value || 0
|
83
93
|
out_of_records, count = false, 0
|
94
|
+
order_by =
|
95
|
+
if append_order_by
|
96
|
+
append_order_by.to_s == model.primary_key.to_s ? append_order_by.to_sym : append_order_by
|
97
|
+
end
|
84
98
|
|
85
99
|
until out_of_records
|
86
100
|
l = limit && batch_size > limit - count ? limit - count : batch_size
|
87
|
-
q = scope
|
101
|
+
q = scope
|
102
|
+
q = q.order(order_by) if order_by
|
103
|
+
q = q.offset(offset).limit(l)
|
88
104
|
results = Query.new(q, use: @use, query_logger: @query_logger, eager_loaders: @eager_loaders).run
|
89
105
|
|
90
106
|
y.yield results if results.any?
|
@@ -20,6 +20,7 @@ module OccamsRecord
|
|
20
20
|
raise MissingColumnError.new(row, e.name)
|
21
21
|
end
|
22
22
|
}.compact.uniq
|
23
|
+
ids.sort! if $occams_record_test
|
23
24
|
|
24
25
|
q = base_scope.where(@ref.association_primary_key => ids)
|
25
26
|
yield q if ids.any?
|
@@ -33,7 +34,7 @@ module OccamsRecord
|
|
33
34
|
#
|
34
35
|
def merge!(assoc_rows, rows)
|
35
36
|
Merge.new(rows, name).
|
36
|
-
single!(assoc_rows, {@ref.foreign_key.to_s => @ref.
|
37
|
+
single!(assoc_rows, {@ref.foreign_key.to_s => @ref.association_primary_key.to_s})
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
@@ -55,6 +55,7 @@ module OccamsRecord
|
|
55
55
|
next if type.nil? or type == ""
|
56
56
|
model = type.constantize
|
57
57
|
ids = rows_of_type.map(&@foreign_key).uniq
|
58
|
+
ids.sort! if $occams_record_test
|
58
59
|
q = base_scope(model).where(@ref.active_record_primary_key => ids)
|
59
60
|
yield q if ids.any?
|
60
61
|
end
|
@@ -156,7 +156,7 @@ module OccamsRecord
|
|
156
156
|
# @param use_transaction [Boolean] Ensure it runs inside of a database transaction
|
157
157
|
# @return [Enumerator] yields batches
|
158
158
|
#
|
159
|
-
def batches(of:, use_transaction: true)
|
159
|
+
def batches(of:, use_transaction: true, append_order_by: nil)
|
160
160
|
unless @sql =~ /LIMIT\s+%\{batch_limit\}/i and @sql =~ /OFFSET\s+%\{batch_offset\}/i
|
161
161
|
raise ArgumentError, "When using find_each/find_in_batches you must specify 'LIMIT %{batch_limit} OFFSET %{batch_offset}'. SQL statement: #{@sql}"
|
162
162
|
end
|
@@ -152,7 +152,7 @@ module OccamsRecord
|
|
152
152
|
def define_ids_reader!(assoc)
|
153
153
|
model = self.class._model
|
154
154
|
ref = model.reflections[assoc]
|
155
|
-
pkey = ref.
|
155
|
+
pkey = ref.klass.primary_key.to_sym
|
156
156
|
|
157
157
|
self.class.class_eval do
|
158
158
|
define_method "#{assoc.singularize}_ids" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: occams-record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Hollinger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '4.2'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '6.
|
22
|
+
version: '6.2'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: '4.2'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '6.
|
32
|
+
version: '6.2'
|
33
33
|
description: A faster, lower-memory querying API for ActiveRecord that returns results
|
34
34
|
as unadorned, read-only objects.
|
35
35
|
email: jordan.hollinger@gmail.com
|
@@ -81,8 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
requirements: []
|
84
|
-
|
85
|
-
rubygems_version: 2.7.6.2
|
84
|
+
rubygems_version: 3.0.3
|
86
85
|
signing_key:
|
87
86
|
specification_version: 4
|
88
87
|
summary: The missing high-efficiency query API for ActiveRecord
|