ohm 0.1.5 → 1.0.0.alpha1
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.
- data/Rakefile +19 -1
- data/lib/ohm.rb +893 -1662
- data/lib/ohm/transaction.rb +129 -0
- data/test/association.rb +33 -0
- data/test/connection.rb +72 -0
- data/test/core.rb +26 -0
- data/test/counters.rb +67 -0
- data/test/extensibility.rb +48 -0
- data/test/filtering.rb +42 -0
- data/test/{hash_key_test.rb → hash_key.rb} +0 -0
- data/test/indices.rb +97 -0
- data/test/{json_test.rb → json.rb} +10 -3
- data/test/lua-save.rb +193 -0
- data/test/lua.rb +47 -0
- data/test/{model_test.rb → model.rb} +325 -439
- data/test/pipeline-performance.rb +65 -0
- data/test/transactions.rb +241 -0
- data/test/uniques.rb +87 -0
- data/test/{associations_test.rb → unused/associations_test.rb} +3 -3
- data/test/{pattern_test.rb → unused/pattern_test.rb} +0 -0
- data/test/{upgrade_script_test.rb → unused/upgrade_script_test.rb} +0 -0
- data/test/{wrapper_test.rb → unused/wrapper_test.rb} +0 -0
- data/test/{validations_test.rb → validations.rb} +20 -70
- metadata +44 -29
- data/lib/ohm/compat-1.8.6.rb +0 -39
- data/lib/ohm/key.rb +0 -35
- data/lib/ohm/pattern.rb +0 -37
- data/lib/ohm/validations.rb +0 -213
- data/lib/ohm/version.rb +0 -5
- data/test/connection_test.rb +0 -101
- data/test/errors_test.rb +0 -120
- data/test/indices_test.rb +0 -213
- data/test/mutex_test.rb +0 -84
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ohm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0.alpha1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Michel Martens
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-03-
|
13
|
+
date: 2012-03-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nest
|
17
|
-
requirement: &
|
17
|
+
requirement: &2156510860 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,21 @@ dependencies:
|
|
22
22
|
version: '1.0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *2156510860
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: scrivener
|
28
|
+
requirement: &2156526680 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2156526680
|
26
37
|
- !ruby/object:Gem::Dependency
|
27
38
|
name: cutest
|
28
|
-
requirement: &
|
39
|
+
requirement: &2156526220 !ruby/object:Gem::Requirement
|
29
40
|
none: false
|
30
41
|
requirements:
|
31
42
|
- - ~>
|
@@ -33,10 +44,10 @@ dependencies:
|
|
33
44
|
version: '0.1'
|
34
45
|
type: :development
|
35
46
|
prerelease: false
|
36
|
-
version_requirements: *
|
47
|
+
version_requirements: *2156526220
|
37
48
|
- !ruby/object:Gem::Dependency
|
38
49
|
name: batch
|
39
|
-
requirement: &
|
50
|
+
requirement: &2156525700 !ruby/object:Gem::Requirement
|
40
51
|
none: false
|
41
52
|
requirements:
|
42
53
|
- - ~>
|
@@ -44,7 +55,7 @@ dependencies:
|
|
44
55
|
version: 0.0.1
|
45
56
|
type: :development
|
46
57
|
prerelease: false
|
47
|
-
version_requirements: *
|
58
|
+
version_requirements: *2156525700
|
48
59
|
description: Ohm is a library that allows to store an object in Redis, a persistent
|
49
60
|
key-value database. It includes an extensible list of validations and has very good
|
50
61
|
performance.
|
@@ -55,30 +66,34 @@ executables: []
|
|
55
66
|
extensions: []
|
56
67
|
extra_rdoc_files: []
|
57
68
|
files:
|
58
|
-
- lib/ohm/
|
59
|
-
- lib/ohm/key.rb
|
60
|
-
- lib/ohm/pattern.rb
|
69
|
+
- lib/ohm/transaction.rb
|
61
70
|
- lib/ohm/utils/upgrade.rb
|
62
|
-
- lib/ohm/validations.rb
|
63
|
-
- lib/ohm/version.rb
|
64
71
|
- lib/ohm.rb
|
65
72
|
- README.markdown
|
66
73
|
- LICENSE
|
67
74
|
- Rakefile
|
68
75
|
- test/1.8.6_test.rb
|
69
|
-
- test/
|
70
|
-
- test/
|
71
|
-
- test/
|
72
|
-
- test/
|
76
|
+
- test/association.rb
|
77
|
+
- test/connection.rb
|
78
|
+
- test/core.rb
|
79
|
+
- test/counters.rb
|
80
|
+
- test/extensibility.rb
|
81
|
+
- test/filtering.rb
|
82
|
+
- test/hash_key.rb
|
73
83
|
- test/helper.rb
|
74
|
-
- test/
|
75
|
-
- test/
|
76
|
-
- test/
|
77
|
-
- test/
|
78
|
-
- test/
|
79
|
-
- test/
|
80
|
-
- test/
|
81
|
-
- test/
|
84
|
+
- test/indices.rb
|
85
|
+
- test/json.rb
|
86
|
+
- test/lua-save.rb
|
87
|
+
- test/lua.rb
|
88
|
+
- test/model.rb
|
89
|
+
- test/pipeline-performance.rb
|
90
|
+
- test/transactions.rb
|
91
|
+
- test/uniques.rb
|
92
|
+
- test/unused/associations_test.rb
|
93
|
+
- test/unused/pattern_test.rb
|
94
|
+
- test/unused/upgrade_script_test.rb
|
95
|
+
- test/unused/wrapper_test.rb
|
96
|
+
- test/validations.rb
|
82
97
|
- test/test.conf
|
83
98
|
homepage: http://github.com/soveran/ohm
|
84
99
|
licenses: []
|
@@ -95,12 +110,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
111
|
none: false
|
97
112
|
requirements:
|
98
|
-
- - ! '
|
113
|
+
- - ! '>'
|
99
114
|
- !ruby/object:Gem::Version
|
100
|
-
version:
|
115
|
+
version: 1.3.1
|
101
116
|
requirements: []
|
102
117
|
rubyforge_project: ohm
|
103
|
-
rubygems_version: 1.8.
|
118
|
+
rubygems_version: 1.8.10
|
104
119
|
signing_key:
|
105
120
|
specification_version: 3
|
106
121
|
summary: Object-hash mapping library for Redis.
|
data/lib/ohm/compat-1.8.6.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
unless "".respond_to?(:lines)
|
2
|
-
class String
|
3
|
-
|
4
|
-
# This version of String#lines is almost fully compatible with that
|
5
|
-
# of Ruby 1.9. If a zero-length record separator is supplied in Ruby
|
6
|
-
# 1.9, the string is split into paragraphs delimited by multiple
|
7
|
-
# successive newlines. This replacement ignores that feature in
|
8
|
-
# favor of code simplicity.
|
9
|
-
def lines(separator = $/)
|
10
|
-
result = split(separator).map { |part| "#{part}#{separator}" }
|
11
|
-
result.each { |r| yield r } if block_given?
|
12
|
-
result
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
unless respond_to?(:tap)
|
18
|
-
class Object
|
19
|
-
def tap
|
20
|
-
yield(self)
|
21
|
-
self
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
module Ohm
|
27
|
-
if defined?(BasicObject)
|
28
|
-
BasicObject = ::BasicObject
|
29
|
-
elsif defined?(BlankSlate)
|
30
|
-
BasicObject = ::BlankSlate
|
31
|
-
else
|
32
|
-
|
33
|
-
# If neither BasicObject (Ruby 1.9) nor BlankSlate (typically provided by Builder)
|
34
|
-
# are present, define our simple implementation inside the Ohm module.
|
35
|
-
class BasicObject
|
36
|
-
instance_methods.each { |meth| undef_method(meth) unless meth =~ /\A(__|instance_eval)/ }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/lib/ohm/key.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
module Ohm
|
2
|
-
|
3
|
-
# Represents a key in Redis. Much of the heavylifting is done using the
|
4
|
-
# Nest library.
|
5
|
-
#
|
6
|
-
# The most important change added by {Ohm::Key} to Nest is the concept of
|
7
|
-
# volatile keys, which are used heavily when doing {Ohm::Model::Set#find} or
|
8
|
-
# {Ohm::Model::Set#except} operations.
|
9
|
-
#
|
10
|
-
# A volatile key is simply a key prefixed with `~`. This gives you the
|
11
|
-
# benefit if quickly seeing which keys are temporary keys by doing something
|
12
|
-
# like:
|
13
|
-
#
|
14
|
-
# $ redis-cli keys "~*"
|
15
|
-
#
|
16
|
-
# @see http://github.com/soveran/nest
|
17
|
-
class Key < Nest
|
18
|
-
def volatile
|
19
|
-
self.index("~") == 0 ? self : self.class.new("~", redis)[self]
|
20
|
-
end
|
21
|
-
|
22
|
-
# Produces a key with `other` suffixed with itself. This is primarily
|
23
|
-
# used for storing SINTERSTORE results.
|
24
|
-
def +(other)
|
25
|
-
self.class.new("#{self}+#{other}", redis)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Produces a key with `other` suffixed with itself. This is primarily
|
29
|
-
# used for storing SDIFFSTORE results.
|
30
|
-
def -(other)
|
31
|
-
self.class.new("#{self}-#{other}", redis)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
data/lib/ohm/pattern.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# Pattern extends Array with case equality to provide meaningful semantics in
|
2
|
-
# case statements.
|
3
|
-
#
|
4
|
-
# After this change, pattern matching-like behavior is possible with
|
5
|
-
# Arrays:
|
6
|
-
#
|
7
|
-
# Pattern[Fixnum, String] === [1, "foo"]
|
8
|
-
# Pattern[Symbol, Array] === [:foo, [1, 2]]
|
9
|
-
#
|
10
|
-
# When used in a case statement, it provides a functionality close to that of
|
11
|
-
# languages with proper pattern matching. It becomes useful when implementing
|
12
|
-
# a polymorphic method:
|
13
|
-
#
|
14
|
-
# def [](index, limit = nil)
|
15
|
-
# case [index, limit]
|
16
|
-
# when Pattern[Fixnum, Fixnum] then
|
17
|
-
# key.lrange(index, limit).collect { |id| model[id] }
|
18
|
-
# when Pattern[Range, nil] then
|
19
|
-
# key.lrange(index.first, index.last).collect { |id| model[id] }
|
20
|
-
# when Pattern[Fixnum, nil] then
|
21
|
-
# model[key.lindex(index)]
|
22
|
-
# end
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
module Ohm
|
26
|
-
class Pattern < Array
|
27
|
-
def ===(other)
|
28
|
-
return false if size != other.size
|
29
|
-
|
30
|
-
each_with_index do |item, index|
|
31
|
-
return false unless item === other[index]
|
32
|
-
end
|
33
|
-
|
34
|
-
true
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/lib/ohm/validations.rb
DELETED
@@ -1,213 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
module Ohm
|
4
|
-
# Provides a base implementation for extensible validation routines.
|
5
|
-
# {Ohm::Validations} currently only provides the following assertions:
|
6
|
-
#
|
7
|
-
# * assert
|
8
|
-
# * assert_present
|
9
|
-
# * assert_format
|
10
|
-
# * assert_numeric
|
11
|
-
#
|
12
|
-
# The core tenets that Ohm::Validations advocates can be summed up in a
|
13
|
-
# few bullet points:
|
14
|
-
#
|
15
|
-
# 1. Validations are much simpler and better done using composition rather
|
16
|
-
# than macros.
|
17
|
-
# 2. Error messages should be kept separate and possibly in the view or
|
18
|
-
# presenter layer.
|
19
|
-
# 3. It should be easy to write your own validation routine.
|
20
|
-
#
|
21
|
-
# Since Ohm's philosophy is to keep the core code small, other validations
|
22
|
-
# are simply added on a per-model or per-project basis.
|
23
|
-
#
|
24
|
-
# If you want other validations you may want to take a peek at Ohm::Contrib
|
25
|
-
# and all of the validation modules it provides.
|
26
|
-
#
|
27
|
-
# @see http://cyx.github.com/ohm-contrib/doc/Ohm/WebValidations.html
|
28
|
-
# @see http://cyx.github.com/ohm-contrib/doc/Ohm/NumberValidations.html
|
29
|
-
# @see http://cyx.github.com/ohm-contrib/doc/Ohm/ExtraValidations.html
|
30
|
-
#
|
31
|
-
# @example
|
32
|
-
#
|
33
|
-
# class Product < Ohm::Model
|
34
|
-
# attribute :title
|
35
|
-
# attribute :price
|
36
|
-
# attribute :date
|
37
|
-
#
|
38
|
-
# def validate
|
39
|
-
# assert_present :title
|
40
|
-
# assert_numeric :price
|
41
|
-
# assert_format :date, /\A[\d]{4}-[\d]{1,2}-[\d]{1,2}\z
|
42
|
-
# end
|
43
|
-
# end
|
44
|
-
#
|
45
|
-
# product = Product.new
|
46
|
-
# product.valid? == false
|
47
|
-
# # => true
|
48
|
-
#
|
49
|
-
# product.errors == [[:title, :not_present], [:price, :not_numeric],
|
50
|
-
# [:date, :format]]
|
51
|
-
# # => true
|
52
|
-
#
|
53
|
-
module Validations
|
54
|
-
# Provides a simple implementation using the Presenter Pattern. When
|
55
|
-
# presenting errors, you have to properly catch all errors generated, or
|
56
|
-
# else you'll get an {Ohm::Validations::Presenter::UnhandledErrors}
|
57
|
-
# exception.
|
58
|
-
class Presenter
|
59
|
-
class UnhandledErrors < StandardError
|
60
|
-
attr :errors
|
61
|
-
|
62
|
-
def initialize(errors)
|
63
|
-
@errors = errors
|
64
|
-
end
|
65
|
-
|
66
|
-
def message
|
67
|
-
"Unhandled errors: #{errors.inspect}"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def initialize(errors)
|
72
|
-
@errors = errors
|
73
|
-
@unhandled = errors.dup
|
74
|
-
@output = []
|
75
|
-
end
|
76
|
-
|
77
|
-
def on(error, message = (block_given? ? yield : raise(ArgumentError)))
|
78
|
-
handle(error) do
|
79
|
-
@output << message
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def ignore(error)
|
84
|
-
handle(error)
|
85
|
-
end
|
86
|
-
|
87
|
-
def present
|
88
|
-
yield(self)
|
89
|
-
raise UnhandledErrors.new(@unhandled) unless @unhandled.empty?
|
90
|
-
@output
|
91
|
-
end
|
92
|
-
|
93
|
-
protected
|
94
|
-
|
95
|
-
def handle(error)
|
96
|
-
if (errors = @errors.select {|e| error === e }).any?
|
97
|
-
@unhandled -= errors
|
98
|
-
yield(errors) if block_given?
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# A simple class for storing all errors. Since {Ohm::Validations::Errors}
|
104
|
-
# extends Array, you can expect all array methods to work on it.
|
105
|
-
class Errors < Array
|
106
|
-
attr_accessor :model
|
107
|
-
|
108
|
-
def initialize(model)
|
109
|
-
@model = model
|
110
|
-
end
|
111
|
-
|
112
|
-
def present(presenter = Presenter, &block)
|
113
|
-
presenter.new(model.errors).present(&block)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
# Check if the current model state is valid. Each call to {#valid?} will
|
118
|
-
# reset the {#errors} array.
|
119
|
-
#
|
120
|
-
# All model validations should be declared in a `validate` method.
|
121
|
-
#
|
122
|
-
# @example
|
123
|
-
#
|
124
|
-
# class Post < Ohm::Model
|
125
|
-
# attribute :title
|
126
|
-
#
|
127
|
-
# def validate
|
128
|
-
# assert_present :title
|
129
|
-
# end
|
130
|
-
# end
|
131
|
-
#
|
132
|
-
def valid?
|
133
|
-
errors.clear
|
134
|
-
validate
|
135
|
-
errors.empty?
|
136
|
-
end
|
137
|
-
|
138
|
-
# Base validate implementation.
|
139
|
-
def validate
|
140
|
-
end
|
141
|
-
|
142
|
-
# All errors for this model.
|
143
|
-
def errors
|
144
|
-
@errors ||= Errors.new(self)
|
145
|
-
end
|
146
|
-
|
147
|
-
protected
|
148
|
-
|
149
|
-
# Allows you to do a validation check against a regular expression.
|
150
|
-
# It's important to note that this internally calls {#assert_present},
|
151
|
-
# therefore you need not structure your regular expression to check
|
152
|
-
# for a non-empty value.
|
153
|
-
#
|
154
|
-
# @param [Symbol] att The attribute you want to verify the format of.
|
155
|
-
# @param [Regexp] format The regular expression with which to compare
|
156
|
-
# the value of att with.
|
157
|
-
# @param [Array<Symbol, Symbol>] error The error that should be returned
|
158
|
-
# when the validation fails.
|
159
|
-
def assert_format(att, format, error = [att, :format])
|
160
|
-
if assert_present(att, error)
|
161
|
-
assert(send(att).to_s.match(format), error)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
# The most basic and highly useful assertion. Simply checks if the
|
166
|
-
# value of the attribute is empty.
|
167
|
-
#
|
168
|
-
# @param [Symbol] att The attribute you wish to verify the presence of.
|
169
|
-
# @param [Array<Symbol, Symbol>] error The error that should be returned
|
170
|
-
# when the validation fails.
|
171
|
-
def assert_present(att, error = [att, :not_present])
|
172
|
-
assert(!send(att).to_s.empty?, error)
|
173
|
-
end
|
174
|
-
|
175
|
-
# Checks if all the characters of an attribute is a digit. If you want to
|
176
|
-
# verify that a value is a decimal, try looking at Ohm::Contrib's
|
177
|
-
# assert_decimal assertion.
|
178
|
-
#
|
179
|
-
# @param [Symbol] att The attribute you wish to verify the numeric format.
|
180
|
-
# @param [Array<Symbol, Symbol>] error The error that should be returned
|
181
|
-
# when the validation fails.
|
182
|
-
# @see http://cyx.github.com/ohm-contrib/doc/Ohm/NumberValidations.html
|
183
|
-
def assert_numeric(att, error = [att, :not_numeric])
|
184
|
-
if assert_present(att, error)
|
185
|
-
assert_format(att, /^\d+$/, error)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
# The grand daddy of all assertions. If you want to build custom
|
190
|
-
# assertions, or even quick and dirty ones, you can simply use this method.
|
191
|
-
#
|
192
|
-
# @example
|
193
|
-
#
|
194
|
-
# class Post < Ohm::Model
|
195
|
-
# attribute :slug
|
196
|
-
# attribute :votes
|
197
|
-
#
|
198
|
-
# def validate
|
199
|
-
# assert_slug :slug
|
200
|
-
# assert votes.to_i > 0, [:votes, :not_valid]
|
201
|
-
# end
|
202
|
-
#
|
203
|
-
# protected
|
204
|
-
# def assert_slug(att, error = [att, :not_slug])
|
205
|
-
# assert send(att).to_s =~ /\A[a-z\-0-9]+\z/, error
|
206
|
-
# end
|
207
|
-
# end
|
208
|
-
def assert(value, error)
|
209
|
-
value or errors.push(error) && false
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|