ector-multi 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/ector-multi.svg)](http://badge.fury.io/rb/ector-multi)
|
3
|
+
[![Build Status](https://travis-ci.org/emancu/ector-multi.svg)](https://travis-ci.org/emancu/ector-multi)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/emancu/ector-multi/badges/gpa.svg)](https://codeclimate.com/github/emancu/ector-multi)
|
5
|
+
[![RubyGem](https://img.shields.io/gem/dt/ector-multi.svg)](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
|