mongoid_collection_snapshot 0.0.1 → 0.1.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.
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  Mongoid Collection Snapshot
2
2
  ===========================
3
3
 
4
- Easy maintenence of collections of processed data in MongoDB with the Mongoid ODM.
4
+ Easy maintenance of collections of processed data in MongoDB with the Mongoid ODM.
5
5
 
6
- Example:
7
- --------
6
+ Quick example:
7
+ --------------
8
8
 
9
9
  Suppose that you have a Mongoid model called `Artwork`, stored
10
10
  in a MongoDB collection called `artworks` and the underlying documents
@@ -78,3 +78,31 @@ method `build`, which populates the collection snapshot and any indexes you need
78
78
  By default, mongoid_collection_snapshot maintains the most recent two snapshots
79
79
  computed any given time.
80
80
 
81
+ Other features
82
+ --------------
83
+
84
+ You can maintain multiple collections atomically within the same snapshot by
85
+ passing unique collection identifiers to ``collection_snaphot`` when you call it
86
+ in your build or query methods:
87
+
88
+ class ArtistStats
89
+ include Mongoid::CollectionSnapshot
90
+
91
+ def build
92
+ # ...
93
+ # define map/reduce for average and max aggregations
94
+ # ...
95
+ Artwork.collection.map_reduce(map_avg, reduce_avg, :out => collection_snapshot('average'))
96
+ Artwork.collection.map_reduce(map_max, reduce_max, :out => collection_snapshot('max'))
97
+ end
98
+
99
+ def average_price(artist)
100
+ doc = collection_snapshot('average').findOne({'_id.artist': artist})
101
+ doc['value']['sum']/doc['value']['count']
102
+ end
103
+
104
+ def max_price(artist)
105
+ doc = collection_snapshot('max').findOne({'_id.artist': artist})
106
+ doc['value']['max']
107
+ end
108
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.1.0
@@ -15,7 +15,7 @@ module Mongoid::CollectionSnapshot
15
15
 
16
16
  before_save :build
17
17
  after_save :ensure_at_most_two_instances_exist
18
- before_destroy :drop_snapshot_collection
18
+ before_destroy :drop_snapshot_collections
19
19
  end
20
20
 
21
21
  module ClassMethods
@@ -24,12 +24,18 @@ module Mongoid::CollectionSnapshot
24
24
  end
25
25
  end
26
26
 
27
- def collection_snapshot
28
- Mongoid.master.collection("#{self.collection.name}.#{workspace_slug}")
27
+ def collection_snapshot(name=nil)
28
+ if name
29
+ Mongoid.master.collection("#{self.collection.name}.#{name}.#{workspace_slug}")
30
+ else
31
+ Mongoid.master.collection("#{self.collection.name}.#{workspace_slug}")
32
+ end
29
33
  end
30
34
 
31
- def drop_snapshot_collection
32
- collection_snapshot.drop
35
+ def drop_snapshot_collections
36
+ Mongoid.master.collections.each do |collection|
37
+ collection.drop if collection.name =~ /^#{self.collection.name}\.([^\.]+\.)?#{workspace_slug}$/
38
+ end
33
39
  end
34
40
 
35
41
  # Since we should always be using the latest instance of this class, this method is
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{mongoid_collection_snapshot}
8
- s.version = "0.0.1"
7
+ s.name = "mongoid_collection_snapshot"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Aaron Windsor"]
12
- s.date = %q{2011-09-02}
13
- s.description = %q{Easy maintenence of collections of processed data in MongoDB with the Mongoid ODM}
14
- s.email = %q{aaron.windsor@gmail.com}
12
+ s.date = "2012-01-24"
13
+ s.description = "Easy maintenence of collections of processed data in MongoDB with the Mongoid ODM"
14
+ s.email = "aaron.windsor@gmail.com"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
17
  "README.md"
@@ -26,17 +26,19 @@ Gem::Specification.new do |s|
26
26
  "mongoid_collection_snapshot.gemspec",
27
27
  "spec/models/artwork.rb",
28
28
  "spec/models/average_artist_price.rb",
29
+ "spec/models/multi_collection_snapshot.rb",
29
30
  "spec/mongoid/collection_snapshot_spec.rb",
30
31
  "spec/spec_helper.rb"
31
32
  ]
32
- s.homepage = %q{http://github.com/aaw/mongoid_collection_snapshot}
33
+ s.homepage = "http://github.com/aaw/mongoid_collection_snapshot"
33
34
  s.licenses = ["MIT"]
34
35
  s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.6.2}
