sequel 3.21.0 → 3.36.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 +855 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +23 -7
- data/Rakefile +42 -24
- data/bin/sequel +26 -8
- data/doc/active_record.rdoc +1 -0
- data/doc/advanced_associations.rdoc +171 -11
- data/doc/association_basics.rdoc +293 -43
- data/doc/dataset_basics.rdoc +5 -5
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +85 -552
- data/doc/model_hooks.rdoc +78 -27
- data/doc/object_model.rdoc +541 -0
- data/doc/opening_databases.rdoc +97 -50
- data/doc/prepared_statements.rdoc +40 -14
- data/doc/querying.rdoc +28 -4
- data/doc/reflection.rdoc +30 -4
- 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/schema_modification.rdoc +572 -0
- data/doc/sharding.rdoc +95 -3
- data/doc/testing.rdoc +129 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +51 -2
- 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 +1 -57
- 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 +47 -0
- data/lib/sequel/adapters/jdbc/derby.rb +287 -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 +29 -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 +58 -48
- 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 +265 -94
- data/lib/sequel/adapters/mock.rb +361 -0
- data/lib/sequel/adapters/mysql.rb +118 -222
- data/lib/sequel/adapters/mysql2.rb +58 -57
- data/lib/sequel/adapters/odbc/mssql.rb +15 -7
- 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 +356 -107
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +342 -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 +335 -118
- data/lib/sequel/adapters/shared/mysql.rb +340 -76
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +243 -45
- data/lib/sequel/adapters/shared/postgres.rb +524 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +265 -89
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +9 -12
- data/lib/sequel/adapters/swift/postgres.rb +9 -74
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +8 -7
- data/lib/sequel/adapters/tinytds.rb +161 -21
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -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 +28 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +38 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +118 -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 +150 -46
- data/lib/sequel/database/query.rb +215 -65
- data/lib/sequel/database/schema_generator.rb +64 -20
- data/lib/sequel/database/schema_methods.rb +212 -54
- data/lib/sequel/dataset/actions.rb +322 -85
- data/lib/sequel/dataset/features.rb +96 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +237 -44
- data/lib/sequel/dataset/sql.rb +698 -278
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +79 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +16 -34
- data/lib/sequel/extensions/migration.rb +97 -11
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/null_dataset.rb +90 -0
- data/lib/sequel/extensions/pg_array.rb +460 -0
- data/lib/sequel/extensions/pg_array_ops.rb +220 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +169 -0
- data/lib/sequel/extensions/pg_hstore.rb +296 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
- data/lib/sequel/extensions/pg_inet.rb +89 -0
- data/lib/sequel/extensions/pg_json.rb +178 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
- data/lib/sequel/extensions/pretty_table.rb +5 -71
- data/lib/sequel/extensions/query.rb +1 -1
- 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 +251 -37
- data/lib/sequel/extensions/select_remove.rb +35 -0
- data/lib/sequel/extensions/server_block.rb +139 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -110
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1187 -393
- data/lib/sequel/model/base.rb +578 -170
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- 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/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -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 +123 -8
- 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 +12 -2
- data/lib/sequel/plugins/many_through_many.rb +79 -28
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +139 -63
- data/lib/sequel/plugins/optimistic_locking.rb +8 -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 +29 -15
- data/lib/sequel/plugins/schema.rb +7 -2
- 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 +10 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- 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/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +526 -59
- data/lib/sequel/timezones.rb +57 -38
- 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 +142 -40
- data/spec/adapters/mysql_spec.rb +380 -234
- data/spec/adapters/oracle_spec.rb +67 -77
- data/spec/adapters/postgres_spec.rb +1050 -212
- data/spec/adapters/spec_helper.rb +8 -5
- data/spec/adapters/sqlite_spec.rb +139 -27
- data/spec/core/connection_pool_spec.rb +196 -93
- data/spec/core/database_spec.rb +879 -510
- data/spec/core/dataset_spec.rb +1415 -1086
- data/spec/core/expression_filters_spec.rb +554 -109
- data/spec/core/mock_adapter_spec.rb +449 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +482 -38
- data/spec/core/spec_helper.rb +6 -48
- 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/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/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +119 -139
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +69 -92
- data/spec/extensions/identity_map_spec.rb +131 -22
- 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 -6
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +48 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- 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 +251 -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 +105 -0
- data/spec/extensions/pg_array_spec.rb +196 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
- data/spec/extensions/pg_hstore_spec.rb +195 -0
- data/spec/extensions/pg_inet_spec.rb +44 -0
- data/spec/extensions/pg_json_spec.rb +101 -0
- data/spec/extensions/pg_statement_cache_spec.rb +209 -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 +168 -0
- data/spec/extensions/query_spec.rb +6 -0
- 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 +429 -22
- data/spec/extensions/schema_spec.rb +25 -21
- 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 +85 -43
- 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 +22 -61
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -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 +4 -7
- 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 +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- 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 +9 -3
- data/spec/integration/dataset_test.rb +605 -91
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +454 -143
- data/spec/integration/prepared_statement_test.rb +263 -128
- data/spec/integration/schema_test.rb +309 -43
- data/spec/integration/spec_helper.rb +40 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +18 -4
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +1067 -661
- data/spec/model/base_spec.rb +329 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +349 -67
- data/spec/model/model_spec.rb +240 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +490 -232
- data/spec/model/spec_helper.rb +14 -71
- data/spec/model/validations_spec.rb +11 -0
- data/spec/rcov.opts +2 -0
- metadata +178 -80
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Dataset
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods that describe what the dataset supports
|
|
4
|
+
# :section: 4 - Methods that describe what the dataset supports
|
|
5
5
|
# These methods all return booleans, with most describing whether or not the
|
|
6
6
|
# dataset supports a feature.
|
|
7
7
|
# ---------------------
|
|
8
8
|
|
|
9
|
-
# Method used to check if WITH is supported
|
|
10
|
-
WITH_SUPPORTED=:select_with_sql
|
|
11
|
-
|
|
12
9
|
# Whether this dataset quotes identifiers.
|
|
13
10
|
def quote_identifiers?
|
|
14
|
-
@quote_identifiers
|
|
11
|
+
if defined?(@quote_identifiers)
|
|
12
|
+
@quote_identifiers
|
|
13
|
+
elsif db.respond_to?(:quote_identifiers?)
|
|
14
|
+
@quote_identifiers = db.quote_identifiers?
|
|
15
|
+
else
|
|
16
|
+
@quote_identifiers = false
|
|
17
|
+
end
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
# Whether this dataset will provide accurate number of rows matched for
|
|
@@ -21,22 +24,59 @@ module Sequel
|
|
|
21
24
|
true
|
|
22
25
|
end
|
|
23
26
|
|
|
27
|
+
# Whether you must use a column alias list for recursive CTEs (false by
|
|
28
|
+
# default).
|
|
29
|
+
def recursive_cte_requires_column_aliases?
|
|
30
|
+
false
|
|
31
|
+
end
|
|
32
|
+
|
|
24
33
|
# Whether the dataset requires SQL standard datetimes (false by default,
|
|
25
34
|
# as most allow strings with ISO 8601 format).
|
|
26
35
|
def requires_sql_standard_datetimes?
|
|
27
36
|
false
|
|
28
37
|
end
|
|
29
38
|
|
|
39
|
+
# Whether type specifiers are required for prepared statement/bound
|
|
40
|
+
# variable argument placeholders (i.e. :bv__integer)
|
|
41
|
+
def requires_placeholder_type_specifiers?
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
|
|
30
45
|
# Whether the dataset supports common table expressions (the WITH clause).
|
|
31
|
-
|
|
32
|
-
|
|
46
|
+
# If given, +type+ can be :select, :insert, :update, or :delete, in which case it
|
|
47
|
+
# determines whether WITH is supported for the respective statement type.
|
|
48
|
+
def supports_cte?(type=:select)
|
|
49
|
+
send(:"#{type}_clause_methods").include?(:"#{type}_with_sql")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Whether the dataset supports common table expressions (the WITH clause)
|
|
53
|
+
# in subqueries. If false, applies the WITH clause to the main query, which can cause issues
|
|
54
|
+
# if multiple WITH clauses use the same name.
|
|
55
|
+
def supports_cte_in_subqueries?
|
|
56
|
+
false
|
|
33
57
|
end
|
|
34
58
|
|
|
35
|
-
# Whether the dataset supports the DISTINCT ON clause, false by default.
|
|
59
|
+
# Whether the dataset supports or can emulate the DISTINCT ON clause, false by default.
|
|
36
60
|
def supports_distinct_on?
|
|
37
61
|
false
|
|
38
62
|
end
|
|
39
63
|
|
|
64
|
+
# Whether the dataset supports CUBE with GROUP BY.
|
|
65
|
+
def supports_group_cube?
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Whether the dataset supports ROLLUP with GROUP BY.
|
|
70
|
+
def supports_group_rollup?
|
|
71
|
+
false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Whether this dataset supports the +insert_select+ method for returning all columns values
|
|
75
|
+
# directly from an insert query.
|
|
76
|
+
def supports_insert_select?
|
|
77
|
+
supports_returning?(:insert)
|
|
78
|
+
end
|
|
79
|
+
|
|
40
80
|
# Whether the dataset supports the INTERSECT and EXCEPT compound operations, true by default.
|
|
41
81
|
def supports_intersect_except?
|
|
42
82
|
true
|
|
@@ -67,7 +107,24 @@ module Sequel
|
|
|
67
107
|
def supports_multiple_column_in?
|
|
68
108
|
true
|
|
69
109
|
end
|
|
110
|
+
|
|
111
|
+
# Whether the dataset supports or can fully emulate the DISTINCT ON clause,
|
|
112
|
+
# including respecting the ORDER BY clause, false by default
|
|
113
|
+
def supports_ordered_distinct_on?
|
|
114
|
+
supports_distinct_on?
|
|
115
|
+
end
|
|
70
116
|
|
|
117
|
+
# Whether the RETURNING clause is supported for the given type of query.
|
|
118
|
+
# +type+ can be :insert, :update, or :delete.
|
|
119
|
+
def supports_returning?(type)
|
|
120
|
+
send(:"#{type}_clause_methods").include?(:"#{type}_returning_sql")
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Whether the database supports SELECT *, column FROM table
|
|
124
|
+
def supports_select_all_and_column?
|
|
125
|
+
true
|
|
126
|
+
end
|
|
127
|
+
|
|
71
128
|
# Whether the dataset supports timezones in literal timestamps
|
|
72
129
|
def supports_timestamp_timezones?
|
|
73
130
|
false
|
|
@@ -82,5 +139,36 @@ module Sequel
|
|
|
82
139
|
def supports_window_functions?
|
|
83
140
|
false
|
|
84
141
|
end
|
|
142
|
+
|
|
143
|
+
# Whether the dataset supports WHERE TRUE (or WHERE 1 for databases that
|
|
144
|
+
# that use 1 for true).
|
|
145
|
+
def supports_where_true?
|
|
146
|
+
true
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
private
|
|
150
|
+
|
|
151
|
+
# Whether insert(nil) or insert({}) must be emulated by
|
|
152
|
+
# using at least one value, false by default.
|
|
153
|
+
def insert_supports_empty_values?
|
|
154
|
+
true
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Whether using an offset returns an extra row number column that should be
|
|
158
|
+
# eliminated, false by default.
|
|
159
|
+
def offset_returns_row_number_column?
|
|
160
|
+
false
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Whether the RETURNING clause is used for the given dataset.
|
|
164
|
+
# +type+ can be :insert, :update, or :delete.
|
|
165
|
+
def uses_returning?(type)
|
|
166
|
+
opts[:returning] && !@opts[:sql] && supports_returning?(type)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Whether the dataset uses WITH ROLLUP/CUBE instead of ROLLUP()/CUBE().
|
|
170
|
+
def uses_with_rollup?
|
|
171
|
+
false
|
|
172
|
+
end
|
|
85
173
|
end
|
|
86
174
|
end
|
data/lib/sequel/dataset/graph.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Dataset
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods related to dataset graphing
|
|
4
|
+
# :section: 5 - Methods related to dataset graphing
|
|
5
5
|
# Dataset graphing changes the dataset to yield hashes where keys are table
|
|
6
6
|
# name symbols and values are hashes representing the columns related to
|
|
7
7
|
# that table. All of these methods return modified copies of the receiver.
|
|
@@ -115,7 +115,11 @@ module Sequel
|
|
|
115
115
|
add_columns = !ds.opts.include?(:graph_aliases)
|
|
116
116
|
|
|
117
117
|
# Setup the initial graph data structure if it doesn't exist
|
|
118
|
-
|
|
118
|
+
if graph = opts[:graph]
|
|
119
|
+
opts[:graph] = graph = graph.dup
|
|
120
|
+
select = opts[:select].dup
|
|
121
|
+
[:column_aliases, :table_aliases, :column_alias_num].each{|k| graph[k] = graph[k].dup}
|
|
122
|
+
else
|
|
119
123
|
master = alias_symbol(ds.first_source_alias)
|
|
120
124
|
raise_alias_error.call if master == table_alias
|
|
121
125
|
# Master hash storing all .graph related information
|
|
@@ -130,10 +134,33 @@ module Sequel
|
|
|
130
134
|
# aliased, but are not included if set_graph_aliases
|
|
131
135
|
# has been used.
|
|
132
136
|
if add_columns
|
|
133
|
-
select = opts[:select]
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
if (select = @opts[:select]) && !select.empty? && !(select.length == 1 && (select.first.is_a?(SQL::ColumnAll)))
|
|
138
|
+
select = select.each do |sel|
|
|
139
|
+
column = case sel
|
|
140
|
+
when Symbol
|
|
141
|
+
_, c, a = split_symbol(sel)
|
|
142
|
+
(a || c).to_sym
|
|
143
|
+
when SQL::Identifier
|
|
144
|
+
sel.value.to_sym
|
|
145
|
+
when SQL::QualifiedIdentifier
|
|
146
|
+
column = sel.column
|
|
147
|
+
column = column.value if column.is_a?(SQL::Identifier)
|
|
148
|
+
column.to_sym
|
|
149
|
+
when SQL::AliasedExpression
|
|
150
|
+
column = sel.aliaz
|
|
151
|
+
column = column.value if column.is_a?(SQL::Identifier)
|
|
152
|
+
column.to_sym
|
|
153
|
+
else
|
|
154
|
+
raise Error, "can't figure out alias to use for graphing for #{sel.inspect}"
|
|
155
|
+
end
|
|
156
|
+
column_aliases[column] = [master, column]
|
|
157
|
+
end
|
|
158
|
+
select = qualified_expression(select, master)
|
|
159
|
+
else
|
|
160
|
+
select = columns.map do |column|
|
|
161
|
+
column_aliases[column] = [master, column]
|
|
162
|
+
SQL::QualifiedIdentifier.new(master, column)
|
|
163
|
+
end
|
|
137
164
|
end
|
|
138
165
|
end
|
|
139
166
|
end
|
|
@@ -147,7 +174,6 @@ module Sequel
|
|
|
147
174
|
|
|
148
175
|
# Add the columns to the selection unless we are ignoring them
|
|
149
176
|
if add_table && add_columns
|
|
150
|
-
select = opts[:select]
|
|
151
177
|
column_aliases = graph[:column_aliases]
|
|
152
178
|
ca_num = graph[:column_alias_num]
|
|
153
179
|
# Which columns to add to the result set
|
|
@@ -165,15 +191,16 @@ module Sequel
|
|
|
165
191
|
column_alias = :"#{column_alias}_#{column_alias_num}"
|
|
166
192
|
ca_num[column_alias] += 1
|
|
167
193
|
end
|
|
168
|
-
[column_alias, SQL::QualifiedIdentifier.new(table_alias, column)
|
|
194
|
+
[column_alias, SQL::AliasedExpression.new(SQL::QualifiedIdentifier.new(table_alias, column), column_alias)]
|
|
169
195
|
else
|
|
170
|
-
|
|
196
|
+
ident = SQL::QualifiedIdentifier.new(table_alias, column)
|
|
197
|
+
[column, ident]
|
|
171
198
|
end
|
|
172
199
|
column_aliases[col_alias] = [table_alias, column]
|
|
173
200
|
select.push(identifier)
|
|
174
201
|
end
|
|
175
202
|
end
|
|
176
|
-
ds
|
|
203
|
+
add_columns ? ds.select(*select) : ds
|
|
177
204
|
end
|
|
178
205
|
|
|
179
206
|
# This allows you to manually specify the graph aliases to use
|
|
@@ -225,7 +252,7 @@ module Sequel
|
|
|
225
252
|
column ||= col_alias
|
|
226
253
|
gas[col_alias] = [table, column]
|
|
227
254
|
identifier = value || SQL::QualifiedIdentifier.new(table, column)
|
|
228
|
-
identifier = SQL::AliasedExpression.new(identifier, col_alias) if value
|
|
255
|
+
identifier = SQL::AliasedExpression.new(identifier, col_alias) if value || column != col_alias
|
|
229
256
|
identifier
|
|
230
257
|
end
|
|
231
258
|
[identifiers, gas]
|
data/lib/sequel/dataset/misc.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Dataset
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Miscellaneous methods
|
|
4
|
+
# :section: 6 - Miscellaneous methods
|
|
5
5
|
# These methods don't fit cleanly into another section.
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
@@ -23,17 +23,13 @@ module Sequel
|
|
|
23
23
|
# DB[:posts]
|
|
24
24
|
#
|
|
25
25
|
# Sequel::Dataset is an abstract class that is not useful by itself. Each
|
|
26
|
-
# database
|
|
26
|
+
# database adapter provides a subclass of Sequel::Dataset, and has
|
|
27
27
|
# the Database#dataset method return an instance of that subclass.
|
|
28
28
|
def initialize(db, opts = nil)
|
|
29
29
|
@db = db
|
|
30
|
-
@quote_identifiers = db.quote_identifiers? if db.respond_to?(:quote_identifiers?)
|
|
31
|
-
@identifier_input_method = db.identifier_input_method if db.respond_to?(:identifier_input_method)
|
|
32
|
-
@identifier_output_method = db.identifier_output_method if db.respond_to?(:identifier_output_method)
|
|
33
30
|
@opts = opts || {}
|
|
34
|
-
@row_proc = nil
|
|
35
31
|
end
|
|
36
|
-
|
|
32
|
+
|
|
37
33
|
# Define a hash value such that datasets with the same DB, opts, and SQL
|
|
38
34
|
# will be consider equal.
|
|
39
35
|
def ==(o)
|
|
@@ -45,15 +41,6 @@ module Sequel
|
|
|
45
41
|
self == o
|
|
46
42
|
end
|
|
47
43
|
|
|
48
|
-
# Return the dataset as an aliased expression with the given alias. You can
|
|
49
|
-
# use this as a FROM or JOIN dataset, or as a column if this dataset
|
|
50
|
-
# returns a single row and column.
|
|
51
|
-
#
|
|
52
|
-
# DB.from(DB[:table].as(:b)) # SELECT * FROM (SELECT * FROM table) AS b
|
|
53
|
-
def as(aliaz)
|
|
54
|
-
::Sequel::SQL::AliasedExpression.new(self, aliaz)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
44
|
# Yield a dataset for each server in the connection pool that is tied to that server.
|
|
58
45
|
# Intended for use in sharded environments where all servers need to be modified
|
|
59
46
|
# with the same data:
|
|
@@ -96,10 +83,10 @@ module Sequel
|
|
|
96
83
|
# have a table, raises an error. If the table is aliased, returns the original
|
|
97
84
|
# table, not the alias
|
|
98
85
|
#
|
|
99
|
-
# DB[:table].
|
|
86
|
+
# DB[:table].first_source_table
|
|
100
87
|
# # => :table
|
|
101
88
|
#
|
|
102
|
-
# DB[:table___t].
|
|
89
|
+
# DB[:table___t].first_source_table
|
|
103
90
|
# # => :table
|
|
104
91
|
def first_source_table
|
|
105
92
|
source = @opts[:from]
|
|
@@ -120,16 +107,48 @@ module Sequel
|
|
|
120
107
|
# Define a hash value such that datasets with the same DB, opts, and SQL
|
|
121
108
|
# will have the same hash value
|
|
122
109
|
def hash
|
|
123
|
-
[db, opts.sort_by{|k| k.to_s}, sql].hash
|
|
110
|
+
[db, opts.sort_by{|k, v| k.to_s}, sql].hash
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# The String instance method to call on identifiers before sending them to
|
|
114
|
+
# the database.
|
|
115
|
+
def identifier_input_method
|
|
116
|
+
if defined?(@identifier_input_method)
|
|
117
|
+
@identifier_input_method
|
|
118
|
+
elsif db.respond_to?(:identifier_input_method)
|
|
119
|
+
@identifier_input_method = db.identifier_input_method
|
|
120
|
+
else
|
|
121
|
+
@identifier_input_method = nil
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# The String instance method to call on identifiers before sending them to
|
|
126
|
+
# the database.
|
|
127
|
+
def identifier_output_method
|
|
128
|
+
if defined?(@identifier_output_method)
|
|
129
|
+
@identifier_output_method
|
|
130
|
+
elsif db.respond_to?(:identifier_output_method)
|
|
131
|
+
@identifier_output_method = db.identifier_output_method
|
|
132
|
+
else
|
|
133
|
+
@identifier_output_method = nil
|
|
134
|
+
end
|
|
124
135
|
end
|
|
125
136
|
|
|
126
137
|
# Returns a string representation of the dataset including the class name
|
|
127
138
|
# and the corresponding SQL select statement.
|
|
128
139
|
def inspect
|
|
129
|
-
|
|
140
|
+
c = self.class
|
|
141
|
+
c = c.superclass while c.name.nil? || c.name == ''
|
|
142
|
+
"#<#{c.name}: #{sql.inspect}>"
|
|
130
143
|
end
|
|
131
144
|
|
|
132
|
-
#
|
|
145
|
+
# The alias to use for the row_number column, used when emulating OFFSET
|
|
146
|
+
# support and for eager limit strategies
|
|
147
|
+
def row_number_column
|
|
148
|
+
:x_sequel_row_number_x
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Splits a possible implicit alias in +c+, handling both SQL::AliasedExpressions
|
|
133
152
|
# and Symbols. Returns an array of two elements, with the first being the
|
|
134
153
|
# main expression, and the second being the alias.
|
|
135
154
|
def split_alias(c)
|
|
@@ -139,6 +158,8 @@ module Sequel
|
|
|
139
158
|
[c_table ? SQL::QualifiedIdentifier.new(c_table, column.to_sym) : column.to_sym, aliaz]
|
|
140
159
|
when SQL::AliasedExpression
|
|
141
160
|
[c.expression, c.aliaz]
|
|
161
|
+
when SQL::JoinClause
|
|
162
|
+
[c.table, c.table_alias]
|
|
142
163
|
else
|
|
143
164
|
[c, nil]
|
|
144
165
|
end
|
|
@@ -151,6 +172,10 @@ module Sequel
|
|
|
151
172
|
# used, where N is an integer starting at 0 and increasing until an
|
|
152
173
|
# unused one is found.
|
|
153
174
|
#
|
|
175
|
+
# You can provide a second addition array argument containing symbols
|
|
176
|
+
# that should not be considered valid table aliases. The current aliases
|
|
177
|
+
# for the FROM and JOIN tables are automatically included in this array.
|
|
178
|
+
#
|
|
154
179
|
# DB[:table].unused_table_alias(:t)
|
|
155
180
|
# # => :t
|
|
156
181
|
#
|
|
@@ -159,9 +184,11 @@ module Sequel
|
|
|
159
184
|
#
|
|
160
185
|
# DB[:table, :table_0].unused_table_alias(:table)
|
|
161
186
|
# # => :table_1
|
|
162
|
-
|
|
187
|
+
#
|
|
188
|
+
# DB[:table, :table_0].unused_table_alias(:table, [:table_1, :table_2])
|
|
189
|
+
# # => :table_3
|
|
190
|
+
def unused_table_alias(table_alias, used_aliases = [])
|
|
163
191
|
table_alias = alias_symbol(table_alias)
|
|
164
|
-
used_aliases = []
|
|
165
192
|
used_aliases += opts[:from].map{|t| alias_symbol(t)} if opts[:from]
|
|
166
193
|
used_aliases += opts[:join].map{|j| j.table_alias ? alias_alias_symbol(j.table_alias) : alias_symbol(j.table)} if opts[:join]
|
|
167
194
|
if used_aliases.include?(table_alias)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Dataset
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Mutation methods
|
|
4
|
+
# :section: 7 - Mutation methods
|
|
5
5
|
# These methods modify the receiving dataset and should be used with care.
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
8
8
|
# All methods that should have a ! method added that modifies the receiver.
|
|
9
|
-
MUTATION_METHODS = QUERY_METHODS
|
|
9
|
+
MUTATION_METHODS = QUERY_METHODS - [:paginate, :naked]
|
|
10
10
|
|
|
11
11
|
# Setup mutation (e.g. filter!) methods. These operate the same as the
|
|
12
12
|
# non-! methods, but replace the options of the current dataset with the
|
|
@@ -21,17 +21,16 @@ module Sequel
|
|
|
21
21
|
def_mutation_method(*MUTATION_METHODS)
|
|
22
22
|
|
|
23
23
|
# Set the method to call on identifiers going into the database for this dataset
|
|
24
|
-
|
|
24
|
+
attr_writer :identifier_input_method
|
|
25
25
|
|
|
26
26
|
# Set the method to call on identifiers coming the database for this dataset
|
|
27
|
-
|
|
27
|
+
attr_writer :identifier_output_method
|
|
28
28
|
|
|
29
29
|
# Whether to quote identifiers for this dataset
|
|
30
30
|
attr_writer :quote_identifiers
|
|
31
31
|
|
|
32
|
-
# The row_proc for this database, should be
|
|
33
|
-
# a single hash argument and returns the object you want
|
|
34
|
-
# each to return.
|
|
32
|
+
# The row_proc for this database, should be any object that responds to +call+ with
|
|
33
|
+
# a single hash argument and returns the object you want #each to return.
|
|
35
34
|
attr_accessor :row_proc
|
|
36
35
|
|
|
37
36
|
# Add a mutation method to this dataset instance.
|
|
@@ -40,6 +39,12 @@ module Sequel
|
|
|
40
39
|
instance_eval("def #{meth}!(*args, &block); mutation_method(:#{meth}, *args, &block) end", __FILE__, __LINE__)
|
|
41
40
|
end
|
|
42
41
|
end
|
|
42
|
+
|
|
43
|
+
# Remove the row_proc from the current dataset.
|
|
44
|
+
def naked!
|
|
45
|
+
self.row_proc = nil
|
|
46
|
+
self
|
|
47
|
+
end
|
|
43
48
|
|
|
44
49
|
private
|
|
45
50
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Dataset
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods related to prepared statements or bound variables
|
|
4
|
+
# :section: 8 - Methods related to prepared statements or bound variables
|
|
5
5
|
# On some adapters, these use native prepared statements and bound variables, on others
|
|
6
6
|
# support is emulated. For details, see the {"Prepared Statements/Bound Variables" guide}[link:files/doc/prepared_statements_rdoc.html].
|
|
7
7
|
# ---------------------
|
|
@@ -12,15 +12,12 @@ module Sequel
|
|
|
12
12
|
# native database support for bind variables and prepared
|
|
13
13
|
# statements (as opposed to the emulated ones used by default).
|
|
14
14
|
module ArgumentMapper
|
|
15
|
-
SQL_QUERY_TYPE = Hash.new{|h,k| h[k] = k}
|
|
16
|
-
SQL_QUERY_TYPE[:first] = SQL_QUERY_TYPE[:all] = :select
|
|
17
|
-
|
|
18
15
|
# The name of the prepared statement, if any.
|
|
19
16
|
attr_accessor :prepared_statement_name
|
|
20
17
|
|
|
21
18
|
# The bind arguments to use for running this prepared statement
|
|
22
19
|
attr_accessor :bind_arguments
|
|
23
|
-
|
|
20
|
+
|
|
24
21
|
# Set the bind arguments based on the hash and call super.
|
|
25
22
|
def call(bind_vars={}, &block)
|
|
26
23
|
ds = bind(bind_vars)
|
|
@@ -35,16 +32,9 @@ module Sequel
|
|
|
35
32
|
return @prepared_sql if @prepared_sql
|
|
36
33
|
@prepared_args ||= []
|
|
37
34
|
@prepared_sql = super
|
|
38
|
-
|
|
35
|
+
@opts[:sql] = @prepared_sql
|
|
39
36
|
@prepared_sql
|
|
40
37
|
end
|
|
41
|
-
|
|
42
|
-
private
|
|
43
|
-
|
|
44
|
-
# The type of query (:select, :insert, :delete, :update).
|
|
45
|
-
def sql_query_type
|
|
46
|
-
SQL_QUERY_TYPE[@prepared_type]
|
|
47
|
-
end
|
|
48
38
|
end
|
|
49
39
|
|
|
50
40
|
# Backbone of the prepared statement support. Grafts bind variable
|
|
@@ -56,6 +46,10 @@ module Sequel
|
|
|
56
46
|
module PreparedStatementMethods
|
|
57
47
|
PLACEHOLDER_RE = /\A\$(.*)\z/
|
|
58
48
|
|
|
49
|
+
# Whether to log the full SQL query. By default, just the prepared statement
|
|
50
|
+
# name is generally logged on adapters that support native prepared statements.
|
|
51
|
+
attr_accessor :log_sql
|
|
52
|
+
|
|
59
53
|
# The type of prepared statement, should be one of :select, :first,
|
|
60
54
|
# :insert, :update, or :delete
|
|
61
55
|
attr_accessor :prepared_type
|
|
@@ -63,6 +57,9 @@ module Sequel
|
|
|
63
57
|
# The array/hash of bound variable placeholder names.
|
|
64
58
|
attr_accessor :prepared_args
|
|
65
59
|
|
|
60
|
+
# The dataset that created this prepared statement.
|
|
61
|
+
attr_accessor :orig_dataset
|
|
62
|
+
|
|
66
63
|
# The argument to supply to insert and update, which may use
|
|
67
64
|
# placeholders specified by prepared_args
|
|
68
65
|
attr_accessor :prepared_modify_values
|
|
@@ -72,31 +69,46 @@ module Sequel
|
|
|
72
69
|
def call(bind_vars={}, &block)
|
|
73
70
|
bind(bind_vars).run(&block)
|
|
74
71
|
end
|
|
72
|
+
|
|
73
|
+
# Send the columns to the original dataset, as calling it
|
|
74
|
+
# on the prepared statement can cause problems.
|
|
75
|
+
def columns
|
|
76
|
+
orig_dataset.columns
|
|
77
|
+
end
|
|
75
78
|
|
|
76
79
|
# Returns the SQL for the prepared statement, depending on
|
|
77
80
|
# the type of the statement and the prepared_modify_values.
|
|
78
81
|
def prepared_sql
|
|
79
82
|
case @prepared_type
|
|
80
|
-
when :select, :all
|
|
83
|
+
when :select, :all, :each
|
|
84
|
+
# Most common scenario, so listed first.
|
|
81
85
|
select_sql
|
|
82
86
|
when :first
|
|
83
87
|
clone(:limit=>1).select_sql
|
|
88
|
+
when :insert_select
|
|
89
|
+
returning.insert_sql(*@prepared_modify_values)
|
|
84
90
|
when :insert
|
|
85
91
|
insert_sql(*@prepared_modify_values)
|
|
86
92
|
when :update
|
|
87
93
|
update_sql(*@prepared_modify_values)
|
|
88
94
|
when :delete
|
|
89
95
|
delete_sql
|
|
96
|
+
else
|
|
97
|
+
select_sql
|
|
90
98
|
end
|
|
91
99
|
end
|
|
92
100
|
|
|
93
101
|
# Changes the values of symbols if they start with $ and
|
|
94
102
|
# prepared_args is present. If so, they are considered placeholders,
|
|
95
103
|
# and they are substituted using prepared_arg.
|
|
96
|
-
def
|
|
104
|
+
def literal_symbol_append(sql, v)
|
|
97
105
|
if @opts[:bind_vars] and match = PLACEHOLDER_RE.match(v.to_s)
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
s = match[1].to_sym
|
|
107
|
+
if prepared_arg?(s)
|
|
108
|
+
literal_append(sql, prepared_arg(s))
|
|
109
|
+
else
|
|
110
|
+
sql << v.to_s
|
|
111
|
+
end
|
|
100
112
|
else
|
|
101
113
|
super
|
|
102
114
|
end
|
|
@@ -117,7 +129,12 @@ module Sequel
|
|
|
117
129
|
def run(&block)
|
|
118
130
|
case @prepared_type
|
|
119
131
|
when :select, :all
|
|
132
|
+
# Most common scenario, so listed first
|
|
120
133
|
all(&block)
|
|
134
|
+
when :each
|
|
135
|
+
each(&block)
|
|
136
|
+
when :insert_select
|
|
137
|
+
with_sql(prepared_sql).first
|
|
121
138
|
when :first
|
|
122
139
|
first
|
|
123
140
|
when :insert
|
|
@@ -126,6 +143,13 @@ module Sequel
|
|
|
126
143
|
update(*@prepared_modify_values)
|
|
127
144
|
when :delete
|
|
128
145
|
delete
|
|
146
|
+
when Array
|
|
147
|
+
case @prepared_type.at(0)
|
|
148
|
+
when :map, :to_hash, :to_hash_groups
|
|
149
|
+
send(*@prepared_type, &block)
|
|
150
|
+
end
|
|
151
|
+
else
|
|
152
|
+
all(&block)
|
|
129
153
|
end
|
|
130
154
|
end
|
|
131
155
|
|
|
@@ -136,11 +160,16 @@ module Sequel
|
|
|
136
160
|
@opts[:bind_vars][k]
|
|
137
161
|
end
|
|
138
162
|
|
|
163
|
+
# Whether there is a bound value for the given key.
|
|
164
|
+
def prepared_arg?(k)
|
|
165
|
+
@opts[:bind_vars].has_key?(k)
|
|
166
|
+
end
|
|
167
|
+
|
|
139
168
|
# Use a clone of the dataset extended with prepared statement
|
|
140
169
|
# support and using the same argument hash so that you can use
|
|
141
170
|
# bind variables/prepared arguments in subselects.
|
|
142
|
-
def
|
|
143
|
-
ps = ds.prepare(:select)
|
|
171
|
+
def subselect_sql_append(sql, ds)
|
|
172
|
+
ps = ds.clone(:append_sql=>sql).prepare(:select)
|
|
144
173
|
ps = ps.bind(@opts[:bind_vars]) if @opts[:bind_vars]
|
|
145
174
|
ps.prepared_args = prepared_args
|
|
146
175
|
ps.prepared_sql
|
|
@@ -171,6 +200,11 @@ module Sequel
|
|
|
171
200
|
prepared_args << k
|
|
172
201
|
prepared_arg_placeholder
|
|
173
202
|
end
|
|
203
|
+
|
|
204
|
+
# Always assume there is a prepared arg in the argument mapper.
|
|
205
|
+
def prepared_arg?(k)
|
|
206
|
+
true
|
|
207
|
+
end
|
|
174
208
|
end
|
|
175
209
|
|
|
176
210
|
# Set the bind variables to use for the call. If bind variables have
|
|
@@ -184,11 +218,9 @@ module Sequel
|
|
|
184
218
|
clone(:bind_vars=>@opts[:bind_vars] ? @opts[:bind_vars].merge(bind_vars) : bind_vars)
|
|
185
219
|
end
|
|
186
220
|
|
|
187
|
-
# For the given type (:select, :insert, :update, or :delete),
|
|
188
|
-
# run the sql with the bind variables
|
|
189
|
-
#
|
|
190
|
-
# insert or update (if one of those types is used),
|
|
191
|
-
# which may contain placeholders.
|
|
221
|
+
# For the given type (:select, :first, :insert, :insert_select, :update, or :delete),
|
|
222
|
+
# run the sql with the bind variables specified in the hash. +values+ is a hash passed to
|
|
223
|
+
# insert or update (if one of those types is used), which may contain placeholders.
|
|
192
224
|
#
|
|
193
225
|
# DB[:table].filter(:id=>:$id).call(:first, :id=>1)
|
|
194
226
|
# # SELECT * FROM table WHERE id = ? LIMIT 1 -- (1)
|
|
@@ -197,11 +229,16 @@ module Sequel
|
|
|
197
229
|
prepare(type, nil, *values).call(bind_variables, &block)
|
|
198
230
|
end
|
|
199
231
|
|
|
200
|
-
# Prepare an SQL statement for later execution.
|
|
201
|
-
#
|
|
202
|
-
#
|
|
203
|
-
#
|
|
204
|
-
#
|
|
232
|
+
# Prepare an SQL statement for later execution. Takes a type similar to #call,
|
|
233
|
+
# and the +name+ symbol of the prepared statement. While +name+ defaults to +nil+,
|
|
234
|
+
# it should always be provided as a symbol for the name of the prepared statement,
|
|
235
|
+
# as some databases require that prepared statements have names.
|
|
236
|
+
#
|
|
237
|
+
# This returns a clone of the dataset extended with PreparedStatementMethods,
|
|
238
|
+
# which you can +call+ with the hash of bind variables to use.
|
|
239
|
+
# The prepared statement is also stored in
|
|
240
|
+
# the associated database, where it can be called by name.
|
|
241
|
+
# The following usage is identical:
|
|
205
242
|
#
|
|
206
243
|
# ps = DB[:table].filter(:name=>:$name).prepare(:first, :select_by_name)
|
|
207
244
|
#
|
|
@@ -212,7 +249,7 @@ module Sequel
|
|
|
212
249
|
# DB.call(:select_by_name, :name=>'Blah') # Same thing
|
|
213
250
|
def prepare(type, name=nil, *values)
|
|
214
251
|
ps = to_prepared_statement(type, values)
|
|
215
|
-
db.
|
|
252
|
+
db.set_prepared_statement(name, ps) if name
|
|
216
253
|
ps
|
|
217
254
|
end
|
|
218
255
|
|
|
@@ -223,6 +260,7 @@ module Sequel
|
|
|
223
260
|
def to_prepared_statement(type, values=nil)
|
|
224
261
|
ps = bind
|
|
225
262
|
ps.extend(PreparedStatementMethods)
|
|
263
|
+
ps.orig_dataset = self
|
|
226
264
|
ps.prepared_type = type
|
|
227
265
|
ps.prepared_modify_values = values
|
|
228
266
|
ps
|