sequel 3.21.0 → 3.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1061 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +103 -63
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +67 -51
- data/doc/advanced_associations.rdoc +189 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +547 -0
- data/doc/opening_databases.rdoc +114 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +18 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +453 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +56 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +73 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +279 -97
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +125 -222
- data/lib/sequel/adapters/mysql2.rb +65 -56
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +349 -53
- data/lib/sequel/adapters/postgres.rb +368 -138
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +343 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +401 -116
- data/lib/sequel/adapters/shared/mysql.rb +424 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +257 -45
- data/lib/sequel/adapters/shared/postgres.rb +675 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +285 -96
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +28 -19
- data/lib/sequel/adapters/tinytds.rb +174 -22
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +11 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +43 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +38 -28
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +190 -46
- data/lib/sequel/database/query.rb +272 -110
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +300 -67
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +305 -54
- data/lib/sequel/dataset/sql.rb +720 -292
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +537 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +313 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +208 -0
- data/lib/sequel/extensions/pg_range.rb +512 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +572 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +58 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +167 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +55 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +649 -122
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +194 -66
- data/spec/adapters/mysql_spec.rb +475 -306
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +1982 -325
- data/spec/adapters/spec_helper.rb +9 -6
- data/spec/adapters/sqlite_spec.rb +203 -75
- data/spec/core/connection_pool_spec.rb +218 -93
- data/spec/core/database_spec.rb +956 -522
- data/spec/core/dataset_spec.rb +1631 -1242
- data/spec/core/expression_filters_spec.rb +690 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +320 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +194 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +323 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +23 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +58 -67
- data/spec/extensions/validation_helpers_spec.rb +31 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +11 -5
- data/spec/integration/dataset_test.rb +717 -129
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +604 -147
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +367 -57
- data/spec/integration/spec_helper.rb +42 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +31 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +209 -80
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -5,97 +5,70 @@ rescue LoadError
|
|
|
5
5
|
end
|
|
6
6
|
raise(LoadError, "require 'mysql' did not define Mysql::CLIENT_MULTI_RESULTS!\n You are probably using the pure ruby mysql.rb driver,\n which Sequel does not support. You need to install\n the C based adapter, and make sure that the mysql.so\n file is loaded instead of the mysql.rb file.\n") unless defined?(Mysql::CLIENT_MULTI_RESULTS)
|
|
7
7
|
|
|
8
|
-
Sequel.require %w'shared/
|
|
8
|
+
Sequel.require %w'shared/mysql_prepared_statements', 'adapters'
|
|
9
9
|
|
|
10
10
|
module Sequel
|
|
11
11
|
# Module for holding all MySQL-related classes and modules for Sequel.
|
|
12
12
|
module MySQL
|
|
13
13
|
TYPE_TRANSLATOR = tt = Class.new do
|
|
14
14
|
def boolean(s) s.to_i != 0 end
|
|
15
|
-
def blob(s) ::Sequel::SQL::Blob.new(s) end
|
|
16
15
|
def integer(s) s.to_i end
|
|
17
16
|
def float(s) s.to_f end
|
|
18
|
-
def decimal(s) ::BigDecimal.new(s) end
|
|
19
|
-
def date(s) ::Sequel.string_to_date(s) end
|
|
20
|
-
def time(s) ::Sequel.string_to_time(s) end
|
|
21
|
-
def timestamp(s) ::Sequel.database_to_application_timestamp(s) end
|
|
22
|
-
def date_conv(s) ::Sequel::MySQL.convert_date_time(:string_to_date, s) end
|
|
23
|
-
def time_conv(s) ::Sequel::MySQL.convert_date_time(:string_to_time, s) end
|
|
24
|
-
def timestamp_conv(s) ::Sequel::MySQL.convert_date_time(:database_to_application_timestamp, s) end
|
|
25
17
|
end.new
|
|
26
18
|
|
|
27
19
|
# Hash with integer keys and callable values for converting MySQL types.
|
|
28
20
|
MYSQL_TYPES = {}
|
|
29
21
|
{
|
|
30
|
-
[0, 246]
|
|
31
|
-
[2, 3, 8, 9, 13, 247, 248]
|
|
32
|
-
[4, 5]
|
|
33
|
-
[249, 250, 251, 252]
|
|
22
|
+
[0, 246] => ::BigDecimal.method(:new),
|
|
23
|
+
[2, 3, 8, 9, 13, 247, 248] => tt.method(:integer),
|
|
24
|
+
[4, 5] => tt.method(:float),
|
|
25
|
+
[249, 250, 251, 252] => ::Sequel::SQL::Blob.method(:new)
|
|
34
26
|
}.each do |k,v|
|
|
35
27
|
k.each{|n| MYSQL_TYPES[n] = v}
|
|
36
28
|
end
|
|
37
29
|
|
|
38
|
-
# Modify the type translator used for the tinyint type based
|
|
39
|
-
# on the value given.
|
|
40
|
-
def self.convert_tinyint_to_bool=(v)
|
|
41
|
-
MYSQL_TYPES[1] = TYPE_TRANSLATOR.method(v ? :boolean : :integer)
|
|
42
|
-
@convert_tinyint_to_bool = v
|
|
43
|
-
end
|
|
44
|
-
self.convert_tinyint_to_bool = convert_tinyint_to_bool
|
|
45
|
-
|
|
46
30
|
class << self
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Modify the type translators for the date, time, and timestamp types
|
|
55
|
-
# depending on the value given.
|
|
56
|
-
def self.convert_invalid_date_time=(v)
|
|
57
|
-
MYSQL_TYPES[11] = TYPE_TRANSLATOR.method(v == false ? :time : :time_conv)
|
|
58
|
-
m = TYPE_TRANSLATOR.method(v == false ? :date : :date_conv)
|
|
59
|
-
[10, 14].each{|i| MYSQL_TYPES[i] = m}
|
|
60
|
-
m = TYPE_TRANSLATOR.method(v == false ? :timestamp : :timestamp_conv)
|
|
61
|
-
[7, 12].each{|i| MYSQL_TYPES[i] = m}
|
|
62
|
-
@convert_invalid_date_time = v
|
|
31
|
+
# Whether to convert invalid date time values by default.
|
|
32
|
+
#
|
|
33
|
+
# Only applies to Sequel::Database instances created after this
|
|
34
|
+
# has been set.
|
|
35
|
+
attr_accessor :convert_invalid_date_time
|
|
63
36
|
end
|
|
64
37
|
self.convert_invalid_date_time = false
|
|
65
38
|
|
|
66
|
-
# If convert_invalid_date_time is nil, :nil, or :string and
|
|
67
|
-
# the conversion raises an InvalidValue exception, return v
|
|
68
|
-
# if :string and nil otherwise.
|
|
69
|
-
def self.convert_date_time(meth, v)
|
|
70
|
-
begin
|
|
71
|
-
Sequel.send(meth, v)
|
|
72
|
-
rescue InvalidValue
|
|
73
|
-
case @convert_invalid_date_time
|
|
74
|
-
when nil, :nil
|
|
75
|
-
nil
|
|
76
|
-
when :string
|
|
77
|
-
v
|
|
78
|
-
else
|
|
79
|
-
raise
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
39
|
# Database class for MySQL databases used with Sequel.
|
|
85
40
|
class Database < Sequel::Database
|
|
86
41
|
include Sequel::MySQL::DatabaseMethods
|
|
42
|
+
include Sequel::MySQL::PreparedStatements::DatabaseMethods
|
|
87
43
|
|
|
88
44
|
# Mysql::Error messages that indicate the current connection should be disconnected
|
|
89
45
|
MYSQL_DATABASE_DISCONNECT_ERRORS = /\A(Commands out of sync; you can't run this command now|Can't connect to local MySQL server through socket|MySQL server has gone away|Lost connection to MySQL server during query)/
|
|
46
|
+
|
|
47
|
+
# Regular expression used for getting accurate number of rows
|
|
48
|
+
# matched by an update statement.
|
|
49
|
+
AFFECTED_ROWS_RE = /Rows matched:\s+(\d+)\s+Changed:\s+\d+\s+Warnings:\s+\d+/.freeze
|
|
90
50
|
|
|
91
51
|
set_adapter_scheme :mysql
|
|
52
|
+
|
|
53
|
+
# Hash of conversion procs for the current database
|
|
54
|
+
attr_reader :conversion_procs
|
|
55
|
+
#
|
|
56
|
+
# Whether to convert tinyint columns to bool for the current database
|
|
57
|
+
attr_reader :convert_tinyint_to_bool
|
|
58
|
+
|
|
59
|
+
# By default, Sequel raises an exception if in invalid date or time is used.
|
|
60
|
+
# However, if this is set to nil or :nil, the adapter treats dates
|
|
61
|
+
# like 0000-00-00 and times like 838:00:00 as nil values. If set to :string,
|
|
62
|
+
# it returns the strings as is.
|
|
63
|
+
attr_reader :convert_invalid_date_time
|
|
92
64
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
65
|
+
def initialize(opts={})
|
|
66
|
+
super
|
|
67
|
+
@conversion_procs = MYSQL_TYPES.dup
|
|
68
|
+
self.convert_tinyint_to_bool = Sequel::MySQL.convert_tinyint_to_bool
|
|
69
|
+
self.convert_invalid_date_time = Sequel::MySQL.convert_invalid_date_time
|
|
97
70
|
end
|
|
98
|
-
|
|
71
|
+
|
|
99
72
|
# Connect to the database. In addition to the usual database options,
|
|
100
73
|
# the following options have effect:
|
|
101
74
|
#
|
|
@@ -139,52 +112,57 @@ module Sequel
|
|
|
139
112
|
opts[:user],
|
|
140
113
|
opts[:password],
|
|
141
114
|
opts[:database],
|
|
142
|
-
opts[:port],
|
|
115
|
+
(opts[:port].to_i if opts[:port]),
|
|
143
116
|
opts[:socket],
|
|
144
117
|
Mysql::CLIENT_MULTI_RESULTS +
|
|
145
118
|
Mysql::CLIENT_MULTI_STATEMENTS +
|
|
146
119
|
(opts[:compress] == false ? 0 : Mysql::CLIENT_COMPRESS)
|
|
147
120
|
)
|
|
148
|
-
sqls =
|
|
121
|
+
sqls = mysql_connection_setting_sqls
|
|
122
|
+
|
|
149
123
|
# Set encoding a slightly different way after connecting,
|
|
150
124
|
# in case the READ_DEFAULT_GROUP overrode the provided encoding.
|
|
151
125
|
# Doesn't work across implicit reconnects, but Sequel doesn't turn on
|
|
152
126
|
# that feature.
|
|
153
|
-
sqls
|
|
154
|
-
|
|
155
|
-
# Increase timeout so mysql server doesn't disconnect us
|
|
156
|
-
# Value used by default is maximum allowed value on Windows.
|
|
157
|
-
sqls << "SET @@wait_timeout = #{opts[:timeout] || 2147483}"
|
|
158
|
-
|
|
159
|
-
# By default, MySQL 'where id is null' selects the last inserted id
|
|
160
|
-
sqls << "SET SQL_AUTO_IS_NULL=0" unless opts[:auto_is_null]
|
|
127
|
+
sqls.unshift("SET NAMES #{literal(encoding.to_s)}") if encoding
|
|
161
128
|
|
|
162
129
|
sqls.each{|sql| log_yield(sql){conn.query(sql)}}
|
|
163
130
|
|
|
164
|
-
|
|
165
|
-
attr_accessor :prepared_statements
|
|
166
|
-
end
|
|
167
|
-
conn.prepared_statements = {}
|
|
131
|
+
add_prepared_statements_cache(conn)
|
|
168
132
|
conn
|
|
169
133
|
end
|
|
170
134
|
|
|
171
|
-
#
|
|
172
|
-
|
|
173
|
-
|
|
135
|
+
# Modify the type translators for the date, time, and timestamp types
|
|
136
|
+
# depending on the value given.
|
|
137
|
+
def convert_invalid_date_time=(v)
|
|
138
|
+
m0 = ::Sequel.method(:string_to_time)
|
|
139
|
+
@conversion_procs[11] = (v != false) ? lambda{|v| convert_date_time(v, &m0)} : m0
|
|
140
|
+
m1 = ::Sequel.method(:string_to_date)
|
|
141
|
+
m = (v != false) ? lambda{|v| convert_date_time(v, &m1)} : m1
|
|
142
|
+
[10, 14].each{|i| @conversion_procs[i] = m}
|
|
143
|
+
m2 = method(:to_application_timestamp)
|
|
144
|
+
m = (v != false) ? lambda{|v| convert_date_time(v, &m2)} : m2
|
|
145
|
+
[7, 12].each{|i| @conversion_procs[i] = m}
|
|
146
|
+
@convert_invalid_date_time = v
|
|
174
147
|
end
|
|
175
|
-
|
|
176
|
-
#
|
|
177
|
-
#
|
|
178
|
-
def
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
elsif sql.is_a?(Symbol)
|
|
182
|
-
execute_prepared_statement(sql, opts, &block)
|
|
183
|
-
else
|
|
184
|
-
synchronize(opts[:server]){|conn| _execute(conn, sql, opts, &block)}
|
|
185
|
-
end
|
|
148
|
+
|
|
149
|
+
# Modify the type translator used for the tinyint type based
|
|
150
|
+
# on the value given.
|
|
151
|
+
def convert_tinyint_to_bool=(v)
|
|
152
|
+
@conversion_procs[1] = TYPE_TRANSLATOR.method(v ? :boolean : :integer)
|
|
153
|
+
@convert_tinyint_to_bool = v
|
|
186
154
|
end
|
|
187
|
-
|
|
155
|
+
|
|
156
|
+
# Return the number of matched rows when executing a delete/update statement.
|
|
157
|
+
def execute_dui(sql, opts={})
|
|
158
|
+
execute(sql, opts){|c| return affected_rows(c)}
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Return the last inserted id when executing an insert statement.
|
|
162
|
+
def execute_insert(sql, opts={})
|
|
163
|
+
execute(sql, opts){|c| return c.insert_id}
|
|
164
|
+
end
|
|
165
|
+
|
|
188
166
|
# Return the version of the MySQL server two which we are connecting.
|
|
189
167
|
def server_version(server=nil)
|
|
190
168
|
@server_version ||= (synchronize(server){|conn| conn.server_version if conn.respond_to?(:server_version)} || super)
|
|
@@ -197,7 +175,7 @@ module Sequel
|
|
|
197
175
|
# yield the connection if a block is given.
|
|
198
176
|
def _execute(conn, sql, opts)
|
|
199
177
|
begin
|
|
200
|
-
r = log_yield(sql){conn.query(sql)}
|
|
178
|
+
r = log_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql){conn.query(sql)}
|
|
201
179
|
if opts[:type] == :select
|
|
202
180
|
yield r if r
|
|
203
181
|
elsif block_given?
|
|
@@ -220,7 +198,7 @@ module Sequel
|
|
|
220
198
|
end
|
|
221
199
|
end
|
|
222
200
|
rescue Mysql::Error => e
|
|
223
|
-
raise_error(e
|
|
201
|
+
raise_error(e)
|
|
224
202
|
ensure
|
|
225
203
|
r.free if r
|
|
226
204
|
# Use up all results to avoid a commands out of sync message.
|
|
@@ -239,15 +217,51 @@ module Sequel
|
|
|
239
217
|
end
|
|
240
218
|
end
|
|
241
219
|
|
|
220
|
+
# Try to get an accurate number of rows matched using the query
|
|
221
|
+
# info. Fall back to affected_rows if there was no match, but
|
|
222
|
+
# that may be inaccurate.
|
|
223
|
+
def affected_rows(conn)
|
|
224
|
+
s = conn.info
|
|
225
|
+
if s && s =~ AFFECTED_ROWS_RE
|
|
226
|
+
$1.to_i
|
|
227
|
+
else
|
|
228
|
+
conn.affected_rows
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
242
232
|
# MySQL connections use the query method to execute SQL without a result
|
|
243
233
|
def connection_execute_method
|
|
244
234
|
:query
|
|
245
235
|
end
|
|
246
236
|
|
|
237
|
+
# If convert_invalid_date_time is nil, :nil, or :string and
|
|
238
|
+
# the conversion raises an InvalidValue exception, return v
|
|
239
|
+
# if :string and nil otherwise.
|
|
240
|
+
def convert_date_time(v)
|
|
241
|
+
begin
|
|
242
|
+
yield v
|
|
243
|
+
rescue InvalidValue
|
|
244
|
+
case @convert_invalid_date_time
|
|
245
|
+
when nil, :nil
|
|
246
|
+
nil
|
|
247
|
+
when :string
|
|
248
|
+
v
|
|
249
|
+
else
|
|
250
|
+
raise
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
247
255
|
# The MySQL adapter main error class is Mysql::Error
|
|
248
256
|
def database_error_classes
|
|
249
257
|
[Mysql::Error]
|
|
250
258
|
end
|
|
259
|
+
|
|
260
|
+
# Raise a disconnect error if the exception message matches the list
|
|
261
|
+
# of recognized exceptions.
|
|
262
|
+
def disconnect_error?(e, opts)
|
|
263
|
+
super || (e.is_a?(::Mysql::Error) && MYSQL_DATABASE_DISCONNECT_ERRORS.match(e.message))
|
|
264
|
+
end
|
|
251
265
|
|
|
252
266
|
# The database name when using the native adapter is always stored in
|
|
253
267
|
# the :database option.
|
|
@@ -262,114 +276,31 @@ module Sequel
|
|
|
262
276
|
nil
|
|
263
277
|
end
|
|
264
278
|
|
|
265
|
-
# Executes a prepared statement on an available connection. If the
|
|
266
|
-
# prepared statement already exists for the connection and has the same
|
|
267
|
-
# SQL, reuse it, otherwise, prepare the new statement. Because of the
|
|
268
|
-
# usual MySQL stupidity, we are forced to name arguments via separate
|
|
269
|
-
# SET queries. Use @sequel_arg_N (for N starting at 1) for these
|
|
270
|
-
# arguments.
|
|
271
|
-
def execute_prepared_statement(ps_name, opts, &block)
|
|
272
|
-
args = opts[:arguments]
|
|
273
|
-
ps = prepared_statements[ps_name]
|
|
274
|
-
sql = ps.prepared_sql
|
|
275
|
-
synchronize(opts[:server]) do |conn|
|
|
276
|
-
unless conn.prepared_statements[ps_name] == sql
|
|
277
|
-
conn.prepared_statements[ps_name] = sql
|
|
278
|
-
_execute(conn, "PREPARE #{ps_name} FROM '#{::Mysql.quote(sql)}'", opts)
|
|
279
|
-
end
|
|
280
|
-
i = 0
|
|
281
|
-
_execute(conn, "SET " + args.map {|arg| "@sequel_arg_#{i+=1} = #{literal(arg)}"}.join(", "), opts) unless args.empty?
|
|
282
|
-
_execute(conn, "EXECUTE #{ps_name}#{" USING #{(1..i).map{|j| "@sequel_arg_#{j}"}.join(', ')}" unless i == 0}", opts, &block)
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
279
|
# Convert tinyint(1) type to boolean if convert_tinyint_to_bool is true
|
|
287
280
|
def schema_column_type(db_type)
|
|
288
|
-
|
|
281
|
+
convert_tinyint_to_bool && db_type == 'tinyint(1)' ? :boolean : super
|
|
289
282
|
end
|
|
290
283
|
end
|
|
291
284
|
|
|
292
285
|
# Dataset class for MySQL datasets accessed via the native driver.
|
|
293
286
|
class Dataset < Sequel::Dataset
|
|
294
287
|
include Sequel::MySQL::DatasetMethods
|
|
295
|
-
include
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
module CallableStatementMethods
|
|
300
|
-
# Extend given dataset with this module so subselects inside subselects in
|
|
301
|
-
# prepared statements work.
|
|
302
|
-
def subselect_sql(ds)
|
|
303
|
-
ps = ds.to_prepared_statement(:select)
|
|
304
|
-
ps.extend(CallableStatementMethods)
|
|
305
|
-
ps = ps.bind(@opts[:bind_vars]) if @opts[:bind_vars]
|
|
306
|
-
ps.prepared_args = prepared_args
|
|
307
|
-
ps.prepared_sql
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
# Methods for MySQL prepared statements using the native driver.
|
|
312
|
-
module PreparedStatementMethods
|
|
313
|
-
include Sequel::Dataset::UnnumberedArgumentMapper
|
|
314
|
-
|
|
315
|
-
private
|
|
316
|
-
|
|
317
|
-
# Execute the prepared statement with the bind arguments instead of
|
|
318
|
-
# the given SQL.
|
|
319
|
-
def execute(sql, opts={}, &block)
|
|
320
|
-
super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
# Same as execute, explicit due to intricacies of alias and super.
|
|
324
|
-
def execute_dui(sql, opts={}, &block)
|
|
325
|
-
super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
326
|
-
end
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
# Methods for MySQL stored procedures using the native driver.
|
|
330
|
-
module StoredProcedureMethods
|
|
331
|
-
include Sequel::Dataset::StoredProcedureMethods
|
|
332
|
-
|
|
333
|
-
private
|
|
334
|
-
|
|
335
|
-
# Execute the database stored procedure with the stored arguments.
|
|
336
|
-
def execute(sql, opts={}, &block)
|
|
337
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
# Same as execute, explicit due to intricacies of alias and super.
|
|
341
|
-
def execute_dui(sql, opts={}, &block)
|
|
342
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
# MySQL is different in that it supports prepared statements but not bound
|
|
347
|
-
# variables outside of prepared statements. The default implementation
|
|
348
|
-
# breaks the use of subselects in prepared statements, so extend the
|
|
349
|
-
# temporary prepared statement that this creates with a module that
|
|
350
|
-
# fixes it.
|
|
351
|
-
def call(type, bind_arguments={}, *values, &block)
|
|
352
|
-
ps = to_prepared_statement(type, values)
|
|
353
|
-
ps.extend(CallableStatementMethods)
|
|
354
|
-
ps.call(bind_arguments, &block)
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
# Delete rows matching this dataset
|
|
358
|
-
def delete
|
|
359
|
-
execute_dui(delete_sql){|c| return c.affected_rows}
|
|
360
|
-
end
|
|
361
|
-
|
|
288
|
+
include Sequel::MySQL::PreparedStatements::DatasetMethods
|
|
289
|
+
|
|
290
|
+
Database::DatasetClass = self
|
|
291
|
+
|
|
362
292
|
# Yield all rows matching this dataset. If the dataset is set to
|
|
363
293
|
# split multiple statements, yield arrays of hashes one per statement
|
|
364
294
|
# instead of yielding results for all statements as hashes.
|
|
365
|
-
def fetch_rows(sql
|
|
295
|
+
def fetch_rows(sql)
|
|
366
296
|
execute(sql) do |r|
|
|
367
297
|
i = -1
|
|
298
|
+
cps = db.conversion_procs
|
|
368
299
|
cols = r.fetch_fields.map do |f|
|
|
369
300
|
# Pretend tinyint is another integer type if its length is not 1, to
|
|
370
301
|
# avoid casting to boolean if Sequel::MySQL.convert_tinyint_to_bool
|
|
371
302
|
# is set.
|
|
372
|
-
type_proc = f.type == 1 && f
|
|
303
|
+
type_proc = f.type == 1 && cast_tinyint_integer?(f) ? cps[2] : cps[f.type]
|
|
373
304
|
[output_identifier(f.name), type_proc, i+=1]
|
|
374
305
|
end
|
|
375
306
|
@columns = cols.map{|c| c.first}
|
|
@@ -378,7 +309,7 @@ module Sequel
|
|
|
378
309
|
yield_rows(r, cols){|h| s << h}
|
|
379
310
|
yield s
|
|
380
311
|
else
|
|
381
|
-
yield_rows(r, cols
|
|
312
|
+
yield_rows(r, cols){|h| yield h}
|
|
382
313
|
end
|
|
383
314
|
end
|
|
384
315
|
self
|
|
@@ -390,28 +321,6 @@ module Sequel
|
|
|
390
321
|
super
|
|
391
322
|
end
|
|
392
323
|
|
|
393
|
-
# Insert a new value into this dataset
|
|
394
|
-
def insert(*values)
|
|
395
|
-
execute_dui(insert_sql(*values)){|c| return c.insert_id}
|
|
396
|
-
end
|
|
397
|
-
|
|
398
|
-
# Store the given type of prepared statement in the associated database
|
|
399
|
-
# with the given name.
|
|
400
|
-
def prepare(type, name=nil, *values)
|
|
401
|
-
ps = to_prepared_statement(type, values)
|
|
402
|
-
ps.extend(PreparedStatementMethods)
|
|
403
|
-
if name
|
|
404
|
-
ps.prepared_statement_name = name
|
|
405
|
-
db.prepared_statements[name] = ps
|
|
406
|
-
end
|
|
407
|
-
ps
|
|
408
|
-
end
|
|
409
|
-
|
|
410
|
-
# Replace (update or insert) the matching row.
|
|
411
|
-
def replace(*args)
|
|
412
|
-
execute_dui(replace_sql(*args)){|c| return c.insert_id}
|
|
413
|
-
end
|
|
414
|
-
|
|
415
324
|
# Makes each yield arrays of rows, with each array containing the rows
|
|
416
325
|
# for a given result set. Does not work with graphing. So you can submit
|
|
417
326
|
# SQL with multiple statements and easily determine which statement
|
|
@@ -428,31 +337,25 @@ module Sequel
|
|
|
428
337
|
ds
|
|
429
338
|
end
|
|
430
339
|
|
|
431
|
-
# Update the matching rows.
|
|
432
|
-
def update(values={})
|
|
433
|
-
execute_dui(update_sql(values)){|c| return c.affected_rows}
|
|
434
|
-
end
|
|
435
|
-
|
|
436
340
|
private
|
|
341
|
+
|
|
342
|
+
# Whether a tinyint field should be casted as an integer. By default,
|
|
343
|
+
# casts to integer if the field length is not 1. Can be overwritten
|
|
344
|
+
# to make tinyint casting dataset dependent.
|
|
345
|
+
def cast_tinyint_integer?(field)
|
|
346
|
+
field.length != 1
|
|
347
|
+
end
|
|
437
348
|
|
|
438
349
|
# Set the :type option to :select if it hasn't been set.
|
|
439
350
|
def execute(sql, opts={}, &block)
|
|
440
351
|
super(sql, {:type=>:select}.merge(opts), &block)
|
|
441
352
|
end
|
|
442
353
|
|
|
443
|
-
# Set the :type option to :dui if it hasn't been set.
|
|
444
|
-
def execute_dui(sql, opts={}, &block)
|
|
445
|
-
super(sql, {:type=>:dui}.merge(opts), &block)
|
|
446
|
-
end
|
|
447
|
-
|
|
448
354
|
# Handle correct quoting of strings using ::MySQL.quote.
|
|
449
|
-
def
|
|
450
|
-
"'
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
# Extend the dataset with the MySQL stored procedure methods.
|
|
454
|
-
def prepare_extend_sproc(ds)
|
|
455
|
-
ds.extend(StoredProcedureMethods)
|
|
355
|
+
def literal_string_append(sql, v)
|
|
356
|
+
sql << "'"
|
|
357
|
+
sql << ::Mysql.quote(v)
|
|
358
|
+
sql << "'"
|
|
456
359
|
end
|
|
457
360
|
|
|
458
361
|
# Yield each row of the given result set r with columns cols
|