36
- s.summary = %q{Easy maintenence of collections of processed data in MongoDB with the Mongoid ODM}
36
+ s.rubygems_version = "1.8.10"
37
+ s.summary = "Easy maintenence of collections of processed data in MongoDB with the Mongoid ODM"
37
38
  s.test_files = [
38
39
  "spec/models/artwork.rb",
39
40
  "spec/models/average_artist_price.rb",
41
+ "spec/models/multi_collection_snapshot.rb",
40
42
  "spec/mongoid/collection_snapshot_spec.rb",
41
43
  "spec/spec_helper.rb"
42
44
  ]
@@ -0,0 +1,14 @@
1
+ class MultiCollectionSnapshot
2
+ include Mongoid::CollectionSnapshot
3
+
4
+ def build
5
+ collection_snapshot('foo').insert({'name' => 'foo!'})
6
+ collection_snapshot('bar').insert({'name' => 'bar!'})
7
+ collection_snapshot('baz').insert({'name' => 'baz!'})
8
+ end
9
+
10
+ def get_names
11
+ ['foo', 'bar', 'baz'].map{ |x| collection_snapshot(x).find_one['name'] }.join('')
12
+ end
13
+
14
+ end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module Mongoid
4
4
  describe CollectionSnapshot do
5
5
 
6
- context "creating a snapshot" do
6
+ context "creating a basic snapshot" do
7
7
 
8
8
  let!(:flowers) { Artwork.create(:name => 'Flowers', :artist => 'Andy Warhol', :price => 3000000) }
9
9
  let!(:guns) { Artwork.create(:name => 'Guns', :artist => 'Andy Warhol', :price => 1000000) }
@@ -12,11 +12,13 @@ module Mongoid
12
12
  it "returns nil if no snapshot has been created" do
13
13
  AverageArtistPrice.latest.should be_nil
14
14
  end
15
+
15
16
  it "runs the build method on creation" do
16
17
  snapshot = AverageArtistPrice.create
17
18
  snapshot.average_price('Andy Warhol').should == 2000000
18
19
  snapshot.average_price('Damien Hirst').should == 1500000
19
20
  end
21
+
20
22
  it "returns the most recent snapshot through the latest methods" do
21
23
  first = AverageArtistPrice.create
22
24
  first.should == AverageArtistPrice.latest
@@ -31,12 +33,47 @@ module Mongoid
31
33
  third = AverageArtistPrice.create
32
34
  AverageArtistPrice.latest.should == third
33
35
  end
36
+
34
37
  it "should only maintain at most two of the latest snapshots to support its calculations" do
38
+ AverageArtistPrice.create
35
39
  10.times do
36
40
  AverageArtistPrice.create
37
- AverageArtistPrice.count.should <= 2
41
+ AverageArtistPrice.count.should == 2
38
42
  end
39
43
  end
44
+
45
+ end
46
+
47
+ context "creating a snapshot containing multiple collections" do
48
+
49
+ it "populates several collections and allows them to be queried" do
50
+ MultiCollectionSnapshot.latest.should be_nil
51
+ 10.times { MultiCollectionSnapshot.create }
52
+ MultiCollectionSnapshot.latest.get_names.should == "foo!bar!baz!"
53
+ end
54
+
55
+ it "safely cleans up all collections used by the snapshot" do
56
+ # Create some collections with names close to the snapshots we'll create
57
+ Mongoid.master["#{MultiCollectionSnapshot.collection.name}.do.not_delete"].insert({'a' => 1})
58
+ Mongoid.master["#{MultiCollectionSnapshot.collection.name}.snapshorty"].insert({'a' => 1})
59
+ Mongoid.master["#{MultiCollectionSnapshot.collection.name}.hello.1"].insert({'a' => 1})
60
+
61
+ MultiCollectionSnapshot.create
62
+ before_create = Mongoid.master.collections.map{ |c| c.name }
63
+ before_create.length.should > 0
64
+
65
+ sleep(1)
66
+ MultiCollectionSnapshot.create
67
+ after_create = Mongoid.master.collections.map{ |c| c.name }
68
+ collections_created = (after_create - before_create).sort
69
+ collections_created.length.should == 3
70
+
71
+ MultiCollectionSnapshot.latest.destroy
72
+ after_destroy = Mongoid.master.collections.map{ |c| c.name }
73
+ collections_destroyed = (after_create - after_destroy).sort
74
+ collections_created.should == collections_destroyed
75
+ end
76
+
40
77
  end
