risky 1.0.1 → 1.1.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,28 @@
1
+ module Risky::GZip
2
+ require 'zlib'
3
+
4
+ GZIP_CONTENT_TYPE = 'application/x-gzip'
5
+
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+ def content_type
12
+ GZIP_CONTENT_TYPE
13
+ end
14
+ end
15
+
16
+ module GZipSerializer
17
+ def self.dump(*args)
18
+ Zlib::Deflate.deflate MultiJson.dump(*args)
19
+ end
20
+
21
+ def self.load(*args)
22
+ MultiJson.load(Zlib::Inflate.inflate *args)
23
+ end
24
+ end
25
+
26
+ Riak::Serializers[GZIP_CONTENT_TYPE] = GZipSerializer
27
+
28
+ end
@@ -4,7 +4,7 @@ module Risky::Indexes
4
4
  def self.included(base)
5
5
  base.instance_eval do
6
6
  @indexes = {}
7
-
7
+
8
8
  def indexes
9
9
  @indexes
10
10
  end
@@ -16,7 +16,7 @@ module Risky::Indexes
16
16
  def index(attribute, opts = {})
17
17
  opts[:bucket] ||= "#{@bucket_name}_by_#{attribute}"
18
18
  @indexes[attribute] = opts
19
-
19
+
20
20
  class_eval %{
21
21
  def self.by_#{attribute}(value)
22
22
  return nil unless value
@@ -40,7 +40,7 @@ module Risky::Indexes
40
40
 
41
41
  def initialize(*a)
42
42
  @old_indexed_values = {}
43
-
43
+
44
44
  super *a
45
45
  end
46
46
 
@@ -94,7 +94,7 @@ module Risky::Indexes
94
94
  # Validate unique indexes
95
95
  self.class.indexes.each do |attr, opts|
96
96
  next unless opts[:unique]
97
-
97
+
98
98
  current = opts[:proc][self] rescue self[attr.to_s]
99
99
  old = @old_indexed_values[attr]
100
100
 
@@ -0,0 +1,337 @@
1
+ # Taken from Rails
2
+
3
+ # encoding: utf-8
4
+ require 'singleton'
5
+
6
+ module Risky::Inflector
7
+ extend self
8
+
9
+ # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
10
+ # inflection rules. Examples:
11
+ #
12
+ # ActiveSupport::Inflector.inflections do |inflect|
13
+ # inflect.plural /^(ox)$/i, '\1\2en'
14
+ # inflect.singular /^(ox)en/i, '\1'
15
+ #
16
+ # inflect.irregular 'octopus', 'octopi'
17
+ #
18
+ # inflect.uncountable "equipment"
19
+ # end
20
+ #
21
+ # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
22
+ # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
23
+ # already have been loaded.
24
+ class Inflections
25
+ include Singleton
26
+
27
+ attr_reader :plurals, :singulars, :uncountables, :humans
28
+
29
+ def initialize
30
+ @plurals, @singulars, @uncountables, @humans = [], [], [], []
31
+ end
32
+
33
+ # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
34
+ # The replacement should always be a string that may include references to the matched data from the rule.
35
+ def plural(rule, replacement)
36
+ @uncountables.delete(rule) if rule.is_a?(String)
37
+ @uncountables.delete(replacement)
38
+ @plurals.insert(0, [rule, replacement])
39
+ end
40
+
41
+ # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
42
+ # The replacement should always be a string that may include references to the matched data from the rule.
43
+ def singular(rule, replacement)
44
+ @uncountables.delete(rule) if rule.is_a?(String)
45
+ @uncountables.delete(replacement)
46
+ @singulars.insert(0, [rule, replacement])
47
+ end
48
+
49
+ # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
50
+ # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
51
+ #
52
+ # Examples:
53
+ # irregular 'octopus', 'octopi'
54
+ # irregular 'person', 'people'
55
+ def irregular(singular, plural)
56
+ @uncountables.delete(singular)
57
+ @uncountables.delete(plural)
58
+ if singular[0,1].upcase == plural[0,1].upcase
59
+ plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
60
+ singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
61
+ else
62
+ plural(Regexp.new("#{singular[0,1].upcase}(?i)#{singular[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
63
+ plural(Regexp.new("#{singular[0,1].downcase}(?i)#{singular[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
64
+ singular(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), singular[0,1].upcase + singular[1..-1])
65
+ singular(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), singular[0,1].downcase + singular[1..-1])
66
+ end
67
+ end
68
+
69
+ # Add uncountable words that shouldn't be attempted inflected.
70
+ #
71
+ # Examples:
72
+ # uncountable "money"
73
+ # uncountable "money", "information"
74
+ # uncountable %w( money information rice )
75
+ def uncountable(*words)
76
+ (@uncountables << words).flatten!
77
+ end
78
+
79
+ # Specifies a humanized form of a string by a regular expression rule or by a string mapping.
80
+ # When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
81
+ # When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
82
+ #
83
+ # Examples:
84
+ # human /_cnt$/i, '\1_count'
85
+ # human "legacy_col_person_name", "Name"
86
+ def human(rule, replacement)
87
+ @humans.insert(0, [rule, replacement])
88
+ end
89
+
90
+ # Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
91
+ # Give the scope as a symbol of the inflection type, the options are: <tt>:plurals</tt>,
92
+ # <tt>:singulars</tt>, <tt>:uncountables</tt>, <tt>:humans</tt>.
93
+ #
94
+ # Examples:
95
+ # clear :all
96
+ # clear :plurals
97
+ def clear(scope = :all)
98
+ case scope
99
+ when :all
100
+ @plurals, @singulars, @uncountables = [], [], []
101
+ else
102
+ instance_variable_set "@#{scope}", []
103
+ end
104
+ end
105
+ end
106
+
107
+ # Yields a singleton instance of Inflector::Inflections so you can specify additional
108
+ # inflector rules.
109
+ #
110
+ # Example:
111
+ # ActiveSupport::Inflector.inflections do |inflect|
112
+ # inflect.uncountable "rails"
113
+ # end
114
+ def inflections
115
+ if block_given?
116
+ yield Inflections.instance
117
+ else
118
+ Inflections.instance
119
+ end
120
+ end
121
+
122
+ # Returns the plural form of the word in the string.
123
+ #
124
+ # Examples:
125
+ # "post".pluralize # => "posts"
126
+ # "octopus".pluralize # => "octopi"
127
+ # "sheep".pluralize # => "sheep"
128
+ # "words".pluralize # => "words"
129
+ # "CamelOctopus".pluralize # => "CamelOctopi"
130
+ def pluralize(word)
131
+ result = word.to_s.dup
132
+
133
+ if word.empty? || inflections.uncountables.include?(result.downcase)
134
+ result
135
+ else
136
+ inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
137
+ result
138
+ end
139
+ end
140
+
141
+ # The reverse of +pluralize+, returns the singular form of a word in a string.
142
+ #
143
+ # Examples:
144
+ # "posts".singularize # => "post"
145
+ # "octopi".singularize # => "octopus"
146
+ # "sheep".singluarize # => "sheep"
147
+ # "word".singularize # => "word"
148
+ # "CamelOctopi".singularize # => "CamelOctopus"
149
+ def singularize(word)
150
+ result = word.to_s.dup
151
+
152
+ if inflections.uncountables.any? { |inflection| result =~ /#{inflection}\Z/i }
153
+ result
154
+ else
155
+ inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
156
+ result
157
+ end
158
+ end
159
+
160
+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
161
+ # is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
162
+ #
163
+ # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
164
+ #
165
+ # Examples:
166
+ # "active_record".camelize # => "ActiveRecord"
167
+ # "active_record".camelize(:lower) # => "activeRecord"
168
+ # "active_record/errors".camelize # => "ActiveRecord::Errors"
169
+ # "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
170
+ def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
171
+ if first_letter_in_uppercase
172
+ lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
173
+ else
174
+ lower_case_and_underscored_word.first.downcase + camelize(lower_case_and_underscored_word)[1..-1]
175
+ end
176
+ end
177
+
178
+ # Capitalizes all the words and replaces some characters in the string to create
179
+ # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
180
+ # used in the Rails internals.
181
+ #
182
+ # +titleize+ is also aliased as as +titlecase+.
183
+ #
184
+ # Examples:
185
+ # "man from the boondocks".titleize # => "Man From The Boondocks"
186
+ # "x-men: the last stand".titleize # => "X Men: The Last Stand"
187
+ def titleize(word)
188
+ humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
189
+ end
190
+
191
+ # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
192
+ #
193
+ # Changes '::' to '/' to convert namespaces to paths.
194
+ #
195
+ # Examples:
196
+ # "ActiveRecord".underscore # => "active_record"
197
+ # "ActiveRecord::Errors".underscore # => active_record/errors
198
+ def underscore(camel_cased_word)
199
+ camel_cased_word.to_s.gsub(/::/, '/').
200
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
201
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
202
+ tr("-", "_").
203
+ downcase
204
+ end
205
+
206
+ # Replaces underscores with dashes in the string.
207
+ #
208
+ # Example:
209
+ # "puni_puni" # => "puni-puni"
210
+ def dasherize(underscored_word)
211
+ underscored_word.gsub(/_/, '-')
212
+ end
213
+
214
+ # Capitalizes the first word and turns underscores into spaces and strips a
215
+ # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
216
+ #
217
+ # Examples:
218
+ # "employee_salary" # => "Employee salary"
219
+ # "author_id" # => "Author"
220
+ def humanize(lower_case_and_underscored_word)
221
+ result = lower_case_and_underscored_word.to_s.dup
222
+
223
+ inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
224
+ result.gsub(/_id$/, "").gsub(/_/, " ").capitalize
225
+ end
226
+
227
+ # Removes the module part from the expression in the string.
228
+ #
229
+ # Examples:
230
+ # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
231
+ # "Inflections".demodulize # => "Inflections"
232
+ def demodulize(class_name_in_module)
233
+ class_name_in_module.to_s.gsub(/^.*::/, '')
234
+ end
235
+
236
+ # Create the name of a table like Rails does for models to table names. This method
237
+ # uses the +pluralize+ method on the last word in the string.
238
+ #
239
+ # Examples
240
+ # "RawScaledScorer".tableize # => "raw_scaled_scorers"
241
+ # "egg_and_ham".tableize # => "egg_and_hams"
242
+ # "fancyCategory".tableize # => "fancy_categories"
243
+ def tableize(class_name)
244
+ pluralize(underscore(class_name))
245
+ end
246
+
247
+ # Create a class name from a plural table name like Rails does for table names to models.
248
+ # Note that this returns a string and not a Class. (To convert to an actual class
249
+ # follow +classify+ with +constantize+.)
250
+ #
251
+ # Examples:
252
+ # "egg_and_hams".classify # => "EggAndHam"
253
+ # "posts".classify # => "Post"
254
+ #
255
+ # Singular names are not handled correctly:
256
+ # "business".classify # => "Busines"
257
+ def classify(table_name)
258
+ # strip out any leading schema name
259
+ camelize(singularize(table_name.to_s.sub(/.*\./, '')))
260
+ end
261
+
262
+ # Creates a foreign key name from a class name.
263
+ # +separate_class_name_and_id_with_underscore+ sets whether
264
+ # the method should put '_' between the name and 'id'.
265
+ #
266
+ # Examples:
267
+ # "Message".foreign_key # => "message_id"
268
+ # "Message".foreign_key(false) # => "messageid"
269
+ # "Admin::Post".foreign_key # => "post_id"
270
+ def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
271
+ underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
272
+ end
273
+
274
+ # Ruby 1.9 introduces an inherit argument for Module#const_get and
275
+ # #const_defined? and changes their default behavior.
276
+ if Module.method(:const_get).arity == 1
277
+ # Tries to find a constant with the name specified in the argument string:
278
+ #
279
+ # "Module".constantize # => Module
280
+ # "Test::Unit".constantize # => Test::Unit
281
+ #
282
+ # The name is assumed to be the one of a top-level constant, no matter whether
283
+ # it starts with "::" or not. No lexical context is taken into account:
284
+ #
285
+ # C = 'outside'
286
+ # module M
287
+ # C = 'inside'
288
+ # C # => 'inside'
289
+ # "C".constantize # => 'outside', same as ::C
290
+ # end
291
+ #
292
+ # NameError is raised when the name is not in CamelCase or the constant is
293
+ # unknown.
294
+ def constantize(camel_cased_word)
295
+ names = camel_cased_word.split('::')
296
+ names.shift if names.empty? || names.first.empty?
297
+
298
+ constant = Object
299
+ names.each do |name|
300
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
301
+ end
302
+ constant
303
+ end
304
+ else
305
+ def constantize(camel_cased_word) #:nodoc:
306
+ names = camel_cased_word.split('::')
307
+ names.shift if names.empty? || names.first.empty?
308
+
309
+ constant = Object
310
+ names.each do |name|
311
+ constant = constant.const_get(name, false) || constant.const_missing(name)
312
+ end
313
+ constant
314
+ end
315
+ end
316
+
317
+ # Turns a number into an ordinal string used to denote the position in an
318
+ # ordered sequence such as 1st, 2nd, 3rd, 4th.
319
+ #
320
+ # Examples:
321
+ # ordinalize(1) # => "1st"
322
+ # ordinalize(2) # => "2nd"
323
+ # ordinalize(1002) # => "1002nd"
324
+ # ordinalize(1003) # => "1003rd"
325
+ def ordinalize(number)
326
+ if (11..13).include?(number.to_i % 100)
327
+ "#{number}th"
328
+ else
329
+ case number.to_i % 10
330
+ when 1; "#{number}st"
331
+ when 2; "#{number}nd"
332
+ when 3; "#{number}rd"
333
+ else "#{number}th"
334
+ end
335
+ end
336
+ end
337
+ end
@@ -0,0 +1,58 @@
1
+ module Risky::ListKeys
2
+
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ # Returns all model instances from the bucket
9
+ def all(opts = {:reload => true})
10
+ find_all_by_key(bucket.keys(opts))
11
+ end
12
+
13
+ # Counts the number of values in the bucket via key streaming.
14
+ def count
15
+ count = 0
16
+ bucket.keys do |keys|
17
+ count += keys.length
18
+ end
19
+ count
20
+ end
21
+
22
+ # Deletes all model instances from the bucket.
23
+ def delete_all
24
+ each do |item|
25
+ item.delete
26
+ end
27
+ end
28
+
29
+ # Iterate over all keys.
30
+ def keys(*a)
31
+ if block_given?
32
+ bucket.keys(*a) do |keys|
33
+ # This API is currently inconsistent from protobuffs to http
34
+ if keys.kind_of? Array
35
+ keys.each do |key|
36
+ yield key
37
+ end
38
+ else
39
+ yield keys
40
+ end
41
+ end
42
+ else
43
+ bucket.keys(*a)
44
+ end
45
+ end
46
+
47
+ # Iterate over all items using key streaming.
48
+ def each
49
+ bucket.keys do |keys|
50
+ keys.each do |key|
51
+ if x = self[key]
52
+ yield x
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end