sequel 4.24.0 → 4.25.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 +40 -0
- data/doc/association_basics.rdoc +2 -5
- data/doc/dataset_basics.rdoc +1 -1
- data/doc/postgresql.rdoc +47 -0
- data/doc/querying.rdoc +5 -0
- data/doc/release_notes/4.25.0.txt +181 -0
- data/lib/sequel/adapters/ibmdb.rb +0 -28
- data/lib/sequel/adapters/shared/db2.rb +31 -2
- data/lib/sequel/adapters/shared/mssql.rb +12 -12
- data/lib/sequel/adapters/shared/postgres.rb +102 -3
- data/lib/sequel/adapters/shared/sqlite.rb +1 -0
- data/lib/sequel/adapters/swift/sqlite.rb +12 -0
- data/lib/sequel/database/schema_generator.rb +4 -0
- data/lib/sequel/database/schema_methods.rb +3 -1
- data/lib/sequel/dataset/actions.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +15 -7
- data/lib/sequel/dataset/query.rb +16 -2
- data/lib/sequel/dataset/sql.rb +19 -16
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +35 -0
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -34
- data/lib/sequel/extensions/pg_json_ops.rb +9 -1
- data/lib/sequel/extensions/query_literals.rb +1 -1
- data/lib/sequel/model/base.rb +7 -11
- data/lib/sequel/model/dataset_module.rb +1 -1
- data/lib/sequel/plugins/association_pks.rb +6 -0
- data/lib/sequel/plugins/dirty.rb +6 -1
- data/lib/sequel/plugins/inverted_subsets.rb +48 -0
- data/lib/sequel/plugins/serialization.rb +2 -0
- data/lib/sequel/plugins/singular_table_names.rb +31 -0
- data/lib/sequel/plugins/static_cache.rb +17 -0
- data/lib/sequel/sql.rb +1 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +12 -0
- data/spec/adapters/mysql_spec.rb +1 -0
- data/spec/adapters/postgres_spec.rb +41 -1
- data/spec/core/database_spec.rb +1 -0
- data/spec/core/dataset_spec.rb +55 -7
- data/spec/core/expression_filters_spec.rb +18 -0
- data/spec/core/schema_spec.rb +10 -2
- data/spec/extensions/association_pks_spec.rb +12 -0
- data/spec/extensions/{empty_array_ignore_nulls_spec.rb → empty_array_consider_nulls_spec.rb} +7 -7
- data/spec/extensions/inverted_subsets_spec.rb +33 -0
- data/spec/extensions/query_literals_spec.rb +16 -0
- data/spec/extensions/serialization_spec.rb +21 -0
- data/spec/extensions/singular_table_names_spec.rb +22 -0
- data/spec/integration/dataset_test.rb +2 -1
- data/spec/integration/prepared_statement_test.rb +35 -1
- data/spec/model/associations_spec.rb +2 -2
- data/spec/model/base_spec.rb +13 -8
- data/spec/model/class_dataset_methods_spec.rb +1 -0
- metadata +10 -5
- data/lib/sequel/adapters/firebird.rb +0 -105
- data/lib/sequel/adapters/informix.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bb525327915d4e6d6e8306e9edd0dc6cd32afa3
|
4
|
+
data.tar.gz: b64f5447c918b9d36b47622629ec697286adc0b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: caa13716ae448d4a3b3c6f4886c2e529f495e843eeb5386b85a264d259bb54d0ffefca3d7cba9c82013d1c96c87bff8691e460e1e0a06806bb64cef18950e284
|
7
|
+
data.tar.gz: 302d93a18b52e0810e74fce6f3d4a87f497f4199fb47045834aecbe193f6796fd910453b0c1669b8d82b3d698ac5bb13346fce825311da03c7a77ab7d89d728c
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,43 @@
|
|
1
|
+
=== 4.25.0 (2015-08-01)
|
2
|
+
|
3
|
+
* Add Dataset#insert_conflict on PostgreSQL 9.5+, for upsert/insert ignore support using INSERT ON CONFLICT (jeremyevans)
|
4
|
+
|
5
|
+
* Support Dataset#group_rollup and #group_cube on PostgreSQL 9.5+ (jeremyevans)
|
6
|
+
|
7
|
+
* Automatically REORG tables when altering when using jdbc/db2 (karlhe) (#1054)
|
8
|
+
|
9
|
+
* Recognize constraint violation exceptions on swift/sqlite (jeremyevans)
|
10
|
+
|
11
|
+
* Recognize another check constraint violation exception message on SQLite (jeremyevans)
|
12
|
+
|
13
|
+
* Allow =~ and !~ to be used on ComplexExpressions (janko-m) (#1050)
|
14
|
+
|
15
|
+
* Support case sensitive SQL Server 2012 in MSSQL metadata queries (knut2) (#1049)
|
16
|
+
|
17
|
+
* Add Dataset#group_append, for appending to the existing GROUP BY clause (YorickPeterse) (#1047)
|
18
|
+
|
19
|
+
* Add inverted_subsets plugin, for creating an inverted subset method for each subset (celsworth) (#1042)
|
20
|
+
|
21
|
+
* Make Dataset#for_update not use the :read_only database when the dataset is executed (jeremyevans) (#1041)
|
22
|
+
|
23
|
+
* Add singular_table_names plugin, for changing Sequel to not pluralize table names by default (jeremyevans)
|
24
|
+
|
25
|
+
* PreparedStatement#prepare now raises an Error (jeremyevans)
|
26
|
+
|
27
|
+
* Clear delayed association pks when refreshing an object (jeremyevans)
|
28
|
+
|
29
|
+
* Add empty_array_consider_nulls extension to make Sequel consider NULL values when using IN/NOT IN with an empty array (jeremyevans)
|
30
|
+
|
31
|
+
* Make Sequel default to ignoring NULL values when using IN/NOT IN with an empty array (jeremyevans)
|
32
|
+
|
33
|
+
* Remove the deprecated firebird and informix adapters (jeremyevans)
|
34
|
+
|
35
|
+
* Make :collate option when creating columns literalize non-String values on PostgreSQL (jeremyevans) (#1040)
|
36
|
+
|
37
|
+
* Make dirty plugin notice when serialized column is changed (celsworth) (#1039)
|
38
|
+
|
39
|
+
* Allow prepared statements to use RETURNING (jeremyevans) (#1036)
|
40
|
+
|
1
41
|
=== 4.24.0 (2015-07-01)
|
2
42
|
|
3
43
|
* Allow class_table_inheritance plugin to support subclasses that don't add additional columns (QuinnHarris, jeremyevans) (#1030)
|
data/doc/association_basics.rdoc
CHANGED
@@ -754,11 +754,8 @@ all associated objects to NULL in a single query. For +many_to_many+
|
|
754
754
|
associations, this deletes all matching rows in the join table.
|
755
755
|
Unlike the add_<i>association</i> and remove_<i>association</i> method, the
|
756
756
|
plural form of the association name is used in this method.
|
757
|
-
The remove_all_<i>association</i> method returns the
|
758
|
-
|
759
|
-
+many_to_many+ associations:
|
760
|
-
|
761
|
-
@rows_modified = @artist.remove_all_albums
|
757
|
+
The remove_all_<i>association</i> method returns the previously cached associated
|
758
|
+
records, or nil if there were no cached associated records.
|
762
759
|
|
763
760
|
=== <i>association</i>_dataset (e.g. albums_dataset)
|
764
761
|
|
data/doc/dataset_basics.rdoc
CHANGED
@@ -78,7 +78,7 @@ SELECT:: select, select_all, select_append, select_group, select_more
|
|
78
78
|
FROM:: from, from_self
|
79
79
|
JOIN:: join, left_join, right_join, full_join, natural_join, natural_left_join, natural_right_join, natural_full_join, cross_join, inner_join, left_outer_join, right_outer_join, full_outer_join, join_table
|
80
80
|
WHERE:: where, filter, exclude, exclude_where, and, or, grep, invert, unfiltered
|
81
|
-
GROUP:: group, group_by, group_and_count, select_group, ungrouped
|
81
|
+
GROUP:: group, group_by, group_and_count, group_append, select_group, ungrouped
|
82
82
|
HAVING:: having, exclude_having, invert, unfiltered
|
83
83
|
ORDER:: order, order_by, order_append, order_prepend, order_more, reverse, reverse_order, unordered
|
84
84
|
LIMIT/OFFSET:: limit, offset, unlimited
|
data/doc/postgresql.rdoc
CHANGED
@@ -185,6 +185,53 @@ When returning is used, instead of returning the number of rows affected (for up
|
|
185
185
|
or the serial primary key value (for insert), it will return an array of hashes with the
|
186
186
|
returned results.
|
187
187
|
|
188
|
+
=== INSERT ON CONFLICT Support
|
189
|
+
|
190
|
+
Starting with PostgreSQL 9.5, you can do an upsert or ignore unique or exclusion constraint
|
191
|
+
violations when inserting using <tt>Dataset#insert_conflict</tt>:
|
192
|
+
|
193
|
+
DB[:table].insert_conflict.insert(:a=>1, :b=>2)
|
194
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
195
|
+
# ON CONFLICT DO NOTHING
|
196
|
+
|
197
|
+
For compatibility with Sequel's MySQL support, you can also use +insert_ignore+:
|
198
|
+
|
199
|
+
DB[:table].insert_ignore.insert(:a=>1, :b=>2)
|
200
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
201
|
+
# ON CONFLICT DO NOTHING
|
202
|
+
|
203
|
+
You can pass a specific constraint name using +:constraint+, to only ignore a specific
|
204
|
+
constraint violation:
|
205
|
+
|
206
|
+
DB[:table].insert_conflict(:constraint=>:table_a_uidx).insert(:a=>1, :b=>2)
|
207
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
208
|
+
# ON CONFLICT ON CONSTRAINT table_a_uidx DO NOTHING
|
209
|
+
|
210
|
+
If the unique or exclusion constraint covers the whole table (e.g. it isn't a partial unique
|
211
|
+
index), then you can just specify the column using the +:target+ option:
|
212
|
+
|
213
|
+
DB[:table].insert_conflict(:target=>:a).insert(:a=>1, :b=>2)
|
214
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
215
|
+
# ON CONFLICT (a) DO NOTHING
|
216
|
+
|
217
|
+
If you want to update the existing row instead of ignoring the constraint violation, you
|
218
|
+
can pass an +:update+ option with a hash of values to update. You must pass either the
|
219
|
+
+:target+ or +:constraint+ options when passing the +:update+ option:
|
220
|
+
|
221
|
+
DB[:table].insert_conflict(:target=>:a, :update=>{:b=>:excluded__b}).insert(:a=>1, :b=>2)
|
222
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
223
|
+
# ON CONFLICT (a) DO UPDATE SET b = excluded.b
|
224
|
+
|
225
|
+
Additionally, if you only want to do the update in certain cases, you can specify an
|
226
|
+
+:update_where+ option, which will be used as a filter. If the row doesn't match the
|
227
|
+
conditions, the constraint violation will be ignored, but the row will not be updated:
|
228
|
+
|
229
|
+
DB[:table].insert_conflict(:constraint=>:table_a_uidx,
|
230
|
+
:update=>{:b=>:excluded__b}, :update_where=>{:table__status_id=>1}).insert(:a=>1, :b=>2)
|
231
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
232
|
+
# ON CONFLICT ON CONSTRAINT table_a_uidx
|
233
|
+
# DO UPDATE SET b = excluded.b WHERE (table.status_id = 1)
|
234
|
+
|
188
235
|
=== Distinct On Specific Columns
|
189
236
|
|
190
237
|
Sequel allows passing columns to <tt>Dataset#distinct</tt>, which will make the dataset return
|
data/doc/querying.rdoc
CHANGED
@@ -677,6 +677,11 @@ You can remove an existing grouping using +ungrouped+:
|
|
677
677
|
|
678
678
|
Album.group(:artist_id).ungrouped
|
679
679
|
# SELECT * FROM albums
|
680
|
+
|
681
|
+
If you want to add a column to the end of the existing grouping columns:
|
682
|
+
|
683
|
+
Album.group(:artist_id).group_append(:name)
|
684
|
+
# SELECT * FROM albums GROUP BY artist_id, name
|
680
685
|
|
681
686
|
A common use of grouping is to count based on the number of grouped rows,
|
682
687
|
and Sequel provides a +group_and_count+ method to make this easier:
|
@@ -0,0 +1,181 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* The =~ and !~ methods are now defined on ComplexExpressions in
|
4
|
+
addition to GenericExpressions, allowing the following code to
|
5
|
+
work:
|
6
|
+
|
7
|
+
DB[:table].where{(column1 + column2) =~ column3}
|
8
|
+
|
9
|
+
* Dataset#group_append has been added for appending to an existing
|
10
|
+
GROUP BY clause:
|
11
|
+
|
12
|
+
ds = DB[:table].group(:column1)
|
13
|
+
# SELECT * FROM table GROUP BY column1
|
14
|
+
|
15
|
+
ds = ds.group_append(:column2)
|
16
|
+
# SELECT * FROM table GROUP BY column1, column2
|
17
|
+
|
18
|
+
* An inverted_subsets plugin has been added, for automatic creation of
|
19
|
+
methods for the inversion of the subset criteria. For example:
|
20
|
+
|
21
|
+
Album.plugin :inverted_subsets
|
22
|
+
Album.subset :published, :published=>true
|
23
|
+
|
24
|
+
Album.published
|
25
|
+
# SELECT * FROM albums WHERE published IS TRUE
|
26
|
+
|
27
|
+
Album.not_published
|
28
|
+
# SELECT * FROM albums WHERE published IS NOT TRUE
|
29
|
+
|
30
|
+
By default, the subset method name is prefixed with "not_". You can
|
31
|
+
pass a block to override the default behavior:
|
32
|
+
|
33
|
+
Album.plugin(:inverted_subsets){|name| "exclude_#{name}"}
|
34
|
+
Album.subset :published, :published=>true
|
35
|
+
|
36
|
+
Album.exclude_published
|
37
|
+
# SELECT * FROM albums WHERE published IS NOT TRUE
|
38
|
+
|
39
|
+
* A singular_table_names plugin has been added, which changes Sequel
|
40
|
+
to not pluralize table names by default.
|
41
|
+
|
42
|
+
Sequel::Model.plugin :singular_table_names
|
43
|
+
class FooBar < Sequel::Model; end
|
44
|
+
FooBar.table_name # => foo_bar
|
45
|
+
|
46
|
+
* Dataset#insert_conflict and #insert_ignore have been added on
|
47
|
+
PostgreSQL. When using PostgreSQL 9.5+, they allow you to ignore
|
48
|
+
unique or exclusion constraint violations on inserting, or to do
|
49
|
+
an update instead:
|
50
|
+
|
51
|
+
DB[:table].insert_conflict.insert(:a=>1, :b=>2)
|
52
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
53
|
+
# ON CONFLICT DO NOTHING
|
54
|
+
|
55
|
+
You can pass a specific constraint name using :constraint, to only
|
56
|
+
ignore a specific constraint violation:
|
57
|
+
|
58
|
+
DB[:table].insert_conflict(:constraint=>:table_a_uidx).
|
59
|
+
insert(:a=>1, :b=>2)
|
60
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
61
|
+
# ON CONFLICT ON CONSTRAINT table_a_uidx DO NOTHING
|
62
|
+
|
63
|
+
If the unique or exclusion constraint covers the whole table (e.g.
|
64
|
+
it isn't a partial unique index), then you can just specify the
|
65
|
+
column using the :target option:
|
66
|
+
|
67
|
+
DB[:table].insert_conflict(:target=>:a).insert(:a=>1, :b=>2)
|
68
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
69
|
+
# ON CONFLICT (a) DO NOTHING
|
70
|
+
|
71
|
+
If you want to update the existing row instead of ignoring the
|
72
|
+
constraint violation, you can pass an :update option with a hash of
|
73
|
+
values to update. You must pass either the :target or :constraint
|
74
|
+
options when passing the :update option:
|
75
|
+
|
76
|
+
DB[:table].insert_conflict(:target=>:a,
|
77
|
+
:update=>{:b=>:excluded__b}).
|
78
|
+
insert(:a=>1, :b=>2)
|
79
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
80
|
+
# ON CONFLICT (a) DO UPDATE SET b = excluded.b
|
81
|
+
|
82
|
+
Additionally, if you only want to do the update in certain cases,
|
83
|
+
you can specify an :update_where option, which will be used as a
|
84
|
+
filter. If the row doesn't match the conditions, the constraint
|
85
|
+
violation will be ignored, but the row will not be updated:
|
86
|
+
|
87
|
+
DB[:table].insert_conflict(:constraint=>:table_a_uidx,
|
88
|
+
:update=>{:b=>:excluded__b},
|
89
|
+
:update_where=>{:table__status_id=>1}).
|
90
|
+
insert(:a=>1, :b=>2)
|
91
|
+
# INSERT INTO TABLE (a, b) VALUES (1, 2)
|
92
|
+
# ON CONFLICT ON CONSTRAINT table_a_uidx
|
93
|
+
# DO UPDATE SET b = excluded.b WHERE (table.status_id = 1)
|
94
|
+
|
95
|
+
* Dataset#group_rollup and #group_cube are now supported when using
|
96
|
+
PostgreSQL 9.5+.
|
97
|
+
|
98
|
+
* Sequel now supports Dataset#returning when using prepared statements
|
99
|
+
and bound variables:
|
100
|
+
|
101
|
+
DB[:table].returning.prepare(:insert, :i, :col=>:$col).
|
102
|
+
call(:col=>42)
|
103
|
+
# => [{:col=>42}]
|
104
|
+
|
105
|
+
= Other Improvements
|
106
|
+
|
107
|
+
* The serialization plugin now integrates with the dirty plugin, so
|
108
|
+
that column changes are detected correctly. However, column values
|
109
|
+
that are changed and then changed back to the original value are
|
110
|
+
still detected as changed.
|
111
|
+
|
112
|
+
* Dataset#for_update and similar locking methods now cause Sequel not
|
113
|
+
to use the :read_only shard if sharding is used.
|
114
|
+
|
115
|
+
* The association_pks plugin now clears cached delayed associated pks
|
116
|
+
when the object is refreshed.
|
117
|
+
|
118
|
+
* The :collate column option when adding columns now literalizes
|
119
|
+
non-String values on PostgreSQL. Previously, the :collate option
|
120
|
+
value was used verbatim. This is because PostgreSQL's collations
|
121
|
+
generally require quoting as they are uppercase or mixed-case.
|
122
|
+
|
123
|
+
* Sequel's metadata parsing methods now support Microsoft SQL Server
|
124
|
+
2012+ when used in case sensitive mode.
|
125
|
+
|
126
|
+
* Sequel now recognizes an addition check constraint violation
|
127
|
+
exception on SQLite.
|
128
|
+
|
129
|
+
* Sequel now recognizes constraint violations when using the
|
130
|
+
swift/sqlite adapter.
|
131
|
+
|
132
|
+
* Sequel now automatically REORGs tables when altering them in the
|
133
|
+
jdbc/db2 adapter.
|
134
|
+
|
135
|
+
= Backwards Compatibility
|
136
|
+
|
137
|
+
* Sequel now defaults to ignoring NULL values when using IN/NOT IN
|
138
|
+
with an empty array. Previously, code such as:
|
139
|
+
|
140
|
+
DB[:table].where(:column=>[])
|
141
|
+
|
142
|
+
would be literalized as:
|
143
|
+
|
144
|
+
SELECT * FROM table WHERE (column != column)
|
145
|
+
|
146
|
+
This yields a NULL value when column is NULL, similarly to how most
|
147
|
+
other SQL operators work. Unfortunately, most databases do not
|
148
|
+
optimize this, and such a query can require a sequential scan of the
|
149
|
+
table.
|
150
|
+
|
151
|
+
Sequel previously shipped with a empty_array_ignore_nulls extension
|
152
|
+
that literalized the query to:
|
153
|
+
|
154
|
+
SELECT * FROM table WHERE (1 = 0)
|
155
|
+
|
156
|
+
which databases will generally optimize to a constant false value,
|
157
|
+
resulting in much faster queries. This behavior is now the default.
|
158
|
+
|
159
|
+
Users that desire the previous behavior can use the new
|
160
|
+
empty_array_consider_nulls extension.
|
161
|
+
|
162
|
+
* The deprecated firebird and informix adapters have been removed.
|
163
|
+
|
164
|
+
* Calling prepare on a prepared statement now raises an exception.
|
165
|
+
It was supported accidently before, as prepared statements are
|
166
|
+
dataset instances.
|
167
|
+
|
168
|
+
* Model::DatasetModule#subset now calls Model.subset instead of
|
169
|
+
the other way around. This makes it possible to modify the
|
170
|
+
behavior of subset in a plugin.
|
171
|
+
|
172
|
+
* The :collate column option change on PostgreSQL can break code
|
173
|
+
that used already quoted values in symbols. For example:
|
174
|
+
|
175
|
+
String :column_name, collate=>:'"C"'
|
176
|
+
|
177
|
+
would need to change to:
|
178
|
+
|
179
|
+
String :column_name, collate=>:C
|
180
|
+
# or
|
181
|
+
String :column_name, collate=>'"C"'
|
@@ -185,15 +185,6 @@ module Sequel
|
|
185
185
|
|
186
186
|
# Hash of connection procs for converting
|
187
187
|
attr_reader :conversion_procs
|
188
|
-
|
189
|
-
# REORG the related table whenever it is altered. This is not always
|
190
|
-
# required, but it is necessary for compatibilty with other Sequel
|
191
|
-
# code in many cases.
|
192
|
-
def alter_table(name, generator=nil)
|
193
|
-
res = super
|
194
|
-
reorg(name)
|
195
|
-
res
|
196
|
-
end
|
197
188
|
|
198
189
|
# Create a new connection object for the given server.
|
199
190
|
def connect(server)
|
@@ -271,25 +262,6 @@ module Sequel
|
|
271
262
|
end
|
272
263
|
end
|
273
264
|
|
274
|
-
# On DB2, a table might need to be REORGed if you are testing existence
|
275
|
-
# of it. This REORGs automatically if the database raises a specific
|
276
|
-
# error that indicates it should be REORGed.
|
277
|
-
def table_exists?(name)
|
278
|
-
v ||= false # only retry once
|
279
|
-
sch, table_name = schema_and_table(name)
|
280
|
-
name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
|
281
|
-
from(name).first
|
282
|
-
true
|
283
|
-
rescue DatabaseError => e
|
284
|
-
if e.to_s =~ /Operation not allowed for reason code "7" on table/ && v == false
|
285
|
-
# table probably needs reorg
|
286
|
-
reorg(name)
|
287
|
-
v = true
|
288
|
-
retry
|
289
|
-
end
|
290
|
-
false
|
291
|
-
end
|
292
|
-
|
293
265
|
private
|
294
266
|
|
295
267
|
# Execute the given SQL on the database.
|
@@ -83,6 +83,25 @@ module Sequel
|
|
83
83
|
true
|
84
84
|
end
|
85
85
|
|
86
|
+
# On DB2, a table might need to be REORGed if you are testing existence
|
87
|
+
# of it. This REORGs automatically if the database raises a specific
|
88
|
+
# error that indicates it should be REORGed.
|
89
|
+
def table_exists?(name)
|
90
|
+
v ||= false # only retry once
|
91
|
+
sch, table_name = schema_and_table(name)
|
92
|
+
name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
|
93
|
+
from(name).first
|
94
|
+
true
|
95
|
+
rescue DatabaseError => e
|
96
|
+
if e.to_s =~ /Operation not allowed for reason code "7" on table/ && v == false
|
97
|
+
# table probably needs reorg
|
98
|
+
reorg(name)
|
99
|
+
v = true
|
100
|
+
retry
|
101
|
+
end
|
102
|
+
false
|
103
|
+
end
|
104
|
+
|
86
105
|
private
|
87
106
|
|
88
107
|
# Handle DB2 specific alter table operations.
|
@@ -119,6 +138,16 @@ module Sequel
|
|
119
138
|
end
|
120
139
|
end
|
121
140
|
|
141
|
+
# REORG the related table whenever it is altered. This is not always
|
142
|
+
# required, but it is necessary for compatibilty with other Sequel
|
143
|
+
# code in many cases.
|
144
|
+
def apply_alter_table(name, ops)
|
145
|
+
alter_table_sql_list(name, ops).each do |sql|
|
146
|
+
execute_ddl(sql)
|
147
|
+
reorg(name)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
122
151
|
# DB2 uses an identity column for autoincrement.
|
123
152
|
def auto_increment_sql
|
124
153
|
AUTOINCREMENT
|
@@ -190,12 +219,12 @@ module Sequel
|
|
190
219
|
# Run the REORG TABLE command for the table, necessary when
|
191
220
|
# the table has been altered.
|
192
221
|
def reorg(table)
|
193
|
-
|
222
|
+
execute_ddl(reorg_sql(table))
|
194
223
|
end
|
195
224
|
|
196
225
|
# The SQL to use for REORGing a table.
|
197
226
|
def reorg_sql(table)
|
198
|
-
"CALL ADMIN_CMD(#{literal("REORG TABLE #{table}")})"
|
227
|
+
"CALL SYSPROC.ADMIN_CMD(#{literal("REORG TABLE #{quote_schema_table(table)}")})"
|
199
228
|
end
|
200
229
|
|
201
230
|
# Treat clob as blob if use_clob_as_blob is true
|
@@ -131,10 +131,10 @@ module Sequel
|
|
131
131
|
schema, table = schema_and_table(table)
|
132
132
|
current_schema = m.call(get(Sequel.function('schema_name')))
|
133
133
|
fk_action_map = FOREIGN_KEY_ACTION_MAP
|
134
|
-
ds = metadata_dataset.from(:
|
135
|
-
join(:
|
136
|
-
join(:
|
137
|
-
join(:
|
134
|
+
ds = metadata_dataset.from(Sequel.lit('[sys].[foreign_keys]').as(:fk)).
|
135
|
+
join(Sequel.lit('[sys].[foreign_key_columns]').as(:fkc), :constraint_object_id => :object_id).
|
136
|
+
join(Sequel.lit('[sys].[all_columns]').as(:pc), :object_id => :fkc__parent_object_id, :column_id => :fkc__parent_column_id).
|
137
|
+
join(Sequel.lit('[sys].[all_columns]').as(:rc), :object_id => :fkc__referenced_object_id, :column_id => :fkc__referenced_column_id).
|
138
138
|
where{{object_schema_name(:fk__parent_object_id) => im.call(schema || current_schema)}}.
|
139
139
|
where{{object_name(:fk__parent_object_id) => im.call(table)}}.
|
140
140
|
select{[:fk__name,
|
@@ -169,10 +169,10 @@ module Sequel
|
|
169
169
|
m = output_identifier_meth
|
170
170
|
im = input_identifier_meth
|
171
171
|
indexes = {}
|
172
|
-
ds = metadata_dataset.from(:
|
173
|
-
join(:
|
174
|
-
join(:
|
175
|
-
join(:
|
172
|
+
ds = metadata_dataset.from(Sequel.lit('[sys].[tables]').as(:t)).
|
173
|
+
join(Sequel.lit('[sys].[indexes]').as(:i), :object_id=>:object_id).
|
174
|
+
join(Sequel.lit('[sys].[index_columns]').as(:ic), :object_id=>:object_id, :index_id=>:index_id).
|
175
|
+
join(Sequel.lit('[sys].[columns]').as(:c), :object_id=>:object_id, :column_id=>:column_id).
|
176
176
|
select(:i__name, :i__is_unique, :c__name___column).
|
177
177
|
where{{t__name=>im.call(table)}}.
|
178
178
|
where(:i__is_primary_key=>0, :i__is_disabled=>0).
|
@@ -433,15 +433,15 @@ module Sequel
|
|
433
433
|
inf_sch_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, s) : Sequel.expr(s)}
|
434
434
|
sys_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, Sequel.qualify(Sequel.lit(''), s)) : Sequel.expr(s)}
|
435
435
|
|
436
|
-
identity_cols = metadata_dataset.from(
|
436
|
+
identity_cols = metadata_dataset.from(Sequel.lit('[sys].[columns]')).
|
437
437
|
where(:object_id=>table_id, :is_identity=>true).
|
438
438
|
select_map(:name)
|
439
439
|
|
440
|
-
pk_index_id = metadata_dataset.from(sys_qual.call(
|
440
|
+
pk_index_id = metadata_dataset.from(sys_qual.call(Sequel.lit('sysindexes'))).
|
441
441
|
where(:id=>table_id, :indid=>1..254){{(status & 2048)=>2048}}.
|
442
442
|
get(:indid)
|
443
|
-
pk_cols = metadata_dataset.from(sys_qual.call(
|
444
|
-
join(sys_qual.call(
|
443
|
+
pk_cols = metadata_dataset.from(sys_qual.call(Sequel.lit('sysindexkeys')).as(:sik)).
|
444
|
+
join(sys_qual.call(Sequel.lit('syscolumns')).as(:sc), :id=>:id, :colid=>:colid).
|
445
445
|
where(:sik__id=>table_id, :sik__indid=>pk_index_id).
|
446
446
|
select_order_map(:sc__name)
|
447
447
|
|