mongoid_silo 0.3.5 → 0.3.6

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 761fdd5682b8ade43547264a6f4e81c5ea9007d2
4
+ data.tar.gz: 7c5f6992a91ab8d4fd883634f86dbaced2adf9e8
5
+ SHA512:
6
+ metadata.gz: 988c3bb22112c2672738154a6ebc2d8146297de6cc95dd0b8f8d8de323e891074b430775247549b6cc8ed1d1d4b209c3985b7bc591970e7f1734b37475ae1ed2
7
+ data.tar.gz: 91bb0e8b95038a8cb700912da9fd3a6ecb7beb63b3036e22a85e156581f799b17547badd990b6acd198d4f480c0ef43b30b0cdde22dfbfb630cb6969af042ae6
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "1.9.3"
3
+ - "2.0.0"
4
4
  services: mongodb
5
- script: bundle exec rspec spec
5
+ script: bundle exec rspec spec
data/app/models/silo.rb CHANGED
@@ -8,6 +8,7 @@ class Silo
8
8
  field :item_id, type: String
9
9
  field :silo_type, type: String
10
10
  field :bag, type: Hash
11
+ field :version, type: Integer, default: 1
11
12
 
12
13
  index item_class: 1
13
14
  index item_id: 1
@@ -18,12 +19,26 @@ class Silo
18
19
  end
19
20
 
20
21
  class << self
21
- def for_id_and_class_with_name item_id, class_name, silo_name
22
- where(item_class: class_name, item_id: item_id, silo_type: silo_name).first
22
+ def for_id_and_class_with_name(item_id, class_name, silo_name, version: 1)
23
+ harvest(item_id, silo_name, class_name: class_name, version: version)
23
24
  end
24
25
 
25
- def for_id_and_name_with_no_class item_id, silo_name
26
- where(item_id: item_id, silo_type: silo_name).first
26
+ def for_id_and_name_with_no_class(item_id, silo_name, version: 1)
27
+ harvest(item_id, silo_name, version: version)
28
+ end
29
+
30
+ def harvest(item_id, silo_name, class_name: nil, version: 1)
31
+ query = {
32
+ item_class: class_name,
33
+ item_id: item_id,
34
+ silo_type: silo_name,
35
+ version: version
36
+ }
37
+
38
+ query = query.delete_if { |field, param| param.nil? }
39
+
40
+ where(query).first
27
41
  end
28
42
  end
29
- end
43
+ end
44
+
@@ -1,60 +1,77 @@
1
1
  require 'sidekiq'
2
2
 
3
3
  module MongoidSilo
4
+ refine String do
5
+ def constantize
6
+ Object.module_eval("::#{foo}", __FILE__, __LINE__)
7
+ end
8
+ end
4
9
 
5
10
  class UpdateSiloWorker
6
11
  include Sidekiq::Worker
7
12
 
8
- def perform(item_id, item_class, name, mode="save", generator=nil, callback=nil)
9
- @item_id, @item_class, @generator, @callback = item_id, item_class, generator, callback
10
- mode.to_s == "save" ? update_silo(name, generator) : destroy_silo(name)
11
- end
13
+ attr_reader :generator, :klass, :id, :name, :callback
12
14
 
15
+ def perform(id, klass, name, mode = :save, generator = nil, callback = nil)
16
+ @id = id.kind_of?(String) ? id : id["$oid"]
17
+ @klass = klass.constantize
18
+ @generator = generator ? generator.constantize : nil
19
+ @callback = callback
20
+ @name = name
21
+
22
+ __send__(mode.to_sym)
23
+ end
13
24
 
14
25
  private
15
- def update_silo name, generator
16
- @item = item_class.send(:find, @item_id)
17
- @silo = Silo.where(item_class: @item_class, item_id: @item_id, silo_type: name).first
18
- @content = generator_class.send(:new, @item).generate
19
- if @silo
20
- @silo.set(:bag, @content)
26
+
27
+ def save
28
+ if generator.versioned_generators.empty?
29
+ save_unversioned_silo
21
30
  else
22
- @silo = Silo.create(item_class: @item_class, item_id: @item_id, bag: @content, silo_type: name)
23
- end
24
- unless @callback.nil? || @callback == ""
25
- @item.__send__(@callback, :updated)
31
+ save_versioned_silo
26
32
  end
33
+
34
+ call_callback(:updated)
27
35
  end
28
36
 
