sequel_model 0.4.2 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,153 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe Sequel::Model, "one_to_one" do
4
+
5
+ before(:each) do
6
+ MODEL_DB.reset
7
+
8
+ @c1 = Class.new(Sequel::Model(:attributes)) do
9
+ end
10
+
11
+ @c2 = Class.new(Sequel::Model(:nodes)) do
12
+ def columns; [:id, :parent_id]; end
13
+ end
14
+
15
+ @dataset = @c2.dataset
16
+
17
+ @dataset.extend(Module.new {
18
+ def fetch_rows(sql)
19
+ @db << sql
20
+ yield({:hey => 1})
21
+ end
22
+ })
23
+ end
24
+
25
+ it "should use implicit key if omitted" do
26
+ @c2.one_to_one :parent, :from => @c2
27
+
28
+ d = @c2.new(:id => 1, :parent_id => 234)
29
+ p = d.parent
30
+ p.class.should == @c2
31
+ p.values.should == {:hey => 1}
32
+
33
+ MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (id = 234) LIMIT 1"]
34
+ end
35
+
36
+ it "should use explicit key if given" do
37
+ @c2.one_to_one :parent, :from => @c2, :key => :blah
38
+
39
+ d = @c2.new(:id => 1, :blah => 567)
40
+ p = d.parent
41
+ p.class.should == @c2
42
+ p.values.should == {:hey => 1}
43
+
44
+ MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (id = 567) LIMIT 1"]
45
+ end
46
+
47
+ # the new implementation doesn't support plain datasets as associations
48
+ # it "should support plain dataset in the from option" do
49
+ # @c2.one_to_one :parent, :from => MODEL_DB[:xyz]
50
+ #
51
+ # d = @c2.new(:id => 1, :parent_id => 789)
52
+ # p = d.parent
53
+ # p.class.should == Hash
54
+ #
55
+ # MODEL_DB.sqls.should == ["SELECT * FROM xyz WHERE (id = 789) LIMIT 1"]
56
+ # end
57
+
58
+ # the new implementation doesn't support plain datasets as associations
59
+ # it "should support table name in the from option" do
60
+ # @c2.one_to_one :parent, :from => :abc
61
+ #
62
+ # d = @c2.new(:id => 1, :parent_id => 789)
63
+ # p = d.parent
64
+ # p.class.should == Hash
65
+ #
66
+ # MODEL_DB.sqls.should == ["SELECT * FROM abc WHERE (id = 789) LIMIT 1"]
67
+ # end
68
+
69
+ it "should return nil if key value is nil" do
70
+ @c2.one_to_one :parent, :from => @c2
71
+
72
+ d = @c2.new(:id => 1)
73
+ d.parent.should == nil
74
+ end
75
+
76
+ it "should define a setter method" do
77
+ @c2.one_to_one :parent, :from => @c2
78
+
79
+ d = @c2.load(:id => 1)
80
+ d.parent = @c2.new(:id => 4321)
81
+ d.values.should == {:id => 1, :parent_id => 4321}
82
+ d.save_changes
83
+ MODEL_DB.sqls.last.should == "UPDATE nodes SET parent_id = 4321 WHERE (id = 1)"
84
+
85
+ d.parent = nil
86
+ d.values.should == {:id => 1, :parent_id => nil}
87
+ d.save_changes
88
+ MODEL_DB.sqls.last.should == "UPDATE nodes SET parent_id = NULL WHERE (id = 1)"
89
+
90
+ e = @c2.new(:id => 6677)
91
+ d.parent = e
92
+ d.values.should == {:id => 1, :parent_id => 6677}
93
+ d.save_changes
94
+ MODEL_DB.sqls.last.should == "UPDATE nodes SET parent_id = 6677 WHERE (id = 1)"
95
+ end
96
+ end
97
+
98
+ describe Sequel::Model, "one_to_many" do
99
+
100
+ before(:each) do
101
+ MODEL_DB.reset
102
+
103
+ @c1 = Class.new(Sequel::Model(:attributes)) do
104
+ end
105
+
106
+ @c2 = Class.new(Sequel::Model(:nodes)) do
107
+ end
108
+ end
109
+
110
+ it "should define a getter method" do
111
+ @c2.one_to_many :attributes, :from => @c1, :key => :node_id
112
+
113
+ n = @c2.new(:id => 1234)
114
+ a = n.attributes
115
+ a.should be_a_kind_of(Sequel::Dataset)
116
+ a.sql.should == 'SELECT * FROM attributes WHERE (node_id = 1234)'
117
+ end
118
+
119
+ # the new implementation doesn't support plain datasets as associations
120
+ # it "should support plain dataset in the from option" do
121
+ # @c2.one_to_many :attributes, :from => MODEL_DB[:xyz], :key => :node_id
122
+ #
123
+ # n = @c2.new(:id => 1234)
124
+ # a = n.attributes
125
+ # a.should be_a_kind_of(Sequel::Dataset)
126
+ # a.sql.should == 'SELECT * FROM xyz WHERE (node_id = 1234)'
127
+ # end
128
+
129
+ # the new implementation doesn't support plain datasets as associations
130
+ # it "should support table name in the from option" do
131
+ # @c2.one_to_many :attributes, :from => :abc, :key => :node_id
132
+ #
133
+ # n = @c2.new(:id => 1234)
134
+ # a = n.attributes
135
+ # a.should be_a_kind_of(Sequel::Dataset)
136
+ # a.sql.should == 'SELECT * FROM abc WHERE (node_id = 1234)'
137
+ # end
138
+
139
+ it "should support implicit key names" do
140
+ $c1 = @c1
141
+
142
+ module Music
143
+ class BlueNote < Sequel::Model
144
+ one_to_many :attributes, :from => $c1
145
+ end
146
+ end
147
+
148
+ n = Music::BlueNote.new(:id => 1234)
149
+ a = n.attributes
150
+ a.should be_a_kind_of(Sequel::Dataset)
151
+ a.sql.should == 'SELECT * FROM attributes WHERE (blue_note_id = 1234)'
152
+ end
153
+ end
@@ -13,6 +13,10 @@ class MockDataset < Sequel::Dataset
13
13
  @db.execute update_sql(*args)