41
78
 
42
79
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_collection_snapshot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-02 00:00:00.000000000 -04:00
13
- default_executable:
12
+ date: 2012-01-24 00:00:00.000000000Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: mongoid_slug
17
- requirement: &75871620 !ruby/object:Gem::Requirement
16
+ requirement: &2156103400 !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ! '>='
@@ -22,10 +21,10 @@ dependencies:
22
21
  version: 0.8.2
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *75871620
24
+ version_requirements: *2156103400
26
25
  - !ruby/object:Gem::Dependency
27
26
  name: mongoid
28
- requirement: &75871010 !ruby/object:Gem::Requirement
27
+ requirement: &2156101560 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
30
  - - ~>
@@ -33,10 +32,10 @@ dependencies:
33
32
  version: 2.0.0
34
33
  type: :development
35
34
  prerelease: false
36
- version_requirements: *75871010
35
+ version_requirements: *2156101560
37
36
  - !ruby/object:Gem::Dependency
38
37
  name: bson_ext
39
- requirement: &75870610 !ruby/object:Gem::Requirement
38
+ requirement: &2156099780 !ruby/object:Gem::Requirement
40
39
  none: false
41
40
  requirements:
42
41
  - - ~>
@@ -44,10 +43,10 @@ dependencies:
44
43
  version: 1.3.0
45
44
  type: :development
46
45
  prerelease: false
47
- version_requirements: *75870610
46
+ version_requirements: *2156099780
48
47
  - !ruby/object:Gem::Dependency
49
48
  name: rspec
50
- requirement: &75796300 !ruby/object:Gem::Requirement
49
+ requirement: &2156095320 !ruby/object:Gem::Requirement
51
50
  none: false
52
51
  requirements:
53
52
  - - ~>
@@ -55,10 +54,10 @@ dependencies:
55
54
  version: 2.5.0
56
55
  type: :development
57
56
  prerelease: false
58
- version_requirements: *75796300
57
+ version_requirements: *2156095320
59
58
  - !ruby/object:Gem::Dependency
60
59
  name: jeweler
61
- requirement: &75795230 !ruby/object:Gem::Requirement
60
+ requirement: &2156093080 !ruby/object:Gem::Requirement
62
61
  none: false
63
62
  requirements:
64
63
  - - ~>
@@ -66,7 +65,7 @@ dependencies:
66
65
  version: 1.5.2
67
66
  type: :development
68
67
  prerelease: false
69
- version_requirements: *75795230
68
+ version_requirements: *2156093080
70
69
  description: Easy maintenence of collections of processed data in MongoDB with the
71
70
  Mongoid ODM
72
71
  email: aaron.windsor@gmail.com
@@ -85,9 +84,9 @@ files:
85
84
  - mongoid_collection_snapshot.gemspec
86
85
  - spec/models/artwork.rb
87
86
  - spec/models/average_artist_price.rb
87
+ - spec/models/multi_collection_snapshot.rb
88
88
  - spec/mongoid/collection_snapshot_spec.rb
89
89
  - spec/spec_helper.rb
90
- has_rdoc: true
91
90
  homepage: http://github.com/aaw/mongoid_collection_snapshot
92
91
  licenses:
93
92
  - MIT
@@ -103,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
102
  version: '0'
104
103
  segments:
105
104
  - 0
106
- hash: 522934671
105
+ hash: -1729910918776026621
107
106
  required_rubygems_version: !ruby/object:Gem::Requirement
108
107
  none: false
109
108
  requirements:
@@ -112,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
111
  version: '0'
113
112
  requirements: []
114
113
  rubyforge_project:
115
- rubygems_version: 1.6.2
114
+ rubygems_version: 1.8.10
116
115
  signing_key:
117
116
  specification_version: 3
118
117
  summary: Easy maintenence of collections of processed data in MongoDB with the Mongoid
@@ -120,5 +119,6 @@ summary: Easy maintenence of collections of processed data in MongoDB with the M
120
119
  test_files:
121
120
  - spec/models/artwork.rb
122
121
  - spec/models/average_artist_price.rb
122
+ - spec/models/multi_collection_snapshot.rb
123
123
  - spec/mongoid/collection_snapshot_spec.rb
124
124
  - spec/spec_helper.rb