29
- def destroy_silo name
30
- @silo = Silo.where(item_class: @item_class, item_id: @item_id, silo_type: name).first
31
- if @silo
32
- @silo.destroy
33
- end
34
- unless @callback.nil? || @callback == ""
35
- @item.__send__(@callback, :destroyed)
37
+ def save_unversioned_silo
38
+ content = generator.send(:new, item).generate
39
+
40
+ save_silo_content(content, version: 1)
41
+ end
42
+
43
+ def save_versioned_silo
44
+ generator.versioned_generators.each do |version, p|
45
+ content = generator.send(:new, item).instance_eval(&p)
46
+ save_silo_content(content, version: version)
36
47
  end
37
48
  end
38
49
 
39
- def item_class
40
- cl = nil
41
- @item_class.split("::").inject(nil) do |parent, identifier|
42
- parent ||= Kernel
43
- cl = parent.const_get(identifier)
50
+ def save_silo_content(content, version: 1)
51
+ if silo = Silo.where(item_class: klass, item_id: id, silo_type: name, version: version).first
52
+ silo.set(:bag, content)
53
+ else
54
+ silo = Silo.create(item_class: klass, item_id: id, bag: content, silo_type: name, version: version)
44
55
  end
45
- cl
46
56
  end
47
57
 
58
+ def destroy
59
+ if silo = Silo.where(item_class: klass, item_id: id, silo_type: name).all
60
+ silo.map(&:destroy)
61
+ end
48
62
 
49
- def generator_class
50
- cl = nil
51
- @generator.split("::").inject(nil) do |parent, identifier|
52
- parent ||= Kernel
53
- cl = parent.const_get(identifier)
63
+ call_callback(:destroyed)
64
+ end
65
+
66
+ def call_callback(event)
67
+ if !callback.to_s.empty?
68
+ item.__send__(callback, :destroyed)
54
69
  end
55
- cl
56
70
  end
57
71
 
72
+ def item
73
+ @item ||= klass.send(:find, id)
74
+ end
58
75
  end
59
-
60
- end
76
+ end
77
+
data/lib/mongoid/silo.rb CHANGED
@@ -25,9 +25,8 @@ module Mongoid
25
25
  end
26
26
  end
27
27
 
28
-
29
-
30
28
  protected
29
+
31
30
  def setup_own_silo name, opts
32
31
  define_method "#{name}_silo" do
33
32
  from_silo name
@@ -54,9 +53,8 @@ module Mongoid
54
53
  arr << out
55
54
  end
56
55
 
57
-
58
56
  registry.each do |key|
59
- key[:class_name].classify.constantize.class_eval <<-EOS, __FILE__, __LINE__+1
57
+ key[:class_name].classify.constantize.class_eval <<-RUBY, __FILE__, __LINE__+1
60
58
  set_callback :save, :after do
61
59
  ident = key[:foreign_key].to_sym
62
60
  MongoidSilo::UpdateSiloWorker.perform_async(self.__send__(ident), "#{key[:parent_class]}", "#{key[:silo_name]}", :save, "#{key[:generator]}", "#{key[:callback]}")
@@ -64,9 +62,9 @@ module Mongoid
64
62
 
65
63
  set_callback :destroy, :after do
66
64
  ident = key[:foreign_key].to_sym
67
- MongoidSilo::UpdateSiloWorker.perform_async(self.__send__(ident), "#{key[:parent_class]}", "#{key[:silo_name]}", :destroy, "#{key[:callback]}")
65
+ MongoidSilo::UpdateSiloWorker.perform_async(self.__send__(ident), "#{key[:parent_class]}", "#{key[:silo_name]}", :save, "#{key[:generator]}", "#{key[:callback]}")
68
66
  end
69
- EOS
67
+ RUBY
70
68
  end
71
69
  end
72
70
  end
@@ -97,4 +95,4 @@ module Mongoid
97
95
  MultiJson.encode from_silo
98
96
  end
99
97
  end
100
- end
98
+ end
@@ -1,8 +1,28 @@
1
1
  module MongoidSilo
2
2
  class GrainBelt
3
-
4
3
  attr_accessor :object
5
-
4
+
5
+ class << self
6
+ attr_accessor :versioned_generators_store
7
+
8
+ def versioned_generators
9
+ @versioned_generators_store ||= {}
10
+
11
+ if self == GrainBelt
12
+ @versioned_generators_store
13
+ else
14
+ superclass.versioned_generators.merge(@versioned_generators_store)
15
+ end
16
+ end
17
+
18
+ def version(*args, &block)
19
+ @versioned_generators_store ||= {}
20
+ args.each do |version|
21
+ @versioned_generators_store[version] = block
22
+ end
23
+ end
24
+ end
25
+
6
26
  def initialize(object)
7
27
  @object = object
8
28
  end