14
14
  end
15
15
 
16
+ def delete(*args)
17
+ @db.execute delete_sql(*args)
18
+ end
19
+
16
20
  def fetch_rows(sql)
17
21
  @db.execute(sql)
18
22
  yield({:id => 1, :x => 1})
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: "0.5"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-02-29 00:00:00 +02:00
12
+ date: 2008-03-08 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,7 +30,7 @@ dependencies:
30
30
  - !ruby/object:Gem::Version
31
31
  version: "1.0"
32
32
  version:
33
- description: Lightweight ORM for Ruby
33
+ description: Model classes for Sequel
34
34
  email: ciconia@gmail.com
35
35
  executables: []
36
36
 
@@ -44,26 +44,27 @@ files:
44
44
  - COPYING
45
45
  - README
46
46
  - Rakefile
47
+ - spec/associations_spec.rb
47
48
  - spec/base_spec.rb
48
49
  - spec/caching_spec.rb
50
+ - spec/deprecated_relations_spec.rb
49
51
  - spec/hooks_spec.rb
50
52
  - spec/model_spec.rb
51
53
  - spec/plugins_spec.rb
52
54
  - spec/rcov.opts
53
55
  - spec/record_spec.rb
54
- - spec/relations_spec.rb
55
56
  - spec/schema_spec.rb
56
57
  - spec/spec.opts
57
58
  - spec/spec_helper.rb
58
59
  - spec/validations_spec.rb
59
60
  - lib/sequel_model
61
+ - lib/sequel_model/associations.rb
60
62
  - lib/sequel_model/base.rb
61
63
  - lib/sequel_model/caching.rb
62
64
  - lib/sequel_model/hooks.rb
