sequel 3.40.0 → 3.41.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.
- data/CHANGELOG +40 -0
- data/README.rdoc +2 -2
- data/doc/advanced_associations.rdoc +12 -0
- data/doc/bin_sequel.rdoc +144 -0
- data/doc/migration.rdoc +1 -1
- data/doc/object_model.rdoc +29 -0
- data/doc/release_notes/3.41.0.txt +155 -0
- data/lib/sequel/adapters/ado.rb +4 -4
- data/lib/sequel/adapters/amalgalite.rb +0 -5
- data/lib/sequel/adapters/cubrid.rb +2 -2
- data/lib/sequel/adapters/db2.rb +9 -5
- data/lib/sequel/adapters/dbi.rb +4 -6
- data/lib/sequel/adapters/do.rb +4 -5
- data/lib/sequel/adapters/firebird.rb +8 -4
- data/lib/sequel/adapters/ibmdb.rb +2 -3
- data/lib/sequel/adapters/informix.rb +0 -6
- data/lib/sequel/adapters/jdbc.rb +11 -7
- data/lib/sequel/adapters/jdbc/db2.rb +22 -0
- data/lib/sequel/adapters/jdbc/derby.rb +5 -5
- data/lib/sequel/adapters/jdbc/h2.rb +0 -5
- data/lib/sequel/adapters/jdbc/jtds.rb +1 -1
- data/lib/sequel/adapters/jdbc/sqlserver.rb +6 -0
- data/lib/sequel/adapters/mock.rb +3 -3
- data/lib/sequel/adapters/mysql.rb +7 -7
- data/lib/sequel/adapters/mysql2.rb +0 -5
- data/lib/sequel/adapters/odbc.rb +4 -4
- data/lib/sequel/adapters/openbase.rb +4 -6
- data/lib/sequel/adapters/oracle.rb +14 -6
- data/lib/sequel/adapters/postgres.rb +12 -8
- data/lib/sequel/adapters/shared/db2.rb +5 -0
- data/lib/sequel/adapters/shared/firebird.rb +10 -0
- data/lib/sequel/adapters/shared/mssql.rb +43 -1
- data/lib/sequel/adapters/shared/mysql.rb +1 -0
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +1 -1
- data/lib/sequel/adapters/shared/postgres.rb +12 -0
- data/lib/sequel/adapters/shared/sqlite.rb +32 -0
- data/lib/sequel/adapters/sqlite.rb +9 -8
- data/lib/sequel/adapters/swift.rb +3 -8
- data/lib/sequel/adapters/tinytds.rb +5 -5
- data/lib/sequel/connection_pool.rb +13 -19
- data/lib/sequel/connection_pool/sharded_single.rb +12 -12
- data/lib/sequel/connection_pool/sharded_threaded.rb +37 -17
- data/lib/sequel/connection_pool/single.rb +6 -3
- data/lib/sequel/connection_pool/threaded.rb +33 -13
- data/lib/sequel/database/connecting.rb +28 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +2 -5
- data/lib/sequel/database/query.rb +2 -2
- data/lib/sequel/database/schema_generator.rb +1 -1
- data/lib/sequel/database/schema_methods.rb +3 -0
- data/lib/sequel/dataset/query.rb +8 -4
- data/lib/sequel/dataset/sql.rb +7 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +1 -1
- data/lib/sequel/extensions/connection_validator.rb +109 -0
- data/lib/sequel/extensions/pg_array.rb +2 -0
- data/lib/sequel/extensions/pg_hstore.rb +2 -0
- data/lib/sequel/extensions/pg_json.rb +4 -0
- data/lib/sequel/extensions/pg_range.rb +1 -0
- data/lib/sequel/extensions/pg_row.rb +4 -0
- data/lib/sequel/plugins/prepared_statements.rb +2 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +53 -10
- data/lib/sequel/plugins/touch.rb +18 -6
- data/lib/sequel/plugins/validation_class_methods.rb +1 -0
- data/lib/sequel/plugins/validation_helpers.rb +3 -1
- data/lib/sequel/sql.rb +61 -19
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/firebird_spec.rb +52 -38
- data/spec/adapters/mssql_spec.rb +67 -0
- data/spec/adapters/mysql_spec.rb +192 -116
- data/spec/adapters/postgres_spec.rb +133 -70
- data/spec/adapters/spec_helper.rb +7 -0
- data/spec/adapters/sqlite_spec.rb +34 -1
- data/spec/core/connection_pool_spec.rb +79 -75
- data/spec/core/database_spec.rb +9 -4
- data/spec/core/dataset_spec.rb +15 -0
- data/spec/core/expression_filters_spec.rb +40 -2
- data/spec/extensions/connection_validator_spec.rb +118 -0
- data/spec/extensions/pg_array_spec.rb +4 -0
- data/spec/extensions/single_table_inheritance_spec.rb +42 -0
- data/spec/extensions/touch_spec.rb +40 -0
- data/spec/extensions/validation_class_methods_spec.rb +19 -1
- data/spec/extensions/validation_helpers_spec.rb +17 -0
- data/spec/integration/database_test.rb +14 -0
- data/spec/integration/dataset_test.rb +3 -3
- data/spec/integration/plugin_test.rb +41 -12
- data/spec/integration/schema_test.rb +14 -0
- data/spec/integration/spec_helper.rb +7 -0
- data/spec/integration/type_test.rb +3 -0
- metadata +9 -3
@@ -99,6 +99,8 @@ module Sequel
|
|
99
99
|
module Postgres
|
100
100
|
# Represents a PostgreSQL array column value.
|
101
101
|
class PGArray < DelegateClass(Array)
|
102
|
+
include Sequel::SQL::AliasMethods
|
103
|
+
|
102
104
|
ARRAY = "ARRAY".freeze
|
103
105
|
DOUBLE_COLON = '::'.freeze
|
104
106
|
EMPTY_BRACKET = '[]'.freeze
|
@@ -63,6 +63,8 @@ module Sequel
|
|
63
63
|
|
64
64
|
# Class representating PostgreSQL JSON column array values.
|
65
65
|
class JSONArray < DelegateClass(Array)
|
66
|
+
include Sequel::SQL::AliasMethods
|
67
|
+
|
66
68
|
# Convert the array to a string using to_json, append a
|
67
69
|
# literalized version of the string to the sql, and explicitly
|
68
70
|
# cast the string to json.
|
@@ -74,6 +76,8 @@ module Sequel
|
|
74
76
|
|
75
77
|
# Class representating PostgreSQL JSON column hash/object values.
|
76
78
|
class JSONHash < DelegateClass(Hash)
|
79
|
+
include Sequel::SQL::AliasMethods
|
80
|
+
|
77
81
|
# Convert the array to a string using to_json, append a
|
78
82
|
# literalized version of the string to the sql, and explicitly
|
79
83
|
# cast the string to json.
|
@@ -81,6 +81,8 @@ module Sequel
|
|
81
81
|
# this is only used for generic PostgreSQL record types, as registered
|
82
82
|
# types use HashRow by default.
|
83
83
|
class ArrayRow < DelegateClass(Array)
|
84
|
+
include Sequel::SQL::AliasMethods
|
85
|
+
|
84
86
|
class << self
|
85
87
|
# The database type for this class. May be nil if this class
|
86
88
|
# done not have a specific database type.
|
@@ -125,6 +127,8 @@ module Sequel
|
|
125
127
|
# Types registered via Database#register_row_type will use this
|
126
128
|
# class by default.
|
127
129
|
class HashRow < DelegateClass(Hash)
|
130
|
+
include Sequel::SQL::AliasMethods
|
131
|
+
|
128
132
|
class << self
|
129
133
|
# The columns associated with this class.
|
130
134
|
attr_accessor :columns
|
@@ -11,7 +11,8 @@ module Sequel
|
|
11
11
|
# of prepared statements that can be created, unless you tightly control how your
|
12
12
|
# model instances are saved.
|
13
13
|
#
|
14
|
-
# This plugin
|
14
|
+
# This plugin does not work correctly with the instance filters plugin
|
15
|
+
# or the update_primary_key plugin.
|
15
16
|
#
|
16
17
|
# Usage:
|
17
18
|
#
|
@@ -35,6 +35,17 @@ module Sequel
|
|
35
35
|
# Employee.plugin :single_table_inheritance, :type,
|
36
36
|
# :model_map=>{'line staff'=>:Staff, 'supervisor'=>:Manager}
|
37
37
|
#
|
38
|
+
# # By default the plugin sets the respective column value
|
39
|
+
# # when a new instance is created.
|
40
|
+
# Staff.create.type == 'line staff'
|
41
|
+
# Manager.create.type == 'supervisor'
|
42
|
+
#
|
43
|
+
# # You can customize this behavior with the :key_chooser option.
|
44
|
+
# # This is most useful when using a non-bijective mapping.
|
45
|
+
# Employee.plugin :single_table_inheritance, :type,
|
46
|
+
# :model_map=>{'line staff'=>:Staff, 'supervisor'=>:Manager},
|
47
|
+
# :key_chooser=>proc{|instance| instance.model.sti_key_map[instance.model.to_s].first || 'stranger' }
|
48
|
+
#
|
38
49
|
# # Using custom procs, with :model_map taking column values
|
39
50
|
# # and yielding either a class, string, symbol, or nil,
|
40
51
|
# # and :key_map taking a class object and returning the column
|
@@ -43,6 +54,15 @@ module Sequel
|
|
43
54
|
# :model_map=>proc{|v| v.reverse},
|
44
55
|
# :key_map=>proc{|klass| klass.name.reverse}
|
45
56
|
#
|
57
|
+
# # You can use the same class for multiple values.
|
58
|
+
# # This is mainly useful when the sti_key column contains multiple values
|
59
|
+
# # which are different but do not require different code.
|
60
|
+
# Employee.plugin :single_table_inheritance, :type,
|
61
|
+
# :model_map=>{'staff' => "Staff",
|
62
|
+
# 'manager => "Manager",
|
63
|
+
# 'overpayed staff => "Staff",
|
64
|
+
# 'underpayed staff' => "Staff"}
|
65
|
+
#
|
46
66
|
# One minor issue to note is that if you specify the <tt>:key_map</tt>
|
47
67
|
# option as a hash, instead of having it inferred from the <tt>:model_map</tt>,
|
48
68
|
# you should only use class name strings as keys, you should not use symbols
|
@@ -57,20 +77,38 @@ module Sequel
|
|
57
77
|
@sti_model_map = opts[:model_map] || lambda{|v| v if v && v != ''}
|
58
78
|
@sti_key_map = if km = opts[:key_map]
|
59
79
|
if km.is_a?(Hash)
|
60
|
-
h = Hash.new
|
61
|
-
|
80
|
+
h = Hash.new do |h,k|
|
81
|
+
unless k.is_a?(String)
|
82
|
+
h[k.to_s]
|
83
|
+
else
|
84
|
+
[]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
km.each do |k,v|
|
88
|
+
h[k.to_s] = [ ] unless h.key?(k.to_s)
|
89
|
+
h[k.to_s].push( *Array(v) )
|
90
|
+
end
|
91
|
+
h
|
62
92
|
else
|
63
93
|
km
|
64
94
|
end
|
65
95
|
elsif sti_model_map.is_a?(Hash)
|
66
|
-
h = Hash.new
|
96
|
+
h = Hash.new do |h,k|
|
97
|
+
unless k.is_a?(String)
|
98
|
+
h[k.to_s]
|
99
|
+
else
|
100
|
+
[]
|
101
|
+
end
|
102
|
+
end
|
67
103
|
sti_model_map.each do |k,v|
|
68
|
-
h[v.to_s] =
|
104
|
+
h[v.to_s] = [ ] unless h.key?(v.to_s)
|
105
|
+
h[v.to_s] << k
|
69
106
|
end
|
70
107
|
h
|
71
108
|
else
|
72
109
|
lambda{|klass| klass.name.to_s}
|
73
110
|
end
|
111
|
+
@sti_key_chooser = opts[:key_chooser] || lambda{|inst| Array(inst.model.sti_key_map[inst.model]).last }
|
74
112
|
dataset.row_proc = lambda{|r| model.sti_load(r)}
|
75
113
|
end
|
76
114
|
end
|
@@ -97,6 +135,10 @@ module Sequel
|
|
97
135
|
# the value of the sti_key column to the appropriate class to use.
|
98
136
|
attr_reader :sti_model_map
|
99
137
|
|
138
|
+
# A proc which returns the value to use for new instances.
|
139
|
+
# This defaults to a lookup in the key map.
|
140
|
+
attr_reader :sti_key_chooser
|
141
|
+
|
100
142
|
# Copy the necessary attributes to the subclasses, and filter the
|
101
143
|
# subclass's dataset based on the sti_kep_map entry for the class.
|
102
144
|
def inherited(subclass)
|
@@ -105,18 +147,19 @@ module Sequel
|
|
105
147
|
sd = sti_dataset
|
106
148
|
skm = sti_key_map
|
107
149
|
smm = sti_model_map
|
108
|
-
|
150
|
+
skc = sti_key_chooser
|
151
|
+
key = Array(skm[subclass]).dup
|
109
152
|
sti_subclass_added(key)
|
110
|
-
ska = [key]
|
111
153
|
rp = dataset.row_proc
|
112
|
-
subclass.set_dataset(sd.filter(SQL::QualifiedIdentifier.new(table_name, sk)=>
|
154
|
+
subclass.set_dataset(sd.filter(SQL::QualifiedIdentifier.new(table_name, sk)=>key), :inherited=>true)
|
113
155
|
subclass.instance_eval do
|
114
156
|
dataset.row_proc = rp
|
115
157
|
@sti_key = sk
|
116
|
-
@sti_key_array =
|
158
|
+
@sti_key_array = key
|
117
159
|
@sti_dataset = sd
|
118
160
|
@sti_key_map = skm
|
119
161
|
@sti_model_map = smm
|
162
|
+
@sti_key_chooser = skc
|
120
163
|
self.simple_table = nil
|
121
164
|
end
|
122
165
|
end
|
@@ -131,7 +174,7 @@ module Sequel
|
|
131
174
|
# keys for all of their descendant classes.
|
132
175
|
def sti_subclass_added(key)
|
133
176
|
if sti_key_array
|
134
|
-
Sequel.synchronize{sti_key_array
|
177
|
+
Sequel.synchronize{sti_key_array.push(*Array(key))}
|
135
178
|
superclass.sti_subclass_added(key)
|
136
179
|
end
|
137
180
|
end
|
@@ -159,7 +202,7 @@ module Sequel
|
|
159
202
|
module InstanceMethods
|
160
203
|
# Set the sti_key column based on the sti_key_map.
|
161
204
|
def before_create
|
162
|
-
send("#{model.sti_key}=", model.
|
205
|
+
send("#{model.sti_key}=", model.sti_key_chooser.call(self)) unless self[model.sti_key]
|
163
206
|
super
|
164
207
|
end
|
165
208
|
end
|
data/lib/sequel/plugins/touch.rb
CHANGED
@@ -52,7 +52,7 @@ module Sequel
|
|
52
52
|
attr_accessor :touch_column
|
53
53
|
|
54
54
|
# A hash specifying the associations to touch when instances are
|
55
|
-
# updated or destroyed. Keys are association
|
55
|
+
# updated or destroyed. Keys are association name symbols and values
|
56
56
|
# are column name symbols.
|
57
57
|
attr_reader :touched_associations
|
58
58
|
|
@@ -71,8 +71,8 @@ module Sequel
|
|
71
71
|
associations.flatten.each do |a|
|
72
72
|
a = {a=>touch_column} if a.is_a?(Symbol)
|
73
73
|
a.each do |k,v|
|
74
|
-
raise(Error, "invalid association: #{k}") unless
|
75
|
-
touched_associations[
|
74
|
+
raise(Error, "invalid association: #{k}") unless association_reflection(k)
|
75
|
+
touched_associations[k] = v
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
@@ -113,10 +113,22 @@ module Sequel
|
|
113
113
|
Sequel::CURRENT_TIMESTAMP
|
114
114
|
end
|
115
115
|
|
116
|
-
#
|
116
|
+
# Update the updated at field for all associated objects that should be touched.
|
117
117
|
def touch_associations
|
118
|
-
model.touched_associations.each do |
|
119
|
-
|
118
|
+
model.touched_associations.each do |assoc, column|
|
119
|
+
r = model.association_reflection(assoc)
|
120
|
+
next unless r.can_have_associated_objects?(self)
|
121
|
+
ds = send(r.dataset_method)
|
122
|
+
|
123
|
+
if ds.send(:joined_dataset?)
|
124
|
+
# Can't update all values at once, so update each instance individually.
|
125
|
+
# Instead if doing a simple save, update via the instance's dataset,
|
126
|
+
# to avoid going into an infinite loop in some cases.
|
127
|
+
send(r[:name]).each{|x| x.this.update(column=>touch_association_value)}
|
128
|
+
else
|
129
|
+
# Update all values at once for performance reasons.
|
130
|
+
ds.update(column=>touch_association_value)
|
131
|
+
end
|
120
132
|
end
|
121
133
|
end
|
122
134
|
|
@@ -224,7 +224,9 @@ module Sequel
|
|
224
224
|
ds = if where
|
225
225
|
where.call(model.dataset, self, arr)
|
226
226
|
else
|
227
|
-
|
227
|
+
vals = arr.map{|x| send(x)}
|
228
|
+
next unless vals.all?
|
229
|
+
model.where(arr.zip(vals))
|
228
230
|
end
|
229
231
|
ds = yield(ds) if block_given?
|
230
232
|
ds = ds.exclude(pk_hash) unless new?
|
data/lib/sequel/sql.rb
CHANGED
@@ -377,6 +377,27 @@ module Sequel
|
|
377
377
|
SQL::EmulatedFunction.new(:char_length, arg)
|
378
378
|
end
|
379
379
|
|
380
|
+
# Return a delayed evaluation that uses the passed block. This is used
|
381
|
+
# to delay evaluations of the code to runtime. For example, with
|
382
|
+
# the following code:
|
383
|
+
#
|
384
|
+
# ds = DB[:table].where{column > Time.now}
|
385
|
+
#
|
386
|
+
# The filter is fixed to the time that where was called. Unless you are
|
387
|
+
# only using the dataset once immediately after creating it, that's
|
388
|
+
# probably not desired. If you just want to set it to the time when the
|
389
|
+
# query is sent to the database, you can wrap it in Sequel.delay:
|
390
|
+
#
|
391
|
+
# ds = DB[:table].where{column > Sequel.delay{Time.now}}
|
392
|
+
#
|
393
|
+
# Note that for dates and timestamps, you are probably better off using
|
394
|
+
# Sequel::CURRENT_DATE and Sequel::CURRENT_TIMESTAMP instead of this
|
395
|
+
# generic delayed evaluation facility.
|
396
|
+
def delay(&block)
|
397
|
+
raise(Error, "Sequel.delay requires a block") unless block
|
398
|
+
SQL::DelayedEvaluation.new(block)
|
399
|
+
end
|
400
|
+
|
380
401
|
# Order the given argument descending.
|
381
402
|
# Options:
|
382
403
|
#
|
@@ -941,27 +962,33 @@ module Sequel
|
|
941
962
|
# ~from_value_pairs(hash)
|
942
963
|
# from_value_pairs(hash, :OR, true)
|
943
964
|
def self.from_value_pairs(pairs, op=:AND, negate=false)
|
944
|
-
pairs = pairs.
|
945
|
-
|
946
|
-
when Range
|
947
|
-
new(:AND, new(:>=, l, r.begin), new(r.exclude_end? ? :< : :<=, l, r.end))
|
948
|
-
when ::Array, ::Sequel::Dataset
|
949
|
-
new(:IN, l, r)
|
950
|
-
when NegativeBooleanConstant
|
951
|
-
new(:"IS NOT", l, r.constant)
|
952
|
-
when BooleanConstant
|
953
|
-
new(:IS, l, r.constant)
|
954
|
-
when NilClass, TrueClass, FalseClass
|
955
|
-
new(:IS, l, r)
|
956
|
-
when Regexp
|
957
|
-
StringExpression.like(l, r)
|
958
|
-
else
|
959
|
-
new(:'=', l, r)
|
960
|
-
end
|
961
|
-
negate ? invert(ce) : ce
|
962
|
-
end
|
965
|
+
pairs = pairs.map{|l,r| from_value_pair(l, r)}
|
966
|
+
pairs.map!{|ce| invert(ce)} if negate
|
963
967
|
pairs.length == 1 ? pairs.at(0) : new(op, *pairs)
|
964
968
|
end
|
969
|
+
|
970
|
+
# Return a BooleanExpression based on the right side of the pair.
|
971
|
+
def self.from_value_pair(l, r)
|
972
|
+
case r
|
973
|
+
when Range
|
974
|
+
new(:AND, new(:>=, l, r.begin), new(r.exclude_end? ? :< : :<=, l, r.end))
|
975
|
+
when ::Array, ::Sequel::Dataset
|
976
|
+
new(:IN, l, r)
|
977
|
+
when NegativeBooleanConstant
|
978
|
+
new(:"IS NOT", l, r.constant)
|
979
|
+
when BooleanConstant
|
980
|
+
new(:IS, l, r.constant)
|
981
|
+
when NilClass, TrueClass, FalseClass
|
982
|
+
new(:IS, l, r)
|
983
|
+
when Regexp
|
984
|
+
StringExpression.like(l, r)
|
985
|
+
when DelayedEvaluation
|
986
|
+
Sequel.delay{from_value_pair(l, r.callable.call)}
|
987
|
+
else
|
988
|
+
new(:'=', l, r)
|
989
|
+
end
|
990
|
+
end
|
991
|
+
private_class_method :from_value_pair
|
965
992
|
|
966
993
|
# Invert the expression, if possible. If the expression cannot
|
967
994
|
# be inverted, raise an error. An inverted expression should match everything that the
|
@@ -1140,6 +1167,21 @@ module Sequel
|
|
1140
1167
|
Constants::NULL=>Constants::NOTNULL, Constants::NOTNULL=>Constants::NULL}
|
1141
1168
|
end
|
1142
1169
|
|
1170
|
+
# Represents a delayed evaluation, encapsulating a callable
|
1171
|
+
# object which returns the value to use when called.
|
1172
|
+
class DelayedEvaluation < GenericExpression
|
1173
|
+
# A callable object that returns the value of the evaluation
|
1174
|
+
# when called.
|
1175
|
+
attr_reader :callable
|
1176
|
+
|
1177
|
+
# Set the callable object
|
1178
|
+
def initialize(callable)
|
1179
|
+
@callable = callable
|
1180
|
+
end
|
1181
|
+
|
1182
|
+
to_s_method :delayed_evaluation_sql, '@callable'
|
1183
|
+
end
|
1184
|
+
|
1143
1185
|
# Represents an SQL function call.
|
1144
1186
|
class Function < GenericExpression
|
1145
1187
|
# The SQL function to call
|
data/lib/sequel/version.rb
CHANGED
@@ -3,7 +3,7 @@ module Sequel
|
|
3
3
|
MAJOR = 3
|
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 = 41
|
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
|
@@ -253,68 +253,82 @@ describe "A Firebird database" do
|
|
253
253
|
|
254
254
|
specify "should allow us to name the sequences" do
|
255
255
|
@db.create_table(:posts){primary_key :id, :sequence_name => "seq_test"}
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
256
|
+
check_sqls do
|
257
|
+
@db.sqls.should == [
|
258
|
+
"DROP SEQUENCE SEQ_TEST",
|
259
|
+
"CREATE TABLE POSTS (ID integer PRIMARY KEY )",
|
260
|
+
"CREATE SEQUENCE SEQ_TEST",
|
261
|
+
" CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_test;\n end\n end\n\n"
|
262
|
+
]
|
263
|
+
end
|
262
264
|
end
|
263
265
|
|
264
266
|
specify "should allow us to set the starting position for the sequences" do
|
265
267
|
@db.create_table(:posts){primary_key :id, :sequence_start_position => 999}
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
268
|
+
check_sqls do
|
269
|
+
@db.sqls.should == [
|
270
|
+
"DROP SEQUENCE SEQ_POSTS_ID",
|
271
|
+
"CREATE TABLE POSTS (ID integer PRIMARY KEY )",
|
272
|
+
"CREATE SEQUENCE SEQ_POSTS_ID",
|
273
|
+
"ALTER SEQUENCE SEQ_POSTS_ID RESTART WITH 999",
|
274
|
+
" CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
|
275
|
+
]
|
276
|
+
end
|
273
277
|
end
|
274
278
|
|
275
279
|
specify "should allow us to name and set the starting position for the sequences" do
|
276
280
|
@db.create_table(:posts){primary_key :id, :sequence_name => "seq_test", :sequence_start_position => 999}
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
281
|
+
check_sqls do
|
282
|
+
@db.sqls.should == [
|
283
|
+
"DROP SEQUENCE SEQ_TEST",
|
284
|
+
"CREATE TABLE POSTS (ID integer PRIMARY KEY )",
|
285
|
+
"CREATE SEQUENCE SEQ_TEST",
|
286
|
+
"ALTER SEQUENCE SEQ_TEST RESTART WITH 999",
|
287
|
+
" CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_test;\n end\n end\n\n"
|
288
|
+
]
|
289
|
+
end
|
284
290
|
end
|
285
291
|
|
286
292
|
specify "should allow us to name the triggers" do
|
287
293
|
@db.create_table(:posts){primary_key :id, :trigger_name => "trig_test"}
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
+
check_sqls do
|
295
|
+
@db.sqls.should == [
|
296
|
+
"DROP SEQUENCE SEQ_POSTS_ID",
|
297
|
+
"CREATE TABLE POSTS (ID integer PRIMARY KEY )",
|
298
|
+
"CREATE SEQUENCE SEQ_POSTS_ID",
|
299
|
+
" CREATE TRIGGER TRIG_TEST for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
|
300
|
+
]
|
301
|
+
end
|
294
302
|
end
|
295
303
|
|
296
304
|
specify "should allow us to not create the sequence" do
|
297
305
|
@db.create_table(:posts){primary_key :id, :create_sequence => false}
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
306
|
+
check_sqls do
|
307
|
+
@db.sqls.should == [
|
308
|
+
"CREATE TABLE POSTS (ID integer PRIMARY KEY )",
|
309
|
+
" CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
|
310
|
+
]
|
311
|
+
end
|
302
312
|
end
|
303
313
|
|
304
314
|
specify "should allow us to not create the trigger" do
|
305
315
|
@db.create_table(:posts){primary_key :id, :create_trigger => false}
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
316
|
+
check_sqls do
|
317
|
+
@db.sqls.should == [
|
318
|
+
"DROP SEQUENCE SEQ_POSTS_ID",
|
319
|
+
"CREATE TABLE POSTS (ID integer PRIMARY KEY )",
|
320
|
+
"CREATE SEQUENCE SEQ_POSTS_ID",
|
321
|
+
]
|
322
|
+
end
|
311
323
|
end
|
312
324
|
|
313
325
|
specify "should allow us to not create either the sequence nor the trigger" do
|
314
326
|
@db.create_table(:posts){primary_key :id, :create_sequence => false, :create_trigger => false}
|
315
|
-
|
316
|
-
|
317
|
-
|
327
|
+
check_sqls do
|
328
|
+
@db.sqls.should == [
|
329
|
+
"CREATE TABLE POSTS (ID integer PRIMARY KEY )"
|
330
|
+
]
|
331
|
+
end
|
318
332
|
end
|
319
333
|
|
320
334
|
specify "should support column operations" do
|