ephemeron 0.1.0
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/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +29 -0
- data/lib/ephemeron.rb +98 -0
- data/lib/ephemeron/addons/controller_addons.rb +11 -0
- data/lib/ephemeron/addons/model_addons.rb +33 -0
- data/lib/ephemeron/errors.rb +12 -0
- data/lib/ephemeron/logger/convert.rb +13 -0
- data/lib/ephemeron/logger/finders.rb +24 -0
- data/lib/ephemeron/railtie.rb +6 -0
- data/lib/ephemeron/settings.rb +19 -0
- data/lib/ephemeron/store/convert.rb +24 -0
- data/lib/ephemeron/store/update.rb +20 -0
- data/lib/ephemeron/validators/before_save.rb +21 -0
- data/lib/ephemeron/validators/store.rb +14 -0
- data/lib/ephemeron/validators/store/allowed_but_unsaved.rb +21 -0
- data/lib/ephemeron/validators/store/unused.rb +25 -0
- data/lib/ephemeron/validators/store_element.rb +17 -0
- data/lib/ephemeron/version.rb +5 -0
- data/lib/ephemeron/writers/callbacks.rb +23 -0
- data/lib/ephemeron/writers/logger.rb +59 -0
- data/lib/ephemeron/writers/store.rb +66 -0
- data/lib/ephemeron/writers/thread_store.rb +9 -0
- data/lib/tasks/ephemeron_tasks.rake +5 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 032a79004b77bffee915f105cd807beb01fcc60c52e829c478fcf615a8fa8184
|
4
|
+
data.tar.gz: 65168d9788376856e6745c083f2a0d467b18deace844719e59024e9027a47db4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 88ddba6984c039180c74433d9dc9447eae247b040700f3de02c0338e6a9ffe95dc3472c7eb982b81a867044d1c214c15cafe0ede0bf9286308d15f59664e403b
|
7
|
+
data.tar.gz: 6488f41b9df17130dbedb9f1db5bfa72e1aeded337863e46fe03e898728ed6aa5dfac2666f8cdaaf7004bf0623900f1073195327e06653994d4b974a17f67f1a
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2019 Zbigniew Humeniuk
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Ephemeron
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'ephemeron'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install ephemeron
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rdoc/task'
|
10
|
+
|
11
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
12
|
+
rdoc.rdoc_dir = 'rdoc'
|
13
|
+
rdoc.title = 'Ephemeron'
|
14
|
+
rdoc.options << '--line-numbers'
|
15
|
+
rdoc.rdoc_files.include('README.md')
|
16
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'bundler/gem_tasks'
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
|
23
|
+
Rake::TestTask.new(:test) do |t|
|
24
|
+
t.libs << 'test'
|
25
|
+
t.pattern = 'test/**/*_test.rb'
|
26
|
+
t.verbose = false
|
27
|
+
end
|
28
|
+
|
29
|
+
task default: :test
|
data/lib/ephemeron.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ephemeron/railtie'
|
4
|
+
|
5
|
+
require 'ephemeron/addons/controller_addons'
|
6
|
+
require 'ephemeron/addons/model_addons'
|
7
|
+
|
8
|
+
require 'ephemeron/writers/thread_store'
|
9
|
+
require 'ephemeron/writers/callbacks'
|
10
|
+
require 'ephemeron/writers/logger'
|
11
|
+
require 'ephemeron/writers/store'
|
12
|
+
|
13
|
+
require 'ephemeron/errors'
|
14
|
+
require 'ephemeron/logger/convert'
|
15
|
+
require 'ephemeron/logger/finders'
|
16
|
+
require 'ephemeron/settings'
|
17
|
+
require 'ephemeron/store/convert'
|
18
|
+
require 'ephemeron/store/update'
|
19
|
+
require 'ephemeron/validators/before_save'
|
20
|
+
require 'ephemeron/validators/store'
|
21
|
+
require 'ephemeron/validators/store_element'
|
22
|
+
require 'ephemeron/validators/store/allowed_but_unsaved'
|
23
|
+
require 'ephemeron/validators/store/unused'
|
24
|
+
|
25
|
+
module Ephemeron
|
26
|
+
module_function
|
27
|
+
|
28
|
+
def configure
|
29
|
+
Ephemeron::Settings::CONFIG.new.tap do |config|
|
30
|
+
yield config
|
31
|
+
Ephemeron::Settings.configure config
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def state
|
36
|
+
Store.store
|
37
|
+
end
|
38
|
+
|
39
|
+
def logs
|
40
|
+
Logger.logs
|
41
|
+
end
|
42
|
+
|
43
|
+
def add(model, as: nil)
|
44
|
+
Store.add model, as: as
|
45
|
+
end
|
46
|
+
|
47
|
+
def proxy
|
48
|
+
Logger.log nil, :proxy_start
|
49
|
+
yield
|
50
|
+
Logger.log nil, :proxy_end
|
51
|
+
end
|
52
|
+
|
53
|
+
def get(key)
|
54
|
+
Store.get key
|
55
|
+
end
|
56
|
+
|
57
|
+
def used(model_s)
|
58
|
+
log_used = ->(model) { Logger.log model, :used }
|
59
|
+
if model_s.is_a? ActiveRecord::Base
|
60
|
+
log_used.call model_s
|
61
|
+
else
|
62
|
+
model_s.each(&log_used)
|
63
|
+
end
|
64
|
+
model_s
|
65
|
+
end
|
66
|
+
|
67
|
+
def allow_save!(model)
|
68
|
+
model.tap { |m| Logger.log m, :save_allowed }
|
69
|
+
end
|
70
|
+
|
71
|
+
def skip_save!(model)
|
72
|
+
Logger.log model, :skip_save
|
73
|
+
end
|
74
|
+
|
75
|
+
def after_save!(&block)
|
76
|
+
Callbacks.add block
|
77
|
+
end
|
78
|
+
|
79
|
+
def finish
|
80
|
+
if Store.aliases[nil] != :abort
|
81
|
+
Store.validate
|
82
|
+
Store.persist
|
83
|
+
Callbacks.call
|
84
|
+
end
|
85
|
+
reset
|
86
|
+
end
|
87
|
+
|
88
|
+
def stop
|
89
|
+
Store.aliases[nil] = :abort
|
90
|
+
end
|
91
|
+
|
92
|
+
def reset
|
93
|
+
Store.reset
|
94
|
+
Logger.reset
|
95
|
+
Callbacks.reset
|
96
|
+
true
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
module ModelAddons
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
after_find lambda { |model|
|
9
|
+
Ephemeron.add model
|
10
|
+
}
|
11
|
+
|
12
|
+
after_validation lambda { |model|
|
13
|
+
Logger.log model, :used, soft: true
|
14
|
+
}
|
15
|
+
|
16
|
+
before_save lambda { |model|
|
17
|
+
Validators::BeforeSave.call model
|
18
|
+
}
|
19
|
+
|
20
|
+
after_create lambda { |model|
|
21
|
+
Store::Update.call model
|
22
|
+
}
|
23
|
+
|
24
|
+
after_save lambda { |model|
|
25
|
+
Logger.log model, :saved
|
26
|
+
}
|
27
|
+
|
28
|
+
after_destroy lambda { |model|
|
29
|
+
Ephemeron::Store.destroy model
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
class Logger
|
5
|
+
module Finders
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def find_all_events_for(model, *events)
|
9
|
+
Logger.logs
|
10
|
+
.filter { |l| events.any? { |e| l == Logger::Convert.call(model, e) } }
|
11
|
+
end
|
12
|
+
|
13
|
+
def find_first_allowed_but_unsaved
|
14
|
+
ary = Logger.logs
|
15
|
+
.reverse
|
16
|
+
.map { |line| line.split ' ' }
|
17
|
+
.find { |arr| %w[save_allowed saved].include?(arr[1]) }
|
18
|
+
return nil if ary.nil? || ary[1] == 'saved'
|
19
|
+
|
20
|
+
Store.store[ary[0]]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
class Settings
|
5
|
+
CONFIG = Struct.new :skip_models
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_writer :skipped_models
|
9
|
+
|
10
|
+
def skipped_models
|
11
|
+
@skipped_models || []
|
12
|
+
end
|
13
|
+
|
14
|
+
def configure(config)
|
15
|
+
Ephemeron::Settings.skipped_models = config.skip_models
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
class Store
|
5
|
+
class Convert
|
6
|
+
class << self
|
7
|
+
def call(model_s, as_new_record: false)
|
8
|
+
return class_name_and_id(model_s, as_new_record) if model_s.is_a?(ActiveRecord::Base)
|
9
|
+
|
10
|
+
model_s.map { |model| class_name_and_id(model) }.join ', '
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def class_name_and_id(model, as_new_record = false)
|
16
|
+
new_record = as_new_record || model.new_record?
|
17
|
+
name = model.class.name.downcase
|
18
|
+
id = new_record ? "new_record##{model.object_id}" : model.id
|
19
|
+
"#{name}##{id}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
class Store
|
5
|
+
module Update
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def call(model)
|
9
|
+
return unless Store.has? model, as_new_record: true
|
10
|
+
|
11
|
+
Store.add model
|
12
|
+
Store.store.delete Convert.call(model, as_new_record: true)
|
13
|
+
|
14
|
+
Store.aliases.find_all { |_, v| v == Convert.call(model, as_new_record: true) }
|
15
|
+
.to_h.keys
|
16
|
+
.each { |key| Store.aliases[key] = Convert.call(model) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
module Validators
|
5
|
+
module BeforeSave
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def call(model)
|
9
|
+
return unless Ephemeron::Store.has? model
|
10
|
+
|
11
|
+
last_event = Ephemeron::Logger::Finders
|
12
|
+
.find_all_events_for(model, :save_allowed, :saved)
|
13
|
+
.last
|
14
|
+
return if last_event == Logger::Convert.call(model, :save_allowed)
|
15
|
+
|
16
|
+
msg = "prior persistence for #{Ephemeron::Store::Convert.call(model)} is prohibited"
|
17
|
+
raise(PersistenceError, msg)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
module Validators
|
5
|
+
module Store
|
6
|
+
module AllowedButUnsaved
|
7
|
+
module_function
|
8
|
+
|
9
|
+
def call
|
10
|
+
model = Ephemeron::Logger::Finders.find_first_allowed_but_unsaved
|
11
|
+
return if model.nil?
|
12
|
+
|
13
|
+
raise(
|
14
|
+
PersistenceError,
|
15
|
+
"save allowed for #{Ephemeron::Store::Convert.call(model)} but never saved"
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
module Validators
|
5
|
+
module Store
|
6
|
+
module Unused
|
7
|
+
module_function
|
8
|
+
|
9
|
+
def call
|
10
|
+
models = Ephemeron::Store
|
11
|
+
.store
|
12
|
+
.filter { |_, model| !model.changed? && !Logger.has?(model, :used) }
|
13
|
+
.values
|
14
|
+
return if models.empty?
|
15
|
+
|
16
|
+
model_ids = Ephemeron::Store::Convert.call(models)
|
17
|
+
raise(
|
18
|
+
StoreError,
|
19
|
+
"#{model_ids} were added to store but neither fetched nor changed"
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
module Validators
|
5
|
+
module StoreElement
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def call(model)
|
9
|
+
return false if Logger.logs.last == Logger::Convert.call(nil, :proxy_start)
|
10
|
+
return false unless model.is_a?(ActiveRecord::Base)
|
11
|
+
return false if Settings.skipped_models.include? model.class.name
|
12
|
+
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
class Callbacks < ThreadStore
|
5
|
+
attribute :ts_after_save_callbacks
|
6
|
+
|
7
|
+
def after_save_callbacks
|
8
|
+
self.ts_after_save_callbacks ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(callback)
|
12
|
+
after_save_callbacks << callback
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
after_save_callbacks.each(&:call)
|
17
|
+
end
|
18
|
+
|
19
|
+
def reset
|
20
|
+
self.ts_after_save_callbacks = []
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
class Logger < ThreadStore
|
5
|
+
attribute :ts_logs
|
6
|
+
|
7
|
+
PROXY_EVENTS = %i[proxy_start proxy_end].freeze
|
8
|
+
VALID_EVENTS = %i[saved save_allowed skip_save used] + PROXY_EVENTS
|
9
|
+
|
10
|
+
def logs
|
11
|
+
self.ts_logs ||= []
|
12
|
+
end
|
13
|
+
|
14
|
+
def has?(model, event)
|
15
|
+
validate model, event
|
16
|
+
logs.include? Convert.call(model, event)
|
17
|
+
end
|
18
|
+
|
19
|
+
def log(model, event, soft: false)
|
20
|
+
validate model, event
|
21
|
+
logs << Convert.call(model, event)
|
22
|
+
rescue LoggerError, StoreError => e
|
23
|
+
raise e unless soft
|
24
|
+
end
|
25
|
+
|
26
|
+
def reset
|
27
|
+
self.ts_logs = []
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def validate(model, event)
|
33
|
+
raise(LoggerError, "event (#{event}) is invalid") if VALID_EVENTS.exclude?(event)
|
34
|
+
return true if validate_proxy_events model, event
|
35
|
+
|
36
|
+
raise(StoreError, "can't #{event_name_for_validate event} for nil") if model.nil?
|
37
|
+
return true if Store.has?(model)
|
38
|
+
return true if event == :saved
|
39
|
+
|
40
|
+
raise StoreError, "can't #{event_name_for_validate event} " \
|
41
|
+
"if #{Store::Convert.call model} is not in store"
|
42
|
+
end
|
43
|
+
|
44
|
+
def validate_proxy_events(model, event)
|
45
|
+
return false if PROXY_EVENTS.exclude?(event)
|
46
|
+
return true if model.nil?
|
47
|
+
|
48
|
+
raise LoggerError, 'Proxy events can be logged for nil only'
|
49
|
+
end
|
50
|
+
|
51
|
+
def event_name_for_validate(event)
|
52
|
+
if event == :used
|
53
|
+
'mark as used'
|
54
|
+
else
|
55
|
+
'log'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ephemeron
|
4
|
+
class Store < ThreadStore
|
5
|
+
attribute :ts_store, :ts_aliases
|
6
|
+
|
7
|
+
def store
|
8
|
+
self.ts_store ||= {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def aliases
|
12
|
+
self.ts_aliases ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def has?(model, as_new_record: false)
|
16
|
+
!store[Convert.call(model, as_new_record: as_new_record)].nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def add(model, as: nil)
|
20
|
+
return unless Validators::StoreElement.call(model)
|
21
|
+
|
22
|
+
key = Convert.call model
|
23
|
+
in_store = !store[key].nil?
|
24
|
+
store[key] = model unless in_store
|
25
|
+
if !as.nil?
|
26
|
+
aliases[as] = key
|
27
|
+
elsif in_store
|
28
|
+
raise StoreError, "#{key} is already in the store"
|
29
|
+
end
|
30
|
+
model
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(key)
|
34
|
+
store[aliases[key]].tap do |model|
|
35
|
+
Logger.log(model, :used) if model
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def validate
|
40
|
+
Validators::Store.call
|
41
|
+
end
|
42
|
+
|
43
|
+
def persist
|
44
|
+
changed_models = store.filter { |_, v| v.changed? }.values
|
45
|
+
.filter { |model| !Logger.has?(model, :skip_save) }
|
46
|
+
ActiveRecord::Base.transaction do
|
47
|
+
changed_models.each do |model|
|
48
|
+
Ephemeron.allow_save! model
|
49
|
+
model.save!
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def destroy(model)
|
55
|
+
key = Convert.call model
|
56
|
+
return if store[key].nil?
|
57
|
+
|
58
|
+
store.delete key
|
59
|
+
end
|
60
|
+
|
61
|
+
def reset
|
62
|
+
self.ts_store = {}
|
63
|
+
self.ts_aliases = {}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ephemeron
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Zbigniew Humeniuk
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '7.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '5.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '7.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: jb
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.7.0
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.7.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec-mocks
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '3.9'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.9'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: sqlite3
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
description: |
|
76
|
+
Ephemeron improves the performance of your app.
|
77
|
+
It takes on itself the persistence of the ActiveRecord objects.
|
78
|
+
It protects you from saving the same object many times.
|
79
|
+
It checks whether a fetched from a database object was used.
|
80
|
+
It allows you to eliminate the controller's before_actions that are unnecessarily called.
|
81
|
+
Ephemeron works in the context of the thread and does the bulk of its job (i.a. persistence) at the end of the thread's lifecycle.
|
82
|
+
Although, you can trigger the finalization at any given moment.
|
83
|
+
You don't have to make a distinction in the code for the part that is responsible for the domain logic and the other responsible for the application layers.
|
84
|
+
email:
|
85
|
+
- hello@artofcode.co
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- MIT-LICENSE
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- lib/ephemeron.rb
|
94
|
+
- lib/ephemeron/addons/controller_addons.rb
|
95
|
+
- lib/ephemeron/addons/model_addons.rb
|
96
|
+
- lib/ephemeron/errors.rb
|
97
|
+
- lib/ephemeron/logger/convert.rb
|
98
|
+
- lib/ephemeron/logger/finders.rb
|
99
|
+
- lib/ephemeron/railtie.rb
|
100
|
+
- lib/ephemeron/settings.rb
|
101
|
+
- lib/ephemeron/store/convert.rb
|
102
|
+
- lib/ephemeron/store/update.rb
|
103
|
+
- lib/ephemeron/validators/before_save.rb
|
104
|
+
- lib/ephemeron/validators/store.rb
|
105
|
+
- lib/ephemeron/validators/store/allowed_but_unsaved.rb
|
106
|
+
- lib/ephemeron/validators/store/unused.rb
|
107
|
+
- lib/ephemeron/validators/store_element.rb
|
108
|
+
- lib/ephemeron/version.rb
|
109
|
+
- lib/ephemeron/writers/callbacks.rb
|
110
|
+
- lib/ephemeron/writers/logger.rb
|
111
|
+
- lib/ephemeron/writers/store.rb
|
112
|
+
- lib/ephemeron/writers/thread_store.rb
|
113
|
+
- lib/tasks/ephemeron_tasks.rake
|
114
|
+
homepage: https://artofcode.co
|
115
|
+
licenses:
|
116
|
+
- MIT
|
117
|
+
metadata: {}
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubygems_version: 3.1.2
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: The organic DDD
|
137
|
+
test_files: []
|