63
65
  - lib/sequel_model/plugins.rb
64
66
  - lib/sequel_model/pretty_table.rb
65
67
  - lib/sequel_model/record.rb
66
- - lib/sequel_model/relations.rb
67
68
  - lib/sequel_model/schema.rb
68
69
  - lib/sequel_model/validations.rb
69
70
  - lib/sequel_model.rb
@@ -74,7 +75,7 @@ post_install_message:
74
75
  rdoc_options:
75
76
  - --quiet
76
77
  - --title
77
- - "Sequel Model: Lightweight ORM for Ruby"
78
+ - "Sequel: The Database Toolkit for Ruby"
78
79
  - --opname
79
80
  - index.html
80
81
  - --line-numbers
@@ -105,6 +106,6 @@ rubyforge_project: sequel
105
106
  rubygems_version: 1.0.1
106
107
  signing_key:
107
108
  specification_version: 2
108
- summary: Lightweight ORM for Ruby
109
+ summary: Model classes for Sequel
109
110
  test_files: []
110
111
 
@@ -1,154 +0,0 @@
1
- module Sequel
2
- class Model
3
- ID_POSTFIX = '_id'.freeze
4
-
5
- # Creates a 1-1 relationship by defining an association method, e.g.:
6
- #
7
- # class Session < Sequel::Model
8
- # end
9
- #
10
- # class Node < Sequel::Model
11
- # one_to_one :producer, :from => Session
12
- # # which is equivalent to
13
- # def producer
14
- # Session[producer_id] if producer_id
15
- # end
16
- # end
17
- #
18
- # You can also set the foreign key explicitly by including a :key option:
19
- #
20
- # one_to_one :producer, :from => Session, :key => :producer_id
21
- #
22
- # The one_to_one macro also creates a setter, which accepts nil, a hash or
23
- # a model instance, e.g.:
24
- #
25
- # p = Producer[1234]
26
- # node = Node[:path => '/']
27
- # node.producer = p
28
- # node.producer_id #=> 1234
29
- #
30
- def self.one_to_one(name, opts)
31
- from = opts[:from]
32
- from || (raise Error, "No association source defined (use :from option)")
33
- key = opts[:key] || (name.to_s + ID_POSTFIX).to_sym
34
-
35
- setter_name = "#{name}=".to_sym
36
-
37
- case from
38
- when Symbol
39
- class_def(name) {(k = @values[key]) ? db[from][:id => k] : nil}
40
- when Sequel::Dataset
41
- class_def(name) {(k = @values[key]) ? from[:id => k] : nil}
42
- else
43
- class_def(name) {(k = @values[key]) ? from[k] : nil}
44
- end
45
- class_def(setter_name) do |v|
46
- case v
47
- when nil
48
- set(key => nil)
49
- when Sequel::Model
50
- set(key => v.pk)
51
- when Hash
52
- set(key => v[:id])
53
- end
54
- end
55
-
56
- # define_method name, &eval(ONE_TO_ONE_PROC % [key, from])
57
- end
58
-
59
- # Creates a 1-N relationship by defining an association method, e.g.:
60
- #
61
- # class Book < Sequel::Model
62
- # end
63
- #
64
- # class Author < Sequel::Model
65
- # one_to_many :books, :from => Book
66
- # # which is equivalent to
67
- # def books
68
- # Book.filter(:author_id => id)
69
- # end
70
- # end
71
- #
72
- # You can also set the foreign key explicitly by including a :key option:
73
- #
74
- # one_to_many :books, :from => Book, :key => :author_id
75
- #
76
- def self.one_to_many(name, opts)
77
- from = opts[:from]
78
- from || (raise Error, "No association source defined (use :from option)")
79
- key = opts[:key] || (self.name.demodulize.underscore.to_s + ID_POSTFIX).to_sym
80
-
81
- case from
82
- when Symbol
83
- class_def(name) {db[from].filter(key => pk)}
84
- else
85
- class_def(name) {from.filter(key => pk)}
86
- end
87
- end
88
-
89
- # TODO: Add/Replace current relations with the following specifications:
90
- # ======================================================================
91
-
92
- # Database modelling is generally done with an ER (Entity Relationship) diagram.
93
- # Shouldn't ORM's facilitate simlilar specification?
94
-
95
- # class Post < Sequel::Model
96
- # relationships do
97
- # # Specify the relationships that exist with the User model (users table)
98
- # # These relationships are precisely the ER diagram connecting arrows.
99
- # end
100
- # end
101
-
102
- #
103
- # = Relationships
104
- #
105
- # are specifications of the ends of the ER diagrams connectors that are touching
106
- # the current model.
107
- #
108
- # one_to_one, has_one
109
- # many_to_one, belongs_to
110
- # many_to_many, has_many
111
- # ?parameters may be :zero, :one, :many which specifies the cardinality of the connection
112
-
113
- # Example:
114
- # class Post < Sequel::Model
115
- # relationships do
116
- # has :one, :blog, :required => true # blog_id field, cannot be null
117
- # has :one, :account # account_id field
118
- # has :many, :comments # comments_posts join table
119
- # has :many, :authors, :required => true # authors_posts join table, requires at least one author
120
- # end
121
- # end
122
-
123
- #
124
- # Relationship API Details
125
- #
126
-
127
- #
128
- # == belongs_to
129
- #
130
-
131
- # Defines an blog and blog= method
132
- # belongs_to :blog
133
-
134
- # Same, but uses "b_id" as the blog's id field.
135
- # belongs_to :blog, :key => :b_id
136
-
137
- # has_many :comments
138
- # * Defines comments method which will query the join table appropriately.
139
- # * Checks to see if a "comments_posts" join table exists (alphabetical order)
140
- # ** If it does not exist, will create the join table.
141
- # ** If options are passed in these will be used to further define the join table.
142
-
143
-
144
- # Benefits:
145
- # * Normalized DB
146
- # * Easy to define join objects
147
- # * Efficient queries, database gets to use indexed fields (pkeys) instead of a string field and an id.
148
- #
149
- # For example, polymorphic associations now become:
150
- # [user] 1-* [addresses_users] *-1 [addresses]
151
- # [companies] 1-* [addresses_companies] *-1 [addresses]
152
- # [clients] 1-* [addresses_clients] *-1 [addresses]
153
- end
154
- end
@@ -1,149 +0,0 @@
1
- require File.join(File.dirname(__FILE__), "spec_helper")
2
-
3
- describe Sequel::Model, "one_to_one" do
4
-
5
- before(:each) do
6
- MODEL_DB.reset
7
-
8
- @c1 = Class.new(Sequel::Model(:attributes)) do
9
- end
10
-
11
- @c2 = Class.new(Sequel::Model(:nodes)) do
12
- end
13
-
14
- @dataset = @c2.dataset
15
-
16
- $sqls = []
17
- @dataset.extend(Module.new {
18
- def fetch_rows(sql)
19
- $sqls << sql
20
- yield({:hey => 1})
21
- end
22
-
23
- def update(values)
24
- $sqls << update_sql(values)
25
- end
26
- }
27
- )
28
- end
29
-
30
- it "should use implicit key if omitted" do
31
- @c2.one_to_one :parent, :from => @c2
32
-
33
- d = @c2.new(:id => 1, :parent_id => 234)
34
- p = d.parent
35
- p.class.should == @c2
36
- p.values.should == {:hey => 1}
37
-
38
- $sqls.should == ["SELECT * FROM nodes WHERE (id = 234) LIMIT 1"]
39
- end
40
-
41
- it "should use explicit key if given" do
42
- @c2.one_to_one :parent, :from => @c2, :key => :blah
43
-
44
- d = @c2.new(:id => 1, :blah => 567)
45
- p = d.parent
46
- p.class.should == @c2
47
- p.values.should == {:hey => 1}
48
-
49
- $sqls.should == ["SELECT * FROM nodes WHERE (id = 567) LIMIT 1"]
50
- end
51
-
52
- it "should support plain dataset in the from option" do
53
- @c2.one_to_one :parent, :from => MODEL_DB[:xyz]
54
-
55
- d = @c2.new(:id => 1, :parent_id => 789)
56
- p = d.parent
57
- p.class.should == Hash
58
-
59
- MODEL_DB.sqls.should == ["SELECT * FROM xyz WHERE (id = 789) LIMIT 1"]
60
- end
61
-
62
- it "should support table name in the from option" do
63
- @c2.one_to_one :parent, :from => :abc
64
-
65
- d = @c2.new(:id => 1, :parent_id => 789)
66
- p = d.parent
67
- p.class.should == Hash
68
-
69
- MODEL_DB.sqls.should == ["SELECT * FROM abc WHERE (id = 789) LIMIT 1"]
70
- end
71
-
72
- it "should return nil if key value is nil" do
73
- @c2.one_to_one :parent, :from => @c2
74
-
75
- d = @c2.new(:id => 1)
76
- d.parent.should == nil
77
- end
78
-
79
- it "should define a setter method" do
80
- @c2.one_to_one :parent, :from => @c2
81
-
82
- d = @c2.new(:id => 1)
83
- d.parent = {:id => 4321}
84
- d.values.should == {:id => 1, :parent_id => 4321}
85
- $sqls.last.should == "UPDATE nodes SET parent_id = 4321 WHERE (id = 1)"
86
-
87
- d.parent = nil
88
- d.values.should == {:id => 1, :parent_id => nil}
89
- $sqls.last.should == "UPDATE nodes SET parent_id = NULL WHERE (id = 1)"
90
-
91
- e = @c2.new(:id => 6677)
92
- d.parent = e
93
- d.values.should == {:id => 1, :parent_id => 6677}
94
- $sqls.last.should == "UPDATE nodes SET parent_id = 6677 WHERE (id = 1)"
95
- end
96
- end
97
-
98
- describe Sequel::Model, "one_to_many" do
99
-
100
- before(:each) do
101
- MODEL_DB.reset
102
-
103
- @c1 = Class.new(Sequel::Model(:attributes)) do
104
- end
105
-
106
- @c2 = Class.new(Sequel::Model(:nodes)) do
107
- end
108
- end
109
-
110
- it "should define a getter method" do
111
- @c2.one_to_many :attributes, :from => @c1, :key => :node_id
112
-
113
- n = @c2.new(:id => 1234)
114
- a = n.attributes
115
- a.should be_a_kind_of(Sequel::Dataset)
116
- a.sql.should == 'SELECT * FROM attributes WHERE (node_id = 1234)'
117
- end
118
-
119
- it "should support plain dataset in the from option" do
120
- @c2.one_to_many :attributes, :from => MODEL_DB[:xyz], :key => :node_id
121
-
122
- n = @c2.new(:id => 1234)
123
- a = n.attributes
124
- a.should be_a_kind_of(Sequel::Dataset)
125
- a.sql.should == 'SELECT * FROM xyz WHERE (node_id = 1234)'
126
- end
127
-
128
- it "should support table name in the from option" do
129
- @c2.one_to_many :attributes, :from => :abc, :key => :node_id
130
-
131
- n = @c2.new(:id => 1234)
132
- a = n.attributes
133
- a.should be_a_kind_of(Sequel::Dataset)
134
- a.sql.should == 'SELECT * FROM abc WHERE (node_id = 1234)'
135
- end
136
-
137
- it "should support implicit key names" do
138
- module Music
139
- class BlueNote < Sequel::Model
140
- one_to_many :attributes, :from => :abc
141
- end
142
- end
143
-
144
- n = Music::BlueNote.new(:id => 1234)
145
- a = n.attributes
146
- a.should be_a_kind_of(Sequel::Dataset)
147
- a.sql.should == 'SELECT * FROM abc WHERE (blue_note_id = 1234)'
148
- end
149
- end