mongoid-autoinc 4.0.0 → 5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -14
- data/lib/autoinc.rb +103 -26
- data/lib/autoinc/incrementor.rb +58 -27
- data/lib/autoinc/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a79423bfe165eec63f29853f0223dc6d2e5eabcc
|
4
|
+
data.tar.gz: 4eaa807480ffff04081b09e38da549963325b356
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9a43d20f68350a8ca2ab2c08c3df91a7653eace2eef842b2ea264c366516fd2b9e3aaca7753143b7ad24599c4b0833a1b708ae5b11ac4e98e4b4ca55e7ff76b
|
7
|
+
data.tar.gz: 371a8ae6062372b2bb63f8e3d519bbf938c83cca91813b5b2600ec71e2f9c98c14103a48f6d65e1d6f9582a2c5eaafa2d8b9a16490c9b1e2b7e1696ca8e4615c
|
data/README.md
CHANGED
@@ -2,8 +2,15 @@
|
|
2
2
|
|
3
3
|
A mongoid plugin to add auto incrementing fields to your documents.
|
4
4
|
|
5
|
-
[![
|
6
|
-
|
5
|
+
[![Inline docs](
|
6
|
+
http://inch-ci.org/github/suweller/mongoid-autoinc.svg?branch=master&style=flat
|
7
|
+
)](http://inch-ci.org/github/suweller/mongoid-autoinc)
|
8
|
+
[![Code Climate](
|
9
|
+
http://img.shields.io/codeclimate/github/suweller/mongoid-autoinc.svg?style=flat
|
10
|
+
)](https://codeclimate.com/github/suweller/mongoid-autoinc)
|
11
|
+
[![Build Status](
|
12
|
+
http://img.shields.io/travis/suweller/mongoid-autoinc.svg?style=flat
|
13
|
+
)](https://travis-ci.org/suweller/mongoid-autoinc)
|
7
14
|
|
8
15
|
# Versions
|
9
16
|
|
@@ -11,8 +18,9 @@ Use 0.1.3 for mongoid 2.0
|
|
11
18
|
|
12
19
|
Use 0.3.0 for mongoid 3.0
|
13
20
|
|
14
|
-
Use
|
15
|
-
|
21
|
+
Use 4.x.x for mongoid 4
|
22
|
+
|
23
|
+
Use 5.x.x for mongoid 5
|
16
24
|
|
17
25
|
## Installation
|
18
26
|
|
@@ -36,16 +44,16 @@ class User
|
|
36
44
|
include Mongoid::Document
|
37
45
|
include Mongoid::Autoinc
|
38
46
|
field :name
|
39
|
-
field :number, :
|
47
|
+
field :number, type: Integer
|
40
48
|
|
41
49
|
increments :number
|
42
50
|
end
|
43
51
|
|
44
|
-
user = User.create(:
|
52
|
+
user = User.create(name: 'Dr. Percival "Perry" Ulysses Cox')
|
45
53
|
user.id # BSON::ObjectId('4d1d150d30f2246bc6000001')
|
46
54
|
user.number # 1
|
47
55
|
|
48
|
-
another_user = User.create(:
|
56
|
+
another_user = User.create(name: 'Bob Kelso')
|
49
57
|
another_user.number # 2
|
50
58
|
```
|
51
59
|
|
@@ -59,9 +67,9 @@ class PatientFile
|
|
59
67
|
include Mongoid::Autoinc
|
60
68
|
|
61
69
|
field :name
|
62
|
-
field :number, :
|
70
|
+
field :number, type: Integer
|
63
71
|
|
64
|
-
increments :number, :
|
72
|
+
increments :number, scope: :patient_id
|
65
73
|
|
66
74
|
belongs_to :patient
|
67
75
|
|
@@ -71,13 +79,13 @@ end
|
|
71
79
|
Scope can also be a Proc:
|
72
80
|
|
73
81
|
``` ruby
|
74
|
-
increments :number, :
|
82
|
+
increments :number, scope: -> { patient.name }
|
75
83
|
```
|
76
84
|
|
77
85
|
### Custom Increment Trigger
|
78
86
|
|
79
87
|
You can trigger the assignment of an increment field manually by passing:
|
80
|
-
|
88
|
+
`auto: false` to the increment field.
|
81
89
|
This allows for more flexible assignment of your increment number:
|
82
90
|
|
83
91
|
``` ruby
|
@@ -88,11 +96,11 @@ class Intern
|
|
88
96
|
field :name
|
89
97
|
field :number
|
90
98
|
|
91
|
-
increments :number, :
|
99
|
+
increments :number, auto: false
|
92
100
|
|
93
101
|
after_save :assign_number_to_jd
|
94
102
|
|
95
|
-
|
103
|
+
protected
|
96
104
|
|
97
105
|
def assign_number_to_jd
|
98
106
|
assign!(:number) if number.blank? && name == 'J.D.'
|
@@ -166,7 +174,7 @@ second_ticket.number # 10
|
|
166
174
|
The step option can also be a Proc:
|
167
175
|
|
168
176
|
``` ruby
|
169
|
-
increments :number, step:
|
177
|
+
increments :number, step: -> { 1 + rand(10) }
|
170
178
|
```
|
171
179
|
|
172
180
|
### Development
|
data/lib/autoinc.rb
CHANGED
@@ -1,19 +1,41 @@
|
|
1
1
|
require 'autoinc/incrementor'
|
2
2
|
|
3
|
+
# namespace all +Mongoid::Autoinc+ functionality to +Mongoid+ to reduce
|
4
|
+
# possible clashes with other gems.
|
3
5
|
module Mongoid
|
4
|
-
|
6
|
+
# Include module to allow defining of autoincrementing fields.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class Invoice
|
10
|
+
# include Mongoid::Document
|
11
|
+
# include Mongoid::Autoinc
|
12
|
+
#
|
13
|
+
# field :number, type: Integer
|
14
|
+
# increments :number
|
15
|
+
# end
|
5
16
|
module Autoinc
|
6
17
|
extend ActiveSupport::Concern
|
7
18
|
|
8
19
|
AlreadyAssignedError = Class.new(StandardError)
|
9
20
|
AutoIncrementsError = Class.new(StandardError)
|
10
21
|
|
11
|
-
included
|
12
|
-
before_create :update_auto_increments
|
13
|
-
end
|
22
|
+
included { before_create(:update_auto_increments) }
|
14
23
|
|
24
|
+
# +Mongoid::Autoinc+ class methods to allow for autoincrementing fields.
|
15
25
|
module ClassMethods
|
16
|
-
|
26
|
+
# Returns all incrementing fields of the document
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# class Invoice
|
30
|
+
# include Mongoid::Document
|
31
|
+
# include Mongoid::Autoinc
|
32
|
+
#
|
33
|
+
# field :number, type: Integer
|
34
|
+
# increments :number
|
35
|
+
# end
|
36
|
+
# Invoice.incrementing_fields # => {number: {auto: true}}
|
37
|
+
#
|
38
|
+
# @return [ Hash ] +Hash+ with fields and their autoincrement options
|
17
39
|
def incrementing_fields
|
18
40
|
if superclass.respond_to?(:incrementing_fields)
|
19
41
|
@incrementing_fields ||= superclass.incrementing_fields.dup
|
@@ -22,58 +44,113 @@ module Mongoid
|
|
22
44
|
end
|
23
45
|
end
|
24
46
|
|
25
|
-
|
26
|
-
|
47
|
+
# Set an autoincrementing field for a +Mongoid::Document+
|
48
|
+
#
|
49
|
+
# @param [ Symbol ] field The name of the field to apply autoincrement to
|
50
|
+
# @param [ Hash ] options The options to pass to that field
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
# class Invoice
|
54
|
+
# include Mongoid::Document
|
55
|
+
# include Mongoid::Autoinc
|
56
|
+
#
|
57
|
+
# field :number, type: Integer
|
58
|
+
# increments :number
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# @example
|
62
|
+
# class User
|
63
|
+
# include Mongoid::Document
|
64
|
+
# include Mongoid::Autoinc
|
65
|
+
#
|
66
|
+
# field :number, type: Integer
|
67
|
+
# increments :number, auto: false
|
68
|
+
# end
|
69
|
+
def increments(field, options = {})
|
70
|
+
incrementing_fields[field] = options.reverse_merge!(auto: true)
|
27
71
|
attr_protected(field) if respond_to?(:attr_protected)
|
28
72
|
end
|
29
|
-
|
30
73
|
end
|
31
74
|
|
75
|
+
# Manually assign the next number to the passed autoinc field.
|
76
|
+
#
|
77
|
+
# @raise [ Mongoid::Autoinc::AutoIncrementsError ] When `auto: true` is set
|
78
|
+
# in the increments call for `field`
|
79
|
+
# @raise [ AlreadyAssignedError ] When called more then once.
|
80
|
+
#
|
81
|
+
# @return [ Fixnum ] The assigned number
|
32
82
|
def assign!(field)
|
33
83
|
options = self.class.incrementing_fields[field]
|
34
|
-
|
35
|
-
|
84
|
+
fail AutoIncrementsError if options[:auto]
|
85
|
+
fail AlreadyAssignedError if send(field).present?
|
36
86
|
increment!(field, options)
|
37
87
|
end
|
38
88
|
|
89
|
+
# Sets autoincrement values for all autoincrement fields.
|
90
|
+
#
|
91
|
+
# @return [ true ]
|
39
92
|
def update_auto_increments
|
40
93
|
self.class.incrementing_fields.each do |field, options|
|
41
94
|
increment!(field, options) if options[:auto]
|
42
|
-
end
|
95
|
+
end && true
|
43
96
|
end
|
44
97
|
|
98
|
+
# Set autoincrement value for the passed autoincrement field,
|
99
|
+
# using the passed options
|
100
|
+
#
|
101
|
+
# @param [ Symbol ] field Field to set the autoincrement value for.
|
102
|
+
# @param [ Hash ] options Options to pass through to the serializer.
|
103
|
+
#
|
104
|
+
# @return [ true ] The value of `write_attribute`
|
45
105
|
def increment!(field, options)
|
46
106
|
options = options.dup
|
47
107
|
model_name = (options.delete(:model_name) || self.class.model_name).to_s
|
48
108
|
options[:scope] = evaluate_scope(options[:scope]) if options[:scope]
|
49
109
|
options[:step] = evaluate_step(options[:step]) if options[:step]
|
50
110
|
write_attribute(
|
51
|
-
field.to_sym,
|
111
|
+
field.to_sym,
|
112
|
+
Mongoid::Autoinc::Incrementor.new(model_name, field, options).inc
|
52
113
|
)
|
53
114
|
end
|
54
115
|
|
116
|
+
# Asserts the validity of the passed scope
|
117
|
+
#
|
118
|
+
# @param [ Object ] scope The +Symbol+ or +Proc+ to evaluate
|
119
|
+
#
|
120
|
+
# @raise [ ArgumentError ] When +scope+ is not a +Symbol+ or +Proc+
|
121
|
+
#
|
122
|
+
# @return [ Object ] The scope of the autoincrement call
|
55
123
|
def evaluate_scope(scope)
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
else raise 'scope is not a Symbol or a Proc'
|
60
|
-
end
|
124
|
+
return send(scope) if scope.is_a? Symbol
|
125
|
+
return instance_exec(&scope) if scope.is_a? Proc
|
126
|
+
fail ArgumentError, 'scope is not a Symbol or a Proc'
|
61
127
|
end
|
62
128
|
|
129
|
+
# Returns the number to add to the current increment
|
130
|
+
#
|
131
|
+
# @param [ Object ] step The +Integer+ to be returned
|
132
|
+
# or +Proc+ to be evaluated
|
133
|
+
#
|
134
|
+
# @raise [ ArgumentError ] When +step+ is not an +Integer+ or +Proc+
|
135
|
+
#
|
136
|
+
# @return [ Integer ] The number to add to the current increment
|
63
137
|
def evaluate_step(step)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
else raise 'step is not an Integer or a Proc'
|
68
|
-
end
|
138
|
+
return step if step.is_a? Integer
|
139
|
+
return evaluate_step_proc(step) if step.is_a? Proc
|
140
|
+
fail ArgumentError, 'step is not an Integer or a Proc'
|
69
141
|
end
|
70
142
|
|
143
|
+
# Executes a proc and returns its +Integer+ value
|
144
|
+
#
|
145
|
+
# @param [ Proc ] step_proc The +Proc+ to call
|
146
|
+
#
|
147
|
+
# @raise [ ArgumentError ] When +step_proc+ does not evaluate to +Integer+
|
148
|
+
#
|
149
|
+
# @return [ Integer ] The number to add to the current increment
|
71
150
|
def evaluate_step_proc(step_proc)
|
72
|
-
result = instance_exec
|
151
|
+
result = instance_exec(&step_proc)
|
73
152
|
return result if result.is_a? Integer
|
74
|
-
|
153
|
+
fail 'step Proc does not evaluate to an Integer'
|
75
154
|
end
|
76
|
-
|
77
155
|
end
|
78
|
-
|
79
156
|
end
|
data/lib/autoinc/incrementor.rb
CHANGED
@@ -1,48 +1,79 @@
|
|
1
1
|
module Mongoid
|
2
|
-
|
3
2
|
module Autoinc
|
4
|
-
|
3
|
+
# Object which wraps the mongodb operations needed to allow for
|
4
|
+
# autoincrementing fields in +Mongoid::Document+ models.
|
5
5
|
class Incrementor
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
6
|
+
# The name of the autoincrementing model.
|
7
|
+
attr_reader(:model_name)
|
8
|
+
|
9
|
+
# The name of the field of the autoincrementing model.
|
10
|
+
attr_reader(:field_name)
|
11
|
+
|
12
|
+
# The constraint, allowing for more then one series on the same
|
13
|
+
# +model_name+ +field_name+ combination.
|
14
|
+
attr_reader(:scope_key)
|
15
|
+
|
16
|
+
# The mongo connection to the autoincrement counters collection.
|
17
|
+
attr_reader(:collection)
|
18
|
+
|
19
|
+
# The autoincrement offset.
|
20
|
+
attr_reader(:seed)
|
21
|
+
|
22
|
+
# How the next autoincrement number should be calculated.
|
23
|
+
attr_reader(:step)
|
24
|
+
|
25
|
+
# Creates a new incrementor object for the passed +field_name+
|
26
|
+
#
|
27
|
+
# @param [ String ] model_name Part of the name of the increment +key+
|
28
|
+
# @param [ String ] field_name The name of the +field+ to increment
|
29
|
+
# @param [ Hash ] options Options to pass to the incrementer
|
30
|
+
#
|
31
|
+
def initialize(model_name, field_name, options = {})
|
32
|
+
@model_name = model_name.to_s
|
33
|
+
@field_name = field_name.to_s
|
34
|
+
@scope_key = options.fetch(:scope, nil)
|
35
|
+
@step = options.fetch(:step, 1)
|
36
|
+
@seed = options.fetch(:seed, nil)
|
37
|
+
@collection = ::Mongoid.default_client['auto_increment_counters']
|
38
|
+
create if @seed && !exists?
|
16
39
|
end
|
17
40
|
|
41
|
+
# Returns the increment key
|
42
|
+
#
|
43
|
+
# @return [ String ] The key to increment
|
18
44
|
def key
|
19
|
-
""
|
20
|
-
|
21
|
-
str << "_#{scope_key}" unless scope_key.blank?
|
22
|
-
end
|
45
|
+
return "#{model_name.underscore}_#{field_name}" if scope_key.blank?
|
46
|
+
"#{model_name.underscore}_#{field_name}_#{scope_key}"
|
23
47
|
end
|
24
48
|
|
49
|
+
# Increments the +value+ of the +key+ and returns it using an atomic op
|
50
|
+
#
|
51
|
+
# @return [ Integer ] The next value of the incrementor
|
25
52
|
def inc
|
26
|
-
|
27
|
-
'_id' => key
|
28
|
-
).modify(
|
29
|
-
{'$inc' => { 'c' => step }},
|
30
|
-
:new => true, :upsert => true
|
31
|
-
)['c']
|
53
|
+
find.find_one_and_update({'$inc' => {c: step}}, upsert: true, return_document: :after).fetch('c')
|
32
54
|
end
|
33
55
|
|
34
56
|
private
|
35
57
|
|
36
|
-
|
37
|
-
|
58
|
+
# Find the incrementor document, using the +key+ id.
|
59
|
+
#
|
60
|
+
# @return [ Hash ] The persisted version of this incrementor.
|
61
|
+
def find
|
62
|
+
collection.find(_id: key)
|
38
63
|
end
|
39
64
|
|
65
|
+
# Persists the incrementor using +key+ as id and +seed+ as value of +c+.
|
66
|
+
#
|
40
67
|
def create
|
41
|
-
collection.
|
68
|
+
collection.insert_one(_id: key, c: seed)
|
42
69
|
end
|
43
70
|
|
71
|
+
# Checks if the incrementor is persisted
|
72
|
+
#
|
73
|
+
# @return [ true, false ] If the incrementor is already persisted.
|
74
|
+
def exists?
|
75
|
+
find.count > 0
|
76
|
+
end
|
44
77
|
end
|
45
|
-
|
46
78
|
end
|
47
|
-
|
48
79
|
end
|
data/lib/autoinc/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-autoinc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2015-12-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: mongoid
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 5.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version:
|
28
|
+
version: 5.0.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: rake
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
115
|
version: '0'
|
116
116
|
requirements: []
|
117
117
|
rubyforge_project:
|
118
|
-
rubygems_version: 2.
|
118
|
+
rubygems_version: 2.4.5.1
|
119
119
|
signing_key:
|
120
120
|
specification_version: 4
|
121
121
|
summary: Add auto incrementing fields to mongoid documents
|