lotus-model 0.1.0 → 0.1.1
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/CHANGELOG.md +159 -0
- data/{LICENSE.txt → LICENSE.md} +0 -0
- data/README.md +29 -28
- data/lib/lotus/entity.rb +6 -13
- data/lib/lotus/model/adapters/memory/query.rb +9 -9
- data/lib/lotus/model/adapters/sql/query.rb +9 -9
- data/lib/lotus/model/mapper.rb +3 -3
- data/lib/lotus/model/mapping/coercer.rb +4 -4
- data/lib/lotus/model/mapping/coercions.rb +162 -0
- data/lib/lotus/model/mapping/collection.rb +2 -2
- data/lib/lotus/model/version.rb +1 -1
- data/lib/lotus/repository.rb +9 -9
- data/lotus-model.gemspec +3 -3
- metadata +10 -47
- data/.gitignore +0 -18
- data/.travis.yml +0 -6
- data/.yardopts +0 -5
- data/Gemfile +0 -16
- data/Rakefile +0 -17
- data/test/entity_test.rb +0 -126
- data/test/fixtures.rb +0 -81
- data/test/model/adapters/abstract_test.rb +0 -75
- data/test/model/adapters/implementation_test.rb +0 -22
- data/test/model/adapters/memory/query_test.rb +0 -91
- data/test/model/adapters/memory_adapter_test.rb +0 -1044
- data/test/model/adapters/sql/query_test.rb +0 -121
- data/test/model/adapters/sql_adapter_test.rb +0 -1078
- data/test/model/mapper_test.rb +0 -94
- data/test/model/mapping/coercer_test.rb +0 -27
- data/test/model/mapping/collection_test.rb +0 -82
- data/test/repository_test.rb +0 -283
- data/test/test_helper.rb +0 -30
- data/test/version_test.rb +0 -7
data/lib/lotus/model/mapper.rb
CHANGED
@@ -2,7 +2,7 @@ require 'lotus/model/mapping'
|
|
2
2
|
|
3
3
|
module Lotus
|
4
4
|
module Model
|
5
|
-
# A persistence mapper that
|
5
|
+
# A persistence mapper that keeps entities independent from database details.
|
6
6
|
#
|
7
7
|
# This is database independent. It can work with SQL, document, and even
|
8
8
|
# with key/value stores.
|
@@ -42,7 +42,7 @@ module Lotus
|
|
42
42
|
#
|
43
43
|
# * #initialize(collection) # Lotus::Model::Mapping::Collection
|
44
44
|
# * #to_record(entity) # translates an entity to the database type
|
45
|
-
# * #from_record(record) # translates a record into an
|
45
|
+
# * #from_record(record) # translates a record into an entity
|
46
46
|
# * #deserialize_*(value) # a set of methods, one for each database column.
|
47
47
|
#
|
48
48
|
# If not given, it uses `Lotus::Model::Mapping::Coercer`, by default.
|
@@ -93,7 +93,7 @@ module Lotus
|
|
93
93
|
#
|
94
94
|
# @since 0.1.0
|
95
95
|
def load!
|
96
|
-
@collections.
|
96
|
+
@collections.each_value { |collection| collection.load! }
|
97
97
|
self
|
98
98
|
end
|
99
99
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'lotus/
|
1
|
+
require 'lotus/model/mapping/coercer'
|
2
2
|
|
3
3
|
module Lotus
|
4
4
|
module Model
|
@@ -42,7 +42,7 @@ module Lotus
|
|
42
42
|
end
|
43
43
|
|
44
44
|
private
|
45
|
-
# Compile itself for
|
45
|
+
# Compile itself for performance boost.
|
46
46
|
#
|
47
47
|
# @api private
|
48
48
|
# @since 0.1.0
|
@@ -50,7 +50,7 @@ module Lotus
|
|
50
50
|
code = @collection.attributes.map do |_,(klass,mapped)|
|
51
51
|
%{
|
52
52
|
def deserialize_#{ mapped }(value)
|
53
|
-
Lotus::
|
53
|
+
Lotus::Model::Mapping::Coercions.#{klass}(value)
|
54
54
|
end
|
55
55
|
}
|
56
56
|
end.join("\n")
|
@@ -66,7 +66,7 @@ module Lotus
|
|
66
66
|
|
67
67
|
def from_record(record)
|
68
68
|
#{ @collection.entity }.new(
|
69
|
-
Hash[*[#{ @collection.attributes.map{|name,(klass,mapped)| ":#{name},Lotus::
|
69
|
+
Hash[*[#{ @collection.attributes.map{|name,(klass,mapped)| ":#{name},Lotus::Model::Mapping::Coercions.#{klass}(record[:#{mapped}])"}.join(',') }]]
|
70
70
|
)
|
71
71
|
end
|
72
72
|
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'lotus/utils/kernel'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module Model
|
5
|
+
module Mapping
|
6
|
+
# Coercions utilities
|
7
|
+
#
|
8
|
+
# @since 0.1.1
|
9
|
+
module Coercions
|
10
|
+
# Coerce into an Array, unless the argument is nil
|
11
|
+
#
|
12
|
+
# @param arg [Object] the object to coerce
|
13
|
+
#
|
14
|
+
# @return [Array] the result of the coercion
|
15
|
+
#
|
16
|
+
# @raise [TypeError] if the argument can't be coerced
|
17
|
+
#
|
18
|
+
# @since 0.1.1
|
19
|
+
#
|
20
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#Array-class_method
|
21
|
+
def self.Array(arg)
|
22
|
+
Utils::Kernel.Array(arg) unless arg.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Coerce into a Boolean, unless the argument is nil
|
26
|
+
#
|
27
|
+
# @param arg [Object] the object to coerce
|
28
|
+
#
|
29
|
+
# @return [Boolean] the result of the coercion
|
30
|
+
#
|
31
|
+
# @raise [TypeError] if the argument can't be coerced
|
32
|
+
#
|
33
|
+
# @since 0.1.1
|
34
|
+
#
|
35
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#Boolean-class_method
|
36
|
+
def self.Boolean(arg)
|
37
|
+
Utils::Kernel.Boolean(arg) unless arg.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
# Coerce into a Date, unless the argument is nil
|
41
|
+
#
|
42
|
+
# @param arg [Object] the object to coerce
|
43
|
+
#
|
44
|
+
# @return [Date] the result of the coercion
|
45
|
+
#
|
46
|
+
# @raise [TypeError] if the argument can't be coerced
|
47
|
+
#
|
48
|
+
# @since 0.1.1
|
49
|
+
#
|
50
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#Date-class_method
|
51
|
+
def self.Date(arg)
|
52
|
+
Utils::Kernel.Date(arg) unless arg.nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
# Coerce into a DateTime, unless the argument is nil
|
56
|
+
#
|
57
|
+
# @param arg [Object] the object to coerce
|
58
|
+
#
|
59
|
+
# @return [DateTime] the result of the coercion
|
60
|
+
#
|
61
|
+
# @raise [TypeError] if the argument can't be coerced
|
62
|
+
#
|
63
|
+
# @since 0.1.1
|
64
|
+
#
|
65
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#DateTime-class_method
|
66
|
+
def self.DateTime(arg)
|
67
|
+
Utils::Kernel.DateTime(arg) unless arg.nil?
|
68
|
+
end
|
69
|
+
|
70
|
+
# Coerce into a Float, unless the argument is nil
|
71
|
+
#
|
72
|
+
# @param arg [Object] the object to coerce
|
73
|
+
#
|
74
|
+
# @return [Float] the result of the coercion
|
75
|
+
#
|
76
|
+
# @raise [TypeError] if the argument can't be coerced
|
77
|
+
#
|
78
|
+
# @since 0.1.1
|
79
|
+
#
|
80
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#Float-class_method
|
81
|
+
def self.Float(arg)
|
82
|
+
Utils::Kernel.Float(arg) unless arg.nil?
|
83
|
+
end
|
84
|
+
|
85
|
+
# Coerce into a Hash, unless the argument is nil
|
86
|
+
#
|
87
|
+
# @param arg [Object] the object to coerce
|
88
|
+
#
|
89
|
+
# @return [Hash] the result of the coercion
|
90
|
+
#
|
91
|
+
# @raise [TypeError] if the argument can't be coerced
|
92
|
+
#
|
93
|
+
# @since 0.1.1
|
94
|
+
#
|
95
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#Hash-class_method
|
96
|
+
def self.Hash(arg)
|
97
|
+
Utils::Kernel.Hash(arg) unless arg.nil?
|
98
|
+
end
|
99
|
+
|
100
|
+
# Coerce into an Integer, unless the argument is nil
|
101
|
+
#
|
102
|
+
# @param arg [Object] the object to coerce
|
103
|
+
#
|
104
|
+
# @return [Integer] the result of the coercion
|
105
|
+
#
|
106
|
+
# @raise [TypeError] if the argument can't be coerced
|
107
|
+
#
|
108
|
+
# @since 0.1.1
|
109
|
+
#
|
110
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#Integer-class_method
|
111
|
+
def self.Integer(arg)
|
112
|
+
Utils::Kernel.Integer(arg) unless arg.nil?
|
113
|
+
end
|
114
|
+
|
115
|
+
# Coerce into a Set, unless the argument is nil
|
116
|
+
#
|
117
|
+
# @param arg [Object] the object to coerce
|
118
|
+
#
|
119
|
+
# @return [Set] the result of the coercion
|
120
|
+
#
|
121
|
+
# @raise [TypeError] if the argument can't be coerced
|
122
|
+
#
|
123
|
+
# @since 0.1.1
|
124
|
+
#
|
125
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#Set-class_method
|
126
|
+
def self.Set(arg)
|
127
|
+
Utils::Kernel.Set(arg) unless arg.nil?
|
128
|
+
end
|
129
|
+
|
130
|
+
# Coerce into a String, unless the argument is nil
|
131
|
+
#
|
132
|
+
# @param arg [Object] the object to coerce
|
133
|
+
#
|
134
|
+
# @return [String] the result of the coercion
|
135
|
+
#
|
136
|
+
# @raise [TypeError] if the argument can't be coerced
|
137
|
+
#
|
138
|
+
# @since 0.1.1
|
139
|
+
#
|
140
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#String-class_method
|
141
|
+
def self.String(arg)
|
142
|
+
Utils::Kernel.String(arg) unless arg.nil?
|
143
|
+
end
|
144
|
+
|
145
|
+
# Coerce into a Time, unless the argument is nil
|
146
|
+
#
|
147
|
+
# @param arg [Object] the object to coerce
|
148
|
+
#
|
149
|
+
# @return [Time] the result of the coercion
|
150
|
+
#
|
151
|
+
# @raise [TypeError] if the argument can't be coerced
|
152
|
+
#
|
153
|
+
# @since 0.1.1
|
154
|
+
#
|
155
|
+
# @see http://rdoc.info/gems/lotus-utils/Lotus/Utils/Kernel#Time-class_method
|
156
|
+
def self.Time(arg)
|
157
|
+
Utils::Kernel.Time(arg) unless arg.nil?
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -87,7 +87,7 @@ module Lotus
|
|
87
87
|
|
88
88
|
# Defines the entity that is persisted with this collection.
|
89
89
|
#
|
90
|
-
# The entity can be any kind of object as long it implements the
|
90
|
+
# The entity can be any kind of object as long as it implements the
|
91
91
|
# following interface: `#initialize(attributes = {})`.
|
92
92
|
#
|
93
93
|
# @param klass [Class] the entity persisted with this collection.
|
@@ -165,7 +165,7 @@ module Lotus
|
|
165
165
|
# This is storage independent. For instance, it can map an SQL column,
|
166
166
|
# a MongoDB attribute or everything that makes sense for your database.
|
167
167
|
#
|
168
|
-
# Each attribute defines
|
168
|
+
# Each attribute defines a Ruby type, to coerce that value from the
|
169
169
|
# database. This fixes a huge problem, because database types don't
|
170
170
|
# match Ruby types.
|
171
171
|
# Think of Redis, where everything is stored as a string or integer,
|
data/lib/lotus/model/version.rb
CHANGED
data/lib/lotus/repository.rb
CHANGED
@@ -2,11 +2,11 @@ require 'lotus/utils/class_attribute'
|
|
2
2
|
|
3
3
|
module Lotus
|
4
4
|
# Mediates between the entities and the persistence layer, by offering an API
|
5
|
-
# to query and execute commands on a
|
5
|
+
# to query and execute commands on a database.
|
6
6
|
#
|
7
7
|
#
|
8
8
|
#
|
9
|
-
# IMPORTANT: A repository MUST be named after an entity, by
|
9
|
+
# IMPORTANT: A repository MUST be named after an entity, by appending the
|
10
10
|
# `Repository` suffix to the entity class name.
|
11
11
|
#
|
12
12
|
# @example
|
@@ -28,15 +28,15 @@ module Lotus
|
|
28
28
|
#
|
29
29
|
#
|
30
30
|
#
|
31
|
-
# A repository is storage
|
31
|
+
# A repository is storage independent.
|
32
32
|
# All the queries and commands are delegated to the current adapter.
|
33
33
|
#
|
34
34
|
# This architecture has several advantages:
|
35
35
|
#
|
36
|
-
# * Applications
|
36
|
+
# * Applications depend on an abstract API, instead of low level details
|
37
37
|
# (Dependency Inversion principle)
|
38
38
|
#
|
39
|
-
# * Applications
|
39
|
+
# * Applications depend on a stable API, that doesn't change if the
|
40
40
|
# storage changes
|
41
41
|
#
|
42
42
|
# * Developers can postpone storage decisions
|
@@ -266,10 +266,10 @@ module Lotus
|
|
266
266
|
# article = Article.new(title: 'Introducing Lotus::Model')
|
267
267
|
# article.id # => nil
|
268
268
|
#
|
269
|
-
# ArticleRepository.
|
269
|
+
# ArticleRepository.create(article) # creates a record
|
270
270
|
# article.id # => 23
|
271
271
|
#
|
272
|
-
# ArticleRepository.
|
272
|
+
# ArticleRepository.create(article) # no-op
|
273
273
|
def create(entity)
|
274
274
|
unless entity.id
|
275
275
|
@adapter.create(collection, entity)
|
@@ -519,7 +519,7 @@ module Lotus
|
|
519
519
|
# IMPORTANT: This feature works only with the Sql adapter.
|
520
520
|
#
|
521
521
|
# A repository is storage independent.
|
522
|
-
# All the queries are
|
522
|
+
# All the queries are delegated to the current adapter, which is
|
523
523
|
# responsible to implement a querying API.
|
524
524
|
#
|
525
525
|
# Lotus::Model is shipped with two adapters:
|
@@ -581,7 +581,7 @@ module Lotus
|
|
581
581
|
@adapter.query(collection, self, &blk)
|
582
582
|
end
|
583
583
|
|
584
|
-
# Negates the filtering conditions of a
|
584
|
+
# Negates the filtering conditions of a given query with the logical
|
585
585
|
# opposite operator.
|
586
586
|
#
|
587
587
|
# This is only supported by the SqlAdapter.
|
data/lotus-model.gemspec
CHANGED
@@ -13,15 +13,15 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = 'http://lotusrb.org'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
|
-
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.files = `git ls-files -z -- lib/* CHANGELOG.md EXAMPLE.md LICENSE.md README.md lotus-model.gemspec`.split("\x0")
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_runtime_dependency 'lotus-utils', '~> 0.
|
21
|
+
spec.add_runtime_dependency 'lotus-utils', '~> 0.2'
|
22
22
|
spec.add_runtime_dependency 'sequel', '~> 4.9'
|
23
23
|
|
24
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
25
25
|
spec.add_development_dependency 'minitest', '~> 5'
|
26
26
|
spec.add_development_dependency 'rake', '~> 10'
|
27
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lotus-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lotus-utils
|
@@ -16,20 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
20
|
-
- - ">"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 0.1.0
|
19
|
+
version: '0.2'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '0.
|
30
|
-
- - ">"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 0.1.0
|
26
|
+
version: '0.2'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: sequel
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,14 +44,14 @@ dependencies:
|
|
50
44
|
requirements:
|
51
45
|
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
|
-
version: '1.
|
47
|
+
version: '1.6'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
51
|
requirements:
|
58
52
|
- - "~>"
|
59
53
|
- !ruby/object:Gem::Version
|
60
|
-
version: '1.
|
54
|
+
version: '1.6'
|
61
55
|
- !ruby/object:Gem::Dependency
|
62
56
|
name: minitest
|
63
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,14 +88,10 @@ executables: []
|
|
94
88
|
extensions: []
|
95
89
|
extra_rdoc_files: []
|
96
90
|
files:
|
97
|
-
-
|
98
|
-
- ".travis.yml"
|
99
|
-
- ".yardopts"
|
91
|
+
- CHANGELOG.md
|
100
92
|
- EXAMPLE.md
|
101
|
-
-
|
102
|
-
- LICENSE.txt
|
93
|
+
- LICENSE.md
|
103
94
|
- README.md
|
104
|
-
- Rakefile
|
105
95
|
- lib/lotus-model.rb
|
106
96
|
- lib/lotus/entity.rb
|
107
97
|
- lib/lotus/model.rb
|
@@ -118,24 +108,11 @@ files:
|
|
118
108
|
- lib/lotus/model/mapper.rb
|
119
109
|
- lib/lotus/model/mapping.rb
|
120
110
|
- lib/lotus/model/mapping/coercer.rb
|
111
|
+
- lib/lotus/model/mapping/coercions.rb
|
121
112
|
- lib/lotus/model/mapping/collection.rb
|
122
113
|
- lib/lotus/model/version.rb
|
123
114
|
- lib/lotus/repository.rb
|
124
115
|
- lotus-model.gemspec
|
125
|
-
- test/entity_test.rb
|
126
|
-
- test/fixtures.rb
|
127
|
-
- test/model/adapters/abstract_test.rb
|
128
|
-
- test/model/adapters/implementation_test.rb
|
129
|
-
- test/model/adapters/memory/query_test.rb
|
130
|
-
- test/model/adapters/memory_adapter_test.rb
|
131
|
-
- test/model/adapters/sql/query_test.rb
|
132
|
-
- test/model/adapters/sql_adapter_test.rb
|
133
|
-
- test/model/mapper_test.rb
|
134
|
-
- test/model/mapping/coercer_test.rb
|
135
|
-
- test/model/mapping/collection_test.rb
|
136
|
-
- test/repository_test.rb
|
137
|
-
- test/test_helper.rb
|
138
|
-
- test/version_test.rb
|
139
116
|
homepage: http://lotusrb.org
|
140
117
|
licenses:
|
141
118
|
- MIT
|
@@ -160,19 +137,5 @@ rubygems_version: 2.2.2
|
|
160
137
|
signing_key:
|
161
138
|
specification_version: 4
|
162
139
|
summary: A persistence layer for Lotus
|
163
|
-
test_files:
|
164
|
-
- test/entity_test.rb
|
165
|
-
- test/fixtures.rb
|
166
|
-
- test/model/adapters/abstract_test.rb
|
167
|
-
- test/model/adapters/implementation_test.rb
|
168
|
-
- test/model/adapters/memory/query_test.rb
|
169
|
-
- test/model/adapters/memory_adapter_test.rb
|
170
|
-
- test/model/adapters/sql/query_test.rb
|
171
|
-
- test/model/adapters/sql_adapter_test.rb
|
172
|
-
- test/model/mapper_test.rb
|
173
|
-
- test/model/mapping/coercer_test.rb
|
174
|
-
- test/model/mapping/collection_test.rb
|
175
|
-
- test/repository_test.rb
|
176
|
-
- test/test_helper.rb
|
177
|
-
- test/version_test.rb
|
140
|
+
test_files: []
|
178
141
|
has_rdoc:
|