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,22 +1,27 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Dataset
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods that execute code on the database
|
|
4
|
+
# :section: 2 - Methods that execute code on the database
|
|
5
5
|
# These methods all execute the dataset's SQL on the database.
|
|
6
6
|
# They don't return modified datasets, so if used in a method chain
|
|
7
7
|
# they should be the last method called.
|
|
8
8
|
# ---------------------
|
|
9
9
|
|
|
10
10
|
# Action methods defined by Sequel that execute code on the database.
|
|
11
|
-
ACTION_METHODS =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
ACTION_METHODS = (<<-METHS).split.map{|x| x.to_sym}
|
|
12
|
+
<< [] []= all avg count columns columns! delete each
|
|
13
|
+
empty? fetch_rows first get import insert insert_multiple interval last
|
|
14
|
+
map max min multi_insert range select_hash select_hash_groups select_map select_order_map
|
|
15
|
+
set single_record single_value sum to_csv to_hash to_hash_groups truncate update
|
|
16
|
+
METHS
|
|
15
17
|
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
# Inserts the given argument into the database. Returns self so it
|
|
19
|
+
# can be used safely when chaining:
|
|
20
|
+
#
|
|
21
|
+
# DB[:items] << {:id=>0, :name=>'Zero'} << DB[:old_items].select(:id, name)
|
|
22
|
+
def <<(arg)
|
|
23
|
+
insert(arg)
|
|
24
|
+
self
|
|
20
25
|
end
|
|
21
26
|
|
|
22
27
|
# Returns the first record matching the conditions. Examples:
|
|
@@ -72,7 +77,7 @@ module Sequel
|
|
|
72
77
|
# # => [:id, :name]
|
|
73
78
|
def columns
|
|
74
79
|
return @columns if @columns
|
|
75
|
-
ds = unfiltered.unordered.clone(:distinct => nil, :limit => 1)
|
|
80
|
+
ds = unfiltered.unordered.clone(:distinct => nil, :limit => 1, :offset=>nil)
|
|
76
81
|
ds.each{break}
|
|
77
82
|
@columns = ds.instance_variable_get(:@columns)
|
|
78
83
|
@columns || []
|
|
@@ -101,10 +106,15 @@ module Sequel
|
|
|
101
106
|
#
|
|
102
107
|
# DB[:table].delete # DELETE * FROM table
|
|
103
108
|
# # => 3
|
|
104
|
-
def delete
|
|
105
|
-
|
|
109
|
+
def delete(&block)
|
|
110
|
+
sql = delete_sql
|
|
111
|
+
if uses_returning?(:delete)
|
|
112
|
+
returning_fetch_rows(sql, &block)
|
|
113
|
+
else
|
|
114
|
+
execute_dui(sql)
|
|
115
|
+
end
|
|
106
116
|
end
|
|
107
|
-
|
|
117
|
+
|
|
108
118
|
# Iterates over the records in the dataset as they are yielded from the
|
|
109
119
|
# database adapter, and returns self.
|
|
110
120
|
#
|
|
@@ -114,23 +124,23 @@ module Sequel
|
|
|
114
124
|
# running additional queries inside the provided block. If you are
|
|
115
125
|
# running queries inside the block, you should use +all+ instead of +each+
|
|
116
126
|
# for the outer queries, or use a separate thread or shard inside +each+:
|
|
117
|
-
def each
|
|
127
|
+
def each
|
|
118
128
|
if @opts[:graph]
|
|
119
|
-
graph_each
|
|
129
|
+
graph_each{|r| yield r}
|
|
120
130
|
elsif row_proc = @row_proc
|
|
121
131
|
fetch_rows(select_sql){|r| yield row_proc.call(r)}
|
|
122
132
|
else
|
|
123
|
-
fetch_rows(select_sql
|
|
133
|
+
fetch_rows(select_sql){|r| yield r}
|
|
124
134
|
end
|
|
125
135
|
self
|
|
126
136
|
end
|
|
127
137
|
|
|
128
138
|
# Returns true if no records exist in the dataset, false otherwise
|
|
129
139
|
#
|
|
130
|
-
# DB[:table].empty? # SELECT 1 FROM table LIMIT 1
|
|
140
|
+
# DB[:table].empty? # SELECT 1 AS one FROM table LIMIT 1
|
|
131
141
|
# # => false
|
|
132
142
|
def empty?
|
|
133
|
-
get(1).nil?
|
|
143
|
+
get(Sequel::SQL::AliasedExpression.new(1, :one)).nil?
|
|
134
144
|
end
|
|
135
145
|
|
|
136
146
|
# Executes a select query and fetches records, yielding each record to the
|
|
@@ -194,12 +204,12 @@ module Sequel
|
|
|
194
204
|
#
|
|
195
205
|
# ds.get{sum(id)} # SELECT sum(id) FROM table LIMIT 1
|
|
196
206
|
# # => 6
|
|
197
|
-
def get(column=nil, &block)
|
|
198
|
-
if
|
|
199
|
-
raise(Error, ARG_BLOCK_ERROR_MSG)
|
|
200
|
-
select(column).single_value
|
|
201
|
-
else
|
|
207
|
+
def get(column=(no_arg=true; nil), &block)
|
|
208
|
+
if block
|
|
209
|
+
raise(Error, ARG_BLOCK_ERROR_MSG) unless no_arg
|
|
202
210
|
select(&block).single_value
|
|
211
|
+
else
|
|
212
|
+
select(column).single_value
|
|
203
213
|
end
|
|
204
214
|
end
|
|
205
215
|
|
|
@@ -219,43 +229,47 @@ module Sequel
|
|
|
219
229
|
# DB[:table].import([:x, :y], DB[:table2].select(:a, :b))
|
|
220
230
|
# # INSERT INTO table (x, y) SELECT a, b FROM table2
|
|
221
231
|
#
|
|
222
|
-
#
|
|
223
|
-
#
|
|
224
|
-
#
|
|
225
|
-
#
|
|
226
|
-
#
|
|
227
|
-
#
|
|
232
|
+
# Options:
|
|
233
|
+
# :commit_every :: Open a new transaction for every given number of records.
|
|
234
|
+
# For example, if you provide a value of 50, will commit
|
|
235
|
+
# after every 50 records.
|
|
236
|
+
# :server :: Set the server/shard to use for the transaction and insert
|
|
237
|
+
# queries.
|
|
238
|
+
# :slice :: Same as :commit_every, :commit_every takes precedence.
|
|
228
239
|
def import(columns, values, opts={})
|
|
229
240
|
return @db.transaction{insert(columns, values)} if values.is_a?(Dataset)
|
|
230
241
|
|
|
231
242
|
return if values.empty?
|
|
232
243
|
raise(Error, IMPORT_ERROR_MSG) if columns.empty?
|
|
244
|
+
ds = opts[:server] ? server(opts[:server]) : self
|
|
233
245
|
|
|
234
246
|
if slice_size = opts[:commit_every] || opts[:slice]
|
|
235
247
|
offset = 0
|
|
236
|
-
|
|
237
|
-
|
|
248
|
+
rows = []
|
|
249
|
+
while offset < values.length
|
|
250
|
+
rows << ds._import(columns, values[offset, slice_size], opts)
|
|
238
251
|
offset += slice_size
|
|
239
|
-
break if offset >= values.length
|
|
240
252
|
end
|
|
253
|
+
rows.flatten
|
|
241
254
|
else
|
|
242
|
-
|
|
243
|
-
@db.transaction{statements.each{|st| execute_dui(st)}}
|
|
255
|
+
ds._import(columns, values, opts)
|
|
244
256
|
end
|
|
245
257
|
end
|
|
246
|
-
|
|
258
|
+
|
|
247
259
|
# Inserts values into the associated table. The returned value is generally
|
|
248
260
|
# the value of the primary key for the inserted row, but that is adapter dependent.
|
|
249
261
|
#
|
|
250
262
|
# +insert+ handles a number of different argument formats:
|
|
251
|
-
#
|
|
252
|
-
#
|
|
253
|
-
#
|
|
254
|
-
#
|
|
255
|
-
#
|
|
256
|
-
#
|
|
257
|
-
#
|
|
258
|
-
#
|
|
263
|
+
# no arguments or single empty hash :: Uses DEFAULT VALUES
|
|
264
|
+
# single hash :: Most common format, treats keys as columns an values as values
|
|
265
|
+
# single array :: Treats entries as values, with no columns
|
|
266
|
+
# two arrays :: Treats first array as columns, second array as values
|
|
267
|
+
# single Dataset :: Treats as an insert based on a selection from the dataset given,
|
|
268
|
+
# with no columns
|
|
269
|
+
# array and dataset :: Treats as an insert based on a selection from the dataset
|
|
270
|
+
# given, with the columns given by the array.
|
|
271
|
+
#
|
|
272
|
+
# Examples:
|
|
259
273
|
#
|
|
260
274
|
# DB[:items].insert
|
|
261
275
|
# # INSERT INTO items DEFAULT VALUES
|
|
@@ -277,27 +291,35 @@ module Sequel
|
|
|
277
291
|
#
|
|
278
292
|
# DB[:items].insert([:a, :b], DB[:old_items])
|
|
279
293
|
# # INSERT INTO items (a, b) SELECT * FROM old_items
|
|
280
|
-
def insert(*values)
|
|
281
|
-
|
|
294
|
+
def insert(*values, &block)
|
|
295
|
+
sql = insert_sql(*values)
|
|
296
|
+
if uses_returning?(:insert)
|
|
297
|
+
returning_fetch_rows(sql, &block)
|
|
298
|
+
else
|
|
299
|
+
execute_insert(sql)
|
|
300
|
+
end
|
|
282
301
|
end
|
|
283
302
|
|
|
284
303
|
# Inserts multiple values. If a block is given it is invoked for each
|
|
285
304
|
# item in the given array before inserting it. See +multi_insert+ as
|
|
286
|
-
# a
|
|
287
|
-
# SQL statement.
|
|
305
|
+
# a possibly faster version that may be able to insert multiple
|
|
306
|
+
# records in one SQL statement (if supported by the database).
|
|
307
|
+
# Returns an array of primary keys of inserted rows.
|
|
288
308
|
#
|
|
289
309
|
# DB[:table].insert_multiple([{:x=>1}, {:x=>2}])
|
|
310
|
+
# # => [4, 5]
|
|
290
311
|
# # INSERT INTO table (x) VALUES (1)
|
|
291
312
|
# # INSERT INTO table (x) VALUES (2)
|
|
292
313
|
#
|
|
293
314
|
# DB[:table].insert_multiple([{:x=>1}, {:x=>2}]){|row| row[:y] = row[:x] * 2}
|
|
315
|
+
# # => [6, 7]
|
|
294
316
|
# # INSERT INTO table (x, y) VALUES (1, 2)
|
|
295
317
|
# # INSERT INTO table (x, y) VALUES (2, 4)
|
|
296
318
|
def insert_multiple(array, &block)
|
|
297
319
|
if block
|
|
298
|
-
array.
|
|
320
|
+
array.map{|i| insert(block.call(i))}
|
|
299
321
|
else
|
|
300
|
-
array.
|
|
322
|
+
array.map{|i| insert(i)}
|
|
301
323
|
end
|
|
302
324
|
end
|
|
303
325
|
|
|
@@ -310,7 +332,7 @@ module Sequel
|
|
|
310
332
|
aggregate_dataset.get{max(column) - min(column)}
|
|
311
333
|
end
|
|
312
334
|
|
|
313
|
-
# Reverses the order and then runs first. Note that this
|
|
335
|
+
# Reverses the order and then runs #first with the given arguments and block. Note that this
|
|
314
336
|
# will not necessarily give you the last record in the dataset,
|
|
315
337
|
# unless you have an unambiguous order. If there is not
|
|
316
338
|
# currently an order for this dataset, raises an +Error+.
|
|
@@ -334,10 +356,20 @@ module Sequel
|
|
|
334
356
|
#
|
|
335
357
|
# DB[:table].map{|r| r[:id] * 2} # SELECT * FROM table
|
|
336
358
|
# # => [2, 4, 6, ...]
|
|
359
|
+
#
|
|
360
|
+
# You can also provide an array of column names:
|
|
361
|
+
#
|
|
362
|
+
# DB[:table].map([:id, :name]) # SELECT * FROM table
|
|
363
|
+
# # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]
|
|
337
364
|
def map(column=nil, &block)
|
|
338
365
|
if column
|
|
339
366
|
raise(Error, ARG_BLOCK_ERROR_MSG) if block
|
|
340
|
-
|
|
367
|
+
return naked.map(column) if row_proc
|
|
368
|
+
if column.is_a?(Array)
|
|
369
|
+
super(){|r| r.values_at(*column)}
|
|
370
|
+
else
|
|
371
|
+
super(){|r| r[column]}
|
|
372
|
+
end
|
|
341
373
|
else
|
|
342
374
|
super(&block)
|
|
343
375
|
end
|
|
@@ -370,7 +402,7 @@ module Sequel
|
|
|
370
402
|
# otherwise some columns could be missed or set to null instead of to default
|
|
371
403
|
# values.
|
|
372
404
|
#
|
|
373
|
-
#
|
|
405
|
+
# This respects the same options as #import.
|
|
374
406
|
def multi_insert(hashes, opts={})
|
|
375
407
|
return if hashes.empty?
|
|
376
408
|
columns = hashes.first.keys
|
|
@@ -389,33 +421,65 @@ module Sequel
|
|
|
389
421
|
end
|
|
390
422
|
|
|
391
423
|
# Returns a hash with key_column values as keys and value_column values as
|
|
392
|
-
# values. Similar to to_hash, but only selects the
|
|
424
|
+
# values. Similar to to_hash, but only selects the columns given.
|
|
393
425
|
#
|
|
394
426
|
# DB[:table].select_hash(:id, :name) # SELECT id, name FROM table
|
|
395
427
|
# # => {1=>'a', 2=>'b', ...}
|
|
428
|
+
#
|
|
429
|
+
# You can also provide an array of column names for either the key_column,
|
|
430
|
+
# the value column, or both:
|
|
431
|
+
#
|
|
432
|
+
# DB[:table].select_hash([:id, :foo], [:name, :bar]) # SELECT * FROM table
|
|
433
|
+
# # {[1, 3]=>['a', 'c'], [2, 4]=>['b', 'd'], ...}
|
|
434
|
+
#
|
|
435
|
+
# When using this method, you must be sure that each expression has an alias
|
|
436
|
+
# that Sequel can determine. Usually you can do this by calling the #as method
|
|
437
|
+
# on the expression and providing an alias.
|
|
396
438
|
def select_hash(key_column, value_column)
|
|
397
|
-
|
|
439
|
+
_select_hash(:to_hash, key_column, value_column)
|
|
398
440
|
end
|
|
399
441
|
|
|
442
|
+
# Returns a hash with key_column values as keys and an array of value_column values.
|
|
443
|
+
# Similar to to_hash_groups, but only selects the columns given.
|
|
444
|
+
#
|
|
445
|
+
# DB[:table].select_hash(:name, :id) # SELECT id, name FROM table
|
|
446
|
+
# # => {'a'=>[1, 4, ...], 'b'=>[2, ...], ...}
|
|
447
|
+
#
|
|
448
|
+
# You can also provide an array of column names for either the key_column,
|
|
449
|
+
# the value column, or both:
|
|
450
|
+
#
|
|
451
|
+
# DB[:table].select_hash([:first, :middle], [:last, :id]) # SELECT * FROM table
|
|
452
|
+
# # {['a', 'b']=>[['c', 1], ['d', 2], ...], ...}
|
|
453
|
+
#
|
|
454
|
+
# When using this method, you must be sure that each expression has an alias
|
|
455
|
+
# that Sequel can determine. Usually you can do this by calling the #as method
|
|
456
|
+
# on the expression and providing an alias.
|
|
457
|
+
def select_hash_groups(key_column, value_column)
|
|
458
|
+
_select_hash(:to_hash_groups, key_column, value_column)
|
|
459
|
+
end
|
|
460
|
+
|
|
400
461
|
# Selects the column given (either as an argument or as a block), and
|
|
401
462
|
# returns an array of all values of that column in the dataset. If you
|
|
402
463
|
# give a block argument that returns an array with multiple entries,
|
|
403
|
-
# the contents of the resulting array are undefined.
|
|
464
|
+
# the contents of the resulting array are undefined. Raises an Error
|
|
465
|
+
# if called with both an argument and a block.
|
|
404
466
|
#
|
|
405
467
|
# DB[:table].select_map(:id) # SELECT id FROM table
|
|
406
468
|
# # => [3, 5, 8, 1, ...]
|
|
407
469
|
#
|
|
408
|
-
# DB[:table].select_map{
|
|
409
|
-
# # => [
|
|
470
|
+
# DB[:table].select_map{id * 2} # SELECT (id * 2) FROM table
|
|
471
|
+
# # => [6, 10, 16, 2, ...]
|
|
472
|
+
#
|
|
473
|
+
# You can also provide an array of column names:
|
|
474
|
+
#
|
|
475
|
+
# DB[:table].select_map([:id, :name]) # SELECT id, name FROM table
|
|
476
|
+
# # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]
|
|
477
|
+
#
|
|
478
|
+
# If you provide an array of expressions, you must be sure that each entry
|
|
479
|
+
# in the array has an alias that Sequel can determine. Usually you can do this
|
|
480
|
+
# by calling the #as method on the expression and providing an alias.
|
|
410
481
|
def select_map(column=nil, &block)
|
|
411
|
-
|
|
412
|
-
ds = if column
|
|
413
|
-
raise(Error, ARG_BLOCK_ERROR_MSG) if block
|
|
414
|
-
ds.select(column)
|
|
415
|
-
else
|
|
416
|
-
ds.select(&block)
|
|
417
|
-
end
|
|
418
|
-
ds.map{|r| r.values.first}
|
|
482
|
+
_select_map(column, false, &block)
|
|
419
483
|
end
|
|
420
484
|
|
|
421
485
|
# The same as select_map, but in addition orders the array by the column.
|
|
@@ -423,19 +487,21 @@ module Sequel
|
|
|
423
487
|
# DB[:table].select_order_map(:id) # SELECT id FROM table ORDER BY id
|
|
424
488
|
# # => [1, 2, 3, 4, ...]
|
|
425
489
|
#
|
|
426
|
-
# DB[:table].select_order_map{
|
|
427
|
-
# # => [
|
|
490
|
+
# DB[:table].select_order_map{id * 2} # SELECT (id * 2) FROM table ORDER BY (id * 2)
|
|
491
|
+
# # => [2, 4, 6, 8, ...]
|
|
492
|
+
#
|
|
493
|
+
# You can also provide an array of column names:
|
|
494
|
+
#
|
|
495
|
+
# DB[:table].select_order_map([:id, :name]) # SELECT id, name FROM table ORDER BY id, name
|
|
496
|
+
# # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]
|
|
497
|
+
#
|
|
498
|
+
# If you provide an array of expressions, you must be sure that each entry
|
|
499
|
+
# in the array has an alias that Sequel can determine. Usually you can do this
|
|
500
|
+
# by calling the #as method on the expression and providing an alias.
|
|
428
501
|
def select_order_map(column=nil, &block)
|
|
429
|
-
|
|
430
|
-
ds = if column
|
|
431
|
-
raise(Error, ARG_BLOCK_ERROR_MSG) if block
|
|
432
|
-
ds.select(column).order(unaliased_identifier(column))
|
|
433
|
-
else
|
|
434
|
-
ds.select(&block).order(&block)
|
|
435
|
-
end
|
|
436
|
-
ds.map{|r| r.values.first}
|
|
502
|
+
_select_map(column, true, &block)
|
|
437
503
|
end
|
|
438
|
-
|
|
504
|
+
|
|
439
505
|
# Alias for update, but not aliased directly so subclasses
|
|
440
506
|
# don't have to override both methods.
|
|
441
507
|
def set(*args)
|
|
@@ -499,11 +565,81 @@ module Sequel
|
|
|
499
565
|
#
|
|
500
566
|
# DB[:table].to_hash(:id) # SELECT * FROM table
|
|
501
567
|
# # {1=>{:id=>1, :name=>'Jim'}, 2=>{:id=>2, :name=>'Bob'}, ...}
|
|
568
|
+
#
|
|
569
|
+
# You can also provide an array of column names for either the key_column,
|
|
570
|
+
# the value column, or both:
|
|
571
|
+
#
|
|
572
|
+
# DB[:table].to_hash([:id, :foo], [:name, :bar]) # SELECT * FROM table
|
|
573
|
+
# # {[1, 3]=>['Jim', 'bo'], [2, 4]=>['Bob', 'be'], ...}
|
|
574
|
+
#
|
|
575
|
+
# DB[:table].to_hash([:id, :name]) # SELECT * FROM table
|
|
576
|
+
# # {[1, 'Jim']=>{:id=>1, :name=>'Jim'}, [2, 'Bob'=>{:id=>2, :name=>'Bob'}, ...}
|
|
502
577
|
def to_hash(key_column, value_column = nil)
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
578
|
+
h = {}
|
|
579
|
+
if value_column
|
|
580
|
+
return naked.to_hash(key_column, value_column) if row_proc
|
|
581
|
+
if value_column.is_a?(Array)
|
|
582
|
+
if key_column.is_a?(Array)
|
|
583
|
+
each{|r| h[r.values_at(*key_column)] = r.values_at(*value_column)}
|
|
584
|
+
else
|
|
585
|
+
each{|r| h[r[key_column]] = r.values_at(*value_column)}
|
|
586
|
+
end
|
|
587
|
+
else
|
|
588
|
+
if key_column.is_a?(Array)
|
|
589
|
+
each{|r| h[r.values_at(*key_column)] = r[value_column]}
|
|
590
|
+
else
|
|
591
|
+
each{|r| h[r[key_column]] = r[value_column]}
|
|
592
|
+
end
|
|
593
|
+
end
|
|
594
|
+
elsif key_column.is_a?(Array)
|
|
595
|
+
each{|r| h[r.values_at(*key_column)] = r}
|
|
596
|
+
else
|
|
597
|
+
each{|r| h[r[key_column]] = r}
|
|
506
598
|
end
|
|
599
|
+
h
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
# Returns a hash with one column used as key and the values being an
|
|
603
|
+
# array of column values. If the value_column is not given or nil, uses
|
|
604
|
+
# the entire hash as the value.
|
|
605
|
+
#
|
|
606
|
+
# DB[:table].to_hash(:name, :id) # SELECT * FROM table
|
|
607
|
+
# # {'Jim'=>[1, 4, 16, ...], 'Bob'=>[2], ...}
|
|
608
|
+
#
|
|
609
|
+
# DB[:table].to_hash(:name) # SELECT * FROM table
|
|
610
|
+
# # {'Jim'=>[{:id=>1, :name=>'Jim'}, {:id=>4, :name=>'Jim'}, ...], 'Bob'=>[{:id=>2, :name=>'Bob'}], ...}
|
|
611
|
+
#
|
|
612
|
+
# You can also provide an array of column names for either the key_column,
|
|
613
|
+
# the value column, or both:
|
|
614
|
+
#
|
|
615
|
+
# DB[:table].to_hash([:first, :middle], [:last, :id]) # SELECT * FROM table
|
|
616
|
+
# # {['Jim', 'Bob']=>[['Smith', 1], ['Jackson', 4], ...], ...}
|
|
617
|
+
#
|
|
618
|
+
# DB[:table].to_hash([:first, :middle]) # SELECT * FROM table
|
|
619
|
+
# # {['Jim', 'Bob']=>[{:id=>1, :first=>'Jim', :middle=>'Bob', :last=>'Smith'}, ...], ...}
|
|
620
|
+
def to_hash_groups(key_column, value_column = nil)
|
|
621
|
+
h = {}
|
|
622
|
+
if value_column
|
|
623
|
+
return naked.to_hash_groups(key_column, value_column) if row_proc
|
|
624
|
+
if value_column.is_a?(Array)
|
|
625
|
+
if key_column.is_a?(Array)
|
|
626
|
+
each{|r| (h[r.values_at(*key_column)] ||= []) << r.values_at(*value_column)}
|
|
627
|
+
else
|
|
628
|
+
each{|r| (h[r[key_column]] ||= []) << r.values_at(*value_column)}
|
|
629
|
+
end
|
|
630
|
+
else
|
|
631
|
+
if key_column.is_a?(Array)
|
|
632
|
+
each{|r| (h[r.values_at(*key_column)] ||= []) << r[value_column]}
|
|
633
|
+
else
|
|
634
|
+
each{|r| (h[r[key_column]] ||= []) << r[value_column]}
|
|
635
|
+
end
|
|
636
|
+
end
|
|
637
|
+
elsif key_column.is_a?(Array)
|
|
638
|
+
each{|r| (h[r.values_at(*key_column)] ||= []) << r}
|
|
639
|
+
else
|
|
640
|
+
each{|r| (h[r[key_column]] ||= []) << r}
|
|
641
|
+
end
|
|
642
|
+
h
|
|
507
643
|
end
|
|
508
644
|
|
|
509
645
|
# Truncates the dataset. Returns nil.
|
|
@@ -522,14 +658,81 @@ module Sequel
|
|
|
522
658
|
# DB[:table].update(:x=>nil) # UPDATE table SET x = NULL
|
|
523
659
|
# # => 10
|
|
524
660
|
#
|
|
525
|
-
# DB[:table].update(:x=>:x+1, :y=>0) # UPDATE table SET x = (x + 1),
|
|
661
|
+
# DB[:table].update(:x=>:x+1, :y=>0) # UPDATE table SET x = (x + 1), y = 0
|
|
526
662
|
# # => 10
|
|
527
|
-
def update(values={})
|
|
528
|
-
|
|
663
|
+
def update(values={}, &block)
|
|
664
|
+
sql = update_sql(values)
|
|
665
|
+
if uses_returning?(:update)
|
|
666
|
+
returning_fetch_rows(sql, &block)
|
|
667
|
+
else
|
|
668
|
+
execute_dui(sql)
|
|
669
|
+
end
|
|
529
670
|
end
|
|
530
671
|
|
|
672
|
+
# Execute the given SQL and return the number of rows deleted. This exists
|
|
673
|
+
# solely as an optimization, replacing with_sql(sql).delete. It's significantly
|
|
674
|
+
# faster as it does not require cloning the current dataset.
|
|
675
|
+
def with_sql_delete(sql)
|
|
676
|
+
execute_dui(sql)
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
protected
|
|
680
|
+
|
|
681
|
+
# Internals of #import. If primary key values are requested, use
|
|
682
|
+
# separate insert commands for each row. Otherwise, call #multi_insert_sql
|
|
683
|
+
# and execute each statement it gives separately.
|
|
684
|
+
def _import(columns, values, opts)
|
|
685
|
+
trans_opts = opts.merge(:server=>@opts[:server])
|
|
686
|
+
if opts[:return] == :primary_key
|
|
687
|
+
@db.transaction(trans_opts){values.map{|v| insert(columns, v)}}
|
|
688
|
+
else
|
|
689
|
+
stmts = multi_insert_sql(columns, values)
|
|
690
|
+
@db.transaction(trans_opts){stmts.each{|st| execute_dui(st)}}
|
|
691
|
+
end
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
# Return an array of arrays of values given by the symbols in ret_cols.
|
|
695
|
+
def _select_map_multiple(ret_cols)
|
|
696
|
+
map{|r| r.values_at(*ret_cols)}
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
# Returns an array of the first value in each row.
|
|
700
|
+
def _select_map_single
|
|
701
|
+
map{|r| r.values.first}
|
|
702
|
+
end
|
|
703
|
+
|
|
531
704
|
private
|
|
532
705
|
|
|
706
|
+
# Internals of +select_hash+ and +select_hash_groups+
|
|
707
|
+
def _select_hash(meth, key_column, value_column)
|
|
708
|
+
if key_column.is_a?(Array)
|
|
709
|
+
if value_column.is_a?(Array)
|
|
710
|
+
select(*(key_column + value_column)).send(meth, key_column.map{|c| hash_key_symbol(c)}, value_column.map{|c| hash_key_symbol(c)})
|
|
711
|
+
else
|
|
712
|
+
select(*(key_column + [value_column])).send(meth, key_column.map{|c| hash_key_symbol(c)}, hash_key_symbol(value_column))
|
|
713
|
+
end
|
|
714
|
+
elsif value_column.is_a?(Array)
|
|
715
|
+
select(key_column, *value_column).send(meth, hash_key_symbol(key_column), value_column.map{|c| hash_key_symbol(c)})
|
|
716
|
+
else
|
|
717
|
+
select(key_column, value_column).send(meth, hash_key_symbol(key_column), hash_key_symbol(value_column))
|
|
718
|
+
end
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
# Internals of +select_map+ and +select_order_map+
|
|
722
|
+
def _select_map(column, order, &block)
|
|
723
|
+
ds = naked.ungraphed
|
|
724
|
+
columns = Array(column)
|
|
725
|
+
virtual_row_columns(columns, block)
|
|
726
|
+
select_cols = order ? columns.map{|c| c.is_a?(SQL::OrderedExpression) ? c.expression : c} : columns
|
|
727
|
+
ds = ds.select(*select_cols)
|
|
728
|
+
ds = ds.order(*columns.map{|c| unaliased_identifier(c)}) if order
|
|
729
|
+
if column.is_a?(Array) || (columns.length > 1)
|
|
730
|
+
ds._select_map_multiple(select_cols.map{|c| hash_key_symbol(c)})
|
|
731
|
+
else
|
|
732
|
+
ds._select_map_single
|
|
733
|
+
end
|
|
734
|
+
end
|
|
735
|
+
|
|
533
736
|
# Set the server to use to :default unless it is already set in the passed opts
|
|
534
737
|
def default_server_opts(opts)
|
|
535
738
|
{:server=>@opts[:server] || :default}.merge(opts)
|
|
@@ -561,9 +764,21 @@ module Sequel
|
|
|
561
764
|
# specifying the symbol that is likely to be used as the hash key
|
|
562
765
|
# for the column when records are returned.
|
|
563
766
|
def hash_key_symbol(s)
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
767
|
+
case s
|
|
768
|
+
when Symbol
|
|
769
|
+
_, c, a = split_symbol(s)
|
|
770
|
+
(a || c).to_sym
|
|
771
|
+
when SQL::Identifier
|
|
772
|
+
hash_key_symbol(s.value)
|
|
773
|
+
when SQL::QualifiedIdentifier
|
|
774
|
+
hash_key_symbol(s.column)
|
|
775
|
+
when SQL::AliasedExpression
|
|
776
|
+
hash_key_symbol(s.aliaz)
|
|
777
|
+
when String
|
|
778
|
+
s.to_sym
|
|
779
|
+
else
|
|
780
|
+
raise(Error, "#{s.inspect} is not supported, should be a Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier, or SQL::AliasedExpression")
|
|
781
|
+
end
|
|
567
782
|
end
|
|
568
783
|
|
|
569
784
|
# Modify the identifier returned from the database based on the
|
|
@@ -580,6 +795,20 @@ module Sequel
|
|
|
580
795
|
def post_load(all_records)
|
|
581
796
|
end
|
|
582
797
|
|
|
798
|
+
# Called by insert/update/delete when returning is used.
|
|
799
|
+
# Yields each row as a plain hash to the block if one is given, or returns
|
|
800
|
+
# an array of plain hashes for all rows if a block is not given
|
|
801
|
+
def returning_fetch_rows(sql, &block)
|
|
802
|
+
if block
|
|
803
|
+
default_server.fetch_rows(sql, &block)
|
|
804
|
+
nil
|
|
805
|
+
else
|
|
806
|
+
rows = []
|
|
807
|
+
default_server.fetch_rows(sql){|r| rows << r}
|
|
808
|
+
rows
|
|
809
|
+
end
|
|
810
|
+
end
|
|
811
|
+
|
|
583
812
|
# Return the unaliased part of the identifier. Handles both
|
|
584
813
|
# implicit aliases in symbols, as well as SQL::AliasedExpression
|
|
585
814
|
# objects. Other objects are returned as is.
|
|
@@ -590,6 +819,14 @@ module Sequel
|
|
|
590
819
|
c_table ? SQL::QualifiedIdentifier.new(c_table, column.to_sym) : column.to_sym
|
|
591
820
|
when SQL::AliasedExpression
|
|
592
821
|
c.expression
|
|
822
|
+
when SQL::OrderedExpression
|
|
823
|
+
expr = c.expression
|
|
824
|
+
if expr.is_a?(Symbol)
|
|
825
|
+
expr = unaliased_identifier(expr)
|
|
826
|
+
SQL::OrderedExpression.new(unaliased_identifier(c.expression), c.descending, :nulls=>c.nulls)
|
|
827
|
+
else
|
|
828
|
+
c
|
|
829
|
+
end
|
|
593
830
|
else
|
|
594
831
|
c
|
|
595
832
|
end
|