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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3fb7ced8f877916cfaea950deed2cb24381cf8f34a8af4b15e11a17c7827e5d
4
- data.tar.gz: c63a11949ac704ebaf48ec98880ad8fb26aeec0024d63bd83fbb3d94e00e6634
3
+ metadata.gz: 6ceea75487deeadf930b9236a44980882ac539042e9d86b6ce5612da9c58642c
4
+ data.tar.gz: 190dab76b6f35d430f97a4be25ccf3fe56b652edb9722c83de844cd5c9d1715e
5
5
  SHA512:
6
- metadata.gz: e69251d02c9361741ee39fbaaa05c037c9a37b6182b4fdc87a1e376f585a9810848da5982e913ae63fc557ef68e33dbdabd3b1c63a9d411340610b4d649c5e29
7
- data.tar.gz: 6def010edc18851479f0f82184c91e4c595bdbd906e82c640b2e8752622b6e1904c063acbf79f438f23f1575acb6c1dffb211da46bfbc4486710e1ad52c1e326
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 won't limit you. (More complete examples are shown later, but these should whet your appetite.)
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.order(model.primary_key.to_sym).offset(offset).limit(l)
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.active_record_primary_key.to_s})
37
+ single!(assoc_rows, {@ref.foreign_key.to_s => @ref.association_primary_key.to_s})
37
38
  end
38
39
  end
39
40
  end
@@ -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.foreign_key => ids)
25
26
  q.where!(@ref.type => rows[0].class&.model_name) if @ref.options[:as]
@@ -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.association_primary_key.to_sym
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
@@ -3,5 +3,5 @@
3
3
  #
4
4
  module OccamsRecord
5
5
  # Library version
6
- VERSION = "1.1.3".freeze
6
+ VERSION = "1.2.0".freeze
7
7
  end
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.1.3
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: 2019-12-17 00:00:00.000000000 Z
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.1'
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.1'
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
- rubyforge_project:
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