vorpal 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjM0OTM4MmE4MDUyYjEzOGFiYmM4YTE1ZGE3NTQwZDE1YzcyZDI4MA==
4
+ ZTFlNjY4ZjU3YWRhNmY2ZDFmZmFiMTBiMTk3ZWY5ZjVhYjc1NTAzYw==
5
5
  data.tar.gz: !binary |-
6
- OTdmZTA0MzU5YzAwMWRiZTYyODliM2M5YmE3NGY2ZTg3MDQ5MDY4MA==
6
+ N2FkZmQzZDBiMjg1MWU5MzJjYzcwMzUxNGNjMzk1NGE0NjkyMjNkYw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZjM0MGQzYjgwNzYzNjM5MTdkYWM3YWVjODgwMTBhMDdiYTU4ZjlmOTcyNWQy
10
- MDVjNDY2NmFmNmQ0NWM3MzU2OWYwZmIzMjBlZmU3ZmYzMGIzMTVmZTgxNjkx
11
- MTY3MjkxYzEwMDkzZmVhODBlYmNmZDIzZjJiZTgwZDMzZDM5ODk=
9
+ NTA5MTJmMWMzM2I5YzE5MmNkYjYzNDhlMzA0NjczZThkMzE1M2M2NDBiYzFj
10
+ ZGE3OTU0Zjc0NGNlNzA4Y2RiNTM4OTgyZjk1ZmY2MjgzNjY4NTNmM2NkMDI4
11
+ MjFlMGYwNzQzZWNiN2FiYTA1MzE3YTk1YmNmZTRmOTNlYzM2MWI=
12
12
  data.tar.gz: !binary |-
13
- OTYwMzhhZDQxMDhiNGU2NmNiYjI5NzdmZGRjZWNjNDczMDczMmEwNjczNGQ3
14
- OTQ2MzBkMWJhYWFlOTkzYzFlNTk4NDIyYmMxNzE3ZmI5ZjBjZGQ2Zjg4ODhj
15
- Yjc5NWRjYmZhN2I0NTRhMTA5MmFhNzM4YWY5OGZiYzVkOWVmMzY=
13
+ YTJhOTJhMjFkZmYwMDJlYmQwZDVmZWY0MzkwMzgyNzRhZDA0NWYyZGFlM2Iy
14
+ NDZmYzc5MzUyNGM4MzFiOTIwYWIxMDRiNWUzMzJlYTcwY2YwMWEzNjRmOGM3
15
+ MGM4Nzg1MzRjMzUxNzgzZmFjOTg2YjU3ZDQ2ZmM0NTlkZDNkMWE=
data/README.md CHANGED
@@ -108,41 +108,41 @@ require 'vorpal'
108
108
 
109
109
  module TreeRepository
110
110
  extend self
111
-
111
+
112
+ class TreeDB < ActiveRecord::Base
113
+ self.table_name = 'trees'
114
+ end
115
+
116
+ class BranchDB < ActiveRecord::Base
117
+ self.table_name = 'branches'
118
+ end
119
+
112
120
  @repository = Vorpal.define do
113
- map Tree do
121
+ map Tree, to: TreeDB do
114
122
  fields :name
115
123
  belongs_to :gardener, owned: false
116
124
  has_many :branches
117
125
  end
118
126
 
119
- map Gardener
120
-
121
- map Branch do
127
+ map Gardener, to: Gardener
128
+
129
+ map Branch, to: BranchDB do
122
130
  fields :length, :diameter
123
131
  belongs_to :tree
124
132
  end
125
133
  end
126
-
134
+
127
135
  def find(id)
128
136
  @repository.load(id, Tree)
129
137
  end
130
-
138
+
131
139
  def save(tree)
132
140
  @repository.persist(tree)
133
141
  end
134
-
142
+
135
143
  def destroy(tree)
136
144
  @repository.destroy(tree)
137
145
  end
138
-
139
- class ARTree < ActiveRecord::Base
140
- self.table_name = 'trees'
141
- end
142
-
143
- class ARBranch < ActiveRecord::Base
144
- self.table_name = 'branches'
145
- end
146
146
  end
