ohm 1.0.0.rc4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -77,7 +77,7 @@ set the environment variable `REDIS_URL`.
77
77
 
78
78
  Here are the options for {Ohm.connect} in detail:
79
79
 
80
- ### :url
80
+ ### :url (recommended)
81
81
 
82
82
  A Redis URL of the form `redis://:<passwd>@<host>:<port>/<db>`.
83
83
  Note that if you specify a URL and one of the other options at
@@ -126,8 +126,8 @@ the example below:
126
126
  ```ruby
127
127
  class Event < Ohm::Model
128
128
  attribute :name
129
- reference :venue, Venue
130
- set :participants, Person
129
+ reference :venue, :Venue
130
+ set :participants, :Person
131
131
  counter :votes
132
132
 
133
133
  index :name
@@ -139,7 +139,7 @@ end
139
139
 
140
140
  class Venue < Ohm::Model
141
141
  attribute :name
142
- collection :events, Event
142
+ collection :events, :Event
143
143
  end
144
144
 
145
145
  class Person < Ohm::Model
@@ -259,7 +259,7 @@ Given the following model declaration:
259
259
  ```ruby
260
260
  class Event < Ohm::Model
261
261
  attribute :name
262
- set :attendees, Person
262
+ set :attendees, :Person
263
263
  end
264
264
  ```
265
265
 
@@ -349,12 +349,12 @@ Ohm lets you declare `references` and `collections` to represent associations.
349
349
  class Post < Ohm::Model
350
350
  attribute :title
351
351
  attribute :body
352
- collection :comments, Comment
352
+ collection :comments, :Comment
353
353
  end
354
354
 
355
355
  class Comment < Ohm::Model
356
356
  attribute :body
357
- reference :post, Post
357
+ reference :post, :Post
358
358
  end
359
359
  ```
360
360
 
@@ -419,14 +419,14 @@ in the other model. The following all produce the same effect:
419
419
 
420
420
  ```ruby
421
421
  # easiest, with the basic assumption that the index is `:post_id`
422
- collection :comments, Comment
422
+ collection :comments, :Comment
423
423
 
424
424
  # we can explicitly declare this as follows too:
425
- collection :comments, Comment, :post
425
+ collection :comments, :Comment, :post
426
426
 
427
427
  # finally, we can use the default argument for the third parameter which
428
428
  # is `to_reference`.
429
- collection :comments, Comment, to_reference
429
+ collection :comments, :Comment, to_reference
430
430
 
431
431
  # exploring `to_reference` reveals a very interesting and simple concept:
432
432
  Post.to_reference == :post
@@ -554,6 +554,51 @@ representation. The error code for this assertion is :not_numeric.
554
554
  assert_numeric :votes
555
555
  ```
556
556
 
557
+ ### assert_url
558
+
559
+ Provides a pretty general URL regular expression match. An important
560
+ point to make is that this assumes that the URL should start with
561
+ `http://` or `https://`. The error code for this assertion is
562
+ `:not_url`.
563
+
564
+ ### assert_email
565
+
566
+ In this current day and age, almost all web applications need to
567
+ validate an email address. This pretty much matches 99% of the emails
568
+ out there. The error code for this assertion is `:not_email`.
569
+
570
+ ### assert_member
571
+
572
+ Checks that a given field is contained within a set of values (i.e.
573
+ like an `ENUM`).
574
+
575
+ ``` ruby
576
+ def validate
577
+ assert_member :state, %w{pending paid delivered}
578
+ end
579
+ ```
580
+
581
+ The error code for this assertion is `:not_valid`
582
+
583
+ ### assert_length
584
+
585
+ Checks that a given field's length falls under a specified range.
586
+
587
+ ``` ruby
588
+ def validate
589
+ assert_length :username, 3..20
590
+ end
591
+ ```
592
+
593
+ The error code for this assertion is `:not_in_range`.
594
+
595
+ ### assert_decimal
596
+
597
+ Checks that a given field looks like a number in the human sense
598
+ of the word. Valid numbers are: 0.1, .1, 1, 1.1, 3.14159, etc.
599
+
600
+ The error code for this assertion is `:not_decimal`.
601
+
557
602
  Errors
