sequel 3.21.0 → 3.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1131 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +106 -65
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +68 -52
- data/doc/advanced_associations.rdoc +201 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/bin_sequel.rdoc +144 -0
- 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 +576 -0
- data/doc/opening_databases.rdoc +121 -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/release_notes/3.40.0.txt +73 -0
- data/doc/release_notes/3.41.0.txt +155 -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/access.rb +334 -0
- data/lib/sequel/adapters/ado/mssql.rb +18 -12
- data/lib/sequel/adapters/ado.rb +69 -21
- data/lib/sequel/adapters/amalgalite.rb +17 -14
- data/lib/sequel/adapters/cubrid.rb +143 -0
- data/lib/sequel/adapters/db2.rb +178 -85
- data/lib/sequel/adapters/dbi.rb +19 -21
- 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 +20 -39
- data/lib/sequel/adapters/firebird.rb +33 -210
- data/lib/sequel/adapters/ibmdb.rb +452 -0
- data/lib/sequel/adapters/informix.rb +6 -29
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
- data/lib/sequel/adapters/jdbc/db2.rb +78 -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 +68 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -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 +16 -28
- 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 +72 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +308 -114
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +130 -230
- data/lib/sequel/adapters/mysql2.rb +64 -63
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +29 -10
- data/lib/sequel/adapters/openbase.rb +7 -11
- data/lib/sequel/adapters/oracle.rb +364 -57
- data/lib/sequel/adapters/postgres.rb +379 -145
- data/lib/sequel/adapters/shared/access.rb +236 -11
- data/lib/sequel/adapters/shared/cubrid.rb +216 -0
- data/lib/sequel/adapters/shared/db2.rb +353 -0
- data/lib/sequel/adapters/shared/firebird.rb +231 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +412 -116
- data/lib/sequel/adapters/shared/mysql.rb +396 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
- data/lib/sequel/adapters/shared/oracle.rb +262 -45
- data/lib/sequel/adapters/shared/postgres.rb +688 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +317 -96
- data/lib/sequel/adapters/sqlite.rb +109 -46
- 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 +31 -27
- data/lib/sequel/adapters/tinytds.rb +177 -25
- 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/split_alter_table.rb +36 -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 +23 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
- data/lib/sequel/connection_pool/single.rb +11 -3
- data/lib/sequel/connection_pool/threaded.rb +69 -20
- data/lib/sequel/connection_pool.rb +20 -18
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +66 -29
- 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 +192 -51
- data/lib/sequel/database/query.rb +299 -114
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +310 -69
- 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 +322 -68
- data/lib/sequel/dataset/sql.rb +716 -293
- 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/connection_validator.rb +109 -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 +539 -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 +334 -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 +212 -0
- data/lib/sequel/extensions/pg_range.rb +513 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +576 -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 +137 -16
- 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 +77 -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 +168 -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 +57 -12
- 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/touch.rb +18 -6
- 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 +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +57 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +721 -141
- 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 +53 -39
- data/spec/adapters/mssql_spec.rb +261 -66
- data/spec/adapters/mysql_spec.rb +597 -352
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +2103 -341
- data/spec/adapters/spec_helper.rb +16 -6
- data/spec/adapters/sqlite_spec.rb +237 -76
- data/spec/core/connection_pool_spec.rb +270 -141
- data/spec/core/database_spec.rb +980 -524
- data/spec/core/dataset_spec.rb +1658 -1243
- data/spec/core/expression_filters_spec.rb +741 -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 +227 -33
- 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/connection_validator_spec.rb +118 -0
- 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 +324 -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 +200 -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 +340 -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 +65 -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 +53 -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 +77 -68
- data/spec/extensions/validation_helpers_spec.rb +48 -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 +25 -5
- data/spec/integration/dataset_test.rb +729 -141
- 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 +871 -160
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +377 -57
- data/spec/integration/spec_helper.rb +49 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +40 -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 +223 -81
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# The server_block extension adds the Database#with_server method, which takes a shard
|
|
2
|
+
# argument and a block, and makes it so that access inside the block will use the
|
|
3
|
+
# specified shard by default.
|
|
4
|
+
#
|
|
5
|
+
# First, you need to enable it on the database object:
|
|
6
|
+
#
|
|
7
|
+
# DB.extension :server_block
|
|
8
|
+
#
|
|
9
|
+
# Then you can call with_server:
|
|
10
|
+
#
|
|
11
|
+
# DB.with_server(:shard1) do
|
|
12
|
+
# DB[:a].all # Uses shard1
|
|
13
|
+
# DB[:a].server(:shard2).all # Uses shard2
|
|
14
|
+
# end
|
|
15
|
+
# DB[:a].all # Uses default
|
|
16
|
+
#
|
|
17
|
+
# You can even nest calls to with_server:
|
|
18
|
+
#
|
|
19
|
+
# DB.with_server(:shard1) do
|
|
20
|
+
# DB[:a].all # Uses shard1
|
|
21
|
+
# DB.with_server(:shard2) do
|
|
22
|
+
# DB[:a].all # Uses shard2
|
|
23
|
+
# end
|
|
24
|
+
# DB[:a].all # Uses shard1
|
|
25
|
+
# end
|
|
26
|
+
# DB[:a].all # Uses default
|
|
27
|
+
#
|
|
28
|
+
# Note this this extension assumes the following shard names should use the
|
|
29
|
+
# server/shard passed to with_server: :default, nil, :read_only. All other
|
|
30
|
+
# shard names will cause the standard behavior to be used.
|
|
31
|
+
|
|
32
|
+
module Sequel
|
|
33
|
+
module ServerBlock
|
|
34
|
+
# Enable the server block on the connection pool, choosing the correct
|
|
35
|
+
# extension depending on whether the connection pool is threaded or not.
|
|
36
|
+
# Also defines the with_server method on the receiver for easy use.
|
|
37
|
+
def self.extended(db)
|
|
38
|
+
pool = db.pool
|
|
39
|
+
if defined?(ShardedThreadedConnectionPool) && pool.is_a?(ShardedThreadedConnectionPool)
|
|
40
|
+
pool.extend(ThreadedServerBlock)
|
|
41
|
+
pool.instance_variable_set(:@default_servers, {})
|
|
42
|
+
else
|
|
43
|
+
pool.extend(UnthreadedServerBlock)
|
|
44
|
+
pool.instance_variable_set(:@default_servers, [])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Delegate to the connection pool
|
|
49
|
+
def with_server(server, &block)
|
|
50
|
+
pool.with_server(server, &block)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Adds with_server support for the sharded single connection pool.
|
|
55
|
+
module UnthreadedServerBlock
|
|
56
|
+
# Set a default server/shard to use inside the block.
|
|
57
|
+
def with_server(server)
|
|
58
|
+
begin
|
|
59
|
+
set_default_server(server)
|
|
60
|
+
yield
|
|
61
|
+
ensure
|
|
62
|
+
clear_default_server
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
# Make the given server the new default server.
|
|
69
|
+
def set_default_server(server)
|
|
70
|
+
@default_servers << server
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Remove the current default server, restoring the
|
|
74
|
+
# previous default server.
|
|
75
|
+
def clear_default_server
|
|
76
|
+
@default_servers.pop
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Use the server given to with_server if appropriate.
|
|
80
|
+
def pick_server(server)
|
|
81
|
+
if @default_servers.empty?
|
|
82
|
+
super
|
|
83
|
+
else
|
|
84
|
+
case server
|
|
85
|
+
when :default, nil, :read_only
|
|
86
|
+
@default_servers.last
|
|
87
|
+
else
|
|
88
|
+
super
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Adds with_server support for the sharded threaded connection pool.
|
|
95
|
+
module ThreadedServerBlock
|
|
96
|
+
# Set a default server/shard to use inside the block for the current
|
|
97
|
+
# thread.
|
|
98
|
+
def with_server(server)
|
|
99
|
+
begin
|
|
100
|
+
set_default_server(server)
|
|
101
|
+
yield
|
|
102
|
+
ensure
|
|
103
|
+
clear_default_server
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
# Make the given server the new default server for the current thread.
|
|
110
|
+
def set_default_server(server)
|
|
111
|
+
sync{(@default_servers[Thread.current] ||= [])} << server
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Remove the current default server for the current thread, restoring the
|
|
115
|
+
# previous default server.
|
|
116
|
+
def clear_default_server
|
|
117
|
+
t = Thread.current
|
|
118
|
+
a = sync{@default_servers[t]}
|
|
119
|
+
a.pop
|
|
120
|
+
sync{@default_servers.delete(t)} if a.empty?
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Use the server given to with_server for the given thread, if appropriate.
|
|
124
|
+
def pick_server(server)
|
|
125
|
+
a = sync{@default_servers[Thread.current]}
|
|
126
|
+
if !a || a.empty?
|
|
127
|
+
super
|
|
128
|
+
else
|
|
129
|
+
case server
|
|
130
|
+
when :default, nil, :read_only
|
|
131
|
+
a.last
|
|
132
|
+
else
|
|
133
|
+
super
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
Database.register_extension(:server_block, ServerBlock)
|
|
140
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# The split_array_nil extension overrides Sequel's default handling of
|
|
2
|
+
# IN/NOT IN with arrays of values to do specific nil checking. For example,
|
|
3
|
+
#
|
|
4
|
+
# ds = DB[:table].where(:column=>[1, nil])
|
|
5
|
+
#
|
|
6
|
+
# By default, that produces the following SQL:
|
|
7
|
+
#
|
|
8
|
+
# SELECT * FROM table WHERE (column IN (1, NULL))
|
|
9
|
+
#
|
|
10
|
+
# However, because NULL = NULL is not true in SQL (it is NULL), this
|
|
11
|
+
# will not return rows in the table where the column is NULL. This
|
|
12
|
+
# extension allows for an alternative behavior more similar to ruby,
|
|
13
|
+
# which will return rows in the table where the column is NULL, using
|
|
14
|
+
# a query like:
|
|
15
|
+
#
|
|
16
|
+
# SELECT * FROM table WHERE ((column IN (1)) OR (column IS NULL)))
|
|
17
|
+
#
|
|
18
|
+
# Similarly, for NOT IN queries:
|
|
19
|
+
#
|
|
20
|
+
# ds = DB[:table].exclude(:column=>[1, nil])
|
|
21
|
+
# # Default:
|
|
22
|
+
# # SELECT * FROM table WHERE (column NOT IN (1, NULL))
|
|
23
|
+
# # with split_array_nils extension:
|
|
24
|
+
# # SELECT * FROM table WHERE ((column NOT IN (1)) AND (column IS NOT NULL)))
|
|
25
|
+
#
|
|
26
|
+
# To use this extension with a single dataset:
|
|
27
|
+
#
|
|
28
|
+
# ds = ds.extension(:split_array_nil)
|
|
29
|
+
#
|
|
30
|
+
# To use this extension for all of a database's datasets:
|
|
31
|
+
#
|
|
32
|
+
# DB.extension(:split_array_nil)
|
|
33
|
+
|
|
34
|
+
module Sequel
|
|
35
|
+
class Dataset
|
|
36
|
+
module SplitArrayNil
|
|
37
|
+
# Over the IN/NOT IN handling with an array of values where one of the
|
|
38
|
+
# values in the array is nil, by removing nils from the array of values,
|
|
39
|
+
# and using a separate OR IS NULL clause for IN or AND IS NOT NULL clause
|
|
40
|
+
# for NOT IN.
|
|
41
|
+
def complex_expression_sql_append(sql, op, args)
|
|
42
|
+
case op
|
|
43
|
+
when :IN, :"NOT IN"
|
|
44
|
+
vals = args.at(1)
|
|
45
|
+
if vals.is_a?(Array) && vals.any?{|v| v.nil?}
|
|
46
|
+
cols = args.at(0)
|
|
47
|
+
vals = vals.compact
|
|
48
|
+
c = Sequel::SQL::BooleanExpression
|
|
49
|
+
if op == :IN
|
|
50
|
+
literal_append(sql, c.new(:OR, c.new(:IN, cols, vals), c.new(:IS, cols, nil)))
|
|
51
|
+
else
|
|
52
|
+
literal_append(sql, c.new(:AND, c.new(:"NOT IN", cols, vals), c.new(:"IS NOT", cols, nil)))
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
super
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
super
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
Dataset.register_extension(:split_array_nil, Dataset::SplitArrayNil)
|
|
65
|
+
end
|
|
@@ -1,122 +1,20 @@
|
|
|
1
1
|
# The sql_expr extension adds the sql_expr method to every object, which
|
|
2
|
-
# returns an object that works nicely with Sequel's DSL
|
|
3
|
-
#
|
|
2
|
+
# returns an wrapped object that works nicely with Sequel's DSL by calling
|
|
3
|
+
# Sequel.expr:
|
|
4
4
|
#
|
|
5
5
|
# 1.sql_expr < :a # 1 < a
|
|
6
6
|
# false.sql_expr & :a # FALSE AND a
|
|
7
7
|
# true.sql_expr | :a # TRUE OR a
|
|
8
8
|
# ~nil.sql_expr # NOT NULL
|
|
9
9
|
# "a".sql_expr + "b" # 'a' || 'b'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# GenericExpression in terms of methods,
|
|
15
|
-
# but has an internal structure of a
|
|
16
|
-
# ComplexExpression. It is used by Object#sql_expr.
|
|
17
|
-
# Since we don't know what specific type of object
|
|
18
|
-
# we are dealing with it, we treat it similarly to
|
|
19
|
-
# how we treat symbols or literal strings, allowing
|
|
20
|
-
# many different types of methods.
|
|
21
|
-
class GenericComplexExpression < ComplexExpression
|
|
22
|
-
include AliasMethods
|
|
23
|
-
include BooleanMethods
|
|
24
|
-
include CastMethods
|
|
25
|
-
include ComplexExpressionMethods
|
|
26
|
-
include InequalityMethods
|
|
27
|
-
include NumericMethods
|
|
28
|
-
include OrderMethods
|
|
29
|
-
include StringMethods
|
|
30
|
-
include SubscriptMethods
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
10
|
+
#
|
|
11
|
+
# To load the extension:
|
|
12
|
+
#
|
|
13
|
+
# Sequel.extension :sql_expr
|
|
34
14
|
|
|
35
15
|
class Object
|
|
36
|
-
# Return
|
|
37
|
-
# Sequel::SQL::GenericComplexExpression. Allows easy use
|
|
38
|
-
# of the Object with Sequel's DSL. You'll probably have
|
|
39
|
-
# to make sure that Sequel knows how to literalize the
|
|
40
|
-
# object properly, though.
|
|
41
|
-
def sql_expr
|
|
42
|
-
Sequel::SQL::GenericComplexExpression.new(:NOOP, self)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
class FalseClass
|
|
47
|
-
# Returns a copy of the object wrapped in a
|
|
48
|
-
# Sequel::SQL::BooleanExpression, allowing easy use
|
|
49
|
-
# of Sequel's DSL:
|
|
50
|
-
#
|
|
51
|
-
# false.sql_expr & :a # FALSE AND a
|
|
52
|
-
def sql_expr
|
|
53
|
-
Sequel::SQL::BooleanExpression.new(:NOOP, self)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
class NilClass
|
|
58
|
-
# Returns a copy of the object wrapped in a
|
|
59
|
-
# Sequel::SQL::BooleanExpression, allowing easy use
|
|
60
|
-
# of Sequel's DSL:
|
|
61
|
-
#
|
|
62
|
-
# ~nil.sql_expr # NOT NULL
|
|
63
|
-
def sql_expr
|
|
64
|
-
Sequel::SQL::BooleanExpression.new(:NOOP, self)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
class Numeric
|
|
69
|
-
# Returns a copy of the object wrapped in a
|
|
70
|
-
# Sequel::SQL::NumericExpression, allowing easy use
|
|
71
|
-
# of Sequel's DSL:
|
|
72
|
-
#
|
|
73
|
-
# 1.sql_expr < :a # 1 < a
|
|
74
|
-
def sql_expr
|
|
75
|
-
Sequel::SQL::NumericExpression.new(:NOOP, self)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
class Proc
|
|
80
|
-
# Evaluates the proc as a virtual row block.
|
|
81
|
-
# If a hash or array of two element arrays is returned,
|
|
82
|
-
# they are converted to a Sequel::SQL::BooleanExpression. Otherwise,
|
|
83
|
-
# unless the object returned is already an Sequel::SQL::Expression,
|
|
84
|
-
# convert the object to an Sequel::SQL::GenericComplexExpression.
|
|
85
|
-
#
|
|
86
|
-
# proc{a(b)}.sql_expr + 1 # a(b) + 1
|
|
87
|
-
# proc{{a=>b}}.sql_expr | true # (a = b) OR TRUE
|
|
88
|
-
# proc{1}.sql_expr + :a # 1 + a
|
|
16
|
+
# Return the object wrapper in an appropriate Sequel expression object.
|
|
89
17
|
def sql_expr
|
|
90
|
-
|
|
91
|
-
if Sequel.condition_specifier?(o)
|
|
92
|
-
Sequel::SQL::BooleanExpression.from_value_pairs(o, :AND)
|
|
93
|
-
elsif o.is_a?(Sequel::SQL::Expression)
|
|
94
|
-
o
|
|
95
|
-
else
|
|
96
|
-
Sequel::SQL::GenericComplexExpression.new(:NOOP, o)
|
|
97
|
-
end
|
|
18
|
+
Sequel.expr(self)
|
|
98
19
|
end
|
|
99
20
|
end
|
|
100
|
-
|
|
101
|
-
class String
|
|
102
|
-
# Returns a copy of the object wrapped in a
|
|
103
|
-
# Sequel::SQL::StringExpression, allowing easy use
|
|
104
|
-
# of Sequel's DSL:
|
|
105
|
-
#
|
|
106
|
-
# "a".sql_expr + :a # 'a' || a
|
|
107
|
-
def sql_expr
|
|
108
|
-
Sequel::SQL::StringExpression.new(:NOOP, self)
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
class TrueClass
|
|
113
|
-
# Returns a copy of the object wrapped in a
|
|
114
|
-
# Sequel::SQL::BooleanExpression, allowing easy use
|
|
115
|
-
# of Sequel's DSL:
|
|
116
|
-
#
|
|
117
|
-
# true.sql_expr | :a # TRUE OR a
|
|
118
|
-
def sql_expr
|
|
119
|
-
Sequel::SQL::BooleanExpression.new(:NOOP, self)
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# The string_date_time extension provides String instance methods
|
|
2
2
|
# for converting the strings to a date (e.g. String#to_date), allowing
|
|
3
3
|
# for backwards compatibility with legacy Sequel code.
|
|
4
|
+
#
|
|
5
|
+
# To load the extension:
|
|
6
|
+
#
|
|
7
|
+
# Sequel.extension :string_date_time
|
|
4
8
|
|
|
5
9
|
class String
|
|
6
10
|
# Converts a string into a Date object.
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
# The thread_local_timezones extension allows you to set a per-thread timezone that
|
|
2
2
|
# will override the default global timezone while the thread is executing. The
|
|
3
3
|
# main use case is for web applications that execute each request in its own thread,
|
|
4
|
-
# and want to set the timezones based on the request.
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# and want to set the timezones based on the request.
|
|
5
|
+
#
|
|
6
|
+
# To load the extension:
|
|
7
|
+
#
|
|
8
|
+
# Sequel.extension :thread_local_timezones
|
|
9
|
+
#
|
|
10
|
+
# The most common example is having the database always store time in
|
|
11
|
+
# UTC, but have the application deal with the timezone of the current
|
|
12
|
+
# user. That can be done with:
|
|
7
13
|
#
|
|
8
14
|
# Sequel.database_timezone = :utc
|
|
9
15
|
# # In each thread:
|
|
@@ -32,7 +38,7 @@ module Sequel
|
|
|
32
38
|
module ThreadLocalTimezones
|
|
33
39
|
%w'application database typecast'.each do |t|
|
|
34
40
|
class_eval("def thread_#{t}_timezone=(tz); Thread.current[:#{t}_timezone] = convert_timezone_setter_arg(tz); end", __FILE__, __LINE__)
|
|
35
|
-
class_eval(<<END, __FILE__, __LINE__)
|
|
41
|
+
class_eval(<<END, __FILE__, __LINE__ + 1)
|
|
36
42
|
def #{t}_timezone
|
|
37
43
|
if tz = Thread.current[:#{t}_timezone]
|
|
38
44
|
tz unless tz == :nil
|
|
@@ -2,111 +2,117 @@
|
|
|
2
2
|
# returns a string that can be processed by graphviz's +dot+ program in
|
|
3
3
|
# order to get a visualization of the dataset. Basically, it shows a version
|
|
4
4
|
# of the dataset's abstract syntax tree.
|
|
5
|
+
#
|
|
6
|
+
# To load the extension:
|
|
7
|
+
#
|
|
8
|
+
# Sequel.extension :to_dot
|
|
5
9
|
|
|
6
10
|
module Sequel
|
|
7
|
-
class
|
|
11
|
+
class ToDot
|
|
8
12
|
# The option keys that should be included in the dot output.
|
|
9
13
|
TO_DOT_OPTIONS = [:with, :distinct, :select, :from, :join, :where, :group, :having, :compounds, :order, :limit, :offset, :lock].freeze
|
|
10
14
|
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
# Given a +Dataset+, return a string in +dot+ format that will
|
|
16
|
+
# generate a visualization of the dataset.
|
|
17
|
+
def self.output(ds)
|
|
18
|
+
new(ds).output
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Given a +Dataset+, parse the internal structure to generate
|
|
22
|
+
# a dataset visualization.
|
|
23
|
+
def initialize(ds)
|
|
24
|
+
@i = 0
|
|
25
|
+
@stack = [@i]
|
|
26
|
+
@dot = ["digraph G {", "0 [label=\"self\"];"]
|
|
27
|
+
v(ds, "")
|
|
28
|
+
@dot << "}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Output the dataset visualization as a string in +dot+ format.
|
|
32
|
+
def output
|
|
33
|
+
@dot.join("\n")
|
|
20
34
|
end
|
|
21
35
|
|
|
22
36
|
private
|
|
23
37
|
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# its children are then added by recursively calling this method. The
|
|
39
|
-
# return value is the integer representing the last created node.
|
|
40
|
-
def _to_dot(dot, l, c, e, i)
|
|
41
|
-
i += 1
|
|
42
|
-
dot << "#{c} -> #{i} [label=\"#{l}\"];" if l
|
|
43
|
-
c = i
|
|
38
|
+
# Add an entry to the +dot+ output with the given label. If +j+
|
|
39
|
+
# is given, it is used directly as the node or transition. Otherwise
|
|
40
|
+
# a node is created for the current object.
|
|
41
|
+
def dot(label, j=nil)
|
|
42
|
+
@dot << "#{j||@i} [label=#{label.to_s.inspect}];"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Recursive method that parses all of Sequel's internal datastructures,
|
|
46
|
+
# adding the appropriate nodes and transitions to the internal +dot+
|
|
47
|
+
# structure.
|
|
48
|
+
def v(e, l)
|
|
49
|
+
@i += 1
|
|
50
|
+
dot(l, "#{@stack.last} -> #{@i}") if l
|
|
51
|
+
@stack.push(@i)
|
|
44
52
|
case e
|
|
45
53
|
when LiteralString
|
|
46
|
-
dot
|
|
47
|
-
i
|
|
54
|
+
dot "#{e.inspect}.lit" # core_sql use
|
|
48
55
|
when Symbol, Numeric, String, Class, TrueClass, FalseClass, NilClass
|
|
49
|
-
dot
|
|
50
|
-
i
|
|
56
|
+
dot e.inspect
|
|
51
57
|
when Array
|
|
52
|
-
dot
|
|
53
|
-
e.each_with_index do |
|
|
54
|
-
|
|
58
|
+
dot "Array"
|
|
59
|
+
e.each_with_index do |val, j|
|
|
60
|
+
v(val, j)
|
|
55
61
|
end
|
|
56
62
|
when Hash
|
|
57
|
-
dot
|
|
58
|
-
e.each do |k,
|
|
59
|
-
|
|
63
|
+
dot "Hash"
|
|
64
|
+
e.each do |k, val|
|
|
65
|
+
v(val, k)
|
|
60
66
|
end
|
|
61
67
|
when SQL::ComplexExpression
|
|
62
|
-
dot
|
|
63
|
-
e.args.each_with_index do |
|
|
64
|
-
|
|
68
|
+
dot "ComplexExpression: #{e.op}"
|
|
69
|
+
e.args.each_with_index do |val, j|
|
|
70
|
+
v(val, j)
|
|
65
71
|
end
|
|
66
72
|
when SQL::Identifier
|
|
67
|
-
dot
|
|
68
|
-
|
|
73
|
+
dot "Identifier"
|
|
74
|
+
v(e.value, :value)
|
|
69
75
|
when SQL::QualifiedIdentifier
|
|
70
|
-
dot
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
dot "QualifiedIdentifier"
|
|
77
|
+
v(e.table, :table)
|
|
78
|
+
v(e.column, :column)
|
|
73
79
|
when SQL::OrderedExpression
|
|
74
|
-
dot
|
|
75
|
-
|
|
80
|
+
dot "OrderedExpression: #{e.descending ? :DESC : :ASC}#{" NULLS #{e.nulls.to_s.upcase}" if e.nulls}"
|
|
81
|
+
v(e.expression, :expression)
|
|
76
82
|
when SQL::AliasedExpression
|
|
77
|
-
dot
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
dot "AliasedExpression"
|
|
84
|
+
v(e.expression, :expression)
|
|
85
|
+
v(e.aliaz, :alias)
|
|
80
86
|
when SQL::CaseExpression
|
|
81
|
-
dot
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
87
|
+
dot "CaseExpression"
|
|
88
|
+
v(e.expression, :expression) if e.expression
|
|
89
|
+
v(e.conditions, :conditions)
|
|
90
|
+
v(e.default, :default)
|
|
85
91
|
when SQL::Cast
|
|
86
|
-
dot
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
dot "Cast"
|
|
93
|
+
v(e.expr, :expr)
|
|
94
|
+
v(e.type, :type)
|
|
89
95
|
when SQL::Function
|
|
90
|
-
dot
|
|
91
|
-
e.args.each_with_index do |
|
|
92
|
-
|
|
96
|
+
dot "Function: #{e.f}"
|
|
97
|
+
e.args.each_with_index do |val, j|
|
|
98
|
+
v(val, j)
|
|
93
99
|
end
|
|
94
100
|
when SQL::Subscript
|
|
95
|
-
dot
|
|
96
|
-
|
|
97
|
-
|
|
101
|
+
dot "Subscript"
|
|
102
|
+
v(e.f, :f)
|
|
103
|
+
v(e.sub, :sub)
|
|
98
104
|
when SQL::WindowFunction
|
|
99
|
-
dot
|
|
100
|
-
|
|
101
|
-
|
|
105
|
+
dot "WindowFunction"
|
|
106
|
+
v(e.function, :function)
|
|
107
|
+
v(e.window, :window)
|
|
102
108
|
when SQL::Window
|
|
103
|
-
dot
|
|
104
|
-
|
|
109
|
+
dot "Window"
|
|
110
|
+
v(e.opts, :opts)
|
|
105
111
|
when SQL::PlaceholderLiteralString
|
|
106
112
|
str = e.str
|
|
107
113
|
str = "(#{str})" if e.parens
|
|
108
|
-
dot
|
|
109
|
-
|
|
114
|
+
dot "PlaceholderLiteralString: #{str.inspect}"
|
|
115
|
+
v(e.args, :args)
|
|
110
116
|
when SQL::JoinClause
|
|
111
117
|
str = "#{e.join_type.to_s.upcase} JOIN"
|
|
112
118
|
if e.is_a?(SQL::JoinOnClause)
|
|
@@ -114,24 +120,34 @@ module Sequel
|
|
|
114
120
|
elsif e.is_a?(SQL::JoinUsingClause)
|
|
115
121
|
str << " USING"
|
|
116
122
|
end
|
|
117
|
-
dot
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
dot str
|
|
124
|
+
v(e.table, :table)
|
|
125
|
+
v(e.table_alias, :alias) if e.table_alias
|
|
120
126
|
if e.is_a?(SQL::JoinOnClause)
|
|
121
|
-
|
|
127
|
+
v(e.on, :on)
|
|
122
128
|
elsif e.is_a?(SQL::JoinUsingClause)
|
|
123
|
-
|
|
129
|
+
v(e.using, :using)
|
|
124
130
|
end
|
|
125
131
|
when Dataset
|
|
126
|
-
dot
|
|
132
|
+
dot "Dataset"
|
|
127
133
|
TO_DOT_OPTIONS.each do |k|
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
if val = e.opts[k]
|
|
135
|
+
v(val, k.to_s)
|
|
136
|
+
end
|
|
130
137
|
end
|
|
131
138
|
else
|
|
132
|
-
dot
|
|
139
|
+
dot "Unhandled: #{e.inspect}"
|
|
133
140
|
end
|
|
134
|
-
|
|
141
|
+
@stack.pop
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
class Dataset
|
|
146
|
+
# Return a string that can be processed by the +dot+ program (included
|
|
147
|
+
# with graphviz) in order to see a visualization of the dataset's
|
|
148
|
+
# abstract syntax tree.
|
|
149
|
+
def to_dot
|
|
150
|
+
ToDot.output(self)
|
|
135
151
|
end
|
|
136
152
|
end
|
|
137
153
|
end
|