147
147
  ```
148
148
 
@@ -184,12 +184,12 @@ It also does not do some things that you might expect from other ORMs:
184
184
 
185
185
  ## Future Enhancements
186
186
  * Aggregate updated_at.
187
- * Support for other DBMSs.
187
+ * Support for other DBMSs (no MySQL support until ids can be generated without inserting into a table!)
188
188
  * Support for other ORMs.
189
189
  * Value objects.
190
- * Remove dependency on ActiveRecord (optimistic locking? updated_at, created_at support? Data type conversions?)
191
- * More efficient object loading (use fewer queries.)
192
- * Different fields names in domain models than in the DB.
190
+ * Remove dependency on ActiveRecord (optimistic locking? updated_at, created_at support? Data type conversions? TimeZone support?)
191
+ * More efficient object loading and persisting (use fewer queries.)
192
+ * Nicer DSL for specifying field that have different names in the domain model than in the DB.
193
193
 
194
194
  ## FAQ
195
195
 
@@ -203,7 +203,16 @@ It also does not do some things that you might expect from other ORMs:
203
203
 
204
204
  **Q.** How do I do more complicated queries against the DB without direct access to ActiveRecord?
205
205
 
206
- **A.** Create a method on a [Repository](http://martinfowler.com/eaaCatalog/repository.html)! They have full access to the DB/ORM so you can use [Arel](https://github.com/rails/arel) and go [crazy](http://asciicasts.com/episodes/239-activerecord-relation-walkthrough) or use direct SQL if you want.
206
+ **A.** Create a method on a [Repository](http://martinfowler.com/eaaCatalog/repository.html)! They have full access to the DB/ORM so you can use [Arel](https://github.com/rails/arel) and go [crazy](http://asciicasts.com/episodes/239-activerecord-relation-walkthrough) or use direct SQL if you want.
207
+
208
+ For example:
209
+
210
+ ```ruby
211
+ def find_all
212
+ ids = TreeDB.pluck(:id) # use an AR query to determine the aggregate ids
213
+ @repository.load_all(ids, Tree) # use the repository to load all the aggregates
214
+ end
215
+ ```
207
216
 
208
217
  **Q.** How do I do validations now that I don't have access to ActiveRecord anymore?
209
218
 
@@ -223,6 +232,14 @@ It also does not do some things that you might expect from other ORMs:
223
232
 
224
233
  **A.** You can use [ActiveModel::Serialization](http://api.rubyonrails.org/classes/ActiveModel/Serialization.html) or [ActiveModel::Serializers](https://github.com/rails-api/active_model_serializers) but they are not heartily recommended. The former is too coupled to the model and the latter is too coupled to Rails controllers. Vorpal includes the [SimpleSerializer](http://rubydoc.info/github/nulogy/vorpal/master/SimpleSerializer) and [SimpleDeserializer](http://rubydoc.info/github/nulogy/vorpal/master/SimpleDeserializer) for this purpose.
225
234
 
235
+ ## Running Tests
236
+
237
+ 1. Start a PostgreSQL server.
238
+ 2. Either:
239
+ * Create a DB user called `vorpal` with password `pass` and a DB called `vorpal_test`. OR:
240
+ * Modify `spec/integration_spec_helper.rb`.
241
+ 3. Run `rake` from the terminal.
242
+
226
243
  ## Contributors
227
244
 
228
245
  * [Sean Kirby](https://github.com/sskirby)
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
- require "bundler/gem_tasks"
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require "bundler/gem_tasks"
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks associated with creating new versions of the gem.'
6
+ end
2
7
 
8
+ require 'rspec/core/rake_task'
9
+ RSpec::Core::RakeTask.new(:spec)
10
+ task :default => :spec
@@ -36,8 +36,6 @@ class AggregateRepository
36
36
  #
37
37
  # @param objects [[Object]] array of aggregate roots to be saved.
38
38
  # @return [[Object]] array of aggregate roots.
39
- #
40
- # TODO: Nil out object ids if one of the objects can't be saved?
41
39
  def persist_all(objects)
42
40
  objects.map(&method(:persist))
43
41
  end
@@ -49,6 +47,9 @@ class AggregateRepository
49
47
  # loaded.
50
48
  # @param domain_class [Class] Type of the root of the aggregate to
51
49
  # be loaded.
50
+ # @param identity_map [Vorpal::IdentityMap] Provide your own IdentityMap instance
51
+ # if you want entity id - unique object mapping for a greater scope than one
52
+ # operation.
52
53
  # @return [Object] Entity with the given primary key value and type.
53
54
  def load(id, domain_class, identity_map=IdentityMap.new)
54
55
  db_object = @configs.config_for(domain_class).load_by_id(id)
@@ -60,6 +61,9 @@ class AggregateRepository
60
61
  # @param ids [[Integer]] Array of primary key values of the roots of the
61
62
  # aggregates to be loaded.
62
63
  # @param domain_class [Class] Type of the roots of the aggregate to be loaded.
64
+ # @param identity_map [Vorpal::IdentityMap] Provide your own IdentityMap instance
65
+ # if you want entity id - unique object mapping for a greater scope than one
66
+ # operation.
63
67
  # @return [[Object]] Entities with the given primary key values and type.
64
68
  def load_all(ids, domain_class, identity_map=IdentityMap.new)
65
69
  ids.map { |id| load(id, domain_class, identity_map) }
@@ -83,8 +87,7 @@ class AggregateRepository
83
87
  # @param objects [[Object]] Array of roots of the aggregates to be destroyed.
84
88
  # @return [[Object]] Roots that were passed in.
85
89
  def destroy_all(objects)
86
- objects.each(&method(:destroy))
87
- objects
90
+ objects.map(&method(:destroy))
88
91
  end
89
92
 
90
93
  private
@@ -77,18 +77,18 @@ class ConfigBuilder
77
77
  def build_class_config
78
78
  Vorpal::ClassConfig.new(
79
79
  domain_class: @domain_class,
80
- table_name: @class_options[:table_name] || table_name,
80
+ db_class: @class_options[:to] || db_class,
81
81
  serializer: @class_options[:serializer] || serializer(fields_with_id),
82
82
  deserializer: @class_options[:deserializer] || deserializer(fields_with_id),
83
83
  )
84
84
  end
85
85
 
86
- def fields_with_id
87
- [:id].concat @fields
86
+ def db_class
87
+ "#{@domain_class.name}DB".constantize
88
88
  end
89
89
 
90
- def table_name
91
- @domain_class.name.tableize
90
+ def fields_with_id
91
+ [:id].concat @fields
92
92
  end
93
93
 
94
94
  def build_has_manys
@@ -39,7 +39,7 @@ end
39
39
 
40
40
  # @private
41
41
  class ClassConfig
42
- attr_reader :serializer, :deserializer, :domain_class, :table_name
42
+ attr_reader :serializer, :deserializer, :domain_class, :db_class
43
43
  attr_accessor :has_manys, :belongs_tos, :has_ones
44
44
 
45
45
  def initialize(attrs)
@@ -57,10 +57,6 @@ class ClassConfig
57
57
  result.column_values(0).map(&:to_i)
58
58
  end
59
59
 
60
- def db_class
61
- @db_class ||= ActiveRecord::Base.descendants.detect { |ar| ar.table_name == table_name }
62
- end
63
-
64
60
  def find_in_db(object)
65
61
  db_class.find(object.id)
66
62
  end
@@ -119,7 +115,7 @@ class ClassConfig
119
115
  private
120
116
 
121
117
  def sequence_name
122
- "#{table_name}_id_seq"
118
+ "#{db_class.table_name}_id_seq"
123
119
  end
124
120
  end
125
121
 
@@ -143,7 +139,7 @@ end
143
139
  # Object associations:
144
140
  # - All object associations are uni-directional
145
141
  # - The end that holds the association is the 'Parent' and the end that
146
- # is refered to is the 'Child' or 'Children'
142
+ # is referred to is the 'Child' or 'Children'
147
143
  #
148
144
  # Relational associations:
149
145
  # - Local end: has FK
@@ -18,8 +18,8 @@ module Configuration
18
18
  #
19
19
  # @param domain_class [Class] Type of the domain model to be mapped
20
20
  # @param options [Hash] Configure how to map the domain model
21
- # @option options [String] :table_name (Name of the domain class snake-cased and pluralized.)
22
- # Name of the relational DB table.
21
+ # @option options [String] :to (Class with the same name as the domain class with a 'DB' appended.)
22
+ # Class of the ActiveRecord object that will map this domain class to the DB.
23
23
  # @option options [Object] :serializer (map the {ConfigBuilder#fields} directly)
24
24
  # Object that will convert the domain objects into a hash.
25
25
  #
@@ -1,3 +1,3 @@
1
1
  module Vorpal
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -12,14 +12,6 @@ ActiveRecord::Base.establish_connection(
12
12
  )
13
13
 
14
14
  RSpec.configure do |config|
15
- # ## Mock Framework
16
- #
17
- # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
18
- #
19
- # config.mock_with :mocha
20
- # config.mock_with :flexmock
21
- # config.mock_with :rr
22
-
23
15
  # implements use_transactional_fixtures = true
24
16
  # from lib/active_record/fixtures.rb
25
17
  # works with Rails 3.2. Probably not with Rails 4
@@ -643,7 +643,7 @@ private
643
643
  belongs_to :environment, owned: false, fk: :environment_id, fk_type: :environment_type, child_class: Swamp
644
644
  end
645
645
 
646
- map Swamp
646
+ map Swamp, to: Swamp
647
647
  end
648
648
  end
649
649
 
@@ -727,7 +727,7 @@ private
727
727
  fields :length
728
728
  end
729
729
 
730
- map Fissure
730
+ map Fissure, to: Fissure
731
731
  end
732
732
  end
733
733
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vorpal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Kirby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-22 00:00:00.000000000 Z
11
+ date: 2015-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake