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