@@ -16,6 +36,6 @@ module MongoidSilo
16
36
  out[attribute] = object.send(attribute) unless ["_type", "_id"].include?(attribute)
17
37
  end
18
38
  end
19
-
20
39
  end
21
- end
40
+ end
41
+
@@ -1,3 +1,3 @@
1
1
  module MongoidSilo
2
- VERSION = "0.3.5"
2
+ VERSION = "0.3.6"
3
3
  end
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe MongoidSilo::GrainBelt do
4
4
  context "Instantiated with a simple model" do
5
-
6
5
  before do
7
6
  @model = create(:project)
8
7
  @silovator = MongoidSilo::GrainBelt.new(@model)
@@ -19,6 +18,48 @@ describe MongoidSilo::GrainBelt do
19
18
  it "generates a hash for storing in the silo" do
20
19
  @silovator.generate.should be_a(Hash)
21
20
  end
21
+ end
22
+
23
+ context "versioning" do
24
+ let(:klass) do
25
+ Class.new(described_class)
26
+ end
27
+
28
+ before do
29
+ klass.versioned_generators_store = {}
30
+ end
31
+
32
+ it "adds a block to the version hash" do
33
+ klass.version(1) do
34
+ "foo"
35
+ end
36
+
37
+ klass.versioned_generators[1].call == "foo"
38
+ end
22
39
 
40
+ it "allows multiple versions to be defined at once" do
41
+ klass.version(1, 2, 3) do
42
+ "foo"
43
+ end
44
+
45
+ received = []
46
+
47
+ klass.versioned_generators.each do |version, proc|
48
+ received << "foo"
49
+ end
50
+
51
+ received.should == ["foo", "foo", "foo"]
52
+ end
53
+
54
+ it "supports subclassing" do
55
+ klass.version(1, 2, 3) do
56
+ "foo"
57
+ end
58
+
59
+ subclass = Class.new(klass)
60
+
61
+ subclass.versioned_generators[1].call.should == "foo"
62
+ end
23
63
  end
24
- end
64
+ end
65
+
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Silo do
4
-
5
4
  context 'simple silos' do
6
5
  before do
7
6
  @project = create(:project)
@@ -12,6 +11,10 @@ describe Silo do
12
11
  Silo.count.should eq(1)
13
12
  end
14
13
 
14
+ it "assigns a default version of 1" do
15
+ Silo.first.version.should eq(1)
16
+ end
17
+
15
18
  it "should contain the name of the project" do
16
19
  @project.default_silo.should eq({"name" => @project.name})
17
20
  end
@@ -26,7 +29,54 @@ describe Silo do
26
29
  @project.destroy
27
30
  Silo.count.should eq(0)
28
31
  end
32
+ end
33
+
34
+ context 'versioned silo' do
35
+ before do
36
+ @project = VersionedProject.create
37
+ end
38
+
39
+ it "should persist a Silo" do
40
+ @project.should be_persisted
41
+ Silo.count.should eq(2)
42
+ end
43
+
44
+ it "assigns the correct version to the generated silos" do
45
+ Silo.all.map(&:version).should == [1, 2]
46
+ end
47
+
48
+ it "assigns the correct attributes to the first silo" do
49
+ Silo.where(version: 1).first.bag.should == { "foo" => "bar" }
50
+ end
51
+
52
+ it "assigns the correct attributes to the second silo" do
53
+ Silo.where(version: 2).first.bag.should == { "foo" => "baz" }
54
+ end
55
+
56
+ it "should delete the silos if the project is deleted" do
57
+ @project.destroy
58
+ Silo.count.should eq(0)
59
+ end
60
+
61
+ describe "#for_id_and_class_with_name" do
62
+ it "supports querying specific versions" do
63
+ args = [@project.id.to_s, @project.class.name, "foobar", version: 2]
64
+
65
+ Silo.for_id_and_class_with_name(*args).bag.should == {
66
+ "foo" => "baz"
67
+ }
68
+ end
69
+ end
70
+
71
+ describe "#for_id_and_name_with_no_class" do
72
+ it "supports querying specific versions" do
73
+ args = [@project.id.to_s, "foobar", version: 2]
29
74
 
75
+ Silo.for_id_and_name_with_no_class(*args).bag.should == {
76
+ "foo" => "baz"
77
+ }
78
+ end
79
+ end
30
80
  end
31
81
 
32
82
  context 'Direct finders and methods:' do
@@ -74,17 +124,18 @@ describe Silo do
74
124
  it "updates a silo on save" do
75
125
  @complex_project.name = Faker::Name.name
76
126
  @complex_project.save
127
+
77
128
  @complex_project.complex_silo["name"].should eq(@complex_project.name)
