sequel 3.21.0 → 3.39.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 +1061 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +103 -63
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +67 -51
- data/doc/advanced_associations.rdoc +189 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +547 -0
- data/doc/opening_databases.rdoc +114 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +18 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +453 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +56 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +73 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +279 -97
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +125 -222
- data/lib/sequel/adapters/mysql2.rb +65 -56
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +349 -53
- data/lib/sequel/adapters/postgres.rb +368 -138
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +343 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +401 -116
- data/lib/sequel/adapters/shared/mysql.rb +424 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +257 -45
- data/lib/sequel/adapters/shared/postgres.rb +675 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +285 -96
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +28 -19
- data/lib/sequel/adapters/tinytds.rb +174 -22
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +11 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +43 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +38 -28
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +190 -46
- data/lib/sequel/database/query.rb +272 -110
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +300 -67
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +305 -54
- data/lib/sequel/dataset/sql.rb +720 -292
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +537 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +313 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +208 -0
- data/lib/sequel/extensions/pg_range.rb +512 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +572 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +58 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +167 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +55 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +649 -122
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +194 -66
- data/spec/adapters/mysql_spec.rb +475 -306
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +1982 -325
- data/spec/adapters/spec_helper.rb +9 -6
- data/spec/adapters/sqlite_spec.rb +203 -75
- data/spec/core/connection_pool_spec.rb +218 -93
- data/spec/core/database_spec.rb +956 -522
- data/spec/core/dataset_spec.rb +1631 -1242
- data/spec/core/expression_filters_spec.rb +690 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +320 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +194 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +323 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +23 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +58 -67
- data/spec/extensions/validation_helpers_spec.rb +31 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +11 -5
- data/spec/integration/dataset_test.rb +717 -129
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +604 -147
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +367 -57
- data/spec/integration/spec_helper.rb +42 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +31 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +209 -80
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
module Access
|
|
3
3
|
module DatabaseMethods
|
|
4
|
+
# Access uses type :access as the database_type
|
|
4
5
|
def database_type
|
|
5
6
|
:access
|
|
6
7
|
end
|
|
7
8
|
|
|
8
|
-
def dataset(opts = nil)
|
|
9
|
-
ds = super
|
|
10
|
-
ds.extend(DatasetMethods)
|
|
11
|
-
ds
|
|
12
|
-
end
|
|
13
|
-
|
|
14
9
|
# Doesn't work, due to security restrictions on MSysObjects
|
|
15
10
|
def tables
|
|
16
11
|
from(:MSysObjects).filter(:Type=>1, :Flags=>0).select_map(:Name).map{|x| x.to_sym}
|
|
17
12
|
end
|
|
18
13
|
|
|
14
|
+
# Access uses type Counter for an autoincrementing keys
|
|
19
15
|
def serial_primary_key_options
|
|
20
16
|
{:primary_key => true, :type=>:Counter}
|
|
21
17
|
end
|
|
@@ -32,18 +28,45 @@ module Sequel
|
|
|
32
28
|
end
|
|
33
29
|
|
|
34
30
|
module DatasetMethods
|
|
35
|
-
SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'limit distinct columns from join where group order having compounds')
|
|
31
|
+
SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'select limit distinct columns from join where group order having compounds')
|
|
32
|
+
DATE_FORMAT = '#%Y-%m-%d#'.freeze
|
|
33
|
+
TIMESTAMP_FORMAT = '#%Y-%m-%d %H:%M:%S#'.freeze
|
|
34
|
+
TOP = " TOP ".freeze
|
|
35
|
+
BRACKET_CLOSE = Dataset::BRACKET_CLOSE
|
|
36
|
+
BRACKET_OPEN = Dataset::BRACKET_OPEN
|
|
36
37
|
|
|
38
|
+
# Access doesn't support INTERSECT or EXCEPT
|
|
37
39
|
def supports_intersect_except?
|
|
38
40
|
false
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
private
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
# Access uses # to quote dates
|
|
46
|
+
def literal_date(d)
|
|
47
|
+
d.strftime(DATE_FORMAT)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Access uses # to quote datetimes
|
|
51
|
+
def literal_datetime(t)
|
|
52
|
+
t.strftime(TIMESTAMP_FORMAT)
|
|
53
|
+
end
|
|
54
|
+
alias literal_time literal_datetime
|
|
55
|
+
|
|
56
|
+
# Access uses TOP for limits
|
|
57
|
+
def select_limit_sql(sql)
|
|
58
|
+
if l = @opts[:limit]
|
|
59
|
+
sql << TOP
|
|
60
|
+
literal_append(sql, l)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Access uses [] for quoting identifiers
|
|
65
|
+
def quoted_identifier_append(sql, v)
|
|
66
|
+
sql << BRACKET_OPEN << v.to_s << BRACKET_CLOSE
|
|
45
67
|
end
|
|
46
68
|
|
|
69
|
+
# Access requires the limit clause come before other clauses
|
|
47
70
|
def select_clause_methods
|
|
48
71
|
SELECT_CLAUSE_METHODS
|
|
49
72
|
end
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
Sequel.require 'adapters/utils/emulate_offset_with_row_number'
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module DB2
|
|
5
|
+
@use_clob_as_blob = true
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
# Whether to use clob as the generic File type, true by default.
|
|
9
|
+
attr_accessor :use_clob_as_blob
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module DatabaseMethods
|
|
13
|
+
AUTOINCREMENT = 'GENERATED ALWAYS AS IDENTITY'.freeze
|
|
14
|
+
NOT_NULL = ' NOT NULL'.freeze
|
|
15
|
+
NULL = ''.freeze
|
|
16
|
+
|
|
17
|
+
# DB2 always uses :db2 as it's database type
|
|
18
|
+
def database_type
|
|
19
|
+
:db2
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Return the database version as a string. Don't rely on this,
|
|
23
|
+
# it may return an integer in the future.
|
|
24
|
+
def db2_version
|
|
25
|
+
return @db2_version if @db2_version
|
|
26
|
+
@db2_version = metadata_dataset.with_sql("select service_level from sysibmadm.env_inst_info").first[:service_level]
|
|
27
|
+
end
|
|
28
|
+
alias_method :server_version, :db2_version
|
|
29
|
+
|
|
30
|
+
# Use SYSIBM.SYSCOLUMNS to get the information on the tables.
|
|
31
|
+
def schema_parse_table(table, opts = {})
|
|
32
|
+
m = output_identifier_meth(opts[:dataset])
|
|
33
|
+
im = input_identifier_meth(opts[:dataset])
|
|
34
|
+
metadata_dataset.with_sql("SELECT * FROM SYSIBM.SYSCOLUMNS WHERE TBNAME = #{literal(im.call(table))} ORDER BY COLNO").
|
|
35
|
+
collect do |column|
|
|
36
|
+
column[:db_type] = column.delete(:typename)
|
|
37
|
+
if column[:db_type] == "DECIMAL"
|
|
38
|
+
column[:db_type] << "(#{column[:longlength]},#{column[:scale]})"
|
|
39
|
+
end
|
|
40
|
+
column[:allow_null] = column.delete(:nulls) == 'Y'
|
|
41
|
+
column[:primary_key] = column.delete(:identity) == 'Y' || !column[:keyseq].nil?
|
|
42
|
+
column[:type] = schema_column_type(column[:db_type])
|
|
43
|
+
[ m.call(column.delete(:name)), column]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Use SYSCAT.TABLES to get the tables for the database
|
|
48
|
+
def tables
|
|
49
|
+
metadata_dataset.
|
|
50
|
+
with_sql("SELECT TABNAME FROM SYSCAT.TABLES WHERE TYPE='T' AND OWNER = #{literal(input_identifier_meth.call(opts[:user]))}").
|
|
51
|
+
all.map{|h| output_identifier_meth.call(h[:tabname]) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Use SYSCAT.TABLES to get the views for the database
|
|
55
|
+
def views
|
|
56
|
+
metadata_dataset.
|
|
57
|
+
with_sql("SELECT TABNAME FROM SYSCAT.TABLES WHERE TYPE='V' AND OWNER = #{literal(input_identifier_meth.call(opts[:user]))}").
|
|
58
|
+
all.map{|h| output_identifier_meth.call(h[:tabname]) }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Use SYSCAT.INDEXES to get the indexes for the table
|
|
62
|
+
def indexes(table, opts = {})
|
|
63
|
+
m = output_identifier_meth
|
|
64
|
+
indexes = {}
|
|
65
|
+
metadata_dataset.
|
|
66
|
+
from(:syscat__indexes).
|
|
67
|
+
select(:indname, :uniquerule, :colnames).
|
|
68
|
+
where(:tabname=>input_identifier_meth.call(table), :system_required=>0).
|
|
69
|
+
each do |r|
|
|
70
|
+
indexes[m.call(r[:indname])] = {:unique=>(r[:uniquerule]=='U'), :columns=>r[:colnames][1..-1].split('+').map{|v| m.call(v)}}
|
|
71
|
+
end
|
|
72
|
+
indexes
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
# Handle DB2 specific alter table operations.
|
|
78
|
+
def alter_table_sql(table, op)
|
|
79
|
+
case op[:op]
|
|
80
|
+
when :add_column
|
|
81
|
+
if op[:primary_key] && op[:auto_increment] && op[:type] == Integer
|
|
82
|
+
[
|
|
83
|
+
"ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op.merge(:auto_increment=>false, :primary_key=>false, :default=>0, :null=>false))}",
|
|
84
|
+
"ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{literal(op[:name])} DROP DEFAULT",
|
|
85
|
+
"ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{literal(op[:name])} SET #{AUTOINCREMENT}"
|
|
86
|
+
]
|
|
87
|
+
else
|
|
88
|
+
"ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
|
|
89
|
+
end
|
|
90
|
+
when :drop_column
|
|
91
|
+
"ALTER TABLE #{quote_schema_table(table)} DROP #{column_definition_sql(op)}"
|
|
92
|
+
when :rename_column # renaming is only possible after db2 v9.7
|
|
93
|
+
"ALTER TABLE #{quote_schema_table(table)} RENAME COLUMN #{quote_identifier(op[:name])} TO #{quote_identifier(op[:new_name])}"
|
|
94
|
+
when :set_column_type
|
|
95
|
+
"ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} SET DATA TYPE #{type_literal(op)}"
|
|
96
|
+
when :set_column_default
|
|
97
|
+
"ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} SET DEFAULT #{literal(op[:default])}"
|
|
98
|
+
when :add_constraint
|
|
99
|
+
if op[:type] == :unique
|
|
100
|
+
sqls = op[:columns].map{|c| ["ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(c)} SET NOT NULL", reorg_sql(table)]}
|
|
101
|
+
sqls << super
|
|
102
|
+
sqls.flatten
|
|
103
|
+
else
|
|
104
|
+
super
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
super
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# DB2 uses an identity column for autoincrement.
|
|
112
|
+
def auto_increment_sql
|
|
113
|
+
AUTOINCREMENT
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Add null/not null SQL fragment to column creation SQL.
|
|
117
|
+
def column_definition_null_sql(sql, column)
|
|
118
|
+
null = column.fetch(:null, column[:allow_null])
|
|
119
|
+
null = false if column[:primary_key]
|
|
120
|
+
|
|
121
|
+
sql << NOT_NULL if null == false
|
|
122
|
+
sql << NULL if null == true
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Supply columns with NOT NULL if they are part of a composite
|
|
126
|
+
# primary/foreign key
|
|
127
|
+
def column_list_sql(g)
|
|
128
|
+
ks = []
|
|
129
|
+
g.constraints.each{|c| ks = c[:columns] if [:primary_key, :foreign_key].include? c[:type]}
|
|
130
|
+
g.columns.each{|c| c[:null] = false if ks.include?(c[:name]) }
|
|
131
|
+
super
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Insert data from the current table into the new table after
|
|
135
|
+
# creating the table, since it is not possible to do it in one step.
|
|
136
|
+
def create_table_as(name, sql, options)
|
|
137
|
+
super
|
|
138
|
+
from(name).insert(sql.is_a?(Dataset) ? sql : dataset.with_sql(sql))
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# DB2 requires parens around the SELECT, and DEFINITION ONLY at the end.
|
|
142
|
+
def create_table_as_sql(name, sql, options)
|
|
143
|
+
"#{create_table_prefix_sql(name, options)} AS (#{sql}) DEFINITION ONLY"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Here we use DGTT which has most backward compatibility, which uses
|
|
147
|
+
# DECLARE instead of CREATE. CGTT can only be used after version 9.7.
|
|
148
|
+
# http://www.ibm.com/developerworks/data/library/techarticle/dm-0912globaltemptable/
|
|
149
|
+
def create_table_prefix_sql(name, options)
|
|
150
|
+
if options[:temp]
|
|
151
|
+
"DECLARE GLOBAL TEMPORARY TABLE #{quote_identifier(name)}"
|
|
152
|
+
else
|
|
153
|
+
super
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# DB2 has issues with quoted identifiers, so
|
|
158
|
+
# turn off database quoting by default.
|
|
159
|
+
def quote_identifiers_default
|
|
160
|
+
false
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# DB2 uses RENAME TABLE to rename tables.
|
|
164
|
+
def rename_table_sql(name, new_name)
|
|
165
|
+
"RENAME TABLE #{quote_schema_table(name)} TO #{quote_schema_table(new_name)}"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Run the REORG TABLE command for the table, necessary when
|
|
169
|
+
# the table has been altered.
|
|
170
|
+
def reorg(table)
|
|
171
|
+
synchronize(opts[:server]){|c| c.execute(reorg_sql(table))}
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# The SQL to use for REORGing a table.
|
|
175
|
+
def reorg_sql(table)
|
|
176
|
+
"CALL ADMIN_CMD(#{literal("REORG TABLE #{table}")})"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# We uses the clob type by default for Files.
|
|
180
|
+
# Note: if user select to use blob, then insert statement should use
|
|
181
|
+
# use this for blob value:
|
|
182
|
+
# cast(X'fffefdfcfbfa' as blob(2G))
|
|
183
|
+
def type_literal_generic_file(column)
|
|
184
|
+
::Sequel::DB2::use_clob_as_blob ? :clob : :blob
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# DB2 uses smallint to store booleans.
|
|
188
|
+
def type_literal_generic_trueclass(column)
|
|
189
|
+
:smallint
|
|
190
|
+
end
|
|
191
|
+
alias type_literal_generic_falseclass type_literal_generic_trueclass
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
module DatasetMethods
|
|
195
|
+
include EmulateOffsetWithRowNumber
|
|
196
|
+
|
|
197
|
+
PAREN_CLOSE = Dataset::PAREN_CLOSE
|
|
198
|
+
PAREN_OPEN = Dataset::PAREN_OPEN
|
|
199
|
+
BITWISE_METHOD_MAP = {:& =>:BITAND, :| => :BITOR, :^ => :BITXOR, :'B~'=>:BITNOT}
|
|
200
|
+
EMULATED_FUNCTION_MAP = {:char_length=>'length'.freeze}
|
|
201
|
+
BOOL_TRUE = '1'.freeze
|
|
202
|
+
BOOL_FALSE = '0'.freeze
|
|
203
|
+
CAST_STRING_OPEN = "RTRIM(CHAR(".freeze
|
|
204
|
+
CAST_STRING_CLOSE = "))".freeze
|
|
205
|
+
FETCH_FIRST_ROW_ONLY = " FETCH FIRST ROW ONLY".freeze
|
|
206
|
+
FETCH_FIRST = " FETCH FIRST ".freeze
|
|
207
|
+
ROWS_ONLY = " ROWS ONLY".freeze
|
|
208
|
+
EMPTY_FROM_TABLE = ' FROM "SYSIBM"."SYSDUMMY1"'.freeze
|
|
209
|
+
|
|
210
|
+
# DB2 casts strings using RTRIM and CHAR instead of VARCHAR.
|
|
211
|
+
def cast_sql_append(sql, expr, type)
|
|
212
|
+
if(type == String)
|
|
213
|
+
sql << CAST_STRING_OPEN
|
|
214
|
+
literal_append(sql, expr)
|
|
215
|
+
sql << CAST_STRING_CLOSE
|
|
216
|
+
else
|
|
217
|
+
super
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Handle DB2 specific LIKE and bitwise operator support, and
|
|
222
|
+
# emulate the extract method, which DB2 doesn't natively support.
|
|
223
|
+
def complex_expression_sql_append(sql, op, args)
|
|
224
|
+
case op
|
|
225
|
+
when :ILIKE
|
|
226
|
+
super(sql, :LIKE, [SQL::Function.new(:upper, args.at(0)), SQL::Function.new(:upper, args.at(1)) ])
|
|
227
|
+
when :"NOT ILIKE"
|
|
228
|
+
super(sql, :"NOT LIKE", [SQL::Function.new(:upper, args.at(0)), SQL::Function.new(:upper, args.at(1)) ])
|
|
229
|
+
when :&, :|, :^
|
|
230
|
+
# works with db2 v9.5 and after
|
|
231
|
+
op = BITWISE_METHOD_MAP[op]
|
|
232
|
+
sql << complex_expression_arg_pairs(args){|a, b| literal(SQL::Function.new(op, a, b))}
|
|
233
|
+
when :<<
|
|
234
|
+
sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} * POWER(2, #{literal(b)}))"}
|
|
235
|
+
when :>>
|
|
236
|
+
sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} / POWER(2, #{literal(b)}))"}
|
|
237
|
+
when :%
|
|
238
|
+
sql << complex_expression_arg_pairs(args){|a, b| "MOD(#{literal(a)}, #{literal(b)})"}
|
|
239
|
+
when :'B~'
|
|
240
|
+
literal_append(sql, SQL::Function.new(:BITNOT, *args))
|
|
241
|
+
when :extract
|
|
242
|
+
sql << args.at(0).to_s
|
|
243
|
+
sql << PAREN_OPEN
|
|
244
|
+
literal_append(sql, args.at(1))
|
|
245
|
+
sql << PAREN_CLOSE
|
|
246
|
+
else
|
|
247
|
+
super
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# DB2 supports GROUP BY CUBE
|
|
252
|
+
def supports_group_cube?
|
|
253
|
+
true
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# DB2 supports GROUP BY ROLLUP
|
|
257
|
+
def supports_group_rollup?
|
|
258
|
+
true
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# DB2 does not support IS TRUE.
|
|
262
|
+
def supports_is_true?
|
|
263
|
+
false
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# DB2 does not support multiple columns in IN.
|
|
267
|
+
def supports_multiple_column_in?
|
|
268
|
+
false
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# DB2 only allows * in SELECT if it is the only thing being selected.
|
|
272
|
+
def supports_select_all_and_column?
|
|
273
|
+
false
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# DB2 does not support fractional seconds in timestamps.
|
|
277
|
+
def supports_timestamp_usecs?
|
|
278
|
+
false
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# DB2 supports window functions
|
|
282
|
+
def supports_window_functions?
|
|
283
|
+
true
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# DB2 does not support WHERE 1.
|
|
287
|
+
def supports_where_true?
|
|
288
|
+
false
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
private
|
|
292
|
+
|
|
293
|
+
# DB2 needs the standard workaround to insert all default values into
|
|
294
|
+
# a table with more than one column.
|
|
295
|
+
def insert_supports_empty_values?
|
|
296
|
+
false
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Use 0 for false on DB2
|
|
300
|
+
def literal_false
|
|
301
|
+
BOOL_FALSE
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# Use 1 for true on DB2
|
|
305
|
+
def literal_true
|
|
306
|
+
BOOL_TRUE
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Add a fallback table for empty from situation
|
|
310
|
+
def select_from_sql(sql)
|
|
311
|
+
@opts[:from] ? super : (sql << EMPTY_FROM_TABLE)
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# Modify the sql to limit the number of rows returned
|
|
315
|
+
# Note:
|
|
316
|
+
#
|
|
317
|
+
# After db2 v9.7, MySQL flavored "LIMIT X OFFSET Y" can be enabled using
|
|
318
|
+
#
|
|
319
|
+
# db2set DB2_COMPATIBILITY_VECTOR=MYSQL
|
|
320
|
+
# db2stop
|
|
321
|
+
# db2start
|
|
322
|
+
#
|
|
323
|
+
# Support for this feature is not used in this adapter however.
|
|
324
|
+
def select_limit_sql(sql)
|
|
325
|
+
if l = @opts[:limit]
|
|
326
|
+
if l == 1
|
|
327
|
+
sql << FETCH_FIRST_ROW_ONLY
|
|
328
|
+
else
|
|
329
|
+
sql << FETCH_FIRST
|
|
330
|
+
literal_append(sql, l)
|
|
331
|
+
sql << ROWS_ONLY
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def _truncate_sql(table)
|
|
337
|
+
# "TRUNCATE #{table} IMMEDIATE" is only for newer version of db2, so we
|
|
338
|
+
# use the following one
|
|
339
|
+
"ALTER TABLE #{quote_schema_table(table)} ACTIVATE NOT LOGGED INITIALLY WITH EMPTY TABLE"
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
end
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
module Sequel
|
|
2
|
+
module Firebird
|
|
3
|
+
module DatabaseMethods
|
|
4
|
+
AUTO_INCREMENT = ''.freeze
|
|
5
|
+
TEMPORARY = 'GLOBAL TEMPORARY '.freeze
|
|
6
|
+
|
|
7
|
+
def clear_primary_key(*tables)
|
|
8
|
+
tables.each{|t| @primary_keys.delete(dataset.send(:input_identifier, t))}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def create_trigger(*args)
|
|
12
|
+
self << create_trigger_sql(*args)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def database_type
|
|
16
|
+
:firebird
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def drop_sequence(name)
|
|
20
|
+
self << drop_sequence_sql(name)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Return primary key for the given table.
|
|
24
|
+
def primary_key(table)
|
|
25
|
+
t = dataset.send(:input_identifier, table)
|
|
26
|
+
@primary_keys.fetch(t) do
|
|
27
|
+
pk = fetch("SELECT RDB$FIELD_NAME FROM RDB$INDEX_SEGMENTS NATURAL JOIN RDB$RELATION_CONSTRAINTS WHERE RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' AND RDB$RELATION_NAME = ?", t).single_value
|
|
28
|
+
@primary_keys[t] = dataset.send(:output_identifier, pk.rstrip) if pk
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def restart_sequence(*args)
|
|
33
|
+
self << restart_sequence_sql(*args)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def sequences(opts={})
|
|
37
|
+
ds = self[:"rdb$generators"].server(opts[:server]).filter(:"rdb$system_flag" => 0).select(:"rdb$generator_name")
|
|
38
|
+
block_given? ? yield(ds) : ds.map{|r| ds.send(:output_identifier, r[:"rdb$generator_name"])}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def tables(opts={})
|
|
42
|
+
tables_or_views(0, opts)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def views(opts={})
|
|
46
|
+
tables_or_views(1, opts)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# Use Firebird specific syntax for add column
|
|
52
|
+
def alter_table_sql(table, op)
|
|
53
|
+
case op[:op]
|
|
54
|
+
when :add_column
|
|
55
|
+
"ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
|
|
56
|
+
when :drop_column
|
|
57
|
+
"ALTER TABLE #{quote_schema_table(table)} DROP #{column_definition_sql(op)}"
|
|
58
|
+
when :rename_column
|
|
59
|
+
"ALTER TABLE #{quote_schema_table(table)} ALTER #{quote_identifier(op[:name])} TO #{quote_identifier(op[:new_name])}"
|
|
60
|
+
when :set_column_type
|
|
61
|
+
"ALTER TABLE #{quote_schema_table(table)} ALTER #{quote_identifier(op[:name])} TYPE #{type_literal(op)}"
|
|
62
|
+
else
|
|
63
|
+
super(table, op)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def auto_increment_sql()
|
|
68
|
+
AUTO_INCREMENT
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def create_sequence_sql(name, opts={})
|
|
72
|
+
"CREATE SEQUENCE #{quote_identifier(name)}"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Firebird gets an override because of the mess of creating a
|
|
76
|
+
# sequence and trigger for auto-incrementing primary keys.
|
|
77
|
+
def create_table_from_generator(name, generator, options)
|
|
78
|
+
drop_statement, create_statements = create_table_sql_list(name, generator, options)
|
|
79
|
+
(execute_ddl(drop_statement) rescue nil) if drop_statement
|
|
80
|
+
create_statements.each{|sql| execute_ddl(sql)}
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def create_table_sql_list(name, generator, options={})
|
|
84
|
+
statements = [create_table_sql(name, generator, options)]
|
|
85
|
+
drop_seq_statement = nil
|
|
86
|
+
generator.columns.each do |c|
|
|
87
|
+
if c[:auto_increment]
|
|
88
|
+
c[:sequence_name] ||= "seq_#{name}_#{c[:name]}"
|
|
89
|
+
unless c[:create_sequence] == false
|
|
90
|
+
drop_seq_statement = drop_sequence_sql(c[:sequence_name])
|
|
91
|
+
statements << create_sequence_sql(c[:sequence_name])
|
|
92
|
+
statements << restart_sequence_sql(c[:sequence_name], {:restart_position => c[:sequence_start_position]}) if c[:sequence_start_position]
|
|
93
|
+
end
|
|
94
|
+
unless c[:create_trigger] == false
|
|
95
|
+
c[:trigger_name] ||= "BI_#{name}_#{c[:name]}"
|
|
96
|
+
c[:quoted_name] = quote_identifier(c[:name])
|
|
97
|
+
trigger_definition = <<-END
|
|
98
|
+
begin
|
|
99
|
+
if ((new.#{c[:quoted_name]} is null) or (new.#{c[:quoted_name]} = 0)) then
|
|
100
|
+
begin
|
|
101
|
+
new.#{c[:quoted_name]} = next value for #{c[:sequence_name]};
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
END
|
|
105
|
+
statements << create_trigger_sql(name, c[:trigger_name], trigger_definition, {:events => [:insert]})
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
[drop_seq_statement, statements]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def create_trigger_sql(table, name, definition, opts={})
|
|
113
|
+
events = opts[:events] ? Array(opts[:events]) : [:insert, :update, :delete]
|
|
114
|
+
whence = opts[:after] ? 'AFTER' : 'BEFORE'
|
|
115
|
+
inactive = opts[:inactive] ? 'INACTIVE' : 'ACTIVE'
|
|
116
|
+
position = opts.fetch(:position, 0)
|
|
117
|
+
sql = <<-end_sql
|
|
118
|
+
CREATE TRIGGER #{quote_identifier(name)} for #{quote_identifier(table)}
|
|
119
|
+
#{inactive} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} position #{position}
|
|
120
|
+
as #{definition}
|
|
121
|
+
end_sql
|
|
122
|
+
sql
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def drop_sequence_sql(name)
|
|
126
|
+
"DROP SEQUENCE #{quote_identifier(name)}"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def remove_cached_schema(table)
|
|
130
|
+
clear_primary_key(table)
|
|
131
|
+
super
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def restart_sequence_sql(name, opts={})
|
|
135
|
+
seq_name = quote_identifier(name)
|
|
136
|
+
"ALTER SEQUENCE #{seq_name} RESTART WITH #{opts[:restart_position]}"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def tables_or_views(type, opts)
|
|
140
|
+
ds = self[:"rdb$relations"].server(opts[:server]).filter(:"rdb$relation_type" => type, Sequel::SQL::Function.new(:COALESCE, :"rdb$system_flag", 0) => 0).select(:"rdb$relation_name")
|
|
141
|
+
ds.map{|r| ds.send(:output_identifier, r[:"rdb$relation_name"].rstrip)}
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def type_literal_generic_string(column)
|
|
145
|
+
column[:text] ? :"BLOB SUB_TYPE TEXT" : super
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
module DatasetMethods
|
|
150
|
+
BOOL_TRUE = '1'.freeze
|
|
151
|
+
BOOL_FALSE = '0'.freeze
|
|
152
|
+
NULL = LiteralString.new('NULL').freeze
|
|
153
|
+
SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'with select distinct limit columns from join where group having compounds order')
|
|
154
|
+
INSERT_CLAUSE_METHODS = Dataset.clause_methods(:insert, %w'insert into columns values returning')
|
|
155
|
+
FIRST = " FIRST ".freeze
|
|
156
|
+
SKIP = " SKIP ".freeze
|
|
157
|
+
|
|
158
|
+
# Insert given values into the database.
|
|
159
|
+
def insert(*values)
|
|
160
|
+
if @opts[:sql] || @opts[:returning]
|
|
161
|
+
super
|
|
162
|
+
else
|
|
163
|
+
returning(insert_pk).insert(*values){|r| return r.values.first}
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Insert a record returning the record inserted
|
|
168
|
+
def insert_select(*values)
|
|
169
|
+
returning.insert(*values){|r| return r}
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def requires_sql_standard_datetimes?
|
|
173
|
+
true
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def supports_insert_select?
|
|
177
|
+
true
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Firebird does not support INTERSECT or EXCEPT
|
|
181
|
+
def supports_intersect_except?
|
|
182
|
+
false
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
private
|
|
186
|
+
|
|
187
|
+
def insert_clause_methods
|
|
188
|
+
INSERT_CLAUSE_METHODS
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def insert_pk(*values)
|
|
192
|
+
pk = db.primary_key(opts[:from].first)
|
|
193
|
+
pk ? Sequel::SQL::Identifier.new(pk) : NULL
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def literal_false
|
|
197
|
+
BOOL_FALSE
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def literal_true
|
|
201
|
+
BOOL_TRUE
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# The order of clauses in the SELECT SQL statement
|
|
205
|
+
def select_clause_methods
|
|
206
|
+
SELECT_CLAUSE_METHODS
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def select_limit_sql(sql)
|
|
210
|
+
if l = @opts[:limit]
|
|
211
|
+
sql << FIRST
|
|
212
|
+
literal_append(sql, l)
|
|
213
|
+
end
|
|
214
|
+
if o = @opts[:offset]
|
|
215
|
+
sql << SKIP
|
|
216
|
+
literal_append(sql, o)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Sequel
|
|
2
|
+
module Informix
|
|
3
|
+
module DatabaseMethods
|
|
4
|
+
TEMPORARY = 'TEMP '.freeze
|
|
5
|
+
|
|
6
|
+
# Informix uses the :informix database type
|
|
7
|
+
def database_type
|
|
8
|
+
:informix
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
# Informix has issues with quoted identifiers, so
|
|
14
|
+
# turn off database quoting by default.
|
|
15
|
+
def quote_identifiers_default
|
|
16
|
+
false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# SQL fragment for showing a table is temporary
|
|
20
|
+
def temporary_table_sql
|
|
21
|
+
TEMPORARY
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
module DatasetMethods
|
|
26
|
+
SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'select limit distinct columns from join where having group compounds order')
|
|
27
|
+
FIRST = " FIRST ".freeze
|
|
28
|
+
SKIP = " SKIP ".freeze
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# Informix does not support INTERSECT or EXCEPT
|
|
33
|
+
def supports_intersect_except?
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def select_clause_methods
|
|
38
|
+
SELECT_CLAUSE_METHODS
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def select_limit_sql(sql)
|
|
42
|
+
if o = @opts[:offset]
|
|
43
|
+
sql << SKIP
|
|
44
|
+
literal_append(sql, o)
|
|
45
|
+
end
|
|
46
|
+
if l = @opts[:limit]
|
|
47
|
+
sql << FIRST
|
|
48
|
+
literal_append(sql, l)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|