ector-multi 0.0.1 → 0.0.2
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/README.md +103 -2
- data/ector-multi.gemspec +1 -1
- data/lib/ector-multi.rb +1 -1
- data/lib/ector-multi/multi.rb +2 -5
- data/test/multi_test.rb +0 -7
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8e4aa1f612414eaba5439d00789aa46958ed335b12c998fcc9bb9147dfb1b82
|
4
|
+
data.tar.gz: 9ae7cca3656321979588be273ae48ee1e08c0a89a2bc97f1abb62fe2497f882b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b52d9f63225f8a9c994b6e69d431fe5f072d19fc3fbb54b92d088bd5ba0bba8c9ee34af054656414ac0c55ed1937a7af4807a5bef9a016b29beb35be38b6ad88
|
7
|
+
data.tar.gz: 8803a86bb7224de8a6b2dd5fc26c55b55c8bff89963fedb7d1ff1331b3a925cb030ddcd4fcc4dee320b0ab10b76f3d7ec2eeeecb84112e620bf5079f38bb3638
|
data/README.md
CHANGED
@@ -1,2 +1,103 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# Ector::Multi
|
2
|
+
[](http://badge.fury.io/rb/ector-multi)
|
3
|
+
[](https://travis-ci.org/emancu/ector-multi)
|
4
|
+
[](https://codeclimate.com/github/emancu/ector-multi)
|
5
|
+
[](https://rubygems.org/gems/ector-multi)
|
6
|
+
|
7
|
+
`Ector::Multi` is an object for grouping multiple DB operations that should be performed in a single database transaction.
|
8
|
+
|
9
|
+
I literally copy the API and idea from [Ecto::Multi](https://hexdocs.pm/ecto/Ecto.Multi.html), so I'm gonna copy the documentation as well.
|
10
|
+
|
11
|
+
## Dependencies
|
12
|
+
|
13
|
+
At this moment, `Ector::Multi` requires `ActiveRecord` as a dependency and relies on it for CRUD operations and transactions.
|
14
|
+
Eventually, I would like to be ORM-agnostic and be able to configure different ORMs and remove the hard dependency.
|
15
|
+
|
16
|
+
## Getting started
|
17
|
+
|
18
|
+
`Ector::Multi` is an object for grouping multiple database operations.
|
19
|
+
|
20
|
+
`Ector::Multi` makes it possible to pack operations that should be performed in a single database transaction and gives a way to introspect the queued operations without actually performing them. Each operation is given a name that is unique and will identify its result in case of success or failure.
|
21
|
+
|
22
|
+
All operations will be executed in the order they were added.
|
23
|
+
|
24
|
+
The `Ector::Multi` object should be considered opaque. You can use common ruby techniques to dig into it, but accessing fields or directly modifying them is not advised.
|
25
|
+
|
26
|
+
|
27
|
+
## Run
|
28
|
+
|
29
|
+
`Ector::Multi` allows you to run arbitrary functions as part of your transaction via `run`.
|
30
|
+
This is especially useful when an operation depends on the value of a previous operation.
|
31
|
+
For this reason, the function given as a callback to run will receive all changes performed by the multi so far.
|
32
|
+
|
33
|
+
The function given to `run` must return _something_ or raise a `Ector::Multi::OperationFailure`. Raising an error will abort any further operations and make the whole multi fail.
|
34
|
+
|
35
|
+
## Example
|
36
|
+
|
37
|
+
Let’s look at an example definition and usage. The use case we’ll be looking into is resetting a password.
|
38
|
+
We need to update the account with proper information, log the request and remove all current sessions:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
module PasswordManager
|
42
|
+
def self.reset(account, params)
|
43
|
+
Ector::Multi.new
|
44
|
+
.update(:account, account, params)
|
45
|
+
.create(:log, Log, account_id: account.id, changed_at: Time.now)
|
46
|
+
.destroy_all(:clear_sessions, Session.where(account_id: account.id))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
We can later execute it in the integration layer using `#commit`:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
result = PasswordManager.reset(account, params).commit
|
55
|
+
```
|
56
|
+
|
57
|
+
The resulting object, a `Ector::Multi::Result`, will tell you if it succeeded or failed. Also, it is possible to dig into the results of each operation.
|
58
|
+
|
59
|
+
## Functions
|
60
|
+
|
61
|
+
`multi.append(second_mutli)`
|
62
|
+
|
63
|
+
Appends the second multi to the first one
|
64
|
+
|
65
|
+
`multi.destroy(name, instance)`
|
66
|
+
|
67
|
+
Adds a destroy operation to the multi
|
68
|
+
|
69
|
+
`multi.delete_all(name, queryable)`
|
70
|
+
|
71
|
+
Adds a destroy_all operation to the multi
|
72
|
+
|
73
|
+
`multi.error(name, value)`
|
74
|
+
|
75
|
+
Causes the multi to fail with the given value
|
76
|
+
|
77
|
+
`multi.create(name, model, attributes, &block = nil)`
|
78
|
+
|
79
|
+
Adds a create operation to the multi
|
80
|
+
|
81
|
+
`Ector::Multi.new`
|
82
|
+
|
83
|
+
Returns an empty Ector::Multi object
|
84
|
+
|
85
|
+
`multi.prepend(second_multi)`
|
86
|
+
|
87
|
+
Prepends the second multi to the first one
|
88
|
+
|
89
|
+
`multi.run(name, &run)`
|
90
|
+
|
91
|
+
Adds a function to run as part of the multi
|
92
|
+
|
93
|
+
`multi.to_list`
|
94
|
+
|
95
|
+
Returns the list of operations stored in multi
|
96
|
+
|
97
|
+
`multi.update(name, instance, updates, &block = nil)`
|
98
|
+
|
99
|
+
Adds an update operation to the multi
|
100
|
+
|
101
|
+
`multi.update_all(name, queryable, updates, &block = nil)`
|
102
|
+
|
103
|
+
Adds an update_all operation to the multi
|
data/ector-multi.gemspec
CHANGED
@@ -23,6 +23,6 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.required_ruby_version = '>= 2.2'
|
24
24
|
|
25
25
|
s.add_dependency 'activerecord', '~> 5.2'
|
26
|
-
s.add_development_dependency 'protest', '~> 0'
|
26
|
+
s.add_development_dependency 'protest', '~> 0.6'
|
27
27
|
s.add_development_dependency 'sqlite3', '~> 0'
|
28
28
|
end
|
data/lib/ector-multi.rb
CHANGED
data/lib/ector-multi/multi.rb
CHANGED
@@ -32,10 +32,6 @@ module Ector
|
|
32
32
|
add_operation Operation::Error.new(name, operation_block(value, nil))
|
33
33
|
end
|
34
34
|
|
35
|
-
def merge(multi)
|
36
|
-
raise NotImplemented
|
37
|
-
end
|
38
|
-
|
39
35
|
def prepend(multi)
|
40
36
|
check_operation_uniqueness!(multi.to_list)
|
41
37
|
|
@@ -59,7 +55,8 @@ module Ector
|
|
59
55
|
def commit
|
60
56
|
results = {}
|
61
57
|
|
62
|
-
operations.find(&:fail_fast?)
|
58
|
+
fail_fast = operations.find(&:fail_fast?)
|
59
|
+
fail_fast.run(results) if fail_fast
|
63
60
|
|
64
61
|
::ActiveRecord::Base.transaction(joinable: false, requires_new: true) do
|
65
62
|
operations.each do |operation|
|
data/test/multi_test.rb
CHANGED
@@ -151,13 +151,6 @@ Protest.describe 'Ector::Multi' do
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
-
context '#merge'
|
155
|
-
|
156
|
-
# test 'returns self' do
|
157
|
-
# assert_equal @multi, @multi.merge(:dummy, ???)
|
158
|
-
# end
|
159
|
-
# end
|
160
|
-
|
161
154
|
context '#prepend' do
|
162
155
|
setup do
|
163
156
|
@left_multi = @multi.run(:left) { }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ector-multi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emiliano Mancuso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '0.6'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
40
|
+
version: '0.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: sqlite3
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|