78
129
  end
79
130
 
80
131
  it "removes the custom silo on destroying the project" do
81
132
  @complex_project.destroy
133
+
82
134
  Silo.count.should eq(0)
83
135
  end
84
136
  end
85
137
 
86
138
  context "Block based constructors:" do
87
-
88
139
  subject(:block_project) { create(:block_project) }
89
140
 
90
141
  it "defines an accessor based on the declared silo name" do
@@ -97,6 +148,7 @@ describe Silo do
97
148
 
98
149
  it "updates the parent when a child is saved" do
99
150
  project_item = create(:block_project_item, block_project_id: block_project.id)
151
+
100
152
  block_project.block_silo["items"][0]["name"].should eq(project_item.name)
101
153
  end
102
154
 
@@ -104,6 +156,7 @@ describe Silo do
104
156
  project_item = create(:block_project_item, block_project_id: block_project.id)
105
157
  project_item.name = Faker::Name.name
106
158
  project_item.save
159
+
107
160
  block_project.block_silo["items"][0]["name"].should eq(project_item.name)
108
161
  end
109
162
 
@@ -113,17 +166,15 @@ describe Silo do
113
166
  project_item3 = create(:block_project_item, block_project_id: block_project.id)
114
167
  block_project.block_silo["items"].length.should eq(3)
115
168
 
116
-
117
169
  project_item2.name = Faker::Name.name
118
170
  project_item2.save
119
-
171
+
120
172
  bp = BlockProject.find block_project.id
121
173
 
122
174
  bp.block_silo["items"].map{|i| i["name"]}.sort.should eq(
123
175
  [project_item1.name, project_item2.name, project_item3.name].sort
124
- )
176
+ )
125
177
  end
126
-
127
178
  end
128
179
 
129
180
  context "Multiple silo constructors:" do
@@ -139,6 +190,7 @@ describe Silo do
139
190
  _expectation = {
140
191
  "name" => @multi_silo_project.name
141
192
  }
193
+
142
194
  @multi_silo_project.name_silo.should eq(_expectation)
143
195
  end
144
196
 
@@ -147,21 +199,25 @@ describe Silo do
147
199
  "city" => @multi_silo_project.city,
148
200
  "county" => @multi_silo_project.county
149
201
  }
202
+
150
203
  @multi_silo_project.location_silo.should eq(_expectation)
151
204
  end
152
205
 
153
206
  it "Correctly updates both silos" do
154
- @multi_silo_project.city = Faker::Address.city
155
- @multi_silo_project.county = Faker::AddressUK.county
156
- @multi_silo_project.name = Faker::Name.name
207
+ @multi_silo_project.city = Faker::Address.city
208
+ @multi_silo_project.county = Faker::AddressUK.county
209
+ @multi_silo_project.name = Faker::Name.name
157
210
  @multi_silo_project.save
211
+
158
212
  _name_silo_expectation = {
159
213
  "name" => @multi_silo_project.name
160
214
  }
215
+
161
216
  _location_silo_expectation = {
162
217
  "city" => @multi_silo_project.city,
163
218
  "county" => @multi_silo_project.county
164
219
  }
220
+
165
221
  @multi_silo_project.name_silo.should eq(_name_silo_expectation)
166
222
  @multi_silo_project.location_silo.should eq(_location_silo_expectation)
167
223
  end
@@ -171,16 +227,13 @@ describe Silo do
171
227
  Silo.count.should eq(0)
172
228
  end
173
229
  end
174
-
230
+
175
231
  context "Callbacks" do
176
232
  subject(:project) { build(:callback_project) }
177
-
233
+
178
234
  it "should trigger a named callback" do
179
235
  CallbackProject.should_receive(:triggered)
180
- project.save
236
+ project.save
181
237
  end
182
-
183
-
184
238
  end
185
-
186
- end
239
+ end
@@ -0,0 +1,9 @@
1
+ class VersionedProject
2
+ include Mongoid::Document
3
+ include Mongoid::Silo
4
+
5
+ silo :foobar do |conf|
6
+ conf.generator = "MakeVersionedProjectGrainBelt"
7
+ end
8
+ end
9
+
@@ -0,0 +1,9 @@
1
+ class MakeVersionedProjectGrainBelt < MongoidSilo::GrainBelt
2
+ version 1 do
3
+ { foo: "bar" }
4
+ end
5
+
6
+ version 2 do
7
+ { foo: "baz" }
8
+ end
9
+ end
metadata CHANGED
@@ -1,64 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_silo
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.3.5
4
+ version: 0.3.6
6
5
  platform: ruby
