sequel 0.4.1.1 → 0.4.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ == 0.4.1.2 (2007-12-04)
2
+
3
+ * Changed Model.is to accept variable arity.
4
+
5
+ * Implemented plugin loading for model classes.
6
+
7
+ * Fixed odbc-mssql and odbc adapters (thanks Dusty.)
8
+
9
+ * Implemented odbc-mssql adapter (thanks Dusty.)
10
+
1
11
  === 0.4.1.1 (2007-11-27)
2
12
 
3
13
  * Fixed #first and #last functionality in Informix::Dataset (thanks Gerardo Santana).
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
6
6
  include FileUtils
7
7
 
8
8
  NAME = "sequel"
9
- VERS = "0.4.1.1"
9
+ VERS = "0.4.1.2"
10
10
  CLEAN.include ['**/.*.sw?', 'pkg/*', '.config', 'doc/*', 'coverage/*']
11
11
  RDOC_OPTS = ['--quiet', '--title', "Sequel: Concise ORM for Ruby",
12
12
  "--opname", "index.html",
@@ -50,7 +50,7 @@ module Sequel
50
50
 
51
51
  def fetch_rows(sql, &block)
52
52
  @db.synchronize do
53
- s = @db.execute select_sql(sql)
53
+ s = @db.execute sql
54
54
  begin
55
55
  @columns = s.columns(true).map {|c| c.name.to_sym}
56
56
  rows = s.fetch_all
@@ -0,0 +1,98 @@
1
+ if !Object.const_defined?('Sequel')
2
+ require File.join(File.dirname(__FILE__), '../../sequel')
3
+ end
4
+
5
+ if !Sequel.const_defined?('ODBC')
6
+ require File.join(File.dirname(__FILE__), 'odbc')
7
+ end
8
+
9
+ module Sequel
10
+ module ODBC
11
+ module MSSQL
12
+ class Database < ODBC::Database
13
+ set_adapter_scheme :odbc_mssql
14
+ # set_adapter_scheme :"odbc-mssql"
15
+
16
+ def dataset(opts = nil)
17
+ MSSQL::Dataset.new(self, opts)
18
+ end
19
+ end
20
+
21
+ class Dataset < ODBC::Dataset
22
+ # Allows you to do .nolock on a query
23
+ def nolock
24
+ clone_merge(:with => "(NOLOCK)")
25
+ end
26
+
27
+ # Formats a SELECT statement using the given options and the dataset
28
+ # options.
29
+ def select_sql(opts = nil)
30
+ opts = opts ? @opts.merge(opts) : @opts
31
+
32
+ if sql = opts[:sql]
33
+ return sql
34
+ end
35
+
36
+ # ADD TOP to SELECT string for LIMITS
37
+ if limit = opts[:limit]
38
+ top = "TOP #{limit} "
39
+ raise SequelError, "Offset not supported" if opts[:offset]
40
+ end
41
+
42
+ columns = opts[:select]
43
+ select_columns = columns ? column_list(columns) : WILDCARD
44
+
45
+ if distinct = opts[:distinct]
46
+ distinct_clause = distinct.empty? ? "DISTINCT" : "DISTINCT ON (#{column_list(distinct)})"
47
+ sql = "SELECT #{top}#{distinct_clause} #{select_columns}"
48
+ else
49
+ sql = "SELECT #{top}#{select_columns}"
50
+ end
51
+
52
+ if opts[:from]
53
+ sql << " FROM #{source_list(opts[:from])}"
54
+ end
55
+
56
+ # ADD WITH to SELECT string for NOLOCK
57
+ if with = opts[:with]
58
+ sql << " WITH #{with}"
59
+ end
60
+
61
+ if join = opts[:join]
62
+ sql << join
63
+ end
64
+
65
+ if where = opts[:where]
66
+ sql << " WHERE #{where}"
67
+ end
68
+
69
+ if group = opts[:group]
70
+ sql << " GROUP BY #{column_list(group)}"
71
+ end
72
+
73
+ if order = opts[:order]
74
+ sql << " ORDER BY #{column_list(order)}"
75
+ end
76
+
77
+ if having = opts[:having]
78
+ sql << " HAVING #{having}"
79
+ end
80
+
81
+ if union = opts[:union]
82
+ sql << (opts[:union_all] ? \
83
+ " UNION ALL #{union.sql}" : " UNION #{union.sql}")
84
+ elsif intersect = opts[:intersect]
85
+ sql << (opts[:intersect_all] ? \
86
+ " INTERSECT ALL #{intersect.sql}" : " INTERSECT #{intersect.sql}")
87
+ elsif except = opts[:except]
88
+ sql << (opts[:except_all] ? \
89
+ " EXCEPT ALL #{except.sql}" : " EXCEPT #{except.sql}")
90
+ end
91
+
92
+ sql
93
+ end
94
+ alias_method :sql, :select_sql
95
+ end
96
+ end
97
+ end
98
+ end
@@ -257,6 +257,7 @@ module Sequel
257
257
  end
258
258
 
259
259
  def self.adapter_class(scheme)
260
+ scheme = scheme.to_s =~ /\-/ ? scheme.to_s.gsub('-', '_').to_sym : scheme.to_sym
260
261
  unless c = @@adapters[scheme.to_sym]
261
262
  require File.join(File.dirname(__FILE__), "adapters/#{scheme}")
262
263
  c = @@adapters[scheme.to_sym]
@@ -420,7 +420,7 @@ module Sequel
420
420
 
421
421
  sql
422
422
  end
423
- alias sql select_sql
423
+ alias_method :sql, :select_sql
424
424
 
425
425
  # Formats an INSERT statement using the given values. If a hash is given,
426
426
  # the resulting statement includes column names. If no values are given,
data/lib/sequel/model.rb CHANGED
@@ -235,21 +235,15 @@ require File.join(File.dirname(__FILE__), 'model/record')
235
235
  require File.join(File.dirname(__FILE__), 'model/schema')
236
236
  require File.join(File.dirname(__FILE__), 'model/relations')
237
237
  require File.join(File.dirname(__FILE__), 'model/caching')
238
+ require File.join(File.dirname(__FILE__), 'model/plugins')
238
239
 
239
240
  module Sequel
240
241
  class Model
241
-
242
242
  # Defines a method that returns a filtered dataset.
243
243
  def self.subset(name, *args, &block)
244
244
  dataset.meta_def(name) {filter(*args, &block)}
245
245
  end
246
-
247
- # Comprehensive description goes here!
248
- def primary_key_hash(value)
249
- # stock implementation
250
- {:id => value}
251
- end
252
-
246
+
253
247
  # Finds a single record according to the supplied filter, e.g.:
254
248
  #
255
249
  # Ticket.find :author => 'Sharon' # => record
@@ -310,42 +304,5 @@ module Sequel
310
304
  def self.all
311
305
  dataset.all
312
306
  end
313
-
314
- # Returns value of attribute.
315
- def [](column)
316
- @values[column]
317
- end
318
- # Sets value of attribute.
319
- def []=(column, value)
320
- @values[column] = value
321
- end
322
-
323
- # Enumerates through all attributes.
324
- #
325
- # === Example:
326
- # Ticket.find(7).each { |k, v| puts "#{k} => #{v}" }
327
- def each(&block)
328
- @values.each(&block)
329
- end
330
- # Returns attribute names.
331
- def keys
332
- @values.keys
333
- end
334
-
335
- # Returns value for <tt>:id</tt> attribute.
336
- def id
337
- @values[:id]
338
- end
339
-
340
- # Compares model instances by values.
341
- def ==(obj)
342
- (obj.class == model) && (obj.values == @values)
343
- end
344
-
345
- # Compares model instances by pkey.
346
- def ===(obj)
347
- (obj.class == model) && (obj.pk == pk)
348
- end
349
-
350
307
  end
351
308
  end
@@ -0,0 +1,29 @@
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
+ plugin_module(plugin).apply(self, *args)
10
+ end
11
+ alias_method :is_a, :is
12
+
13
+ # Returns the module for the specified plugin. If the module is not
14
+ # defined, the corresponding plugin gem is automatically loaded.
15
+ def plugin_module(plugin)
16
+ module_name = plugin.to_s.gsub(/(^|_)(.)/) {$2.upcase}
17
+ if not Sequel::Plugins.const_defined?(module_name)
18
+ require plugin_gem(plugin)
19
+ end
20
+ Sequel::Plugins.const_get(module_name)
21
+ end
22
+
23
+ # Returns the gem name for the given plugin.
24
+ def plugin_gem(plugin)
25
+ "sequel_#{plugin}"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -2,6 +2,42 @@ module Sequel
2
2
  class Model
3
3
  attr_reader :values
4
4
 
5
+ # Returns value of attribute.
6
+ def [](column)
7
+ @values[column]
8
+ end
9
+ # Sets value of attribute.
10
+ def []=(column, value)
11
+ @values[column] = value
12
+ end
13
+
14
+ # Enumerates through all attributes.
15
+ #
16
+ # === Example:
17
+ # Ticket.find(7).each { |k, v| puts "#{k} => #{v}" }
18
+ def each(&block)
19
+ @values.each(&block)
20
+ end
21
+ # Returns attribute names.
22
+ def keys
23
+ @values.keys
24
+ end
25
+
26
+ # Returns value for <tt>:id</tt> attribute.
27
+ def id
28
+ @values[:id]
29
+ end
30
+
31
+ # Compares model instances by values.
32
+ def ==(obj)
33
+ (obj.class == model) && (obj.values == @values)
34
+ end
35
+
36
+ # Compares model instances by pkey.
37
+ def ===(obj)
38
+ (obj.class == model) && (obj.pk == pk)
39
+ end
40
+
5
41
  # Returns key for primary key.
6
42
  def self.primary_key
7
43
  :id
data/spec/model_spec.rb CHANGED
@@ -1039,4 +1039,42 @@ context "Model magic methods" do
1039
1039
  @m.last_by_name('sharon').values.should == {:id => 123, :name => 'hey'}
1040
1040
  @c.sqls.should == ["SELECT * FROM items ORDER BY name DESC LIMIT 1"] * 2
1041
1041
  end
1042
+ end
1043
+
1044
+ module Sequel::Plugins
1045
+ module Timestamped
1046
+ def self.apply(m, opts)
1047
+ m.class_def(:get_stamp) {@values[:stamp]}
1048
+ m.meta_def(:stamp_opts) {opts}
1049
+ m.before_save {@values[:stamp] = Time.now}
1050
+ end
1051
+ end
1052
+ end
1053
+
1054
+ context "A model using a plugin" do
1055
+ specify "should fail if the plugin is not found" do
1056
+ proc do
1057
+ c = Class.new(Sequel::Model) do
1058
+ is :something_or_other
1059
+ end
1060
+ end.should raise_error(LoadError)
1061
+ end
1062
+
1063
+ specify "should apply the plugin to the class" do
1064
+ c = nil
1065
+ proc do
1066
+ c = Class.new(Sequel::Model) do
1067
+ is :timestamped, :a => 1, :b => 2
1068
+ end
1069
+ end.should_not raise_error(LoadError)
1070
+
1071
+ c.should respond_to(:stamp_opts)
1072
+ c.stamp_opts.should == {:a => 1, :b => 2}
1073
+
1074
+ m = c.new
1075
+ m.should respond_to(:get_stamp)
1076
+ t = Time.now
1077
+ m[:stamp] = t
1078
+ m.get_stamp.should == t
1079
+ end
1042
1080
  end
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.1.1
4
+ version: 0.4.1.2
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-11-27 00:00:00 +02:00
12
+ date: 2007-12-04 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -82,6 +82,7 @@ files:
82
82
  - lib/sequel/adapters/informix.rb
83
83
  - lib/sequel/adapters/mysql.rb
84
84
  - lib/sequel/adapters/odbc.rb
85
+ - lib/sequel/adapters/odbc_mssql.rb
85
86
  - lib/sequel/adapters/oracle.rb
86
87
  - lib/sequel/adapters/postgres.rb
87
88
  - lib/sequel/adapters/sqlite.rb
@@ -105,6 +106,7 @@ files:
105
106
  - lib/sequel/model/base.rb
106
107
  - lib/sequel/model/caching.rb
107
108
  - lib/sequel/model/hooks.rb
109
+ - lib/sequel/model/plugins.rb
108
110
  - lib/sequel/model/record.rb
109
111
  - lib/sequel/model/relations.rb
110
112
  - lib/sequel/model/schema.rb