sequel 0.4.5 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -136,15 +136,14 @@ context "A simple dataset" do
136
136
  dbb = Sequel::Database.new
137
137
 
138
138
  @c = Class.new(Sequel::Model) do
139
- db = dbb
140
- set_dataset Sequel::Dataset.new(dbb)
139
+ attr_accessor :values
141
140
  end
142
141
 
143
- v = @c.new(:a => 1)
142
+ v = @c.new; v.values = {:a => 1}
144
143
 
145
144
  @dataset.insert_sql(v).should == "INSERT INTO test (a) VALUES (1)"
146
145
 
147
- v = @c.new({})
146
+ v = @c.new; v.values = {}
148
147
  @dataset.insert_sql(v).should == "INSERT INTO test DEFAULT VALUES"
149
148
  end
150
149
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
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: 2007-12-25 00:00:00 +02:00
12
+ date: 2007-12-30 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: "0"
41
41
  version:
42
- description: Lightweight ORM library for Ruby
42
+ description: Database access for Ruby
43
43
  email: ciconia@gmail.com
44
44
  executables:
45
45
  - sequel
@@ -67,16 +67,6 @@ files:
67
67
  - spec/database_spec.rb
68
68
  - spec/dataset_spec.rb
69
69
  - spec/migration_spec.rb
70
- - spec/model
71
- - spec/model/base_spec.rb
72
- - spec/model/caching_spec.rb
73
- - spec/model/hooks_spec.rb
74
- - spec/model/plugins_spec.rb
75
- - spec/model/record_spec.rb
76
- - spec/model/relations_spec.rb
77
- - spec/model/schema_spec.rb
78
- - spec/model/validations_spec.rb
79
- - spec/model_spec.rb
80
70
  - spec/pretty_table_spec.rb
81
71
  - spec/rcov.opts
82
72
  - spec/schema_generator_spec.rb
@@ -116,15 +106,6 @@ files:
116
106
  - lib/sequel/exceptions.rb
117
107
  - lib/sequel/informix.rb
118
108
  - lib/sequel/migration.rb
119
- - lib/sequel/model
120
- - lib/sequel/model/base.rb
121
- - lib/sequel/model/caching.rb
122
- - lib/sequel/model/hooks.rb
123
- - lib/sequel/model/plugins.rb
124
- - lib/sequel/model/record.rb
125
- - lib/sequel/model/relations.rb
126
- - lib/sequel/model/schema.rb
127
- - lib/sequel/model/validations.rb
128
109
  - lib/sequel/model.rb
129
110
  - lib/sequel/mysql.rb
130
111
  - lib/sequel/odbc.rb
@@ -145,7 +126,7 @@ post_install_message:
145
126
  rdoc_options:
146
127
  - --quiet
147
128
  - --title
148
- - "Sequel: Concise ORM for Ruby"
129
+ - "Sequel: Database access for Ruby"
149
130
  - --opname
150
131
  - index.html
151
132
  - --line-numbers
@@ -176,6 +157,6 @@ rubyforge_project: sequel
176
157
  rubygems_version: 1.0.1
177
158
  signing_key:
178
159
  specification_version: 2
179
- summary: Lightweight ORM library for Ruby
160
+ summary: Database access for Ruby
180
161
  test_files: []
181
162
 