558
603
  ------
559
604
 
@@ -590,51 +635,13 @@ make sure to check them if you need to extend Ohm's functionality.
590
635
 
591
636
  [contrib]: http://cyx.github.com/ohm-contrib/doc/
592
637
 
593
- Tutorials
638
+ Upgrading
594
639
  =========
595
640
 
596
- NOTE: These tutorials were written against Ohm 0.1.x. Please give us
597
- a while to fully update all of them.
598
-
599
- Check the examples to get a feeling of the design patterns for Redis.
600
-
601
- 1. [Activity Feed](http://ohm.keyvalue.org/examples/activity-feed.html)
602
- 2. [Chaining finds](http://ohm.keyvalue.org/examples/chaining.html)
603
- 3. [Serialization to JSON](http://ohm.keyvalue.org/examples/json-hash.html)
604
- 4. [One to many associations](http://ohm.keyvalue.org/examples/one-to-many.html)
605
- 5. [Philosophy behind Ohm](http://ohm.keyvalue.org/examples/philosophy.html)
606
- 6. [Learning Ohm internals](http://ohm.keyvalue.org/examples/redis-logging.html)
607
- 7. [Slugs and permalinks](http://ohm.keyvalue.org/examples/slug.html)
608
- 8. [Tagging](http://ohm.keyvalue.org/examples/tagging.html)
609
-
610
-
611
- Versions
612
- ========
613
-
614
- Ohm uses features from Redis > 2.6.x. If you are stuck in previous
615
- versions, please use Ohm 0.1.x instead.
616
-
617
- Upgrading from 0.0.x to 0.1
618
- ---------------------------
619
-
620
- Since Ohm 0.1 changes the persistence strategy (from 1-key-per-attribute
621
- to Hashes), you'll need to run a script to upgrade your old data set.
622
- Fortunately, it is built in:
623
-
624
- ```ruby
625
- require "ohm/utils/upgrade"
626
-
627
- Ohm.connect :port => 6380
628
-
629
- Ohm::Utils::Upgrade.new([:User, :Post, :Comment]).run
630
- ```
631
-
632
- Yes, you need to provide the model names. The good part is that you
633
- don't have to load your application environment. Since we assume it's
634
- very likely that you have a bunch of data, the script uses
635
- [Batch](http://github.com/djanowski/batch) to show you some progress
636
- while the process runs.
637
-
641
+ The changes in Ohm 1 break the compatibility with previous versions.
642
+ We will do our best to provide a script to ease the pain of upgrading.
643
+ In the meantime, it's recommended that you use the new version only
644
+ for new projects.
638
645
 
639
646
  [redis]: http://redis.io
640
647
  [ohm]: http://github.com/soveran/ohm
data/Rakefile CHANGED
@@ -31,7 +31,7 @@ task :test do
31
31
  end
32
32
 
33
33
  desc "Generate documentation"
34
- task :doc => [:yard, :rocco]
34
+ task :doc => :yard
35
35
 
36
36
  desc "Generated YARD documentation"
37
37
  task :yard do
@@ -65,46 +65,7 @@ task :yard do
65
65
  end
66
66
  end
67
67
 
68
- desc "Generate ROCCO documentation"
69
- task :rocco do
70
- `mkdir doc/examples` unless Dir.exists?("doc/examples")
71
- `rocco examples/*.*`
72
- `mv examples/*.html doc/examples`
73
- end
74
-
75
68
  desc "Deploy documentation"
76
69
  task :deploy do
77
70
  system "rsync --del -avz doc/* ohm.keyvalue.org:deploys/ohm.keyvalue.org/"
78
71
  end
79
-
80
- namespace :examples do
81
- desc "Run all the examples"
82
- task :run do
83
- begin
84
- require "cutest"
85
- rescue LoadError
86
- raise "!! Missing gem `cutest`. Try `gem install cutest`."
87
- end
88
-
89
- Cutest.run(Dir["examples/*.rb"])
90
- end
91
- end
92
-
93
- task :paste_lua_inline do
94
- def wrap(const, data)
95
- ret = "#{const} = (<<-EOT).gsub(/^ {4}/, "")\n"
96
- ret << data.gsub(/^/, " ")
97
- ret << " EOT\n"
98
- end
99
-
100
- save = File.read("./lua/save.lua")
101
- del = File.read("./lua/delete.lua")
102
- # save = "foo"
103
- # del = "bar"
104
-
105
- ohm = File.read("./lib/ohm.rb", :encoding => "utf-8")
106
- ohm.gsub!(/SAVE =(.*?)$(.*?)EOT/m, wrap("SAVE", save))
107
- ohm.gsub!(/DELETE =(.*?)$(.*?)EOT/m, wrap("DELETE", del))
108
-
109
- puts ohm
110
- end
metadata CHANGED
@@ -1,36 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ohm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc4
5
- prerelease: 6
4
+ version: 1.0.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Michel Martens
9
9
  - Damian Janowski
10
+ - Cyril David
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
- date: 2012-04-24 00:00:00.000000000 Z
14
+ date: 2012-04-25 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
- name: nest
17
- requirement: !ruby/object:Gem::Requirement
17
+ name: redis
18
+ requirement: &2156471380 !ruby/object:Gem::Requirement
18
19
  none: false
19
20
  requirements:
20
21
  - - ~>
21
22
  - !ruby/object:Gem::Version
22
- version: '1.0'
23
+ version: '2.2'
23
24
  type: :runtime
24
25
  prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
+ version_requirements: *2156471380
27
+ - !ruby/object:Gem::Dependency
28
+ name: nest
29
+ requirement: &2156470820 !ruby/object:Gem::Requirement
26
30
  none: false
27
31
  requirements:
28
32
  - - ~>
29
33
  - !ruby/object:Gem::Version
30
34
  version: '1.0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: *2156470820
31
38
  - !ruby/object:Gem::Dependency
32
39
  name: scrivener
33
- requirement: !ruby/object:Gem::Requirement
40
+ requirement: &2156470340 !ruby/object:Gem::Requirement
34
41
  none: false
35
42
  requirements:
36
43
  - - ~>
@@ -38,15 +45,10 @@ dependencies:
38
45
  version: 0.0.3
39
46
  type: :runtime
40
47
  prerelease: false
41
- version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
- requirements:
44
- - - ~>
45
- - !ruby/object:Gem::Version
46
- version: 0.0.3
48
+ version_requirements: *2156470340
47
49
  - !ruby/object:Gem::Dependency
48
50
  name: cutest
49
- requirement: !ruby/object:Gem::Requirement
51
+ requirement: &2156469880 !ruby/object:Gem::Requirement
50
52
  none: false
51
53
  requirements:
52
54
  - - ~>
@@ -54,41 +56,20 @@ dependencies:
54
56
  version: '0.1'
55
57
  type: :development
56
58
  prerelease: false
57
- version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
- requirements:
60
- - - ~>
61
- - !ruby/object:Gem::Version
62
- version: '0.1'
63
- - !ruby/object:Gem::Dependency
64
- name: batch
65
- requirement: !ruby/object:Gem::Requirement
66
- none: false
67
- requirements:
68
- - - ~>
69
- - !ruby/object:Gem::Version
70
- version: 0.0.1
71
- type: :development
72
- prerelease: false
73
- version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
- requirements:
76
- - - ~>
77
- - !ruby/object:Gem::Version
78
- version: 0.0.1
59
+ version_requirements: *2156469880
79
60
  description: Ohm is a library that allows to store an object in Redis, a persistent
80
61
  key-value database. It includes an extensible list of validations and has very good
81
62
  performance.
82
63
  email:
83
64
  - michel@soveran.com
84
65
  - djanowski@dimaion.com
66
+ - me@cyrildavid.com
85
67
  executables: []
86
68
  extensions: []
87
69
  extra_rdoc_files: []
88
70
  files:
89
71
  - lib/ohm/json.rb
90
72
  - lib/ohm/transaction.rb
91
- - lib/ohm/utils/upgrade.rb
92
73
  - lib/ohm.rb
93
74
  - README.md
94
75
  - LICENSE
@@ -111,13 +92,9 @@ files:
111
92
  - test/pipeline-performance.rb
112
93
  - test/transactions.rb
113
94
  - test/uniques.rb
114
- - test/unused/associations_test.rb
115
- - test/unused/pattern_test.rb
116
- - test/unused/upgrade_script_test.rb
117
- - test/unused/wrapper_test.rb
118
95
  - test/validations.rb
119
96
  - test/test.conf
120
- homepage: http://github.com/soveran/ohm
97
+ homepage: http://soveran.github.com/ohm/
121
98
  licenses: []
122
99
  post_install_message:
123
100
  rdoc_options: []
@@ -132,13 +109,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
109
  required_rubygems_version: !ruby/object:Gem::Requirement
133
110
  none: false
134
111
  requirements:
135
- - - ! '>'
112
+ - - ! '>='
136
113
  - !ruby/object:Gem::Version
137
- version: 1.3.1
114
+ version: '0'
138
115
  requirements: []
139
116
  rubyforge_project: ohm
140
- rubygems_version: 1.8.23
117
+ rubygems_version: 1.8.11
141
118
  signing_key:
142
119
  specification_version: 3
143
120
  summary: Object-hash mapping library for Redis.
144
121
  test_files: []
122
+ has_rdoc:
@@ -1,53 +0,0 @@
1
- begin
2
- require "batch"
3
- rescue LoadError => e
4
- e.message << "\nTry `gem install batch`."
5
- end
6
-
7
- module Ohm
8
- module Utils
9
- class Upgrade
10
- def redis
11
- Ohm.redis
12
- end
13
-
14
- attr :models
15
- attr :types
16
-
17
- def initialize(models)
18
- @models = models
19
- @types = Hash.new { |hash, model| hash[model] = {} }
20
- end
21
-
22
- def run
23
- models.each do |model|
24
- ns = Ohm::Key.new(model, redis)
25
-
26
- puts "Upgrading #{model}..."
27
-
28
- Batch.each(ns[:all].smembers) do |id|
29
- instance = ns[id]
30
-
31
- attrs = []
32
- deletes = []
33
-
34
- redis.keys(instance["*"]).each do |key|
35
- field = key[instance.size.succ..-1]
36
-
37
- type = (types[model][field] ||= redis.type(key).to_sym)
38
-
39
- if type == :string
40
- attrs << field
41
- attrs << redis.get(key)
42
- deletes << key
43
- end
44
- end
45
-
46
- redis.hmset(instance, *attrs)
47
- redis.del(*deletes)
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,100 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- class Person < Ohm::Model
6
- attribute :name
7
- end
8
-
9
- class ::Note < Ohm::Model
10
- attribute :content
11
- reference :source, Post
12
- collection :comments, Comment
13
- list :ratings, Rating
14
- end
15
-
16
- class ::Comment < Ohm::Model
17
- reference :note, Note
18
- end
19
-
20
- class ::Rating < Ohm::Model
21
- attribute :value
22
- end
23
-
24
- class ::Editor < Ohm::Model
25
- attribute :name
26
- reference :post, Post
27
- end
28
-
29
- class ::Post < Ohm::Model
30
- reference :author, Person
31
- collection :notes, Note, :source
32
- collection :editors, Editor
33
- end
34
-
35
- setup do
36
- @post = Post.create
37
- end
38
-
39
- test "return an instance of Person if author_id has a valid id" do
40
- @post.author_id = Person.create(:name => "Albert").id
41
- @post.save
42
- assert "Albert" == Post[@post.id].author.name
43
- end
44
-
45
- test "assign author_id if author is sent a valid instance" do
46
- @post.author = Person.create(:name => "Albert")
47
- @post.save
48
- assert "Albert" == Post[@post.id].author.name
49
- end
50
-
51
- test "assign nil if nil is passed to author" do
52
- @post.author = nil
53
- @post.save
54
- assert Post[@post.id].author.nil?
55
- end
56
-
57
- test "be cached in an instance variable" do
58
- @author = Person.create(:name => "Albert")
59
- @post.update(:author => @author)
60
-
61
- assert @author == @post.author
62
- assert @post.author.object_id == @post.author.object_id
63
-
64
- @post.update(:author => Person.create(:name => "Bertrand"))
65
-
66
- assert_equal "Bertrand", @post.author.name
67
- assert_equal @post.author.object_id, @post.author.object_id
68
-
69
- @post.update(:author_id => Person.create(:name => "Charles").id)
70
-
71
- assert_equal "Charles", @post.author.name
72
- end
73
-
74
- setup do
75
- @post = Post.create
76
- @note = Note.create(:content => "Interesting stuff", :source => @post)
77
- @comment = Comment.create(:note => @note)
78
- end
79
-
80
- test "return a set of notes" do
81
- assert @note.source == @post
82
- assert @note == @post.notes.first
83
- end
84
-
85
- test "return a set of comments" do
86
- assert @comment == @note.comments.first
87
- end
88
-
89
- test "return a list of ratings" do
90
- @rating = Rating.create(:value => 5)
91
- @note.ratings << @rating
92
-
93
- assert @rating == @note.ratings.first
94
- end
95
-
96
- test "default to the current class name" do
97
- @editor = Editor.create(:name => "Albert", :post => @post)
98
-
99
- assert @editor == @post.editors.first
100
- end
@@ -1,10 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- prepare.clear
6
-
7
- test "should provide pattern matching" do
8
- assert(Ohm::Pattern[1, Fixnum] === [1, 2])
9
- assert(Ohm::Pattern[String, Array] === ["foo", ["bar"]])
10
- end
@@ -1,62 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- require "ohm/utils/upgrade"
6
-
7
- def redis
8
- Ohm.redis
9
- end
10
-
11
- setup do
12
- redis.flushdb
13
-
14
- @users = Ohm::Key.new(:User, Ohm.redis)
15
-
16
- 10.times do
17
- @id = redis.incr(@users[:id])
18
- @user = @users[@id]
19
-
20
- redis.sadd @users[:all], @id
21
-
22
- redis.set @user[:name], "Albert"
23
- redis.set @user[:email], "albert-#{@id}@example.com"
24
- redis.incr @user[:views]
25
-
26
- redis.sadd @user[:posts], 1
27
- redis.sadd @user[:posts], 2
28
-
29
- redis.lpush @user[:comments], 3
30
- redis.lpush @user[:comments], 4
31
-
32
- redis.sadd @user[:_indices], @users[:email][Ohm::Model.encode "albert-#{@id}@example.com"]
33
- redis.sadd @users[:email][Ohm::Model.encode "albert-#{@id}@example.com"], @id
34
- end
35
- end
36
-
37
- test "upgrade to hashes" do
38
- require "stringio"
39
-
40
- stderr, stdout = $stderr, $stdout
41
-
42
- $stderr, $stdout = StringIO.new, StringIO.new
43
-
44
- Ohm::Utils::Upgrade.new([:User]).run
45
-
46
- $stderr, $stdout = stderr, stdout
47
-
48
- @user = @users[1]
49
-
50
- assert redis.get(@user[:name]).nil?
51
- assert redis.get(@user[:email]).nil?
52
- assert redis.get(@user[:views]).nil?
53
-
54
- assert ["1", "2"] == redis.smembers(@user[:posts])
55
-
56
- assert [@users[:email][Ohm::Model.encode "albert-1@example.com"]] == redis.smembers(@user[:_indices])
57
- assert ["1"] == redis.smembers(@users[:email][Ohm::Model.encode "albert-1@example.com"])
58
-
59
- assert "Albert" == redis.hget(@user, :name)
60
- assert "albert-1@example.com" == redis.hget(@user, :email)
61
- assert "1" == redis.hget(@user, :views)
62
- end
@@ -1,22 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- prepare.clear
6
-
7
- $missing_constants = []
8
-
9
- class Object
10
- def self.const_missing(name)
11
- $missing_constants << name
12
- super(name)
13
- end
14
- end
15
-
16
- class Foo < Ohm::Model
17
- set :bars, Bar
18
- end
19
-
20
- test "calls other const_missing hooks" do
21
- assert [:Bar] == $missing_constants
22
- end