sequel 3.40.0 → 3.41.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|