sequel 0.4.5 → 0.5

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.
@@ -1,107 +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(:sessions)
8
- # end
9
- #
10
- # class Node < Sequel::Model(:nodes)
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
- # deprecation
32
- if opts[:class]
33
- warn "The :class option has been deprecated. Please use :from instead."
34
- opts[:from] = opts[:class]
35
- end
36
-
37
- from = opts[:from]
38
- from || (raise Error, "No association source defined (use :from option)")
39
- key = opts[:key] || (name.to_s + ID_POSTFIX).to_sym
40
-
41
- setter_name = "#{name}=".to_sym
42
-
43
- case from
44
- when Symbol
45
- class_def(name) {(k = @values[key]) ? db[from][:id => k] : nil}
46
- when Sequel::Dataset
47
- class_def(name) {(k = @values[key]) ? from[:id => k] : nil}
48
- else
49
- class_def(name) {(k = @values[key]) ? from[k] : nil}
50
- end
51
- class_def(setter_name) do |v|
52
- case v
53
- when nil
54
- set(key => nil)
55
- when Sequel::Model
56
- set(key => v.pk)
57
- when Hash
58
- set(key => v[:id])
59
- end
60
- end
61
-
62
- # define_method name, &eval(ONE_TO_ONE_PROC % [key, from])
63
- end
64
-
65
- # Creates a 1-N relationship by defining an association method, e.g.:
66
- #
67
- # class Book < Sequel::Model(:books)
68
- # end
69
- #
70
- # class Author < Sequel::Model(:authors)
71
- # one_to_many :books, :from => Book
72
- # # which is equivalent to
73
- # def books
74
- # Book.filter(:author_id => id)
75
- # end
76
- # end
77
- #
78
- # You can also set the foreign key explicitly by including a :key option:
79
- #
80
- # one_to_many :books, :from => Book, :key => :author_id
81
- #
82
- def self.one_to_many(name, opts)
83
- # deprecation
84
- if opts[:class]
85
- warn "The :class option has been deprecated. Please use :from instead."
86
- opts[:from] = opts[:class]
87
- end
88
- # deprecation
89
- if opts[:on]
90
- warn "The :on option has been deprecated. Please use :key instead."
91
- opts[:key] = opts[:on]
92
- end
93
-
94
-
95
- from = opts[:from]
96
- from || (raise Error, "No association source defined (use :from option)")
97
- key = opts[:key] || (self.to_s + ID_POSTFIX).to_sym
98
-
99
- case from
100
- when Symbol
101
- class_def(name) {db[from].filter(key => pk)}
102
- else
103
- class_def(name) {from.filter(key => pk)}
104
- end
105
- end
106
- end
107
- end
@@ -1,52 +0,0 @@
1
- module Sequel
2
- class Model
3
- # Defines a table schema (see Schema::Generator for more information).
4
- #
5
- # This is only needed if you want to use the create_table or drop_table
6
- # methods.
7
- def self.set_schema(name = nil, &block)
8
- name ? set_dataset(db[name]) : name = table_name
9
- @schema = Schema::Generator.new(db, &block)
10
- if @schema.primary_key_name
11
- set_primary_key @schema.primary_key_name
12
- end
13
- end
14
-
15
- # Returns table schema for direct descendant of Model.
16
- def self.schema
17
- @schema || ((superclass != Model) && (superclass.schema))
18
- end
19
-
20
- # Returns name of table.
21
- def self.table_name
22
- dataset.opts[:from].first
23
- end
24
-
25
- # Returns true if table exists, false otherwise.
26
- def self.table_exists?
27
- db.table_exists?(table_name)
28
- end
29
-
30
- # Creates table.
31
- def self.create_table
32
- db.create_table_sql_list(table_name, *schema.create_info).each {|s| db << s}
33
- end
34
-
35
- # Drops table.
36
- def self.drop_table
37
- db.execute db.drop_table_sql(table_name)
38
- end
39
-
40
- # Like create_table but invokes drop_table when table_exists? is true.
41
- def self.create_table!
42
- drop_table if table_exists?
43
- create_table
44
- end
45
-
46
- # Deprecated, use create_table! instead.
47
- def self.recreate_table
48
- warn "Model.recreate_table is deprecated. Please use Model.create_table! instead."
49
- create_table!
50
- end
51
- end
52
- end
@@ -1,117 +0,0 @@
1
- module Sequel
2
- class Model
3
- # =Basic Sequel Validations
4
- #
5
- # Sequel validations are based on the Validatable gem http://validatable.rubyforge.org/
6
- #
7
- # To assign default validations to a sequel model:
8
- #
9
- # class MyModel < SequelModel(:items)
10
- # validates do
11
- # format_of...
12
- # presence_of...
13
- # acceptance_of...
14
- # confirmation_of...
15
- # length_of...
16
- # true_for...
17
- # numericality_of...
18
- # format_of...
19
- # validates_base...
20
- # validates_each...
21
- # end
22
- # end
23
- #
24
- # You may also perform the usual 'longhand' way to assign default model validates
25
- # directly within the model class itself:
26
- #
27
- # class MyModel < SequelModel(:items)
28
- # validates_format_of...
29
- # validates_presence_of...
30
- # validates_acceptance_of...
31
- # validates_confirmation_of...
32
- # validates_length_of...
33
- # validates_true_for...
34
- # validates_numericality_of...
35
- # validates_format_of...
36
- # validates_base...
37
- # validates_each...
38
- # end
39
- #
40
- # Each validation allows for arguments:
41
- # TODO: fill the argument options in here
42
- #
43
- # =Advanced Sequel Validations
44
- #
45
- # TODO: verify that advanced validates work as stated (aka write specs)
46
- # NOTE: experimental
47
- #
48
- # To store validates for conditional usage simply specify a name with which to store them
49
- # class User < Sequel::Model
50
- #
51
- # # This set of validates becomes stored as :default and gets injected into the model.
52
- # validates do
53
- # # standard validates calls
54
- # end
55
- #
56
- # validates(:registration) do
57
- # # user registration specific validates
58
- # end
59
- #
60
- # validates(:promotion) do
61
- # # user promotion validates
62
- # end
63
- #
64
- # end
65
- #
66
- # To use the above validates:
67
- #
68
- # @user.valid? # Runs the default validations only.
69
- # @user.valid?(:registration) # Runs both default and registration validations
70
- # @user.valid?(:promotion) # Runs both default and promotion validations
71
- #
72
- # You may determine whether the model has validates via:
73
- #
74
- # has_validations? # will return true / false based on existence of validations on the model.
75
- #
76
- # You may also retrieve the validations block if needed:
77
- #
78
- # validates(:registration) # returns the registration validation block.
79
- #
80
- # validates() method parameters:
81
- # a validations block - runs the validations block on the model & stores as :default
82
- # a name and a validations block - stores the block under the name
83
- # a name - returns a stored block of that name or nil
84
- # nothing - returns true / false based on if validations exist for the model.
85
- #
86
- module Validations
87
- class Generator
88
- def initialize(model_class ,&block)
89
- @model_class = model_class
90
- instance_eval(&block)
91
- end
92
-
93
- def method_missing(method, *args)
94
- method = :"validates_#{method}"
95
- @model_class.send(method, *args)
96
- end
97
- end
98
- end
99
-
100
- begin
101
- require "validatable"
102
- include ::Validatable
103
- def self.validates(&block)
104
- Validations::Generator.new(self, &block)
105
- end
106
- # return true if there are validations stored, false otherwise
107
- def self.has_validations?
108
- validations.length > 0 ? true : false
109
- end
110
- rescue LoadError
111
- STDERR.puts <<-MESSAGE
112
- Install the validatable gem in order to use Sequel Model validations
113
- If you would like model validations to work, install the validatable gem
114
- MESSAGE
115
- end
116
- end
117
- end
@@ -1,148 +0,0 @@
1
- describe "Model attribute setters" do
2
-
3
- before(:each) do
4
- MODEL_DB.reset
5
-
6
- @c = Class.new(Sequel::Model(:items)) do
7
- def columns
8
- [:id, :x, :y]
9
- end
10
- end
11
- end
12
-
13
- it "should mark the column value as changed" do
14
- o = @c.new
15
- o.changed_columns.should == []
16
-
17
- o.x = 2
18
- o.changed_columns.should == [:x]
19
-
20
- o.y = 3
21
- o.changed_columns.should == [:x, :y]
22
-
23
- o.changed_columns.clear
24
-
25
- o[:x] = 2
26
- o.changed_columns.should == [:x]
27
-
28
- o[:y] = 3
29
- o.changed_columns.should == [:x, :y]
30
- end
31
-
32
- end
33
-
34
- describe "Model#serialize" do
35
-
36
- before(:each) do
37
- MODEL_DB.reset
38
- end
39
-
40
- it "should translate values to YAML when creating records" do
41
- @c = Class.new(Sequel::Model(:items)) do
42
- no_primary_key
43
- serialize :abc
44
- end
45
-
46
- @c.create(:abc => 1)
47
- @c.create(:abc => "hello")
48
-
49
- MODEL_DB.sqls.should == [ \
50
- "INSERT INTO items (abc) VALUES ('--- 1\n')", \
51
- "INSERT INTO items (abc) VALUES ('--- hello\n')", \
52
- ]
53
- end
54
-
55
- it "should support calling after the class is defined" do
56
- @c = Class.new(Sequel::Model(:items)) do
57
- no_primary_key
58
- end
59
-
60
- @c.serialize :def
61
-
62
- @c.create(:def => 1)
63
- @c.create(:def => "hello")
64
-
65
- MODEL_DB.sqls.should == [ \
66
- "INSERT INTO items (def) VALUES ('--- 1\n')", \
67
- "INSERT INTO items (def) VALUES ('--- hello\n')", \
68
- ]
69
- end
70
-
71
- it "should support using the Marshal format" do
72
- @c = Class.new(Sequel::Model(:items)) do
73
- no_primary_key
74
- serialize :abc, :format => :marshal
75
- end
76
-
77
- @c.create(:abc => 1)
78
- @c.create(:abc => "hello")
79
-
80
- MODEL_DB.sqls.should == [ \
81
- "INSERT INTO items (abc) VALUES ('\004\bi\006')", \
82
- "INSERT INTO items (abc) VALUES ('\004\b\"\nhello')", \
83
- ]
84
- end
85
-
86
- it "should translate values to and from YAML using accessor methods" do
87
- @c = Class.new(Sequel::Model(:items)) do
88
- serialize :abc, :def
89
- end
90
-
91
- ds = @c.dataset
92
- ds.extend(Module.new {
93
- attr_accessor :raw
94
-
95
- def fetch_rows(sql, &block)
96
- block.call(@raw)
97
- end
98
-
99
- @@sqls = nil
100
-
101
- def insert(*args)
102
- @@sqls = insert_sql(*args)
103
- end
104
-
105
- def update(*args)
106
- @@sqls = update_sql(*args)
107
- end
108
-
109
- def sqls
110
- @@sqls
111
- end
112
-
113
- def columns
114
- [:id, :abc, :def]
115
- end
116
- }
117
- )
118
-
119
- ds.raw = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
120
- o = @c.first
121
- o.id.should == 1
122
- o.abc.should == 1
123
- o.def.should == "hello"
124
-
125
- o.set(:abc => 23)
126
- ds.sqls.should == "UPDATE items SET abc = '#{23.to_yaml}' WHERE (id = 1)"
127
-
128
- ds.raw = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
129
- o = @c.create(:abc => [1, 2, 3])
130
- ds.sqls.should == "INSERT INTO items (abc) VALUES ('#{[1, 2, 3].to_yaml}')"
131
- end
132
-
133
- end
134
-
135
- describe Sequel::Model, "super_dataset" do
136
-
137
- before(:each) do
138
- MODEL_DB.reset
139
- class SubClass < Sequel::Model(:items) ; end
140
- end
141
-
142
- it "should call the superclass's dataset" do
143
- SubClass.should_receive(:superclass).exactly(3).times.and_return(Sequel::Model(:items))
144
- Sequel::Model(:items).should_receive(:dataset)
145
- SubClass.super_dataset
146
- end
147
-
148
- end
@@ -1,148 +0,0 @@
1
- describe Sequel::Model, "caching" do
2
-
3
- before(:each) do
4
- MODEL_DB.reset
5
-
6
- @cache_class = Class.new(Hash) do
7
- attr_accessor :ttl
8
- def set(k, v, ttl); self[k] = v; @ttl = ttl; end
9
- def get(k); self[k]; end
10
- end
11
- cache = @cache_class.new
12
- @cache = cache
13
-
14
- @c = Class.new(Sequel::Model(:items)) do
15
- set_cache cache
16
-
17
- def self.columns
18
- [:name, :id]
19
- end
20
- end
21
-
22
- $cache_dataset_row = {:name => 'sharon', :id => 1}
23
- @dataset = @c.dataset
24
- $sqls = []
25
- @dataset.extend(Module.new {
26
- def fetch_rows(sql)
27
- $sqls << sql
28
- yield $cache_dataset_row
29
- end
30
-
31
- def update(values)
32
- $sqls << update_sql(values)
33
- $cache_dataset_row.merge!(values)
34
- end
35
-
36
- def delete
37
- $sqls << delete_sql
38
- end
39
- })
40
- end
41
-
42
- it "should set the model's cache store" do
43
- @c.cache_store.should be(@cache)
44
- end
45
-
46
- it "should have a default ttl of 3600" do
47
- @c.cache_ttl.should == 3600
48
- end
49
-
50
- it "should take a ttl option" do
51
- @c.set_cache @cache, :ttl => 1234
52
- @c.cache_ttl.should == 1234
53
- end
54
-
55
- it "should offer a set_cache_ttl method for setting the ttl" do
56
- @c.cache_ttl.should == 3600
57
- @c.set_cache_ttl 1234
58
- @c.cache_ttl.should == 1234
59
- end
60
-
61
- it "should generate a cache key appropriate to the class" do
62
- m = @c.new
63
- m.values[:id] = 1
64
- m.cache_key.should == "#{m.class}:1"
65
-
66
- # custom primary key
67
- @c.set_primary_key :ttt
68
- m = @c.new
69
- m.values[:ttt] = 333
70
- m.cache_key.should == "#{m.class}:333"
71
-
72
- # composite primary key
73
- @c.set_primary_key [:a, :b, :c]
74
- m = @c.new
75
- m.values[:a] = 123
76
- m.values[:c] = 456
77
- m.values[:b] = 789
78
- m.cache_key.should == "#{m.class}:123,789,456"
79
- end
80
-
81
- it "should raise error if attempting to generate cache_key and primary key value is null" do
82
- m = @c.new
83
- proc {m.cache_key}.should raise_error(Sequel::Error)
84
-
85
- m.values[:id] = 1
86
- proc {m.cache_key}.should_not raise_error(Sequel::Error)
87
- end
88
-
89
- it "should set the cache when reading from the database" do
90
- $sqls.should == []
91
- @cache.should be_empty
92
-
93
- m = @c[1]
94
- $sqls.should == ['SELECT * FROM items WHERE (id = 1) LIMIT 1']
95
- m.values.should == $cache_dataset_row
96
- @cache[m.cache_key].should == m
97
-
98
- # read from cache
99
- m2 = @c[1]
100
- $sqls.should == ['SELECT * FROM items WHERE (id = 1) LIMIT 1']
101
- m2.should == m
102
- m2.values.should == $cache_dataset_row
103
- end
104
-
105
- it "should delete the cache when writing to the database" do
106
- # fill the cache
107
- m = @c[1]
108
- @cache[m.cache_key].should == m
109
-
110
- m.set(:name => 'tutu')
111
- @cache.has_key?(m.cache_key).should be_false
112
- $sqls.last.should == "UPDATE items SET name = 'tutu' WHERE (id = 1)"
113
-
114
- m = @c[1]
115
- @cache[m.cache_key].should == m
116
- m.name = 'hey'
117
- m.save
118
- @cache.has_key?(m.cache_key).should be_false
119
- $sqls.last.should == "UPDATE items SET name = 'hey', id = 1 WHERE (id = 1)"
120
- end
121
-
122
- it "should delete the cache when deleting the record" do
123
- # fill the cache
124
- m = @c[1]
125
- @cache[m.cache_key].should == m
126
-
127
- m.delete
128
- @cache.has_key?(m.cache_key).should be_false
129
- $sqls.last.should == "DELETE FROM items WHERE (id = 1)"
130
- end
131
-
132
- it "should support #[] as a shortcut to #find with hash" do
133
- m = @c[:id => 3]
134
- @cache[m.cache_key].should be_nil
135
- $sqls.last.should == "SELECT * FROM items WHERE (id = 3) LIMIT 1"
136
-
137
- m = @c[1]
138
- @cache[m.cache_key].should == m
139
- $sqls.should == ["SELECT * FROM items WHERE (id = 3) LIMIT 1", \
140
- "SELECT * FROM items WHERE (id = 1) LIMIT 1"]
141
-
142
- @c[:id => 4]
143
- $sqls.should == ["SELECT * FROM items WHERE (id = 3) LIMIT 1", \
144
- "SELECT * FROM items WHERE (id = 1) LIMIT 1", \
145
- "SELECT * FROM items WHERE (id = 4) LIMIT 1"]
146
- end
147
-
148
- end