sequel 0.4.1.1 → 0.4.1.2

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.
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