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
data/lib/sequel/dataset/query.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Dataset
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods that return modified datasets
|
|
4
|
+
# :section: 1 - Methods that return modified datasets
|
|
5
5
|
# These methods all return modified copies of the receiver.
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
@@ -28,12 +28,14 @@ module Sequel
|
|
|
28
28
|
JOIN_METHODS = (CONDITIONED_JOIN_TYPES + UNCONDITIONED_JOIN_TYPES).map{|x| "#{x}_join".to_sym} + [:join, :join_table]
|
|
29
29
|
|
|
30
30
|
# Methods that return modified datasets
|
|
31
|
-
QUERY_METHODS =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
QUERY_METHODS = (<<-METHS).split.map{|x| x.to_sym} + JOIN_METHODS
|
|
32
|
+
add_graph_aliases and distinct except exclude exclude_having exclude_where
|
|
33
|
+
filter for_update from from_self graph grep group group_and_count group_by having intersect invert
|
|
34
|
+
limit lock_style naked or order order_append order_by order_more order_prepend paginate qualify query
|
|
35
|
+
reverse reverse_order select select_all select_append select_group select_more server
|
|
36
|
+
set_defaults set_graph_aliases set_overrides unfiltered ungraphed ungrouped union
|
|
37
|
+
unlimited unordered where with with_recursive with_sql
|
|
38
|
+
METHS
|
|
37
39
|
|
|
38
40
|
# Adds an further filter to an existing filter using AND. If no filter
|
|
39
41
|
# exists an error is raised. This method is identical to #filter except
|
|
@@ -80,7 +82,7 @@ module Sequel
|
|
|
80
82
|
# :from_self :: Set to false to not wrap the returned dataset in a from_self, use with care.
|
|
81
83
|
#
|
|
82
84
|
# DB[:items].except(DB[:other_items])
|
|
83
|
-
# # SELECT * FROM items EXCEPT SELECT * FROM other_items
|
|
85
|
+
# # SELECT * FROM (SELECT * FROM items EXCEPT SELECT * FROM other_items) AS t1
|
|
84
86
|
#
|
|
85
87
|
# DB[:items].except(DB[:other_items], :all=>true, :from_self=>false)
|
|
86
88
|
# # SELECT * FROM items EXCEPT ALL SELECT * FROM other_items
|
|
@@ -103,12 +105,29 @@ module Sequel
|
|
|
103
105
|
# DB[:items].exclude(:category => 'software', :id=>3)
|
|
104
106
|
# # SELECT * FROM items WHERE ((category != 'software') OR (id != 3))
|
|
105
107
|
def exclude(*cond, &block)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
_filter_or_exclude(true, @opts[:having] ? :having : :where, *cond, &block)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Inverts the given conditions and adds them to the HAVING clause.
|
|
112
|
+
#
|
|
113
|
+
# DB[:items].select_group(:name).exclude_having{count(name) < 2}
|
|
114
|
+
# # SELECT name FROM items GROUP BY name HAVING (count(name) >= 2)
|
|
115
|
+
def exclude_having(*cond, &block)
|
|
116
|
+
_filter_or_exclude(true, :having, *cond, &block)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Inverts the given conditions and adds them to the WHERE clause.
|
|
120
|
+
#
|
|
121
|
+
# DB[:items].select_group(:name).exclude_where(:category => 'software')
|
|
122
|
+
# # SELECT * FROM items WHERE (category != 'software')
|
|
123
|
+
#
|
|
124
|
+
# DB[:items].select_group(:name).
|
|
125
|
+
# exclude_having{count(name) < 2}.
|
|
126
|
+
# exclude_where(:category => 'software')
|
|
127
|
+
# # SELECT name FROM items WHERE (category != 'software')
|
|
128
|
+
# # GROUP BY name HAVING (count(name) >= 2)
|
|
129
|
+
def exclude_where(*cond, &block)
|
|
130
|
+
_filter_or_exclude(true, :where, *cond, &block)
|
|
112
131
|
end
|
|
113
132
|
|
|
114
133
|
# Returns a copy of the dataset with the given conditions imposed upon it.
|
|
@@ -145,7 +164,7 @@ module Sequel
|
|
|
145
164
|
# DB[:items].filter('price < ?', 100)
|
|
146
165
|
# # SELECT * FROM items WHERE price < 100
|
|
147
166
|
#
|
|
148
|
-
# DB[:items].filter([[:id,
|
|
167
|
+
# DB[:items].filter([[:id, [1,2,3]], [:id, 0..10]])
|
|
149
168
|
# # SELECT * FROM items WHERE ((id IN (1, 2, 3)) AND ((id >= 0) AND (id <= 10)))
|
|
150
169
|
#
|
|
151
170
|
# DB[:items].filter('price < 100')
|
|
@@ -184,16 +203,22 @@ module Sequel
|
|
|
184
203
|
def from(*source)
|
|
185
204
|
table_alias_num = 0
|
|
186
205
|
sources = []
|
|
206
|
+
ctes = nil
|
|
187
207
|
source.each do |s|
|
|
188
208
|
case s
|
|
189
209
|
when Hash
|
|
190
210
|
s.each{|k,v| sources << SQL::AliasedExpression.new(k,v)}
|
|
191
211
|
when Dataset
|
|
212
|
+
if hoist_cte?(s)
|
|
213
|
+
ctes ||= []
|
|
214
|
+
ctes += s.opts[:with]
|
|
215
|
+
s = s.clone(:with=>nil)
|
|
216
|
+
end
|
|
192
217
|
sources << SQL::AliasedExpression.new(s, dataset_alias(table_alias_num+=1))
|
|
193
218
|
when Symbol
|
|
194
219
|
sch, table, aliaz = split_symbol(s)
|
|
195
220
|
if aliaz
|
|
196
|
-
s = sch ? SQL::QualifiedIdentifier.new(sch
|
|
221
|
+
s = sch ? SQL::QualifiedIdentifier.new(sch, table) : SQL::Identifier.new(table)
|
|
197
222
|
sources << SQL::AliasedExpression.new(s, aliaz.to_sym)
|
|
198
223
|
else
|
|
199
224
|
sources << s
|
|
@@ -203,6 +228,7 @@ module Sequel
|
|
|
203
228
|
end
|
|
204
229
|
end
|
|
205
230
|
o = {:from=>sources.empty? ? nil : sources}
|
|
231
|
+
o[:with] = (opts[:with] || []) + ctes if ctes
|
|
206
232
|
o[:num_dataset_sources] = table_alias_num if table_alias_num > 0
|
|
207
233
|
clone(o)
|
|
208
234
|
end
|
|
@@ -270,21 +296,25 @@ module Sequel
|
|
|
270
296
|
end
|
|
271
297
|
|
|
272
298
|
# Returns a copy of the dataset with the results grouped by the value of
|
|
273
|
-
# the given columns.
|
|
299
|
+
# the given columns. If a block is given, it is treated
|
|
300
|
+
# as a virtual row block, similar to +filter+.
|
|
274
301
|
#
|
|
275
302
|
# DB[:items].group(:id) # SELECT * FROM items GROUP BY id
|
|
276
303
|
# DB[:items].group(:id, :name) # SELECT * FROM items GROUP BY id, name
|
|
277
|
-
|
|
304
|
+
# DB[:items].group{[a, sum(b)]} # SELECT * FROM items GROUP BY a, sum(b)
|
|
305
|
+
def group(*columns, &block)
|
|
306
|
+
virtual_row_columns(columns, block)
|
|
278
307
|
clone(:group => (columns.compact.empty? ? nil : columns))
|
|
279
308
|
end
|
|
280
309
|
|
|
281
310
|
# Alias of group
|
|
282
|
-
def group_by(*columns)
|
|
283
|
-
group(*columns)
|
|
311
|
+
def group_by(*columns, &block)
|
|
312
|
+
group(*columns, &block)
|
|
284
313
|
end
|
|
285
314
|
|
|
286
315
|
# Returns a dataset grouped by the given column with count by group.
|
|
287
316
|
# Column aliases may be supplied, and will be included in the select clause.
|
|
317
|
+
# If a block is given, it is treated as a virtual row block, similar to +filter+.
|
|
288
318
|
#
|
|
289
319
|
# Examples:
|
|
290
320
|
#
|
|
@@ -299,8 +329,24 @@ module Sequel
|
|
|
299
329
|
# DB[:items].group_and_count(:first_name___name).all
|
|
300
330
|
# # SELECT first_name AS name, count(*) AS count FROM items GROUP BY first_name
|
|
301
331
|
# # => [{:name=>'a', :count=>1}, ...]
|
|
302
|
-
|
|
303
|
-
|
|
332
|
+
#
|
|
333
|
+
# DB[:items].group_and_count{substr(first_name, 1, 1).as(initial)}.all
|
|
334
|
+
# # SELECT substr(first_name, 1, 1) AS initial, count(*) AS count FROM items GROUP BY substr(first_name, 1, 1)
|
|
335
|
+
# # => [{:initial=>'a', :count=>1}, ...]
|
|
336
|
+
def group_and_count(*columns, &block)
|
|
337
|
+
select_group(*columns, &block).select_more(COUNT_OF_ALL_AS_COUNT)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
# Adds the appropriate CUBE syntax to GROUP BY.
|
|
341
|
+
def group_cube
|
|
342
|
+
raise Error, "GROUP BY CUBE not supported on #{db.database_type}" unless supports_group_cube?
|
|
343
|
+
clone(:group_options=>:cube)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
# Adds the appropriate ROLLUP syntax to GROUP BY.
|
|
347
|
+
def group_rollup
|
|
348
|
+
raise Error, "GROUP BY ROLLUP not supported on #{db.database_type}" unless supports_group_rollup?
|
|
349
|
+
clone(:group_options=>:rollup)
|
|
304
350
|
end
|
|
305
351
|
|
|
306
352
|
# Returns a copy of the dataset with the HAVING conditions changed. See #filter for argument types.
|
|
@@ -356,7 +402,11 @@ module Sequel
|
|
|
356
402
|
inner_join(*args, &block)
|
|
357
403
|
end
|
|
358
404
|
|
|
359
|
-
# Returns a joined dataset.
|
|
405
|
+
# Returns a joined dataset. Not usually called directly, users should use the
|
|
406
|
+
# appropriate join method (e.g. join, left_join, natural_join, cross_join) which fills
|
|
407
|
+
# in the +type+ argument.
|
|
408
|
+
#
|
|
409
|
+
# Takes the following arguments:
|
|
360
410
|
#
|
|
361
411
|
# * type - The type of join to do (e.g. :inner)
|
|
362
412
|
# * table - Depends on type:
|
|
@@ -386,7 +436,29 @@ module Sequel
|
|
|
386
436
|
# in which case it yields the table alias/name for the table currently being joined,
|
|
387
437
|
# the table alias/name for the last joined (or first table), and an array of previous
|
|
388
438
|
# SQL::JoinClause. Unlike +filter+, this block is not treated as a virtual row block.
|
|
439
|
+
#
|
|
440
|
+
# Examples:
|
|
441
|
+
#
|
|
442
|
+
# DB[:a].join_table(:cross, :b)
|
|
443
|
+
# # SELECT * FROM a CROSS JOIN b
|
|
444
|
+
#
|
|
445
|
+
# DB[:a].join_table(:inner, DB[:b], :c=>d)
|
|
446
|
+
# # SELECT * FROM a INNER JOIN (SELECT * FROM b) AS t1 ON (t1.c = a.d)
|
|
447
|
+
#
|
|
448
|
+
# DB[:a].join_table(:left, :b___c, [:d])
|
|
449
|
+
# # SELECT * FROM a LEFT JOIN b AS c USING (d)
|
|
450
|
+
#
|
|
451
|
+
# DB[:a].natural_join(:b).join_table(:inner, :c) do |ta, jta, js|
|
|
452
|
+
# (:d.qualify(ta) > :e.qualify(jta)) & {:f.qualify(ta)=>DB.from(js.first.table).select(:g)}
|
|
453
|
+
# end
|
|
454
|
+
# # SELECT * FROM a NATURAL JOIN b INNER JOIN c
|
|
455
|
+
# # ON ((c.d > b.e) AND (c.f IN (SELECT g FROM b)))
|
|
389
456
|
def join_table(type, table, expr=nil, options={}, &block)
|
|
457
|
+
if hoist_cte?(table)
|
|
458
|
+
s, ds = hoist_cte(table)
|
|
459
|
+
return s.join_table(type, ds, expr, options, &block)
|
|
460
|
+
end
|
|
461
|
+
|
|
390
462
|
using_join = expr.is_a?(Array) && !expr.empty? && expr.all?{|x| x.is_a?(Symbol)}
|
|
391
463
|
if using_join && !supports_join_using?
|
|
392
464
|
h = {}
|
|
@@ -431,6 +503,7 @@ module Sequel
|
|
|
431
503
|
v = qualified_column_name(v, last_alias) if v.is_a?(Symbol)
|
|
432
504
|
[k,v]
|
|
433
505
|
end
|
|
506
|
+
expr = SQL::BooleanExpression.from_value_pairs(expr)
|
|
434
507
|
end
|
|
435
508
|
if block
|
|
436
509
|
expr2 = yield(table_name, last_alias, @opts[:join] || [])
|
|
@@ -531,7 +604,7 @@ module Sequel
|
|
|
531
604
|
# DB[:items].order{sum(name).desc} # SELECT * FROM items ORDER BY sum(name) DESC
|
|
532
605
|
# DB[:items].order(nil) # SELECT * FROM items
|
|
533
606
|
def order(*columns, &block)
|
|
534
|
-
columns
|
|
607
|
+
virtual_row_columns(columns, block)
|
|
535
608
|
clone(:order => (columns.compact.empty?) ? nil : columns)
|
|
536
609
|
end
|
|
537
610
|
|
|
@@ -565,7 +638,7 @@ module Sequel
|
|
|
565
638
|
@opts[:order] ? ds.order_more(*@opts[:order]) : ds
|
|
566
639
|
end
|
|
567
640
|
|
|
568
|
-
# Qualify to the given table, or first source if
|
|
641
|
+
# Qualify to the given table, or first source if no table is given.
|
|
569
642
|
#
|
|
570
643
|
# DB[:items].filter(:id=>1).qualify
|
|
571
644
|
# # SELECT items.* FROM items WHERE (items.id = 1)
|
|
@@ -606,6 +679,18 @@ module Sequel
|
|
|
606
679
|
qualify_to(first_source)
|
|
607
680
|
end
|
|
608
681
|
|
|
682
|
+
# Modify the RETURNING clause, only supported on a few databases. If returning
|
|
683
|
+
# is used, instead of insert returning the autogenerated primary key or
|
|
684
|
+
# update/delete returning the number of modified rows, results are
|
|
685
|
+
# returned using +fetch_rows+.
|
|
686
|
+
#
|
|
687
|
+
# DB[:items].returning # RETURNING *
|
|
688
|
+
# DB[:items].returning(nil) # RETURNING NULL
|
|
689
|
+
# DB[:items].returning(:id, :name) # RETURNING id, name
|
|
690
|
+
def returning(*values)
|
|
691
|
+
clone(:returning=>values)
|
|
692
|
+
end
|
|
693
|
+
|
|
609
694
|
# Returns a copy of the dataset with the order reversed. If no order is
|
|
610
695
|
# given, the existing order is inverted.
|
|
611
696
|
#
|
|
@@ -629,7 +714,7 @@ module Sequel
|
|
|
629
714
|
# DB[:items].select(:a, :b) # SELECT a, b FROM items
|
|
630
715
|
# DB[:items].select{[a, sum(b)]} # SELECT a, sum(b) FROM items
|
|
631
716
|
def select(*columns, &block)
|
|
632
|
-
columns
|
|
717
|
+
virtual_row_columns(columns, block)
|
|
633
718
|
m = []
|
|
634
719
|
columns.each do |i|
|
|
635
720
|
i.is_a?(Hash) ? m.concat(i.map{|k, v| SQL::AliasedExpression.new(k,v)}) : m << i
|
|
@@ -637,11 +722,19 @@ module Sequel
|
|
|
637
722
|
clone(:select => m)
|
|
638
723
|
end
|
|
639
724
|
|
|
640
|
-
# Returns a copy of the dataset selecting the wildcard
|
|
725
|
+
# Returns a copy of the dataset selecting the wildcard if no arguments
|
|
726
|
+
# are given. If arguments are given, treat them as tables and select
|
|
727
|
+
# all columns (using the wildcard) from each table.
|
|
641
728
|
#
|
|
642
729
|
# DB[:items].select(:a).select_all # SELECT * FROM items
|
|
643
|
-
|
|
644
|
-
|
|
730
|
+
# DB[:items].select_all(:items) # SELECT items.* FROM items
|
|
731
|
+
# DB[:items].select_all(:items, :foo) # SELECT items.*, foo.* FROM items
|
|
732
|
+
def select_all(*tables)
|
|
733
|
+
if tables.empty?
|
|
734
|
+
clone(:select => nil)
|
|
735
|
+
else
|
|
736
|
+
select(*tables.map{|t| i, a = split_alias(t); a || i}.map{|t| SQL::ColumnAll.new(t)})
|
|
737
|
+
end
|
|
645
738
|
end
|
|
646
739
|
|
|
647
740
|
# Returns a copy of the dataset with the given columns added
|
|
@@ -653,10 +746,29 @@ module Sequel
|
|
|
653
746
|
# DB[:items].select_append(:b) # SELECT *, b FROM items
|
|
654
747
|
def select_append(*columns, &block)
|
|
655
748
|
cur_sel = @opts[:select]
|
|
656
|
-
|
|
749
|
+
if !cur_sel || cur_sel.empty?
|
|
750
|
+
unless supports_select_all_and_column?
|
|
751
|
+
return select_all(*(Array(@opts[:from]) + Array(@opts[:join]))).select_more(*columns, &block)
|
|
752
|
+
end
|
|
753
|
+
cur_sel = [WILDCARD]
|
|
754
|
+
end
|
|
657
755
|
select(*(cur_sel + columns), &block)
|
|
658
756
|
end
|
|
659
757
|
|
|
758
|
+
# Set both the select and group clauses with the given +columns+.
|
|
759
|
+
# Column aliases may be supplied, and will be included in the select clause.
|
|
760
|
+
# This also takes a virtual row block similar to +filter+.
|
|
761
|
+
#
|
|
762
|
+
# DB[:items].select_group(:a, :b)
|
|
763
|
+
# # SELECT a, b FROM items GROUP BY a, b
|
|
764
|
+
#
|
|
765
|
+
# DB[:items].select_group(:c___a){f(c2)}
|
|
766
|
+
# # SELECT c AS a, f(c2) FROM items GROUP BY c, f(c2)
|
|
767
|
+
def select_group(*columns, &block)
|
|
768
|
+
virtual_row_columns(columns, block)
|
|
769
|
+
select(*columns).group(*columns.map{|c| unaliased_identifier(c)})
|
|
770
|
+
end
|
|
771
|
+
|
|
660
772
|
# Returns a copy of the dataset with the given columns added
|
|
661
773
|
# to the existing selected columns. If no columns are currently selected
|
|
662
774
|
# it will just select the columns given.
|
|
@@ -670,7 +782,7 @@ module Sequel
|
|
|
670
782
|
end
|
|
671
783
|
|
|
672
784
|
# Set the server for this dataset to use. Used to pick a specific database
|
|
673
|
-
# shard to run a query against, or to override the default (
|
|
785
|
+
# shard to run a query against, or to override the default (where SELECT uses
|
|
674
786
|
# :read_only database and all other queries use the :default database). This
|
|
675
787
|
# method is always available but is only useful when database sharding is being
|
|
676
788
|
# used.
|
|
@@ -702,6 +814,22 @@ module Sequel
|
|
|
702
814
|
clone(:overrides=>hash.merge(@opts[:overrides]||{}))
|
|
703
815
|
end
|
|
704
816
|
|
|
817
|
+
# Unbind bound variables from this dataset's filter and return an array of two
|
|
818
|
+
# objects. The first object is a modified dataset where the filter has been
|
|
819
|
+
# replaced with one that uses bound variable placeholders. The second object
|
|
820
|
+
# is the hash of unbound variables. You can then prepare and execute (or just
|
|
821
|
+
# call) the dataset with the bound variables to get results.
|
|
822
|
+
#
|
|
823
|
+
# ds, bv = DB[:items].filter(:a=>1).unbind
|
|
824
|
+
# ds # SELECT * FROM items WHERE (a = $a)
|
|
825
|
+
# bv # {:a => 1}
|
|
826
|
+
# ds.call(:select, bv)
|
|
827
|
+
def unbind
|
|
828
|
+
u = Unbinder.new
|
|
829
|
+
ds = clone(:where=>u.transform(opts[:where]), :join=>u.transform(opts[:join]))
|
|
830
|
+
[ds, u.binds]
|
|
831
|
+
end
|
|
832
|
+
|
|
705
833
|
# Returns a copy of the dataset with no filters (HAVING or WHERE clause) applied.
|
|
706
834
|
#
|
|
707
835
|
# DB[:items].group(:a).having(:a=>1).where(:b).unfiltered
|
|
@@ -726,8 +854,8 @@ module Sequel
|
|
|
726
854
|
# :all :: Set to true to use UNION ALL instead of UNION, so duplicate rows can occur
|
|
727
855
|
# :from_self :: Set to false to not wrap the returned dataset in a from_self, use with care.
|
|
728
856
|
#
|
|
729
|
-
# DB[:items].union(DB[:other_items])
|
|
730
|
-
#
|
|
857
|
+
# DB[:items].union(DB[:other_items])
|
|
858
|
+
# # SELECT * FROM (SELECT * FROM items UNION SELECT * FROM other_items) AS t1
|
|
731
859
|
#
|
|
732
860
|
# DB[:items].union(DB[:other_items], :all=>true, :from_self=>false)
|
|
733
861
|
# # SELECT * FROM items UNION ALL SELECT * FROM other_items
|
|
@@ -774,7 +902,12 @@ module Sequel
|
|
|
774
902
|
# # WITH items AS (SELECT * FROM syx WHERE (name LIKE 'A%')) SELECT * FROM items
|
|
775
903
|
def with(name, dataset, opts={})
|
|
776
904
|
raise(Error, 'This datatset does not support common table expressions') unless supports_cte?
|
|
777
|
-
|
|
905
|
+
if hoist_cte?(dataset)
|
|
906
|
+
s, ds = hoist_cte(dataset)
|
|
907
|
+
s.with(name, ds, opts)
|
|
908
|
+
else
|
|
909
|
+
clone(:with=>(@opts[:with]||[]) + [opts.merge(:name=>name, :dataset=>dataset)])
|
|
910
|
+
end
|
|
778
911
|
end
|
|
779
912
|
|
|
780
913
|
# Add a recursive common table expression (CTE) with the given name, a dataset that
|
|
@@ -796,20 +929,50 @@ module Sequel
|
|
|
796
929
|
# # SELECT i AS id, pi AS parent_id FROM t
|
|
797
930
|
def with_recursive(name, nonrecursive, recursive, opts={})
|
|
798
931
|
raise(Error, 'This datatset does not support common table expressions') unless supports_cte?
|
|
799
|
-
|
|
932
|
+
if hoist_cte?(nonrecursive)
|
|
933
|
+
s, ds = hoist_cte(nonrecursive)
|
|
934
|
+
s.with_recursive(name, ds, recursive, opts)
|
|
935
|
+
elsif hoist_cte?(recursive)
|
|
936
|
+
s, ds = hoist_cte(recursive)
|
|
937
|
+
s.with_recursive(name, nonrecursive, ds, opts)
|
|
938
|
+
else
|
|
939
|
+
clone(:with=>(@opts[:with]||[]) + [opts.merge(:recursive=>true, :name=>name, :dataset=>nonrecursive.union(recursive, {:all=>opts[:union_all] != false, :from_self=>false}))])
|
|
940
|
+
end
|
|
800
941
|
end
|
|
801
942
|
|
|
802
943
|
# Returns a copy of the dataset with the static SQL used. This is useful if you want
|
|
803
944
|
# to keep the same row_proc/graph, but change the SQL used to custom SQL.
|
|
804
945
|
#
|
|
805
946
|
# DB[:items].with_sql('SELECT * FROM foo') # SELECT * FROM foo
|
|
947
|
+
#
|
|
948
|
+
# You can use placeholders in your SQL and provide arguments for those placeholders:
|
|
949
|
+
#
|
|
950
|
+
# DB[:items].with_sql('SELECT ? FROM foo', 1) # SELECT 1 FROM foo
|
|
951
|
+
#
|
|
952
|
+
# You can also provide a method name and arguments to call to get the SQL:
|
|
953
|
+
#
|
|
954
|
+
# DB[:items].with_sql(:insert_sql, :b=>1) # INSERT INTO items (b) VALUES (1)
|
|
806
955
|
def with_sql(sql, *args)
|
|
807
|
-
sql
|
|
956
|
+
if sql.is_a?(Symbol)
|
|
957
|
+
sql = send(sql, *args)
|
|
958
|
+
else
|
|
959
|
+
sql = SQL::PlaceholderLiteralString.new(sql, args) unless args.empty?
|
|
960
|
+
end
|
|
808
961
|
clone(:sql=>sql)
|
|
809
962
|
end
|
|
810
963
|
|
|
811
964
|
protected
|
|
812
965
|
|
|
966
|
+
# Add the dataset to the list of compounds
|
|
967
|
+
def compound_clone(type, dataset, opts)
|
|
968
|
+
if hoist_cte?(dataset)
|
|
969
|
+
s, ds = hoist_cte(dataset)
|
|
970
|
+
return s.compound_clone(type, ds, opts)
|
|
971
|
+
end
|
|
972
|
+
ds = compound_from_self.clone(:compounds=>Array(@opts[:compounds]).map{|x| x.dup} + [[type, dataset.compound_from_self, opts[:all]]])
|
|
973
|
+
opts[:from_self] == false ? ds : ds.from_self(opts)
|
|
974
|
+
end
|
|
975
|
+
|
|
813
976
|
# Return true if the dataset has a non-nil value for any key in opts.
|
|
814
977
|
def options_overlap(opts)
|
|
815
978
|
!(@opts.collect{|k,v| k unless v.nil?}.compact & opts).empty?
|
|
@@ -823,22 +986,22 @@ module Sequel
|
|
|
823
986
|
|
|
824
987
|
private
|
|
825
988
|
|
|
826
|
-
# Internal filter method so it works on either the having or where clauses.
|
|
827
|
-
def
|
|
989
|
+
# Internal filter/exclude method so it works on either the having or where clauses.
|
|
990
|
+
def _filter_or_exclude(invert, clause, *cond, &block)
|
|
828
991
|
cond = cond.first if cond.size == 1
|
|
829
992
|
if cond.respond_to?(:empty?) && cond.empty? && !block
|
|
830
993
|
clone
|
|
831
994
|
else
|
|
832
995
|
cond = filter_expr(cond, &block)
|
|
996
|
+
cond = SQL::BooleanExpression.invert(cond) if invert
|
|
833
997
|
cond = SQL::BooleanExpression.new(:AND, @opts[clause], cond) if @opts[clause]
|
|
834
998
|
clone(clause => cond)
|
|
835
999
|
end
|
|
836
1000
|
end
|
|
837
|
-
|
|
838
|
-
#
|
|
839
|
-
def
|
|
840
|
-
|
|
841
|
-
opts[:from_self] == false ? ds : ds.from_self(opts)
|
|
1001
|
+
|
|
1002
|
+
# Internal filter method so it works on either the having or where clauses.
|
|
1003
|
+
def _filter(clause, *cond, &block)
|
|
1004
|
+
_filter_or_exclude(false, clause, *cond, &block)
|
|
842
1005
|
end
|
|
843
1006
|
|
|
844
1007
|
# SQL expression object based on the expr type. See +filter+.
|
|
@@ -867,7 +1030,13 @@ module Sequel
|
|
|
867
1030
|
when Symbol, SQL::Expression
|
|
868
1031
|
expr
|
|
869
1032
|
when TrueClass, FalseClass
|
|
870
|
-
|
|
1033
|
+
if supports_where_true?
|
|
1034
|
+
SQL::BooleanExpression.new(:NOOP, expr)
|
|
1035
|
+
elsif expr
|
|
1036
|
+
SQL::Constants::SQLTRUE
|
|
1037
|
+
else
|
|
1038
|
+
SQL::Constants::SQLFALSE
|
|
1039
|
+
end
|
|
871
1040
|
when String
|
|
872
1041
|
LiteralString.new("(#{expr})")
|
|
873
1042
|
else
|
|
@@ -875,6 +1044,18 @@ module Sequel
|
|
|
875
1044
|
end
|
|
876
1045
|
end
|
|
877
1046
|
|
|
1047
|
+
# Return two datasets, the first a clone of the receiver with the WITH
|
|
1048
|
+
# clause from the given dataset added to it, and the second a clone of
|
|
1049
|
+
# the given dataset with the WITH clause removed.
|
|
1050
|
+
def hoist_cte(ds)
|
|
1051
|
+
[clone(:with => (opts[:with] || []) + ds.opts[:with]), ds.clone(:with => nil)]
|
|
1052
|
+
end
|
|
1053
|
+
|
|
1054
|
+
# Whether CTEs need to be hoisted from the given ds into the current ds.
|
|
1055
|
+
def hoist_cte?(ds)
|
|
1056
|
+
ds.is_a?(Dataset) && ds.opts[:with] && !supports_cte_in_subqueries?
|
|
1057
|
+
end
|
|
1058
|
+
|
|
878
1059
|
# Inverts the given order by breaking it into a list of column references
|
|
879
1060
|
# and inverting them.
|
|
880
1061
|
#
|
|
@@ -892,5 +1073,17 @@ module Sequel
|
|
|
892
1073
|
end
|
|
893
1074
|
end
|
|
894
1075
|
end
|
|
1076
|
+
|
|
1077
|
+
# Return self if the dataset already has a server, or a cloned dataset with the
|
|
1078
|
+
# default server otherwise.
|
|
1079
|
+
def default_server
|
|
1080
|
+
@opts[:server] ? self : clone(:server=>:default)
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
# Treat the +block+ as a virtual_row block if not +nil+ and
|
|
1084
|
+
# add the resulting columns to the +columns+ array (modifies +columns+).
|
|
1085
|
+
def virtual_row_columns(columns, block)
|
|
1086
|
+
columns.concat(Array(Sequel.virtual_row(&block))) if block
|
|
1087
|
+
end
|
|
895
1088
|
end
|
|
896
1089
|
end
|