mongoid_token_r 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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