@@ -1,97 +0,0 @@
1
- module Sequel
2
- class Model
3
- # Returns the database associated with the Model class.
4
- def self.db
5
- @db ||= (superclass != Object) && superclass.db or
6
- raise Error, "No database associated with #{self}"
7
- end
8
-
9
- # Sets the database associated with the Model class.
10
- def self.db=(db)
11
- @db = db
12
- end
13
-
14
- # Called when a database is opened in order to automatically associate the
15
- # first opened database with model classes.
16
- def self.database_opened(db)
17
- @db = db if (self == Model) && !@db
18
- end
19
-
20
- # Returns the dataset associated with the Model class.
21
- def self.dataset
22
- @dataset || super_dataset or
23
- raise Error, "No dataset associated with #{self}"
24
- end
25
-
26
- def self.super_dataset # :nodoc:
27
- superclass.dataset if superclass and superclass.respond_to? :dataset
28
- end
29
-
30
- # Returns the columns in the result set in their original order.
31
- #
32
- # See Dataset#columns for more information.
33
- def self.columns
34
- @columns ||= @dataset.columns or
35
- raise Error, "Could not fetch columns for #{self}"
36
- end
37
-
38
- # Sets the dataset associated with the Model class.
39
- def self.set_dataset(ds)
40
- @db = ds.db
41
- @dataset = ds
42
- @dataset.set_model(self)
43
- @dataset.transform(@transform) if @transform
44
- end
45
-
46
- # Returns the database assoiated with the object's Model class.
47
- def db
48
- @db ||= model.db
49
- end
50
-
51
- # Returns the dataset assoiated with the object's Model class.
52
- #
53
- # See Dataset for more information.
54
- def dataset
55
- model.dataset
56
- end
57
-
58
- # Returns the columns associated with the object's Model class.
59
- def columns
60
- model.columns
61
- end
62
-
63
- # Serializes column with YAML or through marshalling.
64
- def self.serialize(*columns)
65
- format = columns.pop[:format] if Hash === columns.last
66
- format ||= :yaml
67
-
68
- @transform = columns.inject({}) do |m, c|
69
- m[c] = format
70
- m
71
- end
72
- @dataset.transform(@transform) if @dataset
73
- end
74
- end
75
-
76
- # Lets you create a Model class with its table name already set or reopen
77
- # an existing Model.
78
- #
79
- # Makes given dataset inherited.
80
- #
81
- # === Example:
82
- # class Comment < Sequel::Model(:comments)
83
- # table_name # => :comments
84
- #
85
- # # ...
86
- #
87
- # end
88
- def self.Model(source)
89
- @models ||= {}
90
- @models[source] ||= Class.new(Sequel::Model) do
91
- meta_def(:inherited) do |c|
92
- c.set_dataset(source.is_a?(Dataset) ? source : c.db[source])
93
- end
94
- end
95
- end
96
-
97
- end
@@ -1,42 +0,0 @@
1
- module Sequel
2
- class Model
3
- def self.set_cache(store, opts = {})
4
- @cache_store = store
5
- if (ttl = opts[:ttl])
6
- set_cache_ttl(ttl)
7
- end
8
-
9
- meta_def(:[]) do |*args|
10
- if (args.size == 1) && (Hash === (h = args.first))
11
- return dataset[h]
12
- end
13
-
14
- unless obj = @cache_store.get(cache_key_from_values(args))
15
- obj = dataset[primary_key_hash((args.size == 1) ? args.first : args)]
16
- @cache_store.set(cache_key_from_values(args), obj, cache_ttl)
17
- end
18
- obj
19
- end
20
-
21
- class_def(:set) {|v| store.delete(cache_key); super}
22
- class_def(:save) {store.delete(cache_key); super}
23
- class_def(:delete) {store.delete(cache_key); super}
24
- end
25
-
26
- def self.set_cache_ttl(ttl)
27
- @cache_ttl = ttl
28
- end
29
-
30
- def self.cache_store
31
- @cache_store
32
- end
33
-
34
- def self.cache_ttl
35
- @cache_ttl ||= 3600
36
- end
37
-
38
- def self.cache_key_from_values(values)
39
- "#{self}:#{values.join(',')}"
40
- end
41
- end
42
- end
@@ -1,122 +0,0 @@
1
- module Sequel
2
- class Model
3
- # This Hash translates verbs to methodnames used in chain manipulation
4
- # methods.
5
- VERB_TO_METHOD = {:prepend => :unshift, :append => :push}
6
-
7
- # Returns @hooks which is an instance of Hash with its hook identifier
8
- # (Symbol) as key and the chain of hooks (Array) as value.
9
- #
10
- # If it is not already set it'll be with an empty set of hooks.
11
- # This behaviour will change in the future to allow inheritance.
12
- #
13
- # For the time being, you should be able to do:
14
- #
15
- # class A < Sequel::Model(:a)
16
- # before_save { 'Do something...' }
17
- # end
18
- #
19
- # class B < A
20
- # @hooks = superclass.hooks.clone
21
- # before_save # => [#<Proc:0x0000c6e8@(example.rb):123>]
22
- # end
23
- #
24
- # In this case you should remember that the clone doesn't create any new
25
- # instances of your chains, so if you change the chain here it changes in
26
- # its superclass, too.
27
- def self.hooks
28
- @hooks ||= Hash.new { |h, k| h[k] = [] }
29
- end
30
-
31
- # Adds block to chain of Hooks for <tt>:before_save</tt>.
32
- # It can either be prepended (default) or appended.
33
- #
34
- # Returns the chain itself.
35
- #
36
- # Valid verbs are <tt>:prepend</tt> and <tt>:append</tt>.
37
- def self.before_save(verb = :prepend, &block)
38
- hooks[:before_save].send VERB_TO_METHOD.fetch(verb), block if block
39
- hooks[:before_save]
40
- end
41
- # Adds block to chain of Hooks for <tt>:before_create</tt>.
42
- # It can either be prepended (default) or appended.
43
- #
44
- # Returns the chain itself.
45
- #
46
- # Valid verbs are <tt>:prepend</tt> and <tt>:append</tt>.
47
- def self.before_create(verb = :prepend, &block)
48
- hooks[:before_create].send VERB_TO_METHOD.fetch(verb), block if block
49
- hooks[:before_create]
50
- end
51
- # Adds block to chain of Hooks for <tt>:before_update</tt>.
52
- # It can either be prepended (default) or appended.
53
- #
54
- # Returns the chain itself.
55
- #
56
- # Valid verbs are <tt>:prepend</tt> and <tt>:append</tt>.
57
- def self.before_update(verb = :prepend, &block)
58
- hooks[:before_update].send VERB_TO_METHOD.fetch(verb), block if block
59
- hooks[:before_update]
60
- end
61
- # Adds block to chain of Hooks for <tt>:before_destroy</tt>.
62
- # It can either be prepended (default) or appended.
63
- #
64
- # Returns the chain itself.
65
- #
66
- # Valid verbs are <tt>:prepend</tt> and <tt>:append</tt>.
67
- def self.before_destroy(verb = :prepend, &block)
68
- hooks[:before_destroy].send VERB_TO_METHOD.fetch(verb), block if block
69
- hooks[:before_destroy]
70
- end
71
-
72
- # Adds block to chain of Hooks for <tt>:after_save</tt>.
73
- # It can either be prepended or appended (default).
74
- #
75
- # Returns the chain itself.
76
- #
77
- # Valid verbs are <tt>:prepend</tt> and <tt>:append</tt>.
78
- def self.after_save(verb = :append, &block)
79
- hooks[:after_save].send VERB_TO_METHOD.fetch(verb), block if block
80
- hooks[:after_save]
81
- end
82
- # Adds block to chain of Hooks for <tt>:after_create</tt>.
83
- # It can either be prepended or appended (default).
84
- #
85
- # Returns the chain itself.
86
- #
87
- # Valid verbs are <tt>:prepend</tt> and <tt>:append</tt>.
88
- def self.after_create(verb = :append, &block)
89
- hooks[:after_create].send VERB_TO_METHOD.fetch(verb), block if block
90
- hooks[:after_create]
91
- end
92
- # Adds block to chain of Hooks for <tt>:after_update</tt>.
93
- # It can either be prepended or appended (default).
94
- #
95
- # Returns the chain itself.
96
- #
97
- # Valid verbs are <tt>:prepend</tt> and <tt>:append</tt>.
98
- def self.after_update(verb = :append, &block)
99
- hooks[:after_update].send VERB_TO_METHOD.fetch(verb), block if block
100
- hooks[:after_update]
101
- end
102
- # Adds block to chain of Hooks for <tt>:after_destroy</tt>.
103
- # It can either be prepended or appended (default).
104
- #
105
- # Returns the chain itself.
106
- #
107
- # Valid verbs are <tt>:prepend</tt> and <tt>:append</tt>.
108
- def self.after_destroy(verb = :append, &block)
109
- hooks[:after_destroy].send VERB_TO_METHOD.fetch(verb), block if block
110
- hooks[:after_destroy]
111
- end
112
-
113
- # Evaluates specified chain of Hooks through <tt>instance_eval</tt>.
114
- def run_hooks(key)
115
- model.hooks[key].each {|h| instance_eval(&h)}
116
- end
117
-
118
- def self.has_hooks?(key)
119
- hooks[key] && !hooks[key].empty?
120
- end
121
- end
122
- end
@@ -1,44 +0,0 @@
1
- module Sequel
2
- module Plugins; end
3
-
4
- class Model
5
- class << self
6
- # Loads a plugin for use with the model class, passing optional arguments
7
- # to the plugin.
8
- def is(plugin, *args)
9
- m = plugin_module(plugin)
10
- if m.respond_to?(:apply)
11
- m.apply(self, *args)
12
- end
13
- if m.const_defined?("InstanceMethods")
14
- class_def(:"#{plugin}_opts") {args.first}
15
- include(m::InstanceMethods)
16
- end
17
- if m.const_defined?("ClassMethods")
18
- meta_def(:"#{plugin}_opts") {args.first}
19
- metaclass.send(:include, m::ClassMethods)
20
- end
21
- if m.const_defined?("DatasetMethods")
22
- dataset.meta_def(:"#{plugin}_opts") {args.first}
23
- dataset.metaclass.send(:include, m::DatasetMethods)
24
- end
25
- end
26
- alias_method :is_a, :is
27
-
28
- # Returns the module for the specified plugin. If the module is not
29
- # defined, the corresponding plugin gem is automatically loaded.
30
- def plugin_module(plugin)
31
- module_name = plugin.to_s.gsub(/(^|_)(.)/) {$2.upcase}
32
- if not Sequel::Plugins.const_defined?(module_name)
33
- require plugin_gem(plugin)
34
- end
35
- Sequel::Plugins.const_get(module_name)
36
- end
37
-
38
- # Returns the gem name for the given plugin.
39
- def plugin_gem(plugin)
40
- "sequel_#{plugin}"
41
- end
42
- end
43
- end
44
- end
@@ -1,309 +0,0 @@
1
- module Sequel
2
- class Model
3
- attr_reader :values
4
- attr_reader :changed_columns
5
-
6
- # Returns value of attribute.
7
- def [](column)
8
- @values[column]
9
- end
10
- # Sets value of attribute and marks the column as changed.
11
- def []=(column, value)
12
- @values[column] = value
13
- @changed_columns << column unless @changed_columns.include?(column)
14
- end
15
-
16
- # Enumerates through all attributes.
17
- #
18
- # === Example:
19
- # Ticket.find(7).each { |k, v| puts "#{k} => #{v}" }
20
- def each(&block)
21
- @values.each(&block)
22
- end
23
- # Returns attribute names.
24
- def keys
25
- @values.keys
26
- end
27
-
28
- # Returns value for <tt>:id</tt> attribute.
29
- def id
30
- @values[:id]
31
- end
32
-
33
- # Compares model instances by values.
34
- def ==(obj)
35
- (obj.class == model) && (obj.values == @values)
36
- end
37
-
38
- # Compares model instances by pkey.
39
- def ===(obj)
40
- (obj.class == model) && (obj.pk == pk)
41
- end
42
-
43
- # Returns key for primary key.
44
- def self.primary_key
45
- :id
46
- end
47
-
48
- # Returns primary key attribute hash.
49
- def self.primary_key_hash(value)
50
- {:id => value}
51
- end
52
-
53
- # Sets primary key, regular and composite are possible.
54
- #
55
- # == Example:
56
- # class Tagging < Sequel::Model(:taggins)
57
- # # composite key
58
- # set_primary_key :taggable_id, :tag_id
59
- # end
60
- #
61
- # class Person < Sequel::Model(:person)
62
- # # regular key
63
- # set_primary_key :person_id
64
- # end
65
- #
66
- # <i>You can even set it to nil!</i>
67
- def self.set_primary_key(*key)
68
- # if k is nil, we go to no_primary_key
69
- if key.empty? || (key.size == 1 && key.first == nil)
70
- return no_primary_key
71
- end
72
-
73
- # backwards compat
74
- key = (key.length == 1) ? key[0] : key.flatten
75
-
76
- # redefine primary_key
77
- meta_def(:primary_key) {key}
78
-
79
- unless key.is_a? Array # regular primary key
80
- class_def(:this) do
81
- @this ||= dataset.filter(key => @values[key]).limit(1).naked
82
- end
83
- class_def(:pk) do
84
- @pk ||= @values[key]
85
- end
86
- class_def(:pk_hash) do
87
- @pk ||= {key => @values[key]}
88
- end
89
- class_def(:cache_key) do
90
- pk = @values[key] || (raise Error, 'no primary key for this record')
91
- @cache_key ||= "#{self.class}:#{pk}"
92
- end
93
- meta_def(:primary_key_hash) do |v|
94
- {key => v}
95
- end
96
- else # composite key
97
- exp_list = key.map {|k| "#{k.inspect} => @values[#{k.inspect}]"}
98
- block = eval("proc {@this ||= self.class.dataset.filter(#{exp_list.join(',')}).limit(1).naked}")
99
- class_def(:this, &block)
100
-
101
- exp_list = key.map {|k| "@values[#{k.inspect}]"}
102
- block = eval("proc {@pk ||= [#{exp_list.join(',')}]}")
103
- class_def(:pk, &block)
104
-
105
- exp_list = key.map {|k| "#{k.inspect} => @values[#{k.inspect}]"}
106
- block = eval("proc {@this ||= {#{exp_list.join(',')}}}")
107
- class_def(:pk_hash, &block)
108
-
109
- exp_list = key.map {|k| '#{@values[%s]}' % k.inspect}.join(',')
110
- block = eval('proc {@cache_key ||= "#{self.class}:%s"}' % exp_list)
111
- class_def(:cache_key, &block)
112
-
113
- meta_def(:primary_key_hash) do |v|
114
- key.inject({}) {|m, i| m[i] = v.shift; m}
115
- end
116
- end
117
- end
118
-
119
- def self.no_primary_key #:nodoc:
120
- meta_def(:primary_key) {nil}
121
- meta_def(:primary_key_hash) {|v| raise Error, "#{self} does not have a primary key"}
122
- class_def(:this) {raise Error, "No primary key is associated with this model"}
123
- class_def(:pk) {raise Error, "No primary key is associated with this model"}
124
- class_def(:pk_hash) {raise Error, "No primary key is associated with this model"}
125
- class_def(:cache_key) {raise Error, "No primary key is associated with this model"}
126
- end
127
-
128
- # Creates new instance with values set to passed-in Hash ensuring that
129
- # new? returns true.
130
- def self.create(values = {})
131
- db.transaction do
132
- obj = new(values, true)
133
- obj.save
134
- obj
135
- end
136
- end
137
-
138
- class << self
139
- def create_with_params(params)
140
- create(params.reject {|k, v| !columns.include?(k.to_sym)})
141
- end
142
- alias_method :create_with, :create_with_params
143
- end
144
-
145
- # Returns (naked) dataset bound to current instance.
146
- def this
147
- @this ||= self.class.dataset.filter(:id => @values[:id]).limit(1).naked
148
- end
149
-
150
- # Returns a key unique to the underlying record for caching
151
- def cache_key
152
- pk = @values[:id] || (raise Error, 'no primary key for this record')
153
- @cache_key ||= "#{self.class}:#{pk}"
154
- end
155
-
156
- # Returns primary key column(s) for object's Model class.
157
- def primary_key
158
- @primary_key ||= self.class.primary_key
159
- end
160
-
161
- # Returns value for primary key.
162
- def pkey
163
- warn "Model#pkey is deprecated. Please use Model#pk instead."
164
- @pkey ||= @values[self.class.primary_key]
165
- end
166
-
167
- # Returns the primary key value identifying the model instance. Stock implementation.
168
- def pk
169
- @pk ||= @values[:id]
170
- end
171
-
172
- # Returns a hash identifying the model instance. Stock implementation.
173
- def pk_hash
174
- @pk_hash ||= {:id => @values[:id]}
175
- end
176
-
177
- # Creates new instance with values set to passed-in Hash.
178
- #
179
- # This method guesses whether the record exists when
180
- # <tt>new_record</tt> is set to false.
181
- def initialize(values = {}, new_record = false, &block)
182
- @values = values
183
- @changed_columns = []
184
-
185
- @new = new_record
186
- unless @new # determine if it's a new record
187
- k = self.class.primary_key
188
- # if there's no primary key for the model class, or
189
- # @values doesn't contain a primary key value, then
190
- # we regard this instance as new.
191
- @new = (k == nil) || (!(Array === k) && !@values[k])
192
- end
193
-
194
- block[self] if block
195
- end
196
-
197
- # Returns true if the current instance represents a new record.
198
- def new?
199
- @new
200
- end
201
- alias :new_record? :new?
202
-
203
- # Returns true when current instance exists, false otherwise.
204
- def exists?
205
- this.count > 0
206
- end
207
-
208
- # Creates or updates the associated record. This method can also
209
- # accept a list of specific columns to update.
210
- def save(*columns)
211
- run_hooks(:before_save)
212
- if @new
213
- run_hooks(:before_create)
214
- iid = model.dataset.insert(@values)
215
- # if we have a regular primary key and it's not set in @values,
216
- # we assume it's the last inserted id
217
- if (pk = primary_key) && !(Array === pk) && !@values[pk]
218
- @values[pk] = iid
219
- end
220
- if pk
221
- @this = nil # remove memoized this dataset
222
- refresh
223
- end
224
- @new = false
225
- run_hooks(:after_create)
226
- else
227
- run_hooks(:before_update)
228
- if columns.empty?
229
- this.update(@values)
230
- @changed_columns = []
231
- else # update only the specified columns
232
- this.update(@values.reject {|k, v| !columns.include?(k)})
233
- @changed_columns.reject! {|c| columns.include?(c)}
234
- end
235
- run_hooks(:after_update)
236
- end
237
- run_hooks(:after_save)
238
- self
239
- end
240
-
241
- # Saves only changed columns or does nothing if no columns are marked as
242
- # chanaged.
243
- def save_changes
244
- save(*@changed_columns) unless @changed_columns.empty?
245
- end
246
-
247
- # Updates and saves values to database from the passed-in Hash.
248
- def set(values)
249
- this.update(values)
250
- values.each {|k, v| @values[k] = v}
251
- end
252
- alias_method :update, :set
253
-
254
- # Reloads values from database and returns self.
255
- def refresh
256
- @values = this.first || raise(Error, "Record not found")
257
- self
258
- end
259
-
260
- # Like delete but runs hooks before and after delete.
261
- def destroy
262
- db.transaction do
263
- run_hooks(:before_destroy)
264
- delete
265
- run_hooks(:after_destroy)
266
- end
267
- end
268
-
269
- # Deletes and returns self.
270
- def delete
271
- this.delete
272
- self
273
- end
274
-
275
- ATTR_RE = /^([a-zA-Z_]\w*)(=)?$/.freeze
276
-
277
- def method_missing(m, *args) #:nodoc:
278
- if m.to_s =~ ATTR_RE
279
- att = $1.to_sym
280
- write = $2 == '='
281
-
282
- # check whether the column is legal
283
- unless columns.include?(att)
284
- # if read accessor and a value exists for the column, we return it
285
- if !write && @values.has_key?(att)
286
- return @values[att]
287
- end
288
-
289
- # otherwise, raise an error
290
- raise Error, "Invalid column (#{att.inspect}) for #{self}"
291
- end
292
-
293
- # define the column accessor
294
- Thread.exclusive do
295
- if write
296
- model.class_def(m) {|v| self[att] = v}
297
- else
298
- model.class_def(m) {self[att]}
299
- end
300
- end
301
-
302
- # call the accessor
303
- respond_to?(m) ? send(m, *args) : super(m, *args)
304
- else
305
- super(m, *args)
306
- end
307
- end
308
- end
309
- end