mongoid_collection_snapshot 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ Next Release (0.2.0)
2
+ ====================
3
+
4
+ * Added ability to maintain a snapshot of multiple collections atomically - [@aaw](https://github.com/aaw).
5
+ * Added support for [Mongoid 3.0](https://github.com/mongoid/mongoid) - [@dblock](https://github.com/dblock).
6
+ * Relaxed version limitations of [mongoid_slug](https://github.com/digitalplaywright/mongoid-slug) - [@dblock](https://github.com/dblock).
7
+
8
+ Version 0.1.0
9
+ =============
10
+
11
+ * Initial public release - [@aaw](https://github.com/aaw).
data/Gemfile CHANGED
@@ -1,14 +1,10 @@
1
1
  source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
- gem "mongoid_slug", ">= 0.8.2"
6
2
 
7
- # Add dependencies to develop your gem here.
8
- # Include everything needed to run rake, tests, features, etc.
3
+ gem "mongoid", "~> 3.0"
4
+ gem "mongoid_slug"
5
+
9
6
  group :development do
10
- gem "mongoid", "~> 2.0.0"
11
- gem "bson_ext", "~> 1.3.0"
12
- gem "rspec", "~> 2.5.0"
13
- gem "jeweler", "~> 1.5.2"
7
+ gem "mongoid", "~> 3.0"
8
+ gem "rspec", "~> 2.11.0"
9
+ gem "jeweler", "~> 1.8.4"
14
10
  end
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Art.sy
1
+ Copyright (c) 2011-2012 Art.sy
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Mongoid Collection Snapshot
2
2
  ===========================
3
3
 
4
- Easy maintenance of collections of processed data in MongoDB with the Mongoid ODM.
4
+ Easy maintenance of collections of processed data in MongoDB with the Mongoid 3.x ODM.
5
5
 
6
6
  Quick example:
7
7
  --------------
@@ -10,13 +10,13 @@ Suppose that you have a Mongoid model called `Artwork`, stored
10
10
  in a MongoDB collection called `artworks` and the underlying documents
11
11
  look something like:
12
12
 
13
- { name: 'Flowers', artist: 'Andy Warhol', price: 3000000 }
13
+ { name: 'Flowers', artist: 'Andy Warhol', price: 3000000 }
14
14
 
15
15
  From time to time, your system runs a map/reduce job to compute the
16
16
  average price of each artist's works, resulting in a collection called
17
17
  `artist_average_price` that contains documents that look like:
18
18
 
19
- { _id: { artist: 'Andy Warhol'}, value: { price: 1500000 } }
19
+ { _id: { artist: 'Andy Warhol'}, value: { price: 1500000 } }
20
20
 
21
21
  If your system wants to maintain and use this average price data, it has
22
22
  to do so at the level of raw MongoDB operations, since
@@ -33,43 +33,51 @@ of Mongoid.
33
33
 
34
34
  In the example above, we'd set up our average artist price collection like:
35
35
 
36
- class AverageArtistPrice
37
- include Mongoid::CollectionSnapshot
38
-
39
- def build
40
- map = <<-EOS
41
- function() {
42
- emit({artist: this['artist']}, {count: 1, sum: this['price']})
43
- }
44
- EOS
45
-
46
- reduce = <<-EOS
47
- function(key, values) {
48
- var sum = 0;
49
- var count = 0;
50
- values.forEach(function(value) {
51
- sum += value['price'];
52
- count += value['count'];
53
- });
54
- return({count: count, sum: sum});
55
- }
56
- EOS
57
-
58
- Artwork.collection.map_reduce(map, reduce, :out => collection_snapshot.name)
59
- end
60
-
61
- def average_price(artist)
62
- doc = collection_snapshot.findOne({'_id.artist': artist})
63
- doc['value']['sum']/doc['value']['count']
64
- end
65
- end
36
+ ``` ruby
37
+ class AverageArtistPrice
38
+ include Mongoid::CollectionSnapshot
39
+
40
+ def build
41
+ map = <<-EOS
42
+ function() {
43
+ emit({artist: this['artist']}, {count: 1, sum: this['price']})
44
+ }
45
+ EOS
46
+
47
+ reduce = <<-EOS
48
+ function(key, values) {
49
+ var sum = 0;
50
+ var count = 0;
51
+ values.forEach(function(value) {
52
+ sum += value['price'];
53
+ count += value['count'];
54
+ });
55
+ return({count: count, sum: sum});
56
+ }
57
+ EOS
58
+
59
+ Mongoid.default_session.command(
60
+ "mapreduce" => "artworks",
61
+ map: map,
62
+ reduce: reduce,
63
+ out: collection_snapshot.name)
64
+ end
65
+
66
+ def average_price(artist)
67
+ doc = collection_snapshot.find({'_id.artist': artist}).first
68
+ doc['value']['sum']/doc['value']['count']
69
+ end
70
+ end
71
+ ```
66
72
 
67
73
  Now, if you want
68
74
  to schedule a recomputation, just call `AverageArtistPrice.create`. The latest
69
75
  snapshot is always available as `AverageArtistPrice.latest`, so you can write
70
76
  code like:
71
77
 
72
- warhol_expected_price = AverageArtistPrice.latest.average_price('Andy Warhol')
78
+ ``` ruby
79
+ warhol_expected_price = AverageArtistPrice.latest.average_price('Andy Warhol')
80
+ ```
73
81
 
74
82
  And always be sure that you'll never be looking at partial results. The only
75
83
  thing you need to do to hook into mongoid_collection_snapshot is implement the
@@ -85,24 +93,31 @@ You can maintain multiple collections atomically within the same snapshot by
85
93
  passing unique collection identifiers to ``collection_snaphot`` when you call it
86
94
  in your build or query methods:
87
95
 
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
96
+ ``` ruby
97
+ class ArtistStats
98
+ include Mongoid::CollectionSnapshot
99
+
100
+ def build
101
+ # ...
102
+ # define map/reduce for average and max aggregations
103
+ # ...
104
+ Mongoid.default_session.command("mapreduce" => "artworks", map: map_avg, reduce: reduce_avg, out: collection_snapshot('average'))
105
+ Mongoid.default_session.command("mapreduce" => "artworks", map: map_max, reduce: reduce_max, out: collection_snapshot('max'))
106
+ end
107
+
108
+ def average_price(artist)
109
+ doc = collection_snapshot('average').find({'_id.artist': artist}).first
110
+ doc['value']['sum']/doc['value']['count']
111
+ end
112
+
113
+ def max_price(artist)
114
+ doc = collection_snapshot('max').find({'_id.artist': artist}).first
115
+ doc['value']['max']
116
+ end
117
+ end
118
+ ```
119
+
120
+ License
121
+ =======
122
+
123
+ MIT License, see [LICENSE.txt](https://github.com/aaw/mongoid_collection_snapshot/blob/master/LICENSE.txt) for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -9,7 +9,7 @@ module Mongoid::CollectionSnapshot
9
9
  include Mongoid::Slug
10
10
 
11
11
  field :workspace_basename, default: 'snapshot'
12
- slug :workspace_basename, as: :workspace_slug
12
+ slug :workspace_basename
13
13
 
14
14
  field :max_collection_snapshot_instances, default: 2
15
15
 
@@ -26,15 +26,15 @@ module Mongoid::CollectionSnapshot
26
26
 
27
27
  def collection_snapshot(name=nil)
28
28
  if name
29
- Mongoid.master.collection("#{self.collection.name}.#{name}.#{workspace_slug}")
29
+ Mongoid.default_session["#{self.collection.name}.#{name}.#{slug}"]
30
30
  else
31
- Mongoid.master.collection("#{self.collection.name}.#{workspace_slug}")
31
+ Mongoid.default_session["#{self.collection.name}.#{slug}"]
32
32
  end
33
33
  end
34
34
 
35
35
  def drop_snapshot_collections
36
- Mongoid.master.collections.each do |collection|
37
- collection.drop if collection.name =~ /^#{self.collection.name}\.([^\.]+\.)?#{workspace_slug}$/
36
+ Mongoid.default_session.collections.each do |collection|
37
+ collection.drop if collection.name =~ /^#{self.collection.name}\.([^\.]+\.)?#{slug}$/
38
38
  end
39
39
  end
40
40
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "mongoid_collection_snapshot"
8
- s.version = "0.1.0"
8
+ s.version = "0.2.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 = "2012-01-24"
12
+ s.date = "2012-11-04"
13
13
  s.description = "Easy maintenence of collections of processed data in MongoDB with the Mongoid ODM"
14
14
  s.email = "aaron.windsor@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  "README.md"
18
18
  ]
19
19
  s.files = [
20
+ "CHANGELOG.md",
20
21
  "Gemfile",
21
22
  "LICENSE.txt",
22
23
  "README.md",
@@ -33,38 +34,31 @@ Gem::Specification.new do |s|
33
34
  s.homepage = "http://github.com/aaw/mongoid_collection_snapshot"
34
35
  s.licenses = ["MIT"]
35
36
  s.require_paths = ["lib"]
36
- s.rubygems_version = "1.8.10"
37
+ s.rubygems_version = "1.8.24"
37
38
  s.summary = "Easy maintenence of collections of processed data in MongoDB with the Mongoid ODM"
38
- s.test_files = [
39
- "spec/models/artwork.rb",
40
- "spec/models/average_artist_price.rb",
41
- "spec/models/multi_collection_snapshot.rb",
42
- "spec/mongoid/collection_snapshot_spec.rb",
43
- "spec/spec_helper.rb"
44
- ]
45
39
 
46
40
  if s.respond_to? :specification_version then
47
41
  s.specification_version = 3
48
42
 
49
43
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
- s.add_runtime_dependency(%q<mongoid_slug>, [">= 0.8.2"])
51
- s.add_development_dependency(%q<mongoid>, ["~> 2.0.0"])
52
- s.add_development_dependency(%q<bson_ext>, ["~> 1.3.0"])
53
- s.add_development_dependency(%q<rspec>, ["~> 2.5.0"])
54
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
44
+ s.add_runtime_dependency(%q<mongoid>, ["~> 3.0"])
45
+ s.add_runtime_dependency(%q<mongoid_slug>, [">= 0"])
46
+ s.add_development_dependency(%q<mongoid>, ["~> 3.0"])
47
+ s.add_development_dependency(%q<rspec>, ["~> 2.11.0"])
48
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
55
49
  else
56
- s.add_dependency(%q<mongoid_slug>, [">= 0.8.2"])
57
- s.add_dependency(%q<mongoid>, ["~> 2.0.0"])
58
- s.add_dependency(%q<bson_ext>, ["~> 1.3.0"])
59
- s.add_dependency(%q<rspec>, ["~> 2.5.0"])
60
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
50
+ s.add_dependency(%q<mongoid>, ["~> 3.0"])
51
+ s.add_dependency(%q<mongoid_slug>, [">= 0"])
52
+ s.add_dependency(%q<mongoid>, ["~> 3.0"])
53
+ s.add_dependency(%q<rspec>, ["~> 2.11.0"])
54
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
61
55
  end
62
56
  else
63
- s.add_dependency(%q<mongoid_slug>, [">= 0.8.2"])
64
- s.add_dependency(%q<mongoid>, ["~> 2.0.0"])
65
- s.add_dependency(%q<bson_ext>, ["~> 1.3.0"])
66
- s.add_dependency(%q<rspec>, ["~> 2.5.0"])
67
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
57
+ s.add_dependency(%q<mongoid>, ["~> 3.0"])
58
+ s.add_dependency(%q<mongoid_slug>, [">= 0"])
59
+ s.add_dependency(%q<mongoid>, ["~> 3.0"])
60
+ s.add_dependency(%q<rspec>, ["~> 2.11.0"])
61
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
68
62
  end
69
63
  end
70
64
 
@@ -20,11 +20,15 @@ class AverageArtistPrice
20
20
  }
21
21
  EOS
22
22
 
23
- Artwork.collection.map_reduce(map, reduce, :out => collection_snapshot.name)
23
+ Mongoid.default_session.command(
24
+ "mapreduce" => "artworks",
25
+ map: map,
26
+ reduce: reduce,
27
+ out: collection_snapshot.name)
24
28
  end
25
29
 
26
30
  def average_price(artist)
27
- doc = collection_snapshot.find_one({'_id.artist' => artist})
31
+ doc = collection_snapshot.where({'_id.artist' => artist}).first
28
32
  doc['value']['sum']/doc['value']['count']
29
33
  end
30
34
 
@@ -8,7 +8,7 @@ class MultiCollectionSnapshot
8
8
  end
9
9
 
10
10
  def get_names
11
- ['foo', 'bar', 'baz'].map{ |x| collection_snapshot(x).find_one['name'] }.join('')
11
+ ['foo', 'bar', 'baz'].map{ |x| collection_snapshot(x).find.first['name'] }.join('')
12
12
  end
13
13
 
14
14
  end
@@ -54,22 +54,22 @@ module Mongoid
54
54
 
55
55
  it "safely cleans up all collections used by the snapshot" do
56
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})
57
+ Mongoid.default_session["#{MultiCollectionSnapshot.collection.name}.do.not_delete"].insert({'a' => 1})
58
+ Mongoid.default_session["#{MultiCollectionSnapshot.collection.name}.snapshorty"].insert({'a' => 1})
59
+ Mongoid.default_session["#{MultiCollectionSnapshot.collection.name}.hello.1"].insert({'a' => 1})
60
60
 
61
61
  MultiCollectionSnapshot.create
62
- before_create = Mongoid.master.collections.map{ |c| c.name }
62
+ before_create = Mongoid.default_session.collections.map{ |c| c.name }
63
63
  before_create.length.should > 0
64
64
 
65
65
  sleep(1)
66
66
  MultiCollectionSnapshot.create
67
- after_create = Mongoid.master.collections.map{ |c| c.name }
67
+ after_create = Mongoid.default_session.collections.map{ |c| c.name }
68
68
  collections_created = (after_create - before_create).sort
69
69
  collections_created.length.should == 3
70
70
 
71
71
  MultiCollectionSnapshot.latest.destroy
72
- after_destroy = Mongoid.master.collections.map{ |c| c.name }
72
+ after_destroy = Mongoid.default_session.collections.map{ |c| c.name }
73
73
  collections_destroyed = (after_create - after_destroy).sort
74
74
  collections_created.should == collections_destroyed
75
75
  end
data/spec/spec_helper.rb CHANGED
@@ -5,20 +5,18 @@ require 'rspec'
5
5
  require 'mongoid'
6
6
 
7
7
  Mongoid.configure do |config|
8
- name = "mongoid_collection_snapshot_test"
9
- config.master = Mongo::Connection.new.db(name)
10
- config.logger = Logger.new('/dev/null')
8
+ config.connect_to("mongoid_collection_snapshot_test")
11
9
  end
12
10
 
13
11
  require File.expand_path("../../lib/mongoid_collection_snapshot", __FILE__)
14
12
  Dir["#{File.dirname(__FILE__)}/models/**/*.rb"].each { |f| require f }
15
13
 
16
- Rspec.configure do |c|
14
+ RSpec.configure do |c|
17
15
  c.before(:each) do
18
- Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
16
+ Mongoid.purge!
19
17
  end
20
- c.after(:all) do
21
- Mongoid.master.command({'dropDatabase' => 1})
18
+ c.after(:all) do
19
+ Mongoid.default_session.drop
22
20
  end
23
21
  end
24
22
 
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.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,63 +9,88 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-24 00:00:00.000000000Z
12
+ date: 2012-11-04 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongoid
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: mongoid_slug
16
- requirement: &2156103400 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
17
33
  none: false
18
34
  requirements:
19
35
  - - ! '>='
20
36
  - !ruby/object:Gem::Version
21
- version: 0.8.2
37
+ version: '0'
22
38
  type: :runtime
23
39
  prerelease: false
24
- version_requirements: *2156103400
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
25
46
  - !ruby/object:Gem::Dependency
26
47
  name: mongoid
27
- requirement: &2156101560 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
28
49
  none: false
29
50
  requirements:
30
51
  - - ~>
31
52
  - !ruby/object:Gem::Version
32
- version: 2.0.0
53
+ version: '3.0'
33
54
  type: :development
34
55
  prerelease: false
35
- version_requirements: *2156101560
36
- - !ruby/object:Gem::Dependency
37
- name: bson_ext
38
- requirement: &2156099780 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
39
57
  none: false
40
58
  requirements:
41
59
  - - ~>
42
60
  - !ruby/object:Gem::Version
43
- version: 1.3.0
44
- type: :development
45
- prerelease: false
46
- version_requirements: *2156099780
61
+ version: '3.0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: rspec
49
- requirement: &2156095320 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
53
68
  - !ruby/object:Gem::Version
54
- version: 2.5.0
69
+ version: 2.11.0
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *2156095320
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.11.0
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: jeweler
60
- requirement: &2156093080 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ~>
64
84
  - !ruby/object:Gem::Version
65
- version: 1.5.2
85
+ version: 1.8.4
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *2156093080
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.8.4
69
94
  description: Easy maintenence of collections of processed data in MongoDB with the
70
95
  Mongoid ODM
71
96
  email: aaron.windsor@gmail.com
@@ -75,6 +100,7 @@ extra_rdoc_files:
75
100
  - LICENSE.txt
76
101
  - README.md
77
102
  files:
103
+ - CHANGELOG.md
78
104
  - Gemfile
79
105
  - LICENSE.txt
80
106
  - README.md
@@ -102,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
102
128
  version: '0'
103
129
  segments:
104
130
  - 0
105
- hash: -1729910918776026621
131
+ hash: -1957011938527181136
106
132
  required_rubygems_version: !ruby/object:Gem::Requirement
107
133
  none: false
108
134
  requirements:
@@ -111,14 +137,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
137
  version: '0'
112
138
  requirements: []
113
139
  rubyforge_project:
114
- rubygems_version: 1.8.10
140
+ rubygems_version: 1.8.24
115
141
  signing_key:
116
142
  specification_version: 3
117
143
  summary: Easy maintenence of collections of processed data in MongoDB with the Mongoid
118
144
  ODM
119
- test_files:
120
- - spec/models/artwork.rb
121
- - spec/models/average_artist_price.rb
122
- - spec/models/multi_collection_snapshot.rb
123
- - spec/mongoid/collection_snapshot_spec.rb
124
- - spec/spec_helper.rb
145
+ test_files: []