mongoid_token_r 4.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f6d694b67ef23128e4d6dc9d2eb5f9392e1a9843
4
+ data.tar.gz: 17ed3109121d5e9d64228409a87452ffe7d4c717
5
+ SHA512:
6
+ metadata.gz: 01575418d36384691b95b59325bdebc7a4e1fe2491d94c145cc04e9b6007d833ddbe5da50af294737d18da232e63301e3ca17d2515188c4e177d09726336fda7
7
+ data.tar.gz: e642f422be0838e003b05d212e23f26bd00a627787eeaef95d8cf25f9ddf322859111ec5b20202b581d252a9ed9e7a3322e2b1f6a2d89c5a27476b0221b21f8d
File without changes
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,18 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.0
7
+ - 2.1.1
8
+
9
+ gemfile:
10
+ - Gemfile
11
+
12
+ services:
13
+ - mongodb
14
+
15
+ env:
16
+ - CODECLIMATE_REPO_TOKEN=b216164ab66da464aa02fe5b862811ba0526c8dc7ea291ebe53056be4b6b5e1f
17
+
18
+ script: "bundle exec rspec"
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'rspec', '2.14.1'
7
+ gem "codeclimate-test-reporter", require: nil
8
+ gem 'database_cleaner'
9
+ gem 'mongoid-rspec', '1.5.1'
10
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Nicholas Bruning
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,242 @@
1
+ # Mongoid::Token - Short snappy tokens for Mongoid documents
2
+
3
+ [![Build Status](https://secure.travis-ci.org/thetron/mongoid_token.png)](http://travis-ci.org/thetron/mongoid_token)
4
+ [![Code Climate](https://codeclimate.com/github/thetron/mongoid_token.png)](https://codeclimate.com/github/thetron/mongoid_token)
5
+
6
+ This library is a quick and simple way to generate unique, random tokens
7
+ for your mongoid documents, in the cases where you can't, or don't want
8
+ to use slugs, or the default MongoDB ObjectIDs.
9
+
10
+ Mongoid::Token can help turn this:
11
+
12
+ http://bestappever.com/video/4dcfbb3c6a4f1d4c4a000012
13
+
14
+ Into something more like this:
15
+
16
+ http://bestappever.com/video/8tmQ9p
17
+
18
+
19
+ ## Getting started
20
+
21
+ In your gemfile, add:
22
+
23
+ ```ruby
24
+ # For mongoid < 5
25
+ gem 'mongoid_token', '~> 3.0.0'
26
+
27
+ # For mongoid >= 5
28
+ gem 'mongoid_token', '~> 4.0.0'
29
+ ```
30
+
31
+ Then update your bundle
32
+
33
+ $ bundle install
34
+
35
+ In your Mongoid documents, just add `include Mongoid::Token` and the
36
+ `token` method will take care of all the setup, like so:
37
+
38
+ ```ruby
39
+ class Person
40
+ include Mongoid::Document
41
+ include Mongoid::Token
42
+
43
+ field :name
44
+
45
+ token
46
+ end
47
+
48
+ ```
49
+
50
+ And that's it! There's lots of configuration options too - which are all
51
+ listed [below](#configuration). By default, the `token` method will
52
+ create tokens 4 characters long, containing random alphanumeric characters.
53
+
54
+ __Note:__ Mongoid::Token leverages Mongoid's 'safe mode' by
55
+ automatically creating a unique index on your documents using the token
56
+ field. In order to take advantage of this feature (and ensure that your
57
+ documents always have unique tokens) remember to create your indexes.
58
+
59
+ ## Using without Rails
60
+
61
+ If you're using Mongoid without Rails, remember to:
62
+
63
+ require 'mongoid_token'
64
+
65
+ in your app
66
+
67
+ ## Finders
68
+
69
+ By default, the gem will add a convenience `find_by_[token name]` method, to
70
+ make it a tiny bit simpler to query by your tokens. If you'd rather it didn't,
71
+ you can disable these with the
72
+ [`skip_finders` configuration option](#skip-finders-skip_finders).
73
+
74
+ The methods accept either a single token, or an array of tokens:
75
+
76
+ ```ruby
77
+ Video.find_by_token("x3v98") # If your token was named 'token'
78
+ Account.find_by_account_number(["ACC-123456", "ACC-567890"]) # If your token was named 'account_number'
79
+ ```
80
+
81
+ ## Configuration
82
+
83
+ ### Tokens
84
+
85
+ As of `Mongoid::Token` 2.0.0, you can now choose between two different
86
+ systems for managing how your tokens look.
87
+
88
+ For simple setup, you can use
89
+ combination of the [`length`](#length-length) and [`contains`](#contains-contains), which modify the length and
90
+ types of characters to use.
91
+
92
+ For when you need to generate more complex tokens, you can use the
93
+ [`pattern`](#patterns-pattern) option, which allows for very low-level control of the precise
94
+ structure of your tokens, as well as allowing for static strings, like
95
+ prefixes, infixes or suffixes.
96
+
97
+ #### Length (`:length`)
98
+
99
+ This one is easy, it's just an integer.
100
+
101
+ __Example:__
102
+
103
+ ```ruby
104
+ token :length => 6 # Tokens are now of length 6
105
+ token :length => 12 # Whow, whow, whow. Slow down egghead.
106
+ ```
107
+
108
+ You get the idea.
109
+
110
+ The only caveat here is that if used in combination with the
111
+ `:contains => :numeric` option, tokens may vary in length _up to_ the
112
+ specified length.
113
+
114
+ #### Contains (`:contains`)
115
+
116
+ Contains has 7 different options:
117
+
118
+ * `:alphanumeric` - contains uppercase & lowercase characters, as well
119
+ as numbers
120
+ * `:alpha` - contains only uppercase & lowercase characters
121
+ * `:alpha_upper` - contains only uppercase letters
122
+ * `:alpha_lower` - contains only lowercase letters
123
+ * `:numeric` - integer, length may be shorter than `:length`
124
+ * `:fixed_numeric` - integer, but will always be of length `:length`
125
+ * `:fixed_numeric_no_leading_zeros` - same as `:fixed_numeric`, but will
126
+ never start with zeros
127
+ * `:fixed_hex_numeric` - hex integer, but will always be of length `:length`
128
+ * `:fixed_hex_numeric_no_leading_zeros` - same as `:fixed_hex_numeric`, but will
129
+ never start with zeros
130
+
131
+ __Examples:__
132
+ ```ruby
133
+ token :contains => :alpha_upper, :length => 8
134
+ token :contains => :fixed_numeric
135
+ ```
136
+
137
+ #### Patterns (`:pattern`)
138
+
139
+ New in 2.0.0, patterns allow you fine-grained control over how your
140
+ tokens look. It's great for generating random data that has a
141
+ requirements to also have some basic structure. If you use the
142
+ `:pattern` option, it will override both the `:length` and `:contains`
143
+ options.
144
+
145
+ This was designed to operate in a similar way to something like `strftime`,
146
+ if the syntax offends you - please open an issue, I'd love to get some
147
+ feedback here and better refine how these are generated.
148
+
149
+ Any characters in the string are treated as static, except those that are
150
+ proceeded by a `%`. Those special characters represent a single, randomly
151
+ generated character, and are as follows:
152
+
153
+ * `%s` - any uppercase, lowercase, or numeric character
154
+ * `%w` - any uppercase, or lowercase character
155
+ * `%c` - any lowercase character
156
+ * `%C` - any uppercase character
157
+ * `%d` - any digit
158
+ * `%D` - any non-zero digit
159
+
160
+ __Example:__
161
+
162
+ ```ruby
163
+ token :pattern => "PRE-%C%C-%d%d%d%d" # Generates something like: 'PRE-ND-3485'
164
+ ```
165
+
166
+ You can also add a repetition modifier, which can help improve readability on
167
+ more complex patterns. You simply add any integer after the letter.
168
+
169
+ __Examples:__
170
+
171
+ ```ruby
172
+ token :pattern => "APP-%d6" # Generates something like; "APP-638924"
173
+ ```
174
+
175
+ ### Field Name (`:field_name`)
176
+
177
+ This allows you to change the field name used by `Mongoid::Token`
178
+ (default is `:token`). This is particularly handy when you're wanting to
179
+ use multiple tokens one a single document.
180
+
181
+ __Examples:__
182
+ ```ruby
183
+ token :length => 6
184
+ token :field_name => :sharing_token, :length => 12
185
+ token :field_name => :yet_another
186
+ ```
187
+
188
+
189
+ ### Skip Finders (`:skip_finders`)
190
+
191
+ This will prevent the gem from creating the extra `find_by_*` methods.
192
+
193
+ __Example:__
194
+ ```ruby
195
+ token :skip_finders => true
196
+ ```
197
+
198
+
199
+ ### Override to_param (`:override_to_param`)
200
+
201
+ By default, `Mongoid::Token` will override to_param, to make it an easy
202
+ drop-in replacement for the default ObjectIDs. If needed, you can turn
203
+ this behaviour off:
204
+
205
+ __Example:__
206
+ ```ruby
207
+ token :override_to_param => false
208
+ ```
209
+
210
+
211
+ ### Retry Count (`:retry_count`)
212
+
213
+ In the event of a token collision, this gem will attempt to try three
214
+ more times before raising a `Mongoid::Token::CollisionRetriesExceeded`
215
+ error. If you're wanting it to try harder, or less hard, then this
216
+ option is for you.
217
+
218
+ __Examples:__
219
+ ```ruby
220
+ token :retry_count => 9
221
+ token :retry_count => 0
222
+ ```
223
+
224
+ # Notes
225
+
226
+ If you find a problem, please [submit an issue](http://github.com/thetron/mongoid_token/issues) (and a failing test, if
227
+ you can). Pull requests and feature requests are always welcome and
228
+ greatly appreciated.
229
+
230
+ Thanks to everyone that has contributed to this gem over the past year.
231
+ Many, many thanks - you guys rawk.
232
+
233
+
234
+ ## Contributors:
235
+
236
+ Thanks to everyone who has provided support for this gem over the years.
237
+ In particular: [olliem](https://github.com/olliem),
238
+ [msolli](https://github.com/msolli),
239
+ [siong1987](https://github.com/siong1987),
240
+ [stephan778](https://github.com/stephan778),
241
+ [eagleas](https://github.com/eagleas), and
242
+ [jamesotron](https://github.com/jamesotron).
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,49 @@
1
+ $: << File.expand_path("../../lib", __FILE__)
2
+
3
+ require 'database_cleaner'
4
+ require 'mongoid'
5
+ require 'mongoid_token'
6
+ require 'benchmark'
7
+
8
+ Mongoid.configure do |config|
9
+ config.connect_to("mongoid_token_benchmark")
10
+ end
11
+
12
+ DatabaseCleaner.strategy = :truncation
13
+
14
+ # start benchmarks
15
+
16
+ TOKEN_LENGTH = 8
17
+
18
+ class Link
19
+ include Mongoid::Document
20
+ include Mongoid::Token
21
+ field :url
22
+ token :length => TOKEN_LENGTH, :contains => :alphanumeric
23
+ end
24
+
25
+ class NoTokenLink
26
+ include Mongoid::Document
27
+ field :url
28
+ end
29
+
30
+ def create_link(token = true)
31
+ if token
32
+ Link.create(:url => "http://involved.com.au")
33
+ else
34
+ NoTokenLink.create(:url => "http://involved.com.au")
35
+ end
36
+ end
37
+
38
+ Link.destroy_all
39
+ Link.create_indexes
40
+ num_records = [1, 50, 100, 1000, 2000, 3000, 4000]
41
+ puts "-- Alphanumeric token of length #{TOKEN_LENGTH} (#{62**TOKEN_LENGTH} possible tokens)"
42
+ Benchmark.bm do |b|
43
+ num_records.each do |qty|
44
+ b.report("#{qty.to_s.rjust(5, " ")} records "){ qty.times{ create_link(false) } }
45
+ b.report("#{qty.to_s.rjust(5, " ")} records tok"){ qty.times{ create_link } }
46
+ Link.destroy_all
47
+ end
48
+ end
49
+
@@ -0,0 +1,81 @@
1
+ require 'mongoid/token/exceptions'
2
+ require 'mongoid/token/options'
3
+ require 'mongoid/token/generator'
4
+ require 'mongoid/token/finders'
5
+ require 'mongoid/token/collision_resolver'
6
+
7
+ module Mongoid
8
+ module Token
9
+ extend ActiveSupport::Concern
10
+
11
+ module ClassMethods
12
+ def initialize_copy(source)
13
+ super(source)
14
+ self.token = nil
15
+ end
16
+
17
+ def token(*args)
18
+ options = Mongoid::Token::Options.new(args.extract_options!)
19
+
20
+ add_token_field_and_index(options)
21
+ add_token_collision_resolver(options)
22
+ set_token_callbacks(options)
23
+
24
+ define_custom_finders(options) if options.skip_finders? == false
25
+ override_to_param(options) if options.override_to_param?
26
+ end
27
+
28
+ private
29
+ def add_token_field_and_index(options)
30
+ self.field options.field_name, :type => String, :default => default_value(options)
31
+ self.index({ options.field_name => 1 }, { :unique => true, :sparse => true })
32
+ end
33
+
34
+ def add_token_collision_resolver(options)
35
+ resolver = Mongoid::Token::CollisionResolver.new(self, options.field_name, options.retry_count)
36
+ resolver.create_new_token = Proc.new do |document|
37
+ document.send(:create_token, options.field_name, options.pattern)
38
+ end
39
+ end
40
+
41
+ def define_custom_finders(options)
42
+ Finders.define_custom_token_finder_for(self, options.field_name)
43
+ end
44
+
45
+ def set_token_callbacks(options)
46
+ set_callback(:create, :before) do |document|
47
+ document.create_token_if_nil options.field_name, options.pattern
48
+ end
49
+
50
+ set_callback(:save, :before) do |document|
51
+ document.create_token_if_nil options.field_name, options.pattern
52
+ end
53
+ end
54
+
55
+ def override_to_param(options)
56
+ self.send(:define_method, :to_param) do
57
+ self.send(options.field_name) || super()
58
+ end
59
+ end
60
+
61
+ def default_value(options)
62
+ options.generate_on_init && Mongoid::Token::Generator.generate(options.pattern) || nil
63
+ end
64
+ end
65
+
66
+ protected
67
+ def create_token(field_name, pattern)
68
+ self.send :"#{field_name.to_s}=", self.generate_token(pattern)
69
+ end
70
+
71
+ def create_token_if_nil(field_name, pattern)
72
+ if self[field_name.to_sym].blank?
73
+ self.create_token field_name, pattern
74
+ end
75
+ end
76
+
77
+ def generate_token(pattern)
78
+ Mongoid::Token::Generator.generate pattern
79
+ end
80
+ end
81
+ end