mongoid_atomic 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,87 @@
1
+ = Mongoid::Atomic
2
+
3
+ Atomic updates for your Mongoid models.
4
+
5
+ == Installation
6
+
7
+ Add to Gemfile:
8
+
9
+ gem 'mongoid_atomic'
10
+
11
+ == Getting Started
12
+
13
+ Include the module in models where you want it:
14
+
15
+ class User
16
+ include Mongoid::Document
17
+ include Mongoid::Atomic
18
+
19
+ field :username
20
+ field :groups, :type => Array, :default => ['users']
21
+ field :post_count, :type => Integer
22
+ end
23
+
24
+ == Easy and Human Readable Atomic Updates!
25
+
26
+ A simple example. To increment a post count:
27
+
28
+ u = User.where(:name => 'Bill').first
29
+ u.atomic_inc(:post_count)
30
+
31
+ .. which might fit nicely in your Post model:
32
+
33
+ class Post
34
+ include Mongoid::Document
35
+ ...
36
+ references_one :user
37
+ ...
38
+ after_create :update_post_count
39
+ ...
40
+ private
41
+ def update_post_count
42
+ self.user.atomic_inc :post_count
43
+ end
44
+ end
45
+
46
+ .. or join a group:
47
+
48
+ ...
49
+ u.atomic_push(:groups, 'posters')
50
+
51
+
52
+ .. or remove a field:
53
+
54
+ ...
55
+ u.atomic_unset(:deprecated_field)
56
+
57
+ .. or change your name:
58
+
59
+ ...
60
+ u.atomic_set(:username, 'bill')
61
+
62
+ .. or do all of it at once:
63
+
64
+ ...
65
+ u.atomic_update :inc => {:post_count => 1}, :set => {:username => 'bobby'}, :pushAll => {:groups => %w[rubyists developers]}
66
+
67
+ == A Note About Attribute Consistency
68
+
69
+ No effort is made to ensure consistency between the server and instance attributes. There's a good reason for this: the operations are performed inside of the Mongo server and we often don't care about the result. If you need to ensure the consistency of your attributes after an update, call the Mongoid reload method. Example:
70
+
71
+ >> u = User.first
72
+ => #<User....>
73
+
74
+ >> u.post_count
75
+ => 0
76
+
77
+ >> u.atomic_inc :post_count
78
+ => nil
79
+
80
+ >> u.post_count
81
+ => 0
82
+
83
+ >> u.reload
84
+ => #<User....>
85
+
86
+ >> u.post_count
87
+ >= 1
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,50 @@
1
+ module Mongoid::Atomic
2
+ extend ActiveSupport::Concern
3
+
4
+ def atomic_update(options)
5
+ doc = {}
6
+ options.each do |k,v|
7
+ next unless %w[inc set unset push pushAll addToSet pop pull pullAll].include? k.to_s
8
+ doc["$#{k}"] = v
9
+ end
10
+ collection.update({'_id' => self._id}, doc)
11
+ end
12
+
13
+ def atomic_inc(field, by=1)
14
+ atomic_update :inc => { field => by }
15
+ end
16
+ alias :atomic_increment :atomic_inc
17
+
18
+ def atomic_set(field, value)
19
+ atomic_update :set => { field => value }
20
+ end
21
+
22
+ def atomic_unset(field)
23
+ atomic_update :unset => { field => 1 }
24
+ end
25
+
26
+ def atomic_push(field, value)
27
+ atomic_update :push => { field => value }
28
+ end
29
+
30
+ def atomic_push_all(field, array)
31
+ atomic_update :pushAll => { field => array.to_a }
32
+ end
33
+
34
+ def atomic_add_to_set(field, value)
35
+ atomic_update :addToSet => { field => value }
36
+ end
37
+
38
+ def atomic_pop(field, index=1)
39
+ atomic_update :pop => { field => index.to_i }
40
+ end
41
+
42
+ def atomic_pull(field, value)
43
+ atomic_update :pull => { field => value }
44
+ end
45
+
46
+ def atomic_pull_all(field, array)
47
+ atomic_update :pullAll => { field => array.to_a }
48
+ end
49
+
50
+ end
@@ -0,0 +1,9 @@
1
+ class User
2
+ include Mongoid::Document
3
+ include Mongoid::Atomic
4
+
5
+ field :username
6
+ field :groups, :type => Array, :defaults => ['users']
7
+ field :post_count, :type => Integer, :default => 0
8
+
9
+ end
@@ -0,0 +1,92 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Atomic do
4
+
5
+ context "user" do
6
+
7
+ before(:each) do
8
+ @bob = User.create(:username => 'Bob', :groups => %w[users moderators admins])
9
+ @nancy = User.create(:username => 'Nancy', :groups => %w[users peons])
10
+ end
11
+
12
+ it "should increment" do
13
+ @bob.atomic_inc :post_count
14
+ @bob.reload.post_count.should eql 1
15
+ @bob.atomic_inc :post_count
16
+ @bob.reload.post_count.should eql 2
17
+ @bob.atomic_inc :post_count, -2
18
+ @bob.reload.post_count.should eql 0
19
+ @nancy.atomic_inc :post_count, 10
20
+ @nancy.reload.post_count.should eql 10
21
+ end
22
+
23
+ it "should set" do
24
+ @bob.atomic_set :username, 'Robby'
25
+ @bob.reload.username.should eql 'Robby'
26
+ @nancy.atomic_set :groups, %w[users women]
27
+ @nancy.reload.groups.should eql %w[users women]
28
+ end
29
+
30
+ it "should unset" do
31
+ @bob.atomic_unset :groups
32
+ @bob.reload.groups.should eql nil
33
+ end
34
+
35
+ it "should push" do
36
+ @bob.atomic_push :groups, 'bobs'
37
+ @bob.reload.groups.should eql %w[users moderators admins bobs]
38
+ @nancy.atomic_unset :groups
39
+ @nancy.atomic_push :groups, 'women'
40
+ @nancy.atomic_push :groups, 'nancies'
41
+ @nancy.reload.groups.should eql %w[women nancies]
42
+ end
43
+
44
+ it "should push all" do
45
+ @bob.atomic_push_all :groups, %w[executives bosses idiots]
46
+ @bob.reload.groups.should eql %w[users moderators admins executives bosses idiots]
47
+ end
48
+
49
+ it "should add to set" do
50
+ @bob.atomic_add_to_set :groups, 'bobs'
51
+ @bob.reload.groups.should eql %w[users moderators admins bobs]
52
+ @bob.atomic_add_to_set :groups, 'users'
53
+ @bob.reload.groups.should eql %w[users moderators admins bobs]
54
+ end
55
+
56
+ it "should pop" do
57
+ @bob.atomic_pop :groups
58
+ @bob.reload.groups.should eql %w[users moderators]
59
+ @bob.atomic_pop :groups, -1
60
+ @bob.reload.groups.should eql %w[moderators]
61
+ @nancy.atomic_pop :groups, 1
62
+ @nancy.reload.groups.should eql %w[users]
63
+ @nancy.atomic_set :groups, %w[beautiful brunette woman starts_with_n]
64
+ @nancy.atomic_pop :groups, 1
65
+ @nancy.reload.groups.should eql %w[beautiful brunette woman]
66
+ end
67
+
68
+ it "should pull" do
69
+ @bob.atomic_pull :groups, 'users'
70
+ @bob.reload.groups.should eql %w[moderators admins]
71
+ @nancy.atomic_pull :groups, 'peons'
72
+ @nancy.reload.groups.should eql %w[users]
73
+ end
74
+
75
+ it "should pull all" do
76
+ @bob.atomic_pull_all :groups, %w[users admins]
77
+ @bob.reload.groups.should eql %w[moderators]
78
+ end
79
+
80
+ it "should update multiple field at the same time" do
81
+ @bob.atomic_update :inc => {:post_count => 1}, :set => {:username => 'bobby'}, :pushAll => {:groups => %w[bosses idiots]}
82
+ @bob.reload
83
+ @bob.post_count.should eql 1
84
+ @bob.groups.should eql %w[users moderators admins bosses idiots]
85
+ @bob.username.should eql 'bobby'
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
92
+
@@ -0,0 +1,25 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+
4
+ Bundler.require(:default)
5
+
6
+ Mongoid.config.master = Mongo::Connection.new.db("mongoid_atomic_test")
7
+
8
+ require File.expand_path("../../lib/mongoid_atomic", __FILE__)
9
+ Dir["#{File.dirname(__FILE__)}/models/*.rb"].each { |f| require f }
10
+
11
+ DatabaseCleaner.orm = "mongoid"
12
+
13
+ Rspec.configure do |config|
14
+ config.before(:all) do
15
+ DatabaseCleaner.strategy = :truncation
16
+ end
17
+
18
+ config.before(:each) do
19
+ DatabaseCleaner.start
20
+ end
21
+
22
+ config.after(:each) do
23
+ DatabaseCleaner.clean
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid_atomic
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Jason Coene
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-17 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: mongoid
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: -1848230040
30
+ segments:
31
+ - 2
32
+ - 0
33
+ - 0
34
+ - beta4
35
+ version: 2.0.0.beta4
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ description: A collection of instance methods to more easily perform atomic updates to your Mongoid models.
39
+ email: jcoene@gmail.com
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files:
45
+ - README.rdoc
46
+ files:
47
+ - README.rdoc
48
+ - VERSION
49
+ - lib/mongoid_atomic.rb
50
+ - spec/models/user.rb
51
+ - spec/mongoid_atomic_spec.rb
52
+ - spec/spec_helper.rb
53
+ has_rdoc: true
54
+ homepage: http://github.com/jcoene/mongoid_atomic
55
+ licenses: []
56
+
57
+ post_install_message:
58
+ rdoc_options:
59
+ - --charset=UTF-8
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.7
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Atomic updates for your Mongoid models.
87
+ test_files:
88
+ - spec/models/user.rb
89
+ - spec/mongoid_atomic_spec.rb
90
+ - spec/spec_helper.rb