7
6
  authors:
8
7
  - John Maxwell
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-03-08 00:00:00.000000000 Z
11
+ date: 2013-09-10 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- version_requirements: !ruby/object:Gem::Requirement
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: 3.2.9
20
- none: false
21
- name: activesupport
22
20
  type: :runtime
23
21
  prerelease: false
24
- requirement: !ruby/object:Gem::Requirement
22
+ version_requirements: !ruby/object:Gem::Requirement
25
23
  requirements:
26
24
  - - ~>
27
25
  - !ruby/object:Gem::Version
28
26
  version: 3.2.9
29
- none: false
30
27
  - !ruby/object:Gem::Dependency
31
- version_requirements: !ruby/object:Gem::Requirement
28
+ name: mongoid
29
+ requirement: !ruby/object:Gem::Requirement
32
30
  requirements:
33
31
  - - ~>
34
32
  - !ruby/object:Gem::Version
35
33
  version: 3.1.0
36
- none: false
37
- name: mongoid
38
34
  type: :runtime
39
35
  prerelease: false
40
- requirement: !ruby/object:Gem::Requirement
36
+ version_requirements: !ruby/object:Gem::Requirement
41
37
  requirements:
42
38
  - - ~>
43
39
  - !ruby/object:Gem::Version
44
40
  version: 3.1.0
45
- none: false
46
41
  - !ruby/object:Gem::Dependency
47
- version_requirements: !ruby/object:Gem::Requirement
42
+ name: sidekiq
43
+ requirement: !ruby/object:Gem::Requirement
48
44
  requirements:
49
45
  - - ~>
50
46
  - !ruby/object:Gem::Version
51
47
  version: '2.7'
52
- none: false
53
- name: sidekiq
54
48
  type: :runtime
55
49
  prerelease: false
56
- requirement: !ruby/object:Gem::Requirement
50
+ version_requirements: !ruby/object:Gem::Requirement
57
51
  requirements:
58
52
  - - ~>
59
53
  - !ruby/object:Gem::Version
60
54
  version: '2.7'
61
- none: false
62
55
  description: MongoidSilo gives a simple way to create static representations of models
63
56
  email:
64
57
  - john@musicglue.com
@@ -98,33 +91,34 @@ files:
98
91
  - spec/support/models/complex_project.rb
99
92
  - spec/support/models/multi_silo_project.rb
100
93
  - spec/support/models/project.rb
94
+ - spec/support/models/versioned_project.rb
101
95
  - spec/support/silovators/make_block_project_grain_belt.rb
102
96
  - spec/support/silovators/make_complex_grain_belt.rb
103
97
  - spec/support/silovators/make_location_grain_belt.rb
104
98
  - spec/support/silovators/make_name_grain_belt.rb
99
+ - spec/support/silovators/make_versioned_grain_belt.rb
105
100
  homepage: https://github.com/musicglue/mongoid_silo
106
101
  licenses: []
102
+ metadata: {}
107
103
  post_install_message:
108
104
  rdoc_options: []
109
105
  require_paths:
110
106
  - lib
111
107
  required_ruby_version: !ruby/object:Gem::Requirement
112
108
  requirements:
113
- - - ! '>='
109
+ - - '>='
114
110
  - !ruby/object:Gem::Version
115
111
  version: '0'
116
- none: false
117
112
  required_rubygems_version: !ruby/object:Gem::Requirement
118
113
  requirements:
119
- - - ! '>='
114
+ - - '>='
120
115
  - !ruby/object:Gem::Version
121
116
  version: '0'
122
- none: false
123
117
  requirements: []
124
118
  rubyforge_project:
125
- rubygems_version: 1.8.23
119
+ rubygems_version: 2.0.3
126
120
  signing_key:
127
- specification_version: 3
121
+ specification_version: 4
128
122
  summary: MongoidSilo is a bit like a Grain Elevator, but without the grain.
129
123
  test_files:
130
124
  - spec/factories/block_project_factory.rb
@@ -143,8 +137,9 @@ test_files:
143
137
  - spec/support/models/complex_project.rb
144
138
  - spec/support/models/multi_silo_project.rb
145
139
  - spec/support/models/project.rb
140
+ - spec/support/models/versioned_project.rb
146
141
  - spec/support/silovators/make_block_project_grain_belt.rb
147
142
  - spec/support/silovators/make_complex_grain_belt.rb
148
143
  - spec/support/silovators/make_location_grain_belt.rb
149
144
  - spec/support/silovators/make_name_grain_belt.rb
150
- has_rdoc:
145
+ - spec/support/silovators/make_versioned_grain_belt.rb