occams-record 1.0.0.rc6 → 1.0.0.rc7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +4 -4
- data/lib/occams-record/eager_loaders/builder.rb +3 -2
- data/lib/occams-record/eager_loaders/context.rb +1 -2
- data/lib/occams-record/eager_loaders/through.rb +1 -0
- data/lib/occams-record/errors.rb +10 -0
- data/lib/occams-record/query.rb +8 -4
- data/lib/occams-record/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 964e9c20b250ab9599801912147978d7d477104d
|
4
|
+
data.tar.gz: 48184b52dbf038c40508bb6ab06e93399567196e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90243f9b079d7e94a6d474ffdee700dd1212e3066e96e2af89d662d70d7a253e85cbf1a793d9bd377b1962715205efa941a35d48f3b5d984710570f359c6cd24
|
7
|
+
data.tar.gz: 302edf479ab834b775394a6b1962fb0f1a707b81e4ea5e6db9d8441b5ad72e00ca5adf3c86a389f18e0923b621b425192b7eb7eb1fe5cead18c49aa3fbf2c29a
|
data/README.md
CHANGED
@@ -167,13 +167,13 @@ But that's very wasteful. Occams gives us better options: `eager_load_many` and
|
|
167
167
|
```ruby
|
168
168
|
products = OccamsRecord.
|
169
169
|
query(Product.all).
|
170
|
-
eager_load_many(:customers, {:id => :product_id},
|
170
|
+
eager_load_many(:customers, {:id => :product_id}, "
|
171
171
|
SELECT DISTINCT product_id, customers.*
|
172
172
|
FROM line_items
|
173
173
|
INNER JOIN orders ON line_items.order_id = orders.id
|
174
174
|
INNER JOIN customers on orders.customer_id = customers.id
|
175
175
|
WHERE line_items.product_id IN (%{ids})
|
176
|
-
|
176
|
+
", binds: {
|
177
177
|
# additional bind values (ids will be passed in for you)
|
178
178
|
}).
|
179
179
|
run
|
@@ -230,9 +230,9 @@ The following ActiveRecord features are not supported, and likely never will be.
|
|
230
230
|
|
231
231
|
# Benchmarking
|
232
232
|
|
233
|
-
`bundle exec rake bench` will run a suite of speed and memory benchmarks comparing Occams Record to Active Record. [You can find an example of a typical run here.](https://github.com/jhollinger/occams-record/wiki/Measurements)
|
233
|
+
`bundle exec rake bench` will run a suite of speed and memory benchmarks comparing Occams Record to Active Record. [You can find an example of a typical run here.](https://github.com/jhollinger/occams-record/wiki/Measurements) These are primarily used during development to prevent performance regressions. An in-memory Sqlite database is used.
|
234
234
|
|
235
|
-
If you run your own benchmarks, keep in mind exactly what you're measuring. For example if you're benchmarking a report written in AR vs OR, there are many constants in that measurement: the time spent in the database, the time spent sending the database results over the network, any calculations you're doing in Ruby, and the time spent building your html/json/csv/etc. So if OR is 3x
|
235
|
+
If you run your own benchmarks, keep in mind exactly what you're measuring. For example if you're benchmarking a report written in AR vs OR, there are many constants in that measurement: the time spent in the database, the time spent sending the database results over the network, any calculations you're doing in Ruby, and the time spent building your html/json/csv/etc. So if OR is 3x faster than AR, the total runtime of said report *won't* improve by 3x.
|
236
236
|
|
237
237
|
On the other hand, Active Record makes it *very* easy to forget to eager load associations (the N+1 query problem). Occams Record fixes that. So if your report was missing some associations you could see easily see performance improvements well over 3x.
|
238
238
|
|
@@ -19,7 +19,7 @@ module OccamsRecord
|
|
19
19
|
# @param from [Symbol] Opposite of `as`. `assoc` is the custom name and `from` is the name of association on the ActiveRecord model.
|
20
20
|
# @param optimizer [Symbol] Only used for `through` associations. Options are :none (load all intermediate records) | :select (load all intermediate records but only SELECT the necessary columns)
|
21
21
|
# @yield a block where you may perform eager loading on *this* association (optional)
|
22
|
-
# @return
|
22
|
+
# @return self
|
23
23
|
#
|
24
24
|
def eager_load(assoc, scope = nil, select: nil, use: nil, as: nil, from: nil, optimizer: :select, &builder)
|
25
25
|
@eager_loaders.add(assoc, scope, select: select, use: use, as: as, from: from, optimizer: optimizer, &builder)
|
@@ -41,7 +41,6 @@ module OccamsRecord
|
|
41
41
|
# @param optimizer [Symbol] Only used for `through` associations. Options are :none (load all intermediate records) | :select (load all intermediate records but only SELECT the necessary columns)
|
42
42
|
# @return [OccamsRecord::EagerLoaders::Base]
|
43
43
|
#
|
44
|
-
#
|
45
44
|
def nest(assoc, scope = nil, select: nil, use: nil, as: nil, from: nil, optimizer: :select)
|
46
45
|
raise ArgumentError, "OccamsRecord::EagerLoaders::Builder#nest does not accept a block!" if block_given?
|
47
46
|
@eager_loaders.add(assoc, scope, select: select, use: use, as: as, from: from, optimizer: optimizer) ||
|
@@ -73,6 +72,7 @@ module OccamsRecord
|
|
73
72
|
# @param model [ActiveRecord::Base] optional - ActiveRecord model that represents what you're loading. required when using Sqlite.
|
74
73
|
# @param use [Array<Module>] optional - Ruby modules to include in the result objects (single or array)
|
75
74
|
# @yield eager load associations nested under this one
|
75
|
+
# @return self
|
76
76
|
#
|
77
77
|
def eager_load_one(name, mapping, sql, binds: {}, model: nil, use: nil, &builder)
|
78
78
|
@eager_loaders << EagerLoaders::AdHocOne.new(name, mapping, sql, binds: binds, model: model, use: use, &builder)
|
@@ -105,6 +105,7 @@ module OccamsRecord
|
|
105
105
|
# @param binds [Hash] any additional binds for your query.
|
106
106
|
# @param model [ActiveRecord::Base] optional - ActiveRecord model that represents what you're loading. required when using Sqlite.
|
107
107
|
# @yield eager load associations nested under this one
|
108
|
+
# @return self
|
108
109
|
#
|
109
110
|
def eager_load_many(name, mapping, sql, binds: {}, model: nil, use: nil, &builder)
|
110
111
|
@eager_loaders << EagerLoaders::AdHocMany.new(name, mapping, sql, binds: binds, model: model, use: use, &builder)
|
@@ -18,8 +18,7 @@ module OccamsRecord
|
|
18
18
|
# Initialize a new eager loading context.
|
19
19
|
#
|
20
20
|
# @param mode [ActiveRecord::Base] the model that contains the associations that will be referenced.
|
21
|
-
# @param polymorphic [Boolean] When true, model is allowed to change, and it's assumed that not every loader
|
22
|
-
# is applicable to every model.
|
21
|
+
# @param polymorphic [Boolean] When true, model is allowed to change, and it's assumed that not every loader is applicable to every model.
|
23
22
|
#
|
24
23
|
def initialize(model = nil, polymorphic: false)
|
25
24
|
@model, @polymorphic = model, polymorphic
|
data/lib/occams-record/errors.rb
CHANGED
@@ -14,6 +14,11 @@ module OccamsRecord
|
|
14
14
|
@record, @name = record, name
|
15
15
|
@model_name = record.class.model_name
|
16
16
|
end
|
17
|
+
|
18
|
+
# @return [String]
|
19
|
+
def to_s
|
20
|
+
message
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
24
|
# Exception when an unselected column is called on a result row
|
@@ -45,6 +50,11 @@ module OccamsRecord
|
|
45
50
|
@model_name, @attrs = model_name, attrs
|
46
51
|
end
|
47
52
|
|
53
|
+
# @return [String]
|
54
|
+
def to_s
|
55
|
+
message
|
56
|
+
end
|
57
|
+
|
48
58
|
# @return [String]
|
49
59
|
def message
|
50
60
|
"#{model_name} could not be found with #{attrs}!"
|
data/lib/occams-record/query.rb
CHANGED
@@ -3,9 +3,9 @@ require 'occams-record/batches'
|
|
3
3
|
module OccamsRecord
|
4
4
|
#
|
5
5
|
# Starts building a OccamsRecord::Query. Pass it a scope from any of ActiveRecord's query builder
|
6
|
-
# methods or associations. If you want to eager loaded associations, do NOT
|
7
|
-
# Instead
|
8
|
-
# array of objects.
|
6
|
+
# methods or associations. If you want to eager loaded associations, do NOT use ActiveRecord for it.
|
7
|
+
# Instead use OccamsRecord::Query#eager_load. Finally, call `run` (or any Enumerable method) to run
|
8
|
+
# the query and get back an array of objects.
|
9
9
|
#
|
10
10
|
# results = OccamsRecord.
|
11
11
|
# query(Widget.order("name")).
|
@@ -61,6 +61,7 @@ module OccamsRecord
|
|
61
61
|
#
|
62
62
|
# @yield [ActiveRecord::Relation] the current scope which you may modify and return
|
63
63
|
# @return [OccamsRecord::Query]
|
64
|
+
#
|
64
65
|
def query
|
65
66
|
scope = block_given? ? yield(@scope) : @scope
|
66
67
|
Query.new(scope, use: @use, eager_loaders: @eager_loaders, query_logger: @query_logger)
|
@@ -83,8 +84,11 @@ module OccamsRecord
|
|
83
84
|
# # returns ALL rows
|
84
85
|
# occams.run
|
85
86
|
#
|
86
|
-
#
|
87
|
+
# Any Enumerable method (e.g. each, to_a, map, reduce, etc.) may be used instead. Additionally,
|
88
|
+
# `find_each` and `find_in_batches` are available.
|
89
|
+
#
|
87
90
|
# @yield [ActiveRecord::Relation] You may use this to return and run a modified relation
|
91
|
+
# @return [Array<OccamsRecord::Results::Row>]
|
88
92
|
#
|
89
93
|
def run
|
90
94
|
sql = block_given? ? yield(scope).to_sql : scope.to_sql
|
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.0.0.
|
4
|
+
version: 1.0.0.rc7
|
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-01-
|
11
|
+
date: 2019-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -79,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
version: 1.3.1
|
80
80
|
requirements: []
|
81
81
|
rubyforge_project:
|
82
|
-
rubygems_version: 2.
|
82
|
+
rubygems_version: 2.5.2.3
|
83
83
|
signing_key:
|
84
84
|
specification_version: 4
|
85
85
|
summary: The missing high-efficiency query API for ActiveRecord
|