esse-sequel 0.0.1.beta1
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 +7 -0
- data/.rubocop.yml +37 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +21 -0
- data/README.md +265 -0
- data/Rakefile +8 -0
- data/docs/README.md +55 -0
- data/docs/api.md +119 -0
- data/docs/usage.md +211 -0
- data/lib/esse/plugins/sequel.rb +55 -0
- data/lib/esse/sequel/callbacks/indexing_on_create.rb +16 -0
- data/lib/esse/sequel/callbacks/indexing_on_destroy.rb +18 -0
- data/lib/esse/sequel/callbacks/indexing_on_update.rb +60 -0
- data/lib/esse/sequel/callbacks/update_lazy_attribute.rb +27 -0
- data/lib/esse/sequel/callbacks.rb +66 -0
- data/lib/esse/sequel/collection.rb +191 -0
- data/lib/esse/sequel/hooks.rb +11 -0
- data/lib/esse/sequel/model.rb +138 -0
- data/lib/esse/sequel/version.rb +7 -0
- data/lib/esse/sequel.rb +16 -0
- data/mise.toml +2 -0
- metadata +232 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 556f57525adf41b371e1e117bf9a31d4c72967ec400a46bcd2de4d6b155b0536
|
|
4
|
+
data.tar.gz: 0ae837cc171d0065ec04fec57130f82613932de578c90a5c4fd98da982c98582
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 46fd592b16c0f972389d6116fba050d5396ed26e2485964c18f09b1de23af37d739ae71e331daca1f1c2702e196191f90f0bd2b90e2517c56bde3b9c1944461b
|
|
7
|
+
data.tar.gz: 40a434be03f7339f8f39096777dd6e2d068b948b32c101cef1ec614af5ccc9eb7ccf063554a42de7cf4fe33502b20f3ef3e6b7863e0fcd8dca277b1dbfa203d0
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
inherit_mode:
|
|
2
|
+
merge:
|
|
3
|
+
- Exclude
|
|
4
|
+
|
|
5
|
+
plugins:
|
|
6
|
+
- rubocop-performance
|
|
7
|
+
- rubocop-rspec
|
|
8
|
+
|
|
9
|
+
require:
|
|
10
|
+
- standard/cop/block_single_line_braces
|
|
11
|
+
|
|
12
|
+
inherit_gem:
|
|
13
|
+
standard: config/base.yml
|
|
14
|
+
|
|
15
|
+
AllCops:
|
|
16
|
+
TargetRubyVersion: 2.6
|
|
17
|
+
SuggestExtensions: false
|
|
18
|
+
Exclude:
|
|
19
|
+
- "db/**/*"
|
|
20
|
+
- "tmp/**/*"
|
|
21
|
+
- "vendor/**/*"
|
|
22
|
+
NewCops: enable
|
|
23
|
+
|
|
24
|
+
RSpec/MultipleExpectations:
|
|
25
|
+
Enabled: false
|
|
26
|
+
|
|
27
|
+
RSpec/ExampleLength:
|
|
28
|
+
Enabled: false
|
|
29
|
+
|
|
30
|
+
RSpec/MultipleMemoizedHelpers:
|
|
31
|
+
Enabled: false
|
|
32
|
+
|
|
33
|
+
RSpec/MessageSpies:
|
|
34
|
+
Enabled: false
|
|
35
|
+
|
|
36
|
+
RSpec/StubbedMock:
|
|
37
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## 0.0.1.beta1
|
|
8
|
+
The first release of the esse-sequel plugin
|
|
9
|
+
* Added: Initial implementation of the plugin
|
data/Gemfile
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
6
|
+
|
|
7
|
+
gem "esse", "~> 0.3.4"
|
|
8
|
+
gem "sqlite3"
|
|
9
|
+
gem "esse-rspec"
|
|
10
|
+
gem "logger"
|
|
11
|
+
gem "elasticsearch", "~> 7.17", ">= 7.17.10"
|
|
12
|
+
|
|
13
|
+
# Specify your gem's dependencies in esse-sequel.gemspec
|
|
14
|
+
gemspec
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Marcos G. Zimmermann
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# Esse Sequel Plugin
|
|
2
|
+
|
|
3
|
+
This gem is a [esse](https://github.com/marcosgz/esse) plugin for the Sequel ORM. It provides a set of methods to simplify implementation of Sequel models as datasource of esse indexes.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
Full guides, usage examples, and API reference are published at **[gems.marcosz.com.br/esse-sequel](https://gems.marcosz.com.br/esse-sequel/)** — part of the [marcosgz Ruby gem catalogue](https://gems.marcosz.com.br).
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add this line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem 'esse-sequel'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
And then execute:
|
|
18
|
+
|
|
19
|
+
$ bundle install
|
|
20
|
+
|
|
21
|
+
Or install it yourself as:
|
|
22
|
+
|
|
23
|
+
$ gem install esse-sequel
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
Add the `:sequel` plugin and configure the `collection` with the Sequel model you want to use.
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
class UsersIndex < Esse::Index
|
|
31
|
+
plugin :sequel
|
|
32
|
+
|
|
33
|
+
repository :user do
|
|
34
|
+
collection ::User
|
|
35
|
+
document # ...
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Using multiple repositories is also possible:
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
class UsersIndex < Esse::Index
|
|
44
|
+
plugin :sequel
|
|
45
|
+
|
|
46
|
+
repository :account do
|
|
47
|
+
collection ::Account
|
|
48
|
+
document # ...
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
repository :admin do
|
|
52
|
+
collection ::User.where(admin: true)
|
|
53
|
+
document # ...
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Collection Scope
|
|
59
|
+
It's also possible to specify custom scopes to the repository collection to be used to import data to the index:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
class UsersIndex < Esse::Index
|
|
63
|
+
plugin :sequel
|
|
64
|
+
|
|
65
|
+
repository :user do
|
|
66
|
+
collection ::User do
|
|
67
|
+
scope :active, -> { where(active: true) }
|
|
68
|
+
scope :role, ->(role) { where(role: role) }
|
|
69
|
+
end
|
|
70
|
+
document # ...
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Import data using the scopes
|
|
75
|
+
# > UsersIndex.import(context: { active: true, role: 'admin' })
|
|
76
|
+
#
|
|
77
|
+
# Streaming data using the scopes
|
|
78
|
+
# > UsersIndex.documents(active: true, role: 'admin').first
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Collection Batch Context
|
|
82
|
+
|
|
83
|
+
Assume that you have a collection of orders and you want to also include the customer data that lives in a external system. To avoid making a request for each order, you can use the `batch_context` to fetch the data in batches and make it available in the document context.
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
class OrdersIndex < Esse::Index
|
|
87
|
+
plugin :sequel
|
|
88
|
+
|
|
89
|
+
repository :order do
|
|
90
|
+
collection ::Order do
|
|
91
|
+
batch_context :customers do |orders, **_existing_context|
|
|
92
|
+
# The return value will be available in the document context
|
|
93
|
+
# { customers: <value returned from this block> }
|
|
94
|
+
ExternalSystem::Customer.find_all_by_ids(orders.map(&:customer_id)).index_by(&:id) # => { 1 => <Customer>, 2 => <Customer> }
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
document do |order, customers: {}, **_|
|
|
98
|
+
customer = customers[order.customer_id]
|
|
99
|
+
{
|
|
100
|
+
id: order.id,
|
|
101
|
+
customer: {
|
|
102
|
+
id: customer&.id,
|
|
103
|
+
name: customer&.name
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
For Sequel associations, you can define the repository collection by eager loading the associations as usual:
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
|
|
115
|
+
class OrdersIndex < Esse::Index
|
|
116
|
+
plugin :sequel
|
|
117
|
+
|
|
118
|
+
repository :order do
|
|
119
|
+
collection ::Order.eager(:customer)
|
|
120
|
+
document do |order, **_|
|
|
121
|
+
{
|
|
122
|
+
id: order.id,
|
|
123
|
+
customer: {
|
|
124
|
+
id: order.customer&.id,
|
|
125
|
+
name: order.customer&.name
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Data Streaming Options
|
|
134
|
+
|
|
135
|
+
By default the collection supports 3 streaming options:
|
|
136
|
+
* `batch_size`: the number of documents to be streamed in each batch. Default is 1000;
|
|
137
|
+
* `start`: the primary key value to start from, inclusive of the value;
|
|
138
|
+
* `finish`: the primary key value to end at, inclusive of the value;
|
|
139
|
+
|
|
140
|
+
This is useful when you want to import simultaneous data. You can make one process import all records between 1 and 10,000, and another from 10,000 and beyond
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
UsersIndex.import(context: { start: 1, finish: 10000, batch_size: 500 })
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The default value of `batch_size` can be also defined in the `collection` configuration:
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
class UsersIndex < Esse::Index
|
|
150
|
+
plugin :sequel
|
|
151
|
+
|
|
152
|
+
repository :user do
|
|
153
|
+
collection ::User, batch_size: 500
|
|
154
|
+
document # ...
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Database Server (Sharding)
|
|
160
|
+
|
|
161
|
+
If the Sequel database is configured with multiple servers, the collection queries can be routed to one of them using the `connect_with` option or the `connected_to` method:
|
|
162
|
+
|
|
163
|
+
```ruby
|
|
164
|
+
DB = Sequel.connect(ENV["DATABASE_URL"], servers: { read_only: { host: "replica" } })
|
|
165
|
+
|
|
166
|
+
class UsersIndex < Esse::Index
|
|
167
|
+
plugin :sequel
|
|
168
|
+
|
|
169
|
+
repository :user do
|
|
170
|
+
collection ::User, connect_with: { server: :read_only }
|
|
171
|
+
# or
|
|
172
|
+
collection ::User do
|
|
173
|
+
connected_to server: :read_only
|
|
174
|
+
end
|
|
175
|
+
document # ...
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The collection dataset runs on the given server. When the [server_block](https://sequel.jeremyevans.net/rdoc-plugins/files/lib/sequel/extensions/server_block_rb.html) extension is loaded (`DB.extension :server_block`), the whole batch iteration, including `batch_context` queries, runs inside `DB.with_server`.
|
|
181
|
+
|
|
182
|
+
### Indexing Callbacks
|
|
183
|
+
|
|
184
|
+
The `index_callback` callback can be used to automatically index or delete documents after commit on create/update/destroy events. Include the `Esse::Sequel::Model` module in the model to enable it.
|
|
185
|
+
|
|
186
|
+
```ruby
|
|
187
|
+
class UsersIndex < Esse::Index
|
|
188
|
+
plugin :sequel
|
|
189
|
+
|
|
190
|
+
repository :user, const: true do
|
|
191
|
+
collection ::User
|
|
192
|
+
document # ...
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
class User < Sequel::Model
|
|
197
|
+
include Esse::Sequel::Model
|
|
198
|
+
many_to_one :organization
|
|
199
|
+
|
|
200
|
+
# Using a index and repository as argument. Note that the index name is used instead of the
|
|
201
|
+
# of the constant name. it's so because index and model depends on each other should result in
|
|
202
|
+
# circular dependencies issues.
|
|
203
|
+
index_callback 'users_index:user'
|
|
204
|
+
# Using a block to direct a different object to be indexed
|
|
205
|
+
index_callback('organizations') { organization } # The `_index` suffix and repo name is optional on the index name
|
|
206
|
+
end
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Callbacks run in the `after_create`, `after_update` and `after_destroy` model hooks and are deferred with `DB.after_commit`, so documents are only indexed after the transaction commits, and are not indexed at all when it is rolled back. Models that override these hooks must call `super`.
|
|
210
|
+
|
|
211
|
+
When a document uses a routing key, the update callback also deletes the document from its previous routing when the routing value changes. This requires the previous column values, so load the [dirty](https://sequel.jeremyevans.net/rdoc-plugins/classes/Sequel/Plugins/Dirty.html) plugin in those models:
|
|
212
|
+
|
|
213
|
+
```ruby
|
|
214
|
+
class City < Sequel::Model
|
|
215
|
+
plugin :dirty
|
|
216
|
+
include Esse::Sequel::Model
|
|
217
|
+
|
|
218
|
+
index_callback 'geos_index:city'
|
|
219
|
+
end
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Callbacks can also be disabled/enabled globally:
|
|
223
|
+
|
|
224
|
+
```ruby
|
|
225
|
+
Esse::Sequel::Hooks.disable!
|
|
226
|
+
Esse::Sequel::Hooks.enable!
|
|
227
|
+
Esse::Sequel::Hooks.without_indexing do
|
|
228
|
+
10.times { User.create! }
|
|
229
|
+
end
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
or by some specific list of index or index's repository
|
|
233
|
+
|
|
234
|
+
```ruby
|
|
235
|
+
Esse::Sequel::Hooks.disable!(UsersIndex.repo)
|
|
236
|
+
Esse::Sequel::Hooks.enable!(UsersIndex.repo)
|
|
237
|
+
Esse::Sequel::Hooks.without_indexing(AccountsIndex, UsersIndex.repo) do
|
|
238
|
+
10.times { User.create! }
|
|
239
|
+
end
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
or by the model that the callback is configured
|
|
243
|
+
|
|
244
|
+
```ruby
|
|
245
|
+
User.without_indexing do
|
|
246
|
+
10.times { User.create! }
|
|
247
|
+
end
|
|
248
|
+
User.without_indexing(AccountsIndex) do
|
|
249
|
+
10.times { User.create! }
|
|
250
|
+
end
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Development
|
|
254
|
+
|
|
255
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
256
|
+
|
|
257
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
258
|
+
|
|
259
|
+
## Contributing
|
|
260
|
+
|
|
261
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/marcosgz/esse-sequel.
|
|
262
|
+
|
|
263
|
+
## License
|
|
264
|
+
|
|
265
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/docs/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# esse-sequel
|
|
2
|
+
|
|
3
|
+
Sequel ORM integration for [Esse](../../esse/docs/README.md). The API mirrors [esse-active_record](../../esse-active_record/docs/README.md) — if you know one, you know the other.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- [Usage guide](usage.md)
|
|
8
|
+
- [API reference](api.md)
|
|
9
|
+
|
|
10
|
+
## What you get
|
|
11
|
+
|
|
12
|
+
- `collection Model` DSL for repositories.
|
|
13
|
+
- `scope`, `batch_context`, `connected_to` inside collections.
|
|
14
|
+
- `index_callback` and `update_lazy_attribute_callback` on Sequel models.
|
|
15
|
+
- `Esse::Sequel::Hooks` for enabling/disabling indexing globally or per-repo.
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
# Gemfile
|
|
21
|
+
gem 'esse', '>= 0.3.0'
|
|
22
|
+
gem 'esse-sequel'
|
|
23
|
+
gem 'sequel', '>= 5.0'
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
class UsersIndex < Esse::Index
|
|
28
|
+
plugin :sequel
|
|
29
|
+
|
|
30
|
+
repository :user do
|
|
31
|
+
collection ::User do
|
|
32
|
+
scope :active, -> { where(active: true) }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
document { |u, **| { _id: u.id, name: u.name } }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class User < Sequel::Model
|
|
40
|
+
include Esse::Sequel::Model
|
|
41
|
+
index_callback 'users_index:user'
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Every `User.create`, `update`, and `destroy` now syncs to Elasticsearch.
|
|
46
|
+
|
|
47
|
+
## Version
|
|
48
|
+
|
|
49
|
+
- Version: **0.0.1.beta1**
|
|
50
|
+
- Ruby: `>= 2.4.0`
|
|
51
|
+
- Depends on: `esse >= 0.3.0`, `esse-hooks`, `sequel >= 5.0`
|
|
52
|
+
|
|
53
|
+
## License
|
|
54
|
+
|
|
55
|
+
MIT.
|
data/docs/api.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
## `Esse::Plugins::Sequel`
|
|
4
|
+
|
|
5
|
+
Registered with:
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
plugin :sequel
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Repository class methods
|
|
12
|
+
|
|
13
|
+
#### `collection(model, **opts, &block)`
|
|
14
|
+
|
|
15
|
+
Accepts a `Sequel::Model` class or a `Sequel::Dataset`. Produces an `Esse::Sequel::Collection` subclass.
|
|
16
|
+
|
|
17
|
+
| Argument | Description |
|
|
18
|
+
|----------|-------------|
|
|
19
|
+
| `model` | Sequel model class or dataset |
|
|
20
|
+
| `batch_size:` | Records per batch (default `1000`) |
|
|
21
|
+
| `connect_with:` | `{server: :name}` to run the queries on a Sequel server (shard) |
|
|
22
|
+
| `&block` | Evaluated in the collection class scope (`scope`, `batch_context`, `connected_to`) |
|
|
23
|
+
|
|
24
|
+
#### `dataset(**params)`
|
|
25
|
+
|
|
26
|
+
Returns the filtered `Sequel::Dataset` after applying scopes.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## `Esse::Sequel::Collection`
|
|
31
|
+
|
|
32
|
+
Base class. Same interface as `Esse::ActiveRecord::Collection`. Batches are fetched with keyset pagination over the model primary key.
|
|
33
|
+
|
|
34
|
+
### Class-level DSL
|
|
35
|
+
|
|
36
|
+
- `scope(name, proc = nil, override: false, &block)` — define a named scope.
|
|
37
|
+
- `batch_context(name, proc = nil, override: false, &block)` — define a batch enrichment fetcher.
|
|
38
|
+
- `connected_to(server:)` — run the queries on the given Sequel server. Uses `DB.with_server` for the whole iteration when the `server_block` extension is loaded.
|
|
39
|
+
|
|
40
|
+
### Instance methods
|
|
41
|
+
|
|
42
|
+
| Method | Description |
|
|
43
|
+
|--------|-------------|
|
|
44
|
+
| `each { |rows, **ctx| }` | Iterate batches with scopes + contexts applied |
|
|
45
|
+
| `each_batch_ids { |ids| }` | Iterate ID-only batches |
|
|
46
|
+
| `count` / `size` | Total row count |
|
|
47
|
+
| `dataset(**kwargs)` | Filtered `Sequel::Dataset` |
|
|
48
|
+
|
|
49
|
+
Constructor:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
CollectionClass.new(start: 1, finish: 10_000, batch_size: 500, **scope_args)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## `Esse::Sequel::Model`
|
|
58
|
+
|
|
59
|
+
Mixin for Sequel models. `include` it to enable callbacks.
|
|
60
|
+
|
|
61
|
+
### `index_callback(reference, on: [...], with: nil, **opts, &block)`
|
|
62
|
+
|
|
63
|
+
Registers a callback that runs after the transaction commits (`DB.after_commit` from the model `after_create`/`after_update`/`after_destroy` hooks).
|
|
64
|
+
|
|
65
|
+
| Option | Description |
|
|
66
|
+
|--------|-------------|
|
|
67
|
+
| `reference` | `'index_name:repo_name'` (or class form) |
|
|
68
|
+
| `on:` | Subset of `[:create, :update, :destroy]`, default all |
|
|
69
|
+
| `with:` | `:update` for partial updates |
|
|
70
|
+
| `if:` / `unless:` | Conditional predicates |
|
|
71
|
+
| `&block` | Optional — return the object to index |
|
|
72
|
+
|
|
73
|
+
Raises if the same repo already has a callback registered.
|
|
74
|
+
|
|
75
|
+
### `update_lazy_attribute_callback(reference, attribute, on: [...], **opts, &block)`
|
|
76
|
+
|
|
77
|
+
Registers a callback that calls `repo.update_documents_attribute(attribute, ids, opts)`.
|
|
78
|
+
|
|
79
|
+
### `without_indexing(*repos, &block)`
|
|
80
|
+
|
|
81
|
+
Temporarily disables callbacks for this model class.
|
|
82
|
+
|
|
83
|
+
### `esse_callbacks`
|
|
84
|
+
|
|
85
|
+
Returns a frozen hash of registered callbacks per reference.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## `Esse::Sequel::Hooks`
|
|
90
|
+
|
|
91
|
+
Includes `Esse::Hooks[store_key: :esse_sequel_hooks]`. See [esse-hooks](../../esse-hooks/docs/README.md) for the full API. Methods include:
|
|
92
|
+
|
|
93
|
+
- `disable!` / `enable!` (global or per-repo).
|
|
94
|
+
- `with_indexing` / `without_indexing` (scoped).
|
|
95
|
+
- `with_indexing_for_model` / `without_indexing_for_model`.
|
|
96
|
+
- `enabled?` / `disabled?` / `enabled_for_model?`.
|
|
97
|
+
- `resolve_index_repository(reference)`.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Built-in callbacks
|
|
102
|
+
|
|
103
|
+
Registered in `Esse::Sequel::Callbacks`. All inherit from `Esse::Sequel::Callback`.
|
|
104
|
+
|
|
105
|
+
| Callback | Behavior |
|
|
106
|
+
|----------|----------|
|
|
107
|
+
| `IndexingOnCreate` | `repo.index(document)` on create |
|
|
108
|
+
| `IndexingOnUpdate` | `repo.update(document)` or `repo.index(document)` (depending on `with:`). Handles routing changes by deleting the previous document at the old routing (requires the `dirty` plugin). |
|
|
109
|
+
| `IndexingOnDestroy` | `repo.delete(document)` on destroy. Silently handles `NotFoundError`. |
|
|
110
|
+
| `UpdateLazyAttribute` | `repo.update_documents_attribute(attribute, ids, opts)` |
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Deprecated methods
|
|
115
|
+
|
|
116
|
+
| Deprecated | Use instead |
|
|
117
|
+
|------------|-------------|
|
|
118
|
+
| `index_callbacks` | `index_callback` |
|
|
119
|
+
| `esse_index_repos` | `esse_callbacks` |
|