mongoid_silo 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
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