datamappify 0.20.1 → 0.30.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 +4 -4
- data/.gitignore +2 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +10 -4
- data/README.md +28 -33
- data/datamappify.gemspec +3 -1
- data/lib/datamappify/data/criteria/active_record/count.rb +12 -0
- data/lib/datamappify/data/criteria/active_record/destroy.rb +17 -0
- data/lib/datamappify/data/criteria/active_record/exists.rb +13 -0
- data/lib/datamappify/data/criteria/active_record/find.rb +12 -0
- data/lib/datamappify/data/criteria/active_record/find_by_key.rb +12 -0
- data/lib/datamappify/data/criteria/active_record/save.rb +23 -0
- data/lib/datamappify/data/criteria/active_record/save_by_key.rb +14 -0
- data/lib/datamappify/data/criteria/active_record/transaction.rb +13 -0
- data/lib/datamappify/data/criteria/common.rb +96 -0
- data/lib/datamappify/data/criteria/relational/count.rb +13 -0
- data/lib/datamappify/data/criteria/relational/find.rb +23 -0
- data/lib/datamappify/data/criteria/relational/find_by_key.rb +17 -0
- data/lib/datamappify/data/criteria/relational/save.rb +26 -0
- data/lib/datamappify/data/criteria/relational/save_by_key.rb +15 -0
- data/lib/datamappify/data/criteria/sequel/count.rb +12 -0
- data/lib/datamappify/data/criteria/sequel/destroy.rb +17 -0
- data/lib/datamappify/data/criteria/sequel/exists.rb +13 -0
- data/lib/datamappify/data/criteria/sequel/find.rb +12 -0
- data/lib/datamappify/data/criteria/sequel/find_by_key.rb +12 -0
- data/lib/datamappify/data/criteria/sequel/save.rb +23 -0
- data/lib/datamappify/data/criteria/sequel/save_by_key.rb +14 -0
- data/lib/datamappify/data/criteria/sequel/transaction.rb +13 -0
- data/lib/datamappify/data/criteria.rb +8 -0
- data/lib/datamappify/data/errors.rb +1 -0
- data/lib/datamappify/data/mapper/attribute.rb +52 -0
- data/lib/datamappify/data/mapper.rb +95 -0
- data/lib/datamappify/data/provider/active_record.rb +7 -7
- data/lib/datamappify/data/provider/common_provider.rb +67 -0
- data/lib/datamappify/data/provider/sequel.rb +9 -9
- data/lib/datamappify/data/provider.rb +12 -0
- data/lib/datamappify/data/record.rb +13 -0
- data/lib/datamappify/data.rb +4 -0
- data/lib/datamappify/repository/mapping_dsl.rb +28 -0
- data/lib/datamappify/repository/query_method/count.rb +12 -0
- data/lib/datamappify/repository/query_method/destroy.rb +25 -0
- data/lib/datamappify/repository/query_method/find.rb +41 -0
- data/lib/datamappify/repository/query_method/method.rb +73 -0
- data/lib/datamappify/repository/query_method/save.rb +42 -0
- data/lib/datamappify/repository/query_method/transaction.rb +18 -0
- data/lib/datamappify/repository/query_method.rb +3 -0
- data/lib/datamappify/repository.rb +58 -92
- data/lib/datamappify/version.rb +1 -1
- data/lib/datamappify.rb +10 -5
- data/spec/repository/persistence_spec.rb +15 -23
- data/spec/repository_spec.rb +9 -5
- metadata +70 -15
- data/lib/datamappify/data/provider/active_record/persistence.rb +0 -31
- data/lib/datamappify/data/provider/common/persistence.rb +0 -57
- data/lib/datamappify/data/provider/common/relational/persistence.rb +0 -85
- data/lib/datamappify/data/provider/common/relational/record/mapper.rb +0 -24
- data/lib/datamappify/data/provider/common/relational/record/writer.rb +0 -67
- data/lib/datamappify/data/provider/sequel/persistence.rb +0 -31
- data/lib/datamappify/repository/attribute_source_data_class_builder.rb +0 -28
- data/lib/datamappify/repository/attributes_mapper.rb +0 -55
- data/lib/datamappify/repository/dsl.rb +0 -22
- data/lib/datamappify/repository/mapping_hash.rb +0 -8
- data/lib/datamappify/util.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afcba7b889daac95e25ea353220e7f418082515d
|
4
|
+
data.tar.gz: d0cd4d8e8a01595ffe831c204ad52cccdafef85f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d95340abf96122fc88f136f028d31b0bf5b15915bbab6bc72e8a9180202ac8220e723c0b39f55b24b223640231580cbf8ae17636c118b86530bd9c81c0fceb40
|
7
|
+
data.tar.gz: e90bcfb79e7f232bcab801f73326d3088891454aa93db4cf6060590fc2fafc3f5bbf0bb8cd172aa3b017ab8677442db95a369c3d7615852123eded0c98114b72
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--protected --private
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
## master
|
2
2
|
|
3
|
+
## 0.30.0 [2013-04-12]
|
4
|
+
|
5
|
+
- __Completely reimplemented Datamappify__
|
6
|
+
- Things are more decoupled and cleaner in general.
|
7
|
+
- Leaner `Repository` syntax, i.e. `UserRepository` instead of the more verbose `UserRepository.instance`.
|
8
|
+
|
3
9
|
## 0.20.1 [2013-03-19]
|
4
10
|
|
5
11
|
- Fixed the leftover `require 'active_record'` in the code so the gem works without ActiveRecord.
|
@@ -7,11 +13,11 @@
|
|
7
13
|
## 0.20.0 [2013-03-19]
|
8
14
|
|
9
15
|
- __Completely rewritten Repository__
|
10
|
-
- Repository now handles data construction from different ORM objects
|
16
|
+
- Repository now handles data construction from different ORM objects.
|
11
17
|
- ActiveRecord has now been demoted to being a data provider, it is no longer tightly coupled with Repository, this means __we could have multiple data providers__!
|
12
|
-
- Repository is now much more robust
|
13
|
-
- As a result of robustness, it fixed an issue where updating an existing entity with new data records from mapped attributes will not persist the new data records correctly
|
14
|
-
- `#save` and `#destroy` now support accepting an array as their argument
|
18
|
+
- Repository is now much more robust.
|
19
|
+
- As a result of robustness, it fixed an issue where updating an existing entity with new data records from mapped attributes will not persist the new data records correctly.
|
20
|
+
- `#save` and `#destroy` now support accepting an array as their argument.
|
15
21
|
- Added support for Sequel!
|
16
22
|
- Added support for mapping entity attributes to different ORMs!
|
17
23
|
|
data/README.md
CHANGED
@@ -1,34 +1,31 @@
|
|
1
1
|
# Datamappify [](http://badge.fury.io/rb/datamappify) [](http://travis-ci.org/fredwu/datamappify) [](https://coveralls.io/r/fredwu/datamappify) [](https://codeclimate.com/github/fredwu/datamappify)
|
2
2
|
|
3
|
-
Separate domain logic from data persistence, based on the [Repository Pattern](http://martinfowler.com/eaaCatalog/repository.html).
|
4
|
-
|
5
|
-
Datamappify is NOT associated with the [Datamapper](https://github.com/datamapper/) project.
|
6
|
-
|
7
3
|
__Datamappify is current in Proof-of-Concept stage, do NOT use it for anything other than experimentation.__
|
8
4
|
|
9
5
|
## Overview
|
10
6
|
|
11
|
-
|
7
|
+
Compose and manage domain logic and data persistence separately and intelligently, Datamappify is loosely based on the [Repository Pattern](http://martinfowler.com/eaaCatalog/repository.html) and [Entity Aggregation](http://msdn.microsoft.com/en-au/library/ff649505.aspx).
|
8
|
+
|
9
|
+
Datamappify is built using [Virtus](https://github.com/solnic/virtus) and existing ORMs (ActiveRecord and Sequel, etc). The design goal is to utilise the powerfulness of existing ORMs as well as to separate domain logic (model behaviour) from data persistence.
|
12
10
|
|
13
11
|
Datamappify consists of three components:
|
14
12
|
|
15
|
-
- __Entity__
|
16
|
-
- __Data__ as the name suggests, holds your model data. It is an ActiveRecord
|
13
|
+
- __Entity__ contains models behaviour, think an ActiveRecord model with the persistence specifics removed.
|
14
|
+
- __Data__ as the name suggests, holds your model data. It is an ORM object (ActiveRecord and Sequel, etc).
|
17
15
|
- __Repository__ is responsible for data retrieval and persistence, e.g. `find`, `save` and `destroy`, etc.
|
18
16
|
|
19
|
-
|
17
|
+
Note: Datamappify is NOT affiliated with the [Datamapper](https://github.com/datamapper/) project.
|
20
18
|
|
21
|
-
|
19
|
+
### Supported ORMs for Persistence
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
And then execute:
|
21
|
+
- ActiveRecord
|
22
|
+
- Sequel
|
26
23
|
|
27
|
-
|
24
|
+
## Installation
|
28
25
|
|
29
|
-
|
26
|
+
Add this line to your application's Gemfile:
|
30
27
|
|
31
|
-
|
28
|
+
gem 'datamappify'
|
32
29
|
|
33
30
|
## Usage
|
34
31
|
|
@@ -91,8 +88,8 @@ end
|
|
91
88
|
Pass in an id or an array of ids.
|
92
89
|
|
93
90
|
```ruby
|
94
|
-
user = UserRepository.
|
95
|
-
users = UserRepository.
|
91
|
+
user = UserRepository.find(1)
|
92
|
+
users = UserRepository.find([1, 2, 3])
|
96
93
|
```
|
97
94
|
|
98
95
|
#### Saving/updating entities
|
@@ -102,8 +99,8 @@ Pass in an entity or an array of entities.
|
|
102
99
|
There is also `save!` that raises `Datamappify::Data::EntityNotSaved`.
|
103
100
|
|
104
101
|
```ruby
|
105
|
-
UserRepository.
|
106
|
-
UserRepository.
|
102
|
+
UserRepository.save(user)
|
103
|
+
UserRepository.save([user, user2, user3])
|
107
104
|
```
|
108
105
|
|
109
106
|
#### Destroying an entity
|
@@ -115,28 +112,24 @@ There is also `destroy!` that raises `Datamappify::Data::EntityNotDestroyed`.
|
|
115
112
|
Note that due to the attributes mapping, any data found in mapped ActiveRecord objects are not touched.
|
116
113
|
|
117
114
|
```ruby
|
118
|
-
UserRepository.
|
119
|
-
UserRepository.
|
120
|
-
UserRepository.
|
121
|
-
UserRepository.
|
115
|
+
UserRepository.destroy(1)
|
116
|
+
UserRepository.destroy([1, 2, 3])
|
117
|
+
UserRepository.destroy(user)
|
118
|
+
UserRepository.destroy([user, user2, user3])
|
122
119
|
```
|
123
120
|
|
124
|
-
## Supported ORMs
|
125
|
-
|
126
|
-
- ActiveRecord
|
127
|
-
- Sequel
|
128
|
-
|
129
121
|
## Changelog
|
130
122
|
|
131
123
|
Refer to [CHANGELOG](CHANGELOG.md).
|
132
124
|
|
133
125
|
## Todo
|
134
126
|
|
135
|
-
-
|
127
|
+
- Track dirty entity attributes.
|
128
|
+
- Attribute lazy-loading.
|
136
129
|
- Hooks for persistence (`before_save` and `after_save`, etc).
|
137
|
-
-
|
130
|
+
- [Authoritative source](http://msdn.microsoft.com/en-au/library/ff649505.aspx).
|
131
|
+
- Enforce attribute type casting.
|
138
132
|
- Support for configurable primary keys and foreign keys.
|
139
|
-
- Entity should dictate Data, so schema and migrations should be automatically generated.
|
140
133
|
|
141
134
|
## Similar Projects
|
142
135
|
|
@@ -144,9 +137,11 @@ Refer to [CHANGELOG](CHANGELOG.md).
|
|
144
137
|
- [Edr](https://github.com/nulogy/edr)
|
145
138
|
- [Minimapper](https://github.com/joakimk/minimapper)
|
146
139
|
|
147
|
-
##
|
140
|
+
## Credits
|
148
141
|
|
149
|
-
[Fred Wu](http://fredwu.me/)
|
142
|
+
- [Fred Wu](http://fredwu.me/) - author.
|
143
|
+
- [James Ladd](http://jamesladdcode.com/) for reviewing the code and giving advice on architectural decisions.
|
144
|
+
- [Locomote](http://www.locomote.com.au/) - where Datamappify is built and being tested in product development.
|
150
145
|
|
151
146
|
## License
|
152
147
|
|
data/datamappify.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Datamappify::VERSION
|
9
9
|
spec.authors = ["Fred Wu"]
|
10
10
|
spec.email = ["ifredwu@gmail.com"]
|
11
|
-
spec.description = %q{
|
11
|
+
spec.description = %q{Compose and manage domain logic and data persistence separately and intelligently.}
|
12
12
|
spec.summary = spec.description
|
13
13
|
spec.homepage = "https://github.com/fredwu/datamappify"
|
14
14
|
spec.license = "MIT"
|
@@ -23,6 +23,8 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.3"
|
25
25
|
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "redcarpet"
|
27
|
+
spec.add_development_dependency "yard"
|
26
28
|
spec.add_development_dependency "rspec"
|
27
29
|
spec.add_development_dependency "pry"
|
28
30
|
spec.add_development_dependency "simplecov"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Datamappify
|
2
|
+
module Data
|
3
|
+
module Criteria
|
4
|
+
module ActiveRecord
|
5
|
+
class Destroy < Common
|
6
|
+
def initialize(source_class, id)
|
7
|
+
super(source_class, nil, id)
|
8
|
+
end
|
9
|
+
|
10
|
+
def result
|
11
|
+
source_class.destroy(criteria)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'datamappify/data/criteria/relational/save'
|
2
|
+
|
3
|
+
module Datamappify
|
4
|
+
module Data
|
5
|
+
module Criteria
|
6
|
+
module ActiveRecord
|
7
|
+
class Save < Relational::Save
|
8
|
+
private
|
9
|
+
|
10
|
+
def save_record
|
11
|
+
record = source_class.where(criteria).first_or_initialize
|
12
|
+
save(record)
|
13
|
+
end
|
14
|
+
|
15
|
+
def save(record)
|
16
|
+
record.update_attributes attributes_and_values
|
17
|
+
record
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'datamappify/data/criteria/relational/save_by_key'
|
2
|
+
require 'datamappify/data/criteria/active_record/save'
|
3
|
+
|
4
|
+
module Datamappify
|
5
|
+
module Data
|
6
|
+
module Criteria
|
7
|
+
module ActiveRecord
|
8
|
+
class SaveByKey < Save
|
9
|
+
include Relational::SaveByKey
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Datamappify
|
2
|
+
module Data
|
3
|
+
module Criteria
|
4
|
+
# Provides a set of useful methods for common criteria tasks,
|
5
|
+
# all +Criteria+ objects inherit from +Common+
|
6
|
+
class Common
|
7
|
+
# @return [Class]
|
8
|
+
attr_reader :source_class
|
9
|
+
|
10
|
+
# @return [Entity]
|
11
|
+
attr_reader :entity
|
12
|
+
|
13
|
+
# @return [void]
|
14
|
+
attr_reader :criteria
|
15
|
+
|
16
|
+
# @return [Set]
|
17
|
+
attr_reader :attributes
|
18
|
+
|
19
|
+
# @param source_class [Class]
|
20
|
+
#
|
21
|
+
# @param args [any]
|
22
|
+
#
|
23
|
+
# @yield
|
24
|
+
# an optional block
|
25
|
+
def initialize(source_class, *args, &block)
|
26
|
+
@source_class = source_class
|
27
|
+
@entity, @criteria, @attributes = *args
|
28
|
+
@block = block
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
# Key name of either the primary key (e.g. +id+) or foreign key (e.g. +user_id+)
|
34
|
+
#
|
35
|
+
# @return [Symbol]
|
36
|
+
def key_name
|
37
|
+
primary_record? ? :id : "#{entity.class.name.demodulize.underscore}_id".to_sym
|
38
|
+
end
|
39
|
+
|
40
|
+
# The value of {#key_name}
|
41
|
+
#
|
42
|
+
# @return [void]
|
43
|
+
def key_value
|
44
|
+
criteria.with_indifferent_access[key_name]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Determines whether or not it's going to be a new record by looking at the {#key_value}
|
48
|
+
#
|
49
|
+
# @return [Boolean]
|
50
|
+
def new_record?
|
51
|
+
key_value.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
# Determines whether or not it's a primary record by comparing the source class and the entity class
|
55
|
+
#
|
56
|
+
# @return [Boolean]
|
57
|
+
def primary_record?
|
58
|
+
source_class.name.demodulize == entity.class.name.demodulize
|
59
|
+
end
|
60
|
+
|
61
|
+
# Ignores the current Criteria's operation if there is no dirty attributes
|
62
|
+
#
|
63
|
+
# @return [Boolean]
|
64
|
+
def ignore?
|
65
|
+
attributes_and_values.empty?
|
66
|
+
end
|
67
|
+
|
68
|
+
# Attributes with their corresponding values
|
69
|
+
#
|
70
|
+
# @return [Hash]
|
71
|
+
def attributes_and_values
|
72
|
+
hash = {}
|
73
|
+
|
74
|
+
attributes.each do |attribute|
|
75
|
+
unless ignore_attribute?(attribute)
|
76
|
+
hash[attribute.source_attribute_name] = entity.send(attribute.name)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
hash
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# Ignores the attribute if it isn't dirty or if it's a primary key
|
86
|
+
#
|
87
|
+
# @todo implement proper dirty attribute tracking
|
88
|
+
#
|
89
|
+
# @return [Boolean]
|
90
|
+
def ignore_attribute?(attribute)
|
91
|
+
entity.send(attribute.name).nil? || attribute.primary_key?
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Datamappify
|
2
|
+
module Data
|
3
|
+
module Criteria
|
4
|
+
module Relational
|
5
|
+
class Find < Common
|
6
|
+
def result
|
7
|
+
record = source_class.where(criteria).first
|
8
|
+
|
9
|
+
update_entity_with(record) if record
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def update_entity_with(record)
|
15
|
+
attributes.each do |attribute|
|
16
|
+
entity.send("#{attribute.name}=", record.send(attribute.source_attribute_name))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'datamappify/data/criteria/relational/find'
|
2
|
+
|
3
|
+
module Datamappify
|
4
|
+
module Data
|
5
|
+
module Criteria
|
6
|
+
module Relational
|
7
|
+
class FindByKey < Find
|
8
|
+
def initialize(source_class, entity, attributes, &block)
|
9
|
+
super(source_class, entity, nil, attributes, &block)
|
10
|
+
|
11
|
+
@criteria = { key_name => entity.id }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Datamappify
|
2
|
+
module Data
|
3
|
+
module Criteria
|
4
|
+
module Relational
|
5
|
+
class Save < Common
|
6
|
+
def result
|
7
|
+
new_record? ? create_record : save_record unless ignore?
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def create_record
|
13
|
+
record = source_class.new(criteria)
|
14
|
+
saved_record = save(record)
|
15
|
+
|
16
|
+
update_entity_with(saved_record) if primary_record?
|
17
|
+
end
|
18
|
+
|
19
|
+
def update_entity_with(record)
|
20
|
+
entity.id = record.send(key_name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Datamappify
|
2
|
+
module Data
|
3
|
+
module Criteria
|
4
|
+
module Relational
|
5
|
+
module SaveByKey
|
6
|
+
def initialize(source_class, entity, attributes, &block)
|
7
|
+
super(source_class, entity, {}, attributes, &block)
|
8
|
+
|
9
|
+
@criteria = { key_name => entity.id } unless entity.id.nil?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Datamappify
|
2
|
+
module Data
|
3
|
+
module Criteria
|
4
|
+
module Sequel
|
5
|
+
class Destroy < Common
|
6
|
+
def initialize(source_class, id)
|
7
|
+
super(source_class, nil, id)
|
8
|
+
end
|
9
|
+
|
10
|
+
def result
|
11
|
+
source_class.where(:id => criteria).destroy
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'datamappify/data/criteria/relational/save'
|
2
|
+
|
3
|
+
module Datamappify
|
4
|
+
module Data
|
5
|
+
module Criteria
|
6
|
+
module Sequel
|
7
|
+
class Save < Relational::Save
|
8
|
+
private
|
9
|
+
|
10
|
+
def save_record
|
11
|
+
record = source_class.find(criteria) || source_class.new(criteria)
|
12
|
+
save(record)
|
13
|
+
end
|
14
|
+
|
15
|
+
def save(record)
|
16
|
+
record.update attributes_and_values
|
17
|
+
record
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'datamappify/data/criteria/relational/save_by_key'
|
2
|
+
require 'datamappify/data/criteria/sequel/save'
|
3
|
+
|
4
|
+
module Datamappify
|
5
|
+
module Data
|
6
|
+
module Criteria
|
7
|
+
module Sequel
|
8
|
+
class SaveByKey < Save
|
9
|
+
include Relational::SaveByKey
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|