sequel 4.12.0 → 4.13.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG +64 -0
- data/Rakefile +3 -1
- data/bin/sequel +13 -5
- data/doc/release_notes/4.13.0.txt +169 -0
- data/doc/sql.rdoc +3 -3
- data/lib/sequel/adapters/do.rb +11 -23
- data/lib/sequel/adapters/do/mysql.rb +8 -0
- data/lib/sequel/adapters/do/postgres.rb +8 -0
- data/lib/sequel/adapters/do/{sqlite.rb → sqlite3.rb} +9 -0
- data/lib/sequel/adapters/jdbc.rb +16 -139
- data/lib/sequel/adapters/jdbc/as400.rb +9 -0
- data/lib/sequel/adapters/jdbc/cubrid.rb +9 -0
- data/lib/sequel/adapters/jdbc/db2.rb +9 -0
- data/lib/sequel/adapters/jdbc/derby.rb +9 -0
- data/lib/sequel/adapters/jdbc/{firebird.rb → firebirdsql.rb} +9 -0
- data/lib/sequel/adapters/jdbc/h2.rb +10 -0
- data/lib/sequel/adapters/jdbc/hsqldb.rb +9 -0
- data/lib/sequel/adapters/jdbc/{informix.rb → informix-sqli.rb} +9 -0
- data/lib/sequel/adapters/jdbc/{progress.rb → jdbcprogress.rb} +9 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +10 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +14 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +9 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +9 -0
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +23 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +10 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +10 -0
- data/lib/sequel/adapters/odbc.rb +6 -14
- data/lib/sequel/adapters/odbc/db2.rb +9 -0
- data/lib/sequel/adapters/odbc/mssql.rb +8 -0
- data/lib/sequel/adapters/odbc/progress.rb +8 -0
- data/lib/sequel/adapters/oracle.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +1 -1
- data/lib/sequel/adapters/shared/firebird.rb +8 -1
- data/lib/sequel/adapters/shared/mssql.rb +68 -27
- data/lib/sequel/adapters/shared/mysql.rb +3 -5
- data/lib/sequel/adapters/shared/oracle.rb +17 -3
- data/lib/sequel/adapters/shared/postgres.rb +9 -4
- data/lib/sequel/adapters/shared/sqlanywhere.rb +6 -6
- data/lib/sequel/database/connecting.rb +38 -17
- data/lib/sequel/dataset/actions.rb +6 -2
- data/lib/sequel/dataset/graph.rb +18 -20
- data/lib/sequel/dataset/misc.rb +37 -0
- data/lib/sequel/dataset/prepared_statements.rb +1 -2
- data/lib/sequel/dataset/query.rb +1 -0
- data/lib/sequel/dataset/sql.rb +17 -10
- data/lib/sequel/extensions/dataset_source_alias.rb +90 -0
- data/lib/sequel/extensions/pg_array.rb +14 -10
- data/lib/sequel/extensions/pg_enum.rb +135 -0
- data/lib/sequel/extensions/pg_hstore.rb +4 -6
- data/lib/sequel/extensions/pg_inet.rb +4 -5
- data/lib/sequel/extensions/pg_interval.rb +3 -3
- data/lib/sequel/extensions/pg_json.rb +16 -12
- data/lib/sequel/extensions/pg_range.rb +5 -3
- data/lib/sequel/extensions/pg_row.rb +2 -2
- data/lib/sequel/extensions/round_timestamps.rb +52 -0
- data/lib/sequel/model.rb +5 -2
- data/lib/sequel/model/associations.rb +29 -3
- data/lib/sequel/model/base.rb +68 -29
- data/lib/sequel/plugins/class_table_inheritance.rb +25 -16
- data/lib/sequel/plugins/column_select.rb +57 -0
- data/lib/sequel/plugins/composition.rb +14 -16
- data/lib/sequel/plugins/dirty.rb +9 -11
- data/lib/sequel/plugins/insert_returning_select.rb +70 -0
- data/lib/sequel/plugins/instance_filters.rb +7 -9
- data/lib/sequel/plugins/lazy_attributes.rb +16 -4
- data/lib/sequel/plugins/list.rb +9 -0
- data/lib/sequel/plugins/modification_detection.rb +90 -0
- data/lib/sequel/plugins/serialization.rb +13 -15
- data/lib/sequel/plugins/serialization_modification_detection.rb +9 -9
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/timestamps.rb +6 -6
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +7 -0
- data/spec/adapters/postgres_spec.rb +41 -0
- data/spec/bin_spec.rb +4 -1
- data/spec/core/database_spec.rb +6 -0
- data/spec/core/dataset_spec.rb +100 -90
- data/spec/core/object_graph_spec.rb +5 -0
- data/spec/extensions/class_table_inheritance_spec.rb +18 -13
- data/spec/extensions/column_select_spec.rb +108 -0
- data/spec/extensions/composition_spec.rb +20 -0
- data/spec/extensions/dataset_source_alias_spec.rb +51 -0
- data/spec/extensions/insert_returning_select_spec.rb +46 -0
- data/spec/extensions/lazy_attributes_spec.rb +24 -20
- data/spec/extensions/list_spec.rb +5 -0
- data/spec/extensions/modification_detection_spec.rb +80 -0
- data/spec/extensions/pg_enum_spec.rb +64 -0
- data/spec/extensions/pg_json_spec.rb +7 -13
- data/spec/extensions/prepared_statements_spec.rb +6 -4
- data/spec/extensions/round_timestamps_spec.rb +43 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +10 -1
- data/spec/extensions/serialization_spec.rb +18 -0
- data/spec/extensions/single_table_inheritance_spec.rb +5 -0
- data/spec/extensions/timestamps_spec.rb +6 -0
- data/spec/integration/plugin_test.rb +14 -8
- data/spec/integration/prepared_statement_test.rb +12 -0
- data/spec/model/associations_spec.rb +24 -0
- data/spec/model/model_spec.rb +13 -3
- data/spec/model/record_spec.rb +24 -1
- metadata +22 -6
|
@@ -59,15 +59,6 @@ module Sequel
|
|
|
59
59
|
clear_instance_filters
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
# Duplicate internal structures when duplicating model instance.
|
|
63
|
-
def dup
|
|
64
|
-
ifs = instance_filters.dup
|
|
65
|
-
super.instance_eval do
|
|
66
|
-
@instance_filters = ifs
|
|
67
|
-
self
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
62
|
# Freeze the instance filters when freezing the object
|
|
72
63
|
def freeze
|
|
73
64
|
instance_filters.freeze
|
|
@@ -93,6 +84,13 @@ module Sequel
|
|
|
93
84
|
end
|
|
94
85
|
end
|
|
95
86
|
|
|
87
|
+
# Duplicate internal structures when duplicating model instance.
|
|
88
|
+
def initialize_copy(other)
|
|
89
|
+
super
|
|
90
|
+
@instance_filters = other.send(:instance_filters).dup
|
|
91
|
+
self
|
|
92
|
+
end
|
|
93
|
+
|
|
96
94
|
# Lazily initialize the instance filter array.
|
|
97
95
|
def instance_filters
|
|
98
96
|
@instance_filters ||= []
|
|
@@ -17,6 +17,13 @@ module Sequel
|
|
|
17
17
|
#
|
|
18
18
|
# # You can specify multiple columns to lazily load:
|
|
19
19
|
# Album.plugin :lazy_attributes, :review, :tracklist
|
|
20
|
+
#
|
|
21
|
+
# Note that by default on databases that supporting RETURNING,
|
|
22
|
+
# using explicit column selections will cause instance creations
|
|
23
|
+
# to use two queries (insert and refresh) instead of a single
|
|
24
|
+
# query using RETURNING. You can use the insert_returning_select
|
|
25
|
+
# plugin to automatically use RETURNING for instance creations
|
|
26
|
+
# for models using the lazy_attributes plugin.
|
|
20
27
|
module LazyAttributes
|
|
21
28
|
# Lazy attributes requires the tactical_eager_loading plugin
|
|
22
29
|
def self.apply(model, *attrs)
|
|
@@ -37,7 +44,10 @@ module Sequel
|
|
|
37
44
|
# For each attribute given, create an accessor method that allows a lazy
|
|
38
45
|
# lookup of the attribute. Each attribute should be given as a symbol.
|
|
39
46
|
def lazy_attributes(*attrs)
|
|
40
|
-
|
|
47
|
+
unless select = dataset.opts[:select]
|
|
48
|
+
select = dataset.columns.map{|c| Sequel.qualify(dataset.first_source, c)}
|
|
49
|
+
end
|
|
50
|
+
set_dataset(dataset.select(*select.reject{|c| attrs.include?(dataset.send(:_hash_key_symbol, c))}))
|
|
41
51
|
attrs.each{|a| define_lazy_attribute_getter(a)}
|
|
42
52
|
end
|
|
43
53
|
|
|
@@ -66,8 +76,9 @@ module Sequel
|
|
|
66
76
|
# the attribute for just the current object. Return the value of
|
|
67
77
|
# the attribute for the current object.
|
|
68
78
|
def lazy_attribute_lookup(a)
|
|
79
|
+
selection = Sequel.qualify(model.table_name, a)
|
|
69
80
|
if frozen?
|
|
70
|
-
return this.dup.
|
|
81
|
+
return this.dup.get(selection)
|
|
71
82
|
end
|
|
72
83
|
|
|
73
84
|
if retrieved_with
|
|
@@ -75,14 +86,15 @@ module Sequel
|
|
|
75
86
|
composite_pk = true if primary_key.is_a?(Array)
|
|
76
87
|
id_map = {}
|
|
77
88
|
retrieved_with.each{|o| id_map[o.pk] = o unless o.values.has_key?(a) || o.frozen?}
|
|
78
|
-
model.
|
|
89
|
+
predicate_key = composite_pk ? primary_key.map{|k| Sequel.qualify(model.table_name, k)} : Sequel.qualify(model.table_name, primary_key)
|
|
90
|
+
model.select(*(Array(primary_key).map{|k| Sequel.qualify(model.table_name, k)} + [selection])).where(predicate_key=>id_map.keys).naked.each do |row|
|
|
79
91
|
obj = id_map[composite_pk ? row.values_at(*primary_key) : row[primary_key]]
|
|
80
92
|
if obj && !obj.values.has_key?(a)
|
|
81
93
|
obj.values[a] = row[a]
|
|
82
94
|
end
|
|
83
95
|
end
|
|
84
96
|
end
|
|
85
|
-
values[a] = this.
|
|
97
|
+
values[a] = this.get(selection) unless values.has_key?(a)
|
|
86
98
|
values[a]
|
|
87
99
|
end
|
|
88
100
|
end
|
data/lib/sequel/plugins/list.rb
CHANGED
|
@@ -96,6 +96,15 @@ module Sequel
|
|
|
96
96
|
super
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
+
# When destroying an instance, move all entries after the instance down
|
|
100
|
+
# one position, so that there aren't any gaps
|
|
101
|
+
def after_destroy
|
|
102
|
+
super
|
|
103
|
+
|
|
104
|
+
f = Sequel.expr(position_field)
|
|
105
|
+
list_dataset.where(f > position_value).update(f => f - 1)
|
|
106
|
+
end
|
|
107
|
+
|
|
99
108
|
# Find the last position in the list containing this instance.
|
|
100
109
|
def last_position
|
|
101
110
|
list_dataset.max(position_field).to_i
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module Sequel
|
|
2
|
+
module Plugins
|
|
3
|
+
# This plugin automatically detects in-place modifications to
|
|
4
|
+
# columns as well as direct modifications of the values hash.
|
|
5
|
+
#
|
|
6
|
+
# class User < Sequel::Model
|
|
7
|
+
# plugin :modification_detection
|
|
8
|
+
# end
|
|
9
|
+
# user = User[1]
|
|
10
|
+
# user.a # => 'a'
|
|
11
|
+
# user.a << 'b'
|
|
12
|
+
# user.save_changes
|
|
13
|
+
# # UPDATE users SET a = 'ab' WHERE (id = 1)
|
|
14
|
+
#
|
|
15
|
+
# Note that for this plugin to work correctly, the column values must
|
|
16
|
+
# correctly implement the #hash method, returning the same value if
|
|
17
|
+
# the object is equal, and a different value if the object is not equal.
|
|
18
|
+
#
|
|
19
|
+
# Note that this plugin causes a performance hit for all retrieved
|
|
20
|
+
# objects, so it shouldn't be used in cases where performance is a
|
|
21
|
+
# primary concern.
|
|
22
|
+
#
|
|
23
|
+
# Usage:
|
|
24
|
+
#
|
|
25
|
+
# # Make all model subclass automatically detect column modifications
|
|
26
|
+
# Sequel::Model.plugin :modification_detection
|
|
27
|
+
#
|
|
28
|
+
# # Make the Album class automatically detect column modifications
|
|
29
|
+
# Album.plugin :modification_detection
|
|
30
|
+
module ModificationDetection
|
|
31
|
+
module ClassMethods
|
|
32
|
+
# Calculate the hashes for all of the column values, so that they
|
|
33
|
+
# can be compared later to determine if the column value has changed.
|
|
34
|
+
def call(_)
|
|
35
|
+
v = super
|
|
36
|
+
v.calculate_values_hashes
|
|
37
|
+
v
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
module InstanceMethods
|
|
42
|
+
# Recalculate the column value hashes after updating.
|
|
43
|
+
def after_update
|
|
44
|
+
super
|
|
45
|
+
recalculate_values_hashes
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Calculate the column hash values if they haven't been already calculated.
|
|
49
|
+
def calculate_values_hashes
|
|
50
|
+
@values_hashes || recalculate_values_hashes
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Detect which columns have been modified by comparing the cached hash
|
|
54
|
+
# value to the hash of the current value.
|
|
55
|
+
def changed_columns
|
|
56
|
+
cc = super
|
|
57
|
+
changed = []
|
|
58
|
+
v = @values
|
|
59
|
+
if vh = @values_hashes
|
|
60
|
+
(vh.keys - cc).each{|c| changed << c unless v.has_key?(c) && vh[c] == v[c].hash}
|
|
61
|
+
end
|
|
62
|
+
cc + changed
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
# Recalculate the column value hashes after manually refreshing.
|
|
68
|
+
def _refresh(dataset)
|
|
69
|
+
super
|
|
70
|
+
recalculate_values_hashes
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Recalculate the column value hashes after refreshing after saving a new object.
|
|
74
|
+
def _save_refresh
|
|
75
|
+
super
|
|
76
|
+
recalculate_values_hashes
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Recalculate the column value hashes, caching them for later use.
|
|
80
|
+
def recalculate_values_hashes
|
|
81
|
+
vh = {}
|
|
82
|
+
@values.each do |k,v|
|
|
83
|
+
vh[k] = v.hash
|
|
84
|
+
end
|
|
85
|
+
@values_hashes = vh.freeze
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -175,26 +175,11 @@ module Sequel
|
|
|
175
175
|
end
|
|
176
176
|
|
|
177
177
|
module InstanceMethods
|
|
178
|
-
# Serialize deserialized values before saving
|
|
179
|
-
def before_save
|
|
180
|
-
serialize_deserialized_values
|
|
181
|
-
super
|
|
182
|
-
end
|
|
183
|
-
|
|
184
178
|
# Hash of deserialized values, used as a cache.
|
|
185
179
|
def deserialized_values
|
|
186
180
|
@deserialized_values ||= {}
|
|
187
181
|
end
|
|
188
182
|
|
|
189
|
-
# Freeze the deserialized values
|
|
190
|
-
def dup
|
|
191
|
-
dv = deserialized_values.dup
|
|
192
|
-
super.instance_eval do
|
|
193
|
-
@deserialized_values = dv
|
|
194
|
-
self
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
|
|
198
183
|
# Freeze the deserialized values
|
|
199
184
|
def freeze
|
|
200
185
|
deserialized_values.freeze
|
|
@@ -203,6 +188,12 @@ module Sequel
|
|
|
203
188
|
|
|
204
189
|
private
|
|
205
190
|
|
|
191
|
+
# Serialize deserialized values before saving
|
|
192
|
+
def _before_validation
|
|
193
|
+
serialize_deserialized_values
|
|
194
|
+
super
|
|
195
|
+
end
|
|
196
|
+
|
|
206
197
|
# Clear any cached deserialized values when doing a manual refresh.
|
|
207
198
|
def _refresh_set_values(hash)
|
|
208
199
|
@deserialized_values.clear if @deserialized_values
|
|
@@ -218,6 +209,13 @@ module Sequel
|
|
|
218
209
|
end
|
|
219
210
|
end
|
|
220
211
|
|
|
212
|
+
# Dup the deserialized values when duping model instance.
|
|
213
|
+
def initialize_copy(other)
|
|
214
|
+
super
|
|
215
|
+
@deserialized_values = other.deserialized_values.dup
|
|
216
|
+
self
|
|
217
|
+
end
|
|
218
|
+
|
|
221
219
|
# Serialize all deserialized values
|
|
222
220
|
def serialize_deserialized_values
|
|
223
221
|
deserialized_values.each{|k,v| @values[k] = serialize_value(k, v)}
|
|
@@ -45,15 +45,6 @@ module Sequel
|
|
|
45
45
|
cc
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
# Duplicate the original deserialized values when duplicating instance.
|
|
49
|
-
def dup
|
|
50
|
-
o = @original_deserialized_values
|
|
51
|
-
super.instance_eval do
|
|
52
|
-
@original_deserialized_values = o.dup if o
|
|
53
|
-
self
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
48
|
# Freeze the original deserialized values when freezing the instance.
|
|
58
49
|
def freeze
|
|
59
50
|
@original_deserialized_values ||= {}
|
|
@@ -63,6 +54,15 @@ module Sequel
|
|
|
63
54
|
|
|
64
55
|
private
|
|
65
56
|
|
|
57
|
+
# Duplicate the original deserialized values when duplicating instance.
|
|
58
|
+
def initialize_copy(other)
|
|
59
|
+
super
|
|
60
|
+
if o = other.instance_variable_get(:@original_deserialized_values)
|
|
61
|
+
@original_deserialized_values = o.dup
|
|
62
|
+
end
|
|
63
|
+
self
|
|
64
|
+
end
|
|
65
|
+
|
|
66
66
|
# For new objects, serialize any existing deserialized values so that changes can
|
|
67
67
|
# be detected.
|
|
68
68
|
def initialize_set(values)
|
|
@@ -215,8 +215,10 @@ module Sequel
|
|
|
215
215
|
end
|
|
216
216
|
|
|
217
217
|
module InstanceMethods
|
|
218
|
+
private
|
|
219
|
+
|
|
218
220
|
# Set the sti_key column based on the sti_key_map.
|
|
219
|
-
def
|
|
221
|
+
def _before_validation
|
|
220
222
|
if new? && !self[model.sti_key]
|
|
221
223
|
send("#{model.sti_key}=", model.sti_key_chooser.call(self))
|
|
222
224
|
end
|
|
@@ -57,12 +57,6 @@ module Sequel
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
module InstanceMethods
|
|
60
|
-
# Set the create timestamp when creating
|
|
61
|
-
def before_validation
|
|
62
|
-
set_create_timestamp if new?
|
|
63
|
-
super
|
|
64
|
-
end
|
|
65
|
-
|
|
66
60
|
# Set the update timestamp when updating
|
|
67
61
|
def before_update
|
|
68
62
|
set_update_timestamp
|
|
@@ -71,6 +65,12 @@ module Sequel
|
|
|
71
65
|
|
|
72
66
|
private
|
|
73
67
|
|
|
68
|
+
# Set the create timestamp when creating
|
|
69
|
+
def _before_validation
|
|
70
|
+
set_create_timestamp if new?
|
|
71
|
+
super
|
|
72
|
+
end
|
|
73
|
+
|
|
74
74
|
# If the object has accessor methods for the create timestamp field, and
|
|
75
75
|
# the create timestamp value is nil or overwriting it is allowed, set the
|
|
76
76
|
# create timestamp field to the time given or the current time. If setting
|
data/lib/sequel/version.rb
CHANGED
|
@@ -3,7 +3,7 @@ module Sequel
|
|
|
3
3
|
MAJOR = 4
|
|
4
4
|
# The minor version of Sequel. Bumped for every non-patch level
|
|
5
5
|
# release, generally around once a month.
|
|
6
|
-
MINOR =
|
|
6
|
+
MINOR = 13
|
|
7
7
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
|
8
8
|
# releases that fix regressions from previous versions.
|
|
9
9
|
TINY = 0
|
data/spec/adapters/mysql_spec.rb
CHANGED
|
@@ -509,6 +509,13 @@ describe "A MySQL database" do
|
|
|
509
509
|
end
|
|
510
510
|
end
|
|
511
511
|
|
|
512
|
+
specify "should correctly format CREATE TABLE statements with foreign keys, when :key != the default (:id)" do
|
|
513
|
+
@db.create_table(:items){primary_key :id; Integer :other_than_id; foreign_key :p_id, :items, :key => :other_than_id, :null => false, :on_delete => :cascade}
|
|
514
|
+
check_sqls do
|
|
515
|
+
@db.sqls.should == ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `other_than_id` integer, `p_id` integer NOT NULL, UNIQUE (`other_than_id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`other_than_id`) ON DELETE CASCADE)"]
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
|
|
512
519
|
specify "should correctly format ALTER TABLE statements with foreign keys" do
|
|
513
520
|
@db.create_table(:items){Integer :id}
|
|
514
521
|
@db.create_table(:users){primary_key :id}
|
|
@@ -3436,3 +3436,44 @@ describe 'pg_static_cache_updater extension' do
|
|
|
3436
3436
|
q.pop
|
|
3437
3437
|
end
|
|
3438
3438
|
end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG && DB.server_version >= 90000
|
|
3439
|
+
|
|
3440
|
+
describe 'PostgreSQL enum types' do
|
|
3441
|
+
before(:all) do
|
|
3442
|
+
@db = DB
|
|
3443
|
+
@db.extension :pg_array, :pg_enum
|
|
3444
|
+
@db.create_enum(:test_enum, %w'a b c d')
|
|
3445
|
+
|
|
3446
|
+
@db.create_table!(:test_enumt) do
|
|
3447
|
+
test_enum :t
|
|
3448
|
+
end
|
|
3449
|
+
end
|
|
3450
|
+
after(:all) do
|
|
3451
|
+
@db.drop_table?(:test_enumt)
|
|
3452
|
+
@db.drop_enum(:test_enum)
|
|
3453
|
+
end
|
|
3454
|
+
|
|
3455
|
+
specify "should return correct entries in the schema" do
|
|
3456
|
+
s = @db.schema(:test_enumt)
|
|
3457
|
+
s.first.last[:type].should == :enum
|
|
3458
|
+
s.first.last[:enum_values].should == %w'a b c d'
|
|
3459
|
+
end
|
|
3460
|
+
|
|
3461
|
+
it "should add array parsers for enum values" do
|
|
3462
|
+
@db.get(Sequel.pg_array(%w'a b', :test_enum)).should == %w'a b'
|
|
3463
|
+
end if DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
|
3464
|
+
|
|
3465
|
+
it "should set up model typecasting correctly" do
|
|
3466
|
+
c = Class.new(Sequel::Model(:test_enumt))
|
|
3467
|
+
o = c.new
|
|
3468
|
+
o.t = :a
|
|
3469
|
+
o.t.should == 'a'
|
|
3470
|
+
end
|
|
3471
|
+
|
|
3472
|
+
it "should add values to existing enum" do
|
|
3473
|
+
@db.add_enum_value(:test_enum, 'e')
|
|
3474
|
+
@db.add_enum_value(:test_enum, 'f', :after=>'a')
|
|
3475
|
+
@db.add_enum_value(:test_enum, 'g', :before=>'b')
|
|
3476
|
+
@db.add_enum_value(:test_enum, 'a', :if_not_exists=>true) if @db.server_version >= 90300
|
|
3477
|
+
@db.schema(:test_enumt, :reload=>true).first.last[:enum_values].should == %w'a f g b c d e'
|
|
3478
|
+
end if DB.server_version >= 90100
|
|
3479
|
+
end
|
data/spec/bin_spec.rb
CHANGED
|
@@ -56,6 +56,7 @@ describe "bin/sequel" do
|
|
|
56
56
|
bin(:args=>'-c "print DB.tables.inspect"').should == '[]'
|
|
57
57
|
DB.create_table(:a){Integer :a}
|
|
58
58
|
bin(:args=>'-c "print DB.tables.inspect"').should == '[:a]'
|
|
59
|
+
bin(:args=>'-v -c "print DB.tables.inspect"').should == "sequel #{Sequel.version}\n[:a]"
|
|
59
60
|
end
|
|
60
61
|
|
|
61
62
|
it "-C should copy databases" do
|
|
@@ -188,7 +189,7 @@ END
|
|
|
188
189
|
bin(:args=>'-t -c "lambda{lambda{lambda{raise \'foo\'}.call}.call}.call"', :stderr=>true).count("\n").should > 3
|
|
189
190
|
end
|
|
190
191
|
|
|
191
|
-
it "-v should output the Sequel version" do
|
|
192
|
+
it "-v should output the Sequel version and exit if database is not given" do
|
|
192
193
|
bin(:args=>"-v", :no_conn=>true).should == "sequel #{Sequel.version}\n"
|
|
193
194
|
end
|
|
194
195
|
|
|
@@ -201,6 +202,7 @@ END
|
|
|
201
202
|
bin(:args=>'-D -d', :stderr=>true).should == "Error: Cannot specify -D and -d together\n"
|
|
202
203
|
bin(:args=>'-m foo -d', :stderr=>true).should == "Error: Cannot specify -m and -d together\n"
|
|
203
204
|
bin(:args=>'-S foo -d', :stderr=>true).should == "Error: Cannot specify -S and -d together\n"
|
|
205
|
+
bin(:args=>'-S foo -C', :stderr=>true).should == "Error: Cannot specify -S and -C together\n"
|
|
204
206
|
end
|
|
205
207
|
|
|
206
208
|
it "should use a mock database if no database is given" do
|
|
@@ -243,6 +245,7 @@ END
|
|
|
243
245
|
bin(:post=>TMP_FILE).should == '[]'
|
|
244
246
|
DB.create_table(:a){Integer :a}
|
|
245
247
|
bin(:post=>TMP_FILE).should == '[:a]'
|
|
248
|
+
bin(:post=>TMP_FILE, :args=>'-v').should == "sequel #{Sequel.version}\n[:a]"
|
|
246
249
|
end
|
|
247
250
|
|
|
248
251
|
it "should run code provided on stdin" do
|
data/spec/core/database_spec.rb
CHANGED
|
@@ -1290,6 +1290,12 @@ describe "A broken adapter (lib is there but the class is not)" do
|
|
|
1290
1290
|
end
|
|
1291
1291
|
end
|
|
1292
1292
|
|
|
1293
|
+
describe "Sequel::Database.load_adapter" do
|
|
1294
|
+
specify "should not raise an error if subadapter does not exist" do
|
|
1295
|
+
Sequel::Database.load_adapter(:foo, :subdir=>'bar').should == nil
|
|
1296
|
+
end
|
|
1297
|
+
end
|
|
1298
|
+
|
|
1293
1299
|
describe "A single threaded database" do
|
|
1294
1300
|
after do
|
|
1295
1301
|
Sequel::Database.single_threaded = false
|
data/spec/core/dataset_spec.rb
CHANGED
|
@@ -982,22 +982,17 @@ describe "Dataset#literal" do
|
|
|
982
982
|
d.literal(d).should == "(#{d.sql})"
|
|
983
983
|
end
|
|
984
984
|
|
|
985
|
-
specify "should literalize
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
@dataset.literal(
|
|
985
|
+
specify "should literalize times properly" do
|
|
986
|
+
@dataset.literal(Sequel::SQLTime.create(1, 2, 3, 500000)).should == "'01:02:03.500000'"
|
|
987
|
+
@dataset.literal(Time.local(2010, 1, 2, 3, 4, 5, 500000)).should == "'2010-01-02 03:04:05.500000'"
|
|
988
|
+
@dataset.literal(DateTime.new(2010, 1, 2, 3, 4, Rational(55, 10))).should == "'2010-01-02 03:04:05.500000'"
|
|
989
989
|
end
|
|
990
990
|
|
|
991
|
-
specify "should literalize
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
@dataset.literal(
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
specify "should literalize DateTime properly" do
|
|
998
|
-
t = DateTime.now
|
|
999
|
-
s = t.strftime("'%Y-%m-%d %H:%M:%S")
|
|
1000
|
-
@dataset.literal(t).should == "#{s}.#{sprintf('%06i', t.sec_fraction * (RUBY_VERSION < '1.9.0' ? 86400000000 : 1000000))}'"
|
|
991
|
+
specify "should literalize times properly for databases supporting millisecond precision" do
|
|
992
|
+
meta_def(@dataset, :timestamp_precision){3}
|
|
993
|
+
@dataset.literal(Sequel::SQLTime.create(1, 2, 3, 500000)).should == "'01:02:03.500'"
|
|
994
|
+
@dataset.literal(Time.local(2010, 1, 2, 3, 4, 5, 500000)).should == "'2010-01-02 03:04:05.500'"
|
|
995
|
+
@dataset.literal(DateTime.new(2010, 1, 2, 3, 4, Rational(55, 10))).should == "'2010-01-02 03:04:05.500'"
|
|
1001
996
|
end
|
|
1002
997
|
|
|
1003
998
|
specify "should literalize Date properly" do
|
|
@@ -1015,52 +1010,19 @@ describe "Dataset#literal" do
|
|
|
1015
1010
|
|
|
1016
1011
|
specify "should literalize Time, DateTime, Date properly if SQL standard format is required" do
|
|
1017
1012
|
meta_def(@dataset, :requires_sql_standard_datetimes?){true}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
@dataset.literal(t).should == "#{s}.#{sprintf('%06i', t.usec)}'"
|
|
1022
|
-
|
|
1023
|
-
t = DateTime.now
|
|
1024
|
-
s = t.strftime("TIMESTAMP '%Y-%m-%d %H:%M:%S")
|
|
1025
|
-
@dataset.literal(t).should == "#{s}.#{sprintf('%06i', t.sec_fraction* (RUBY_VERSION < '1.9.0' ? 86400000000 : 1000000))}'"
|
|
1026
|
-
|
|
1027
|
-
d = Date.today
|
|
1028
|
-
s = d.strftime("DATE '%Y-%m-%d'")
|
|
1029
|
-
@dataset.literal(d).should == s
|
|
1013
|
+
@dataset.literal(Time.local(2010, 1, 2, 3, 4, 5, 500000)).should == "TIMESTAMP '2010-01-02 03:04:05.500000'"
|
|
1014
|
+
@dataset.literal(DateTime.new(2010, 1, 2, 3, 4, Rational(55, 10))).should == "TIMESTAMP '2010-01-02 03:04:05.500000'"
|
|
1015
|
+
@dataset.literal(Date.new(2010, 1, 2)).should == "DATE '2010-01-02'"
|
|
1030
1016
|
end
|
|
1031
1017
|
|
|
1032
1018
|
specify "should literalize Time and DateTime properly if the database support timezones in timestamps" do
|
|
1033
1019
|
meta_def(@dataset, :supports_timestamp_timezones?){true}
|
|
1020
|
+
@dataset.literal(Time.utc(2010, 1, 2, 3, 4, 5, 500000)).should == "'2010-01-02 03:04:05.500000+0000'"
|
|
1021
|
+
@dataset.literal(DateTime.new(2010, 1, 2, 3, 4, Rational(55, 10))).should == "'2010-01-02 03:04:05.500000+0000'"
|
|
1034
1022
|
|
|
1035
|
-
t = Time.now.utc
|
|
1036
|
-
s = t.strftime("'%Y-%m-%d %H:%M:%S")
|
|
1037
|
-
@dataset.literal(t).should == "#{s}.#{sprintf('%06i', t.usec)}+0000'"
|
|
1038
|
-
|
|
1039
|
-
t = DateTime.now.new_offset(0)
|
|
1040
|
-
s = t.strftime("'%Y-%m-%d %H:%M:%S")
|
|
1041
|
-
@dataset.literal(t).should == "#{s}.#{sprintf('%06i', t.sec_fraction* (RUBY_VERSION < '1.9.0' ? 86400000000 : 1000000))}+0000'"
|
|
1042
|
-
end
|
|
1043
|
-
|
|
1044
|
-
specify "should literalize Time and DateTime properly if the database doesn't support usecs in timestamps" do
|
|
1045
1023
|
meta_def(@dataset, :supports_timestamp_usecs?){false}
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
s = t.strftime("'%Y-%m-%d %H:%M:%S")
|
|
1049
|
-
@dataset.literal(t).should == "#{s}'"
|
|
1050
|
-
|
|
1051
|
-
t = DateTime.now.new_offset(0)
|
|
1052
|
-
s = t.strftime("'%Y-%m-%d %H:%M:%S")
|
|
1053
|
-
@dataset.literal(t).should == "#{s}'"
|
|
1054
|
-
|
|
1055
|
-
meta_def(@dataset, :supports_timestamp_timezones?){true}
|
|
1056
|
-
|
|
1057
|
-
t = Time.now.utc
|
|
1058
|
-
s = t.strftime("'%Y-%m-%d %H:%M:%S")
|
|
1059
|
-
@dataset.literal(t).should == "#{s}+0000'"
|
|
1060
|
-
|
|
1061
|
-
t = DateTime.now.new_offset(0)
|
|
1062
|
-
s = t.strftime("'%Y-%m-%d %H:%M:%S")
|
|
1063
|
-
@dataset.literal(t).should == "#{s}+0000'"
|
|
1024
|
+
@dataset.literal(Time.utc(2010, 1, 2, 3, 4, 5)).should == "'2010-01-02 03:04:05+0000'"
|
|
1025
|
+
@dataset.literal(DateTime.new(2010, 1, 2, 3, 4, 5)).should == "'2010-01-02 03:04:05+0000'"
|
|
1064
1026
|
end
|
|
1065
1027
|
|
|
1066
1028
|
specify "should not modify literal strings" do
|
|
@@ -3249,6 +3211,11 @@ describe "Dataset#insert_sql" do
|
|
|
3249
3211
|
specify "should accept an array of columns and an LiteralString" do
|
|
3250
3212
|
@ds.insert_sql([:a, :b, :c], Sequel.lit('VALUES (1, 2, 3)')).should == "INSERT INTO items (a, b, c) VALUES (1, 2, 3)"
|
|
3251
3213
|
end
|
|
3214
|
+
|
|
3215
|
+
specify "should use unaliased table name" do
|
|
3216
|
+
@ds.from(:items___i).insert_sql(1).should == "INSERT INTO items VALUES (1)"
|
|
3217
|
+
@ds.from(Sequel.as(:items, :i)).insert_sql(1).should == "INSERT INTO items VALUES (1)"
|
|
3218
|
+
end
|
|
3252
3219
|
end
|
|
3253
3220
|
|
|
3254
3221
|
describe "Dataset#inspect" do
|
|
@@ -3457,7 +3424,7 @@ describe "Dataset prepared statements and bound variables " do
|
|
|
3457
3424
|
before do
|
|
3458
3425
|
@db = Sequel.mock
|
|
3459
3426
|
@ds = @db[:items]
|
|
3460
|
-
meta_def(@ds, :
|
|
3427
|
+
meta_def(@ds, :insert_select_sql){|*v| "#{insert_sql(*v)} RETURNING *" }
|
|
3461
3428
|
end
|
|
3462
3429
|
|
|
3463
3430
|
specify "#call should take a type and bind hash and interpolate it" do
|
|
@@ -3935,7 +3902,12 @@ describe "Sequel timezone support" do
|
|
|
3935
3902
|
@dataset = @db.dataset
|
|
3936
3903
|
meta_def(@dataset, :supports_timestamp_timezones?){true}
|
|
3937
3904
|
meta_def(@dataset, :supports_timestamp_usecs?){false}
|
|
3938
|
-
@
|
|
3905
|
+
@utc_time = Time.utc(2010, 1, 2, 3, 4, 5)
|
|
3906
|
+
@local_time = Time.local(2010, 1, 2, 3, 4, 5)
|
|
3907
|
+
@offset = sprintf("%+03i%02i", *(@local_time.utc_offset/60).divmod(60))
|
|
3908
|
+
@dt_offset = @local_time.utc_offset/Rational(86400, 1)
|
|
3909
|
+
@utc_datetime = DateTime.new(2010, 1, 2, 3, 4, 5)
|
|
3910
|
+
@local_datetime = DateTime.new(2010, 1, 2, 3, 4, 5, @dt_offset)
|
|
3939
3911
|
end
|
|
3940
3912
|
after do
|
|
3941
3913
|
Sequel.default_timezone = nil
|
|
@@ -3944,50 +3916,26 @@ describe "Sequel timezone support" do
|
|
|
3944
3916
|
|
|
3945
3917
|
specify "should handle an database timezone of :utc when literalizing values" do
|
|
3946
3918
|
Sequel.database_timezone = :utc
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
s = t.getutc.strftime("'%Y-%m-%d %H:%M:%S")
|
|
3950
|
-
@dataset.literal(t).should == "#{s}+0000'"
|
|
3951
|
-
|
|
3952
|
-
t = DateTime.now
|
|
3953
|
-
s = t.new_offset(0).strftime("'%Y-%m-%d %H:%M:%S")
|
|
3954
|
-
@dataset.literal(t).should == "#{s}+0000'"
|
|
3919
|
+
@dataset.literal(Time.utc(2010, 1, 2, 3, 4, 5)).should == "'2010-01-02 03:04:05+0000'"
|
|
3920
|
+
@dataset.literal(DateTime.new(2010, 1, 2, 3, 4, 5)).should == "'2010-01-02 03:04:05+0000'"
|
|
3955
3921
|
end
|
|
3956
3922
|
|
|
3957
3923
|
specify "should handle an database timezone of :local when literalizing values" do
|
|
3958
3924
|
Sequel.database_timezone = :local
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
s = t.getlocal.strftime("'%Y-%m-%d %H:%M:%S")
|
|
3962
|
-
@dataset.literal(t).should == "#{s}#{@offset}'"
|
|
3963
|
-
|
|
3964
|
-
t = DateTime.now.new_offset(0)
|
|
3965
|
-
s = t.new_offset(DateTime.now.offset).strftime("'%Y-%m-%d %H:%M:%S")
|
|
3966
|
-
@dataset.literal(t).should == "#{s}#{@offset}'"
|
|
3925
|
+
@dataset.literal(Time.local(2010, 1, 2, 3, 4, 5)).should == "'2010-01-02 03:04:05#{@offset}'"
|
|
3926
|
+
@dataset.literal(DateTime.new(2010, 1, 2, 3, 4, 5, @dt_offset)).should == "'2010-01-02 03:04:05#{@offset}'"
|
|
3967
3927
|
end
|
|
3968
3928
|
|
|
3969
3929
|
specify "should have Database#timezone override Sequel.database_timezone" do
|
|
3970
3930
|
Sequel.database_timezone = :local
|
|
3971
3931
|
@db.timezone = :utc
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
s = t.getutc.strftime("'%Y-%m-%d %H:%M:%S")
|
|
3975
|
-
@dataset.literal(t).should == "#{s}+0000'"
|
|
3976
|
-
|
|
3977
|
-
t = DateTime.now
|
|
3978
|
-
s = t.new_offset(0).strftime("'%Y-%m-%d %H:%M:%S")
|
|
3979
|
-
@dataset.literal(t).should == "#{s}+0000'"
|
|
3932
|
+
@dataset.literal(Time.utc(2010, 1, 2, 3, 4, 5)).should == "'2010-01-02 03:04:05+0000'"
|
|
3933
|
+
@dataset.literal(DateTime.new(2010, 1, 2, 3, 4, 5)).should == "'2010-01-02 03:04:05+0000'"
|
|
3980
3934
|
|
|
3981
3935
|
Sequel.database_timezone = :utc
|
|
3982
3936
|
@db.timezone = :local
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
s = t.getlocal.strftime("'%Y-%m-%d %H:%M:%S")
|
|
3986
|
-
@dataset.literal(t).should == "#{s}#{@offset}'"
|
|
3987
|
-
|
|
3988
|
-
t = DateTime.now.new_offset(0)
|
|
3989
|
-
s = t.new_offset(DateTime.now.offset).strftime("'%Y-%m-%d %H:%M:%S")
|
|
3990
|
-
@dataset.literal(t).should == "#{s}#{@offset}'"
|
|
3937
|
+
@dataset.literal(Time.local(2010, 1, 2, 3, 4, 5)).should == "'2010-01-02 03:04:05#{@offset}'"
|
|
3938
|
+
@dataset.literal(DateTime.new(2010, 1, 2, 3, 4, 5, @dt_offset)).should == "'2010-01-02 03:04:05#{@offset}'"
|
|
3991
3939
|
end
|
|
3992
3940
|
|
|
3993
3941
|
specify "should handle converting database timestamps into application timestamps" do
|
|
@@ -4418,9 +4366,10 @@ end
|
|
|
4418
4366
|
|
|
4419
4367
|
describe "Dataset#returning" do
|
|
4420
4368
|
before do
|
|
4421
|
-
@
|
|
4369
|
+
@db = Sequel.mock(:fetch=>proc{|s| {:foo=>s}})
|
|
4370
|
+
@db.extend_datasets{def supports_returning?(type) true end}
|
|
4371
|
+
@ds = @db[:t].returning(:foo)
|
|
4422
4372
|
@pr = proc do
|
|
4423
|
-
def @ds.supports_returning?(*) true end
|
|
4424
4373
|
sc = class << @ds; self; end
|
|
4425
4374
|
Sequel::Dataset.def_sql_method(sc, :delete, %w'delete from where returning')
|
|
4426
4375
|
Sequel::Dataset.def_sql_method(sc, :insert, %w'insert into columns values returning')
|
|
@@ -4458,6 +4407,11 @@ describe "Dataset#returning" do
|
|
|
4458
4407
|
@ds.insert(1).should == [{:foo=>"INSERT INTO t VALUES (1) RETURNING foo"}]
|
|
4459
4408
|
@ds.update(:foo=>1).should == [{:foo=>"UPDATE t SET foo = 1 RETURNING foo"}]
|
|
4460
4409
|
end
|
|
4410
|
+
|
|
4411
|
+
specify "should raise an error if RETURNING is not supported" do
|
|
4412
|
+
@db.extend_datasets{def supports_returning?(type) false end}
|
|
4413
|
+
proc{@db[:t].returning}.should raise_error(Sequel::Error)
|
|
4414
|
+
end
|
|
4461
4415
|
end
|
|
4462
4416
|
|
|
4463
4417
|
describe "Dataset emulating bitwise operator support" do
|
|
@@ -4943,3 +4897,59 @@ describe "Dataset emulated complex expression operators" do
|
|
|
4943
4897
|
@ds.literal(~@n).should == "((0 - x) - 1)"
|
|
4944
4898
|
end
|
|
4945
4899
|
end
|
|
4900
|
+
|
|
4901
|
+
describe "#joined_dataset?" do
|
|
4902
|
+
before do
|
|
4903
|
+
@ds = Sequel.mock.dataset
|
|
4904
|
+
end
|
|
4905
|
+
|
|
4906
|
+
it "should be false if the dataset has 0 or 1 from table" do
|
|
4907
|
+
@ds.joined_dataset?.should == false
|
|
4908
|
+
@ds.from(:a).joined_dataset?.should == false
|
|
4909
|
+
end
|
|
4910
|
+
|
|
4911
|
+
it "should be true if the dataset has 2 or more from tables" do
|
|
4912
|
+
@ds.from(:a, :b).joined_dataset?.should == true
|
|
4913
|
+
@ds.from(:a, :b, :c).joined_dataset?.should == true
|
|
4914
|
+
end
|
|
4915
|
+
|
|
4916
|
+
it "should be true if the dataset has any join tables" do
|
|
4917
|
+
@ds.from(:a).cross_join(:b).joined_dataset?.should == true
|
|
4918
|
+
end
|
|
4919
|
+
end
|
|
4920
|
+
|
|
4921
|
+
describe "#unqualified_column_for" do
|
|
4922
|
+
before do
|
|
4923
|
+
@ds = Sequel.mock.dataset
|
|
4924
|
+
end
|
|
4925
|
+
|
|
4926
|
+
it "should handle Symbols" do
|
|
4927
|
+
@ds.unqualified_column_for(:a).should == Sequel.identifier('a')
|
|
4928
|
+
@ds.unqualified_column_for(:b__a).should == Sequel.identifier('a')
|
|
4929
|
+
@ds.unqualified_column_for(:a___c).should == Sequel.identifier('a').as('c')
|
|
4930
|
+
@ds.unqualified_column_for(:b__a___c).should == Sequel.identifier('a').as('c')
|
|
4931
|
+
end
|
|
4932
|
+
|
|
4933
|
+
it "should handle SQL::Identifiers" do
|
|
4934
|
+
@ds.unqualified_column_for(Sequel.identifier(:a)).should == Sequel.identifier(:a)
|
|
4935
|
+
end
|
|
4936
|
+
|
|
4937
|
+
it "should handle SQL::QualifiedIdentifiers" do
|
|
4938
|
+
@ds.unqualified_column_for(Sequel.qualify(:b, :a)).should == Sequel.identifier('a')
|
|
4939
|
+
@ds.unqualified_column_for(Sequel.qualify(:b, 'a')).should == Sequel.identifier('a')
|
|
4940
|
+
end
|
|
4941
|
+
|
|
4942
|
+
it "should handle SQL::AliasedExpressions" do
|
|
4943
|
+
@ds.unqualified_column_for(Sequel.qualify(:b, :a).as(:c)).should == Sequel.identifier('a').as(:c)
|
|
4944
|
+
end
|
|
4945
|
+
|
|
4946
|
+
it "should return nil for other objects" do
|
|
4947
|
+
@ds.unqualified_column_for(Object.new).should == nil
|
|
4948
|
+
@ds.unqualified_column_for('a').should == nil
|
|
4949
|
+
end
|
|
4950
|
+
|
|
4951
|
+
it "should return nil for other objects inside SQL::AliasedExpressions" do
|
|
4952
|
+
@ds.unqualified_column_for(Sequel.as(Object.new, 'a')).should == nil
|
|
4953
|
+
@ds.unqualified_column_for(Sequel.as('a', 'b')).should == nil
|
|
4954
|
+
end
|
|
4955
|
+
end
|