risky 1.0.1 → 1.1.0

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