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
data/spec/adapters/mysql_spec.rb
CHANGED
|
@@ -14,10 +14,6 @@ INTEGRATION_DB = MYSQL_DB unless defined?(INTEGRATION_DB)
|
|
|
14
14
|
|
|
15
15
|
MYSQL_URI = URI.parse(MYSQL_DB.uri)
|
|
16
16
|
|
|
17
|
-
MYSQL_DB.create_table! :test2 do
|
|
18
|
-
text :name
|
|
19
|
-
integer :value
|
|
20
|
-
end
|
|
21
17
|
def MYSQL_DB.sqls
|
|
22
18
|
(@sqls ||= [])
|
|
23
19
|
end
|
|
@@ -26,9 +22,7 @@ def logger.method_missing(m, msg)
|
|
|
26
22
|
MYSQL_DB.sqls << msg
|
|
27
23
|
end
|
|
28
24
|
MYSQL_DB.loggers = [logger]
|
|
29
|
-
MYSQL_DB.drop_table(:items
|
|
30
|
-
MYSQL_DB.drop_table(:dolls) rescue nil
|
|
31
|
-
MYSQL_DB.drop_table(:booltest) rescue nil
|
|
25
|
+
MYSQL_DB.drop_table?(:items, :dolls, :booltest)
|
|
32
26
|
|
|
33
27
|
SQL_BEGIN = 'BEGIN'
|
|
34
28
|
SQL_ROLLBACK = 'ROLLBACK'
|
|
@@ -40,29 +34,29 @@ describe "MySQL", '#create_table' do
|
|
|
40
34
|
MYSQL_DB.sqls.clear
|
|
41
35
|
end
|
|
42
36
|
after do
|
|
43
|
-
@db.drop_table(:dolls)
|
|
37
|
+
@db.drop_table?(:dolls)
|
|
44
38
|
end
|
|
45
|
-
|
|
39
|
+
|
|
46
40
|
specify "should allow to specify options for MySQL" do
|
|
47
41
|
@db.create_table(:dolls, :engine => 'MyISAM', :charset => 'latin2'){text :name}
|
|
48
|
-
@db.sqls.should == ["CREATE TABLE dolls (name text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
|
|
42
|
+
@db.sqls.should == ["CREATE TABLE `dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
|
|
49
43
|
end
|
|
50
|
-
|
|
44
|
+
|
|
51
45
|
specify "should create a temporary table" do
|
|
52
46
|
@db.create_table(:tmp_dolls, :temp => true, :engine => 'MyISAM', :charset => 'latin2'){text :name}
|
|
53
|
-
@db.sqls.should == ["CREATE TEMPORARY TABLE tmp_dolls (name text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
|
|
47
|
+
@db.sqls.should == ["CREATE TEMPORARY TABLE `tmp_dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
|
|
54
48
|
end
|
|
55
|
-
|
|
49
|
+
|
|
56
50
|
specify "should not use a default for a String :text=>true type" do
|
|
57
51
|
@db.create_table(:dolls){String :name, :text=>true, :default=>'blah'}
|
|
58
|
-
@db.sqls.should == ["CREATE TABLE dolls (name text)"]
|
|
52
|
+
@db.sqls.should == ["CREATE TABLE `dolls` (`name` text)"]
|
|
59
53
|
end
|
|
60
|
-
|
|
54
|
+
|
|
61
55
|
specify "should not use a default for a File type" do
|
|
62
56
|
@db.create_table(:dolls){File :name, :default=>'blah'}
|
|
63
|
-
@db.sqls.should == ["CREATE TABLE dolls (name blob)"]
|
|
57
|
+
@db.sqls.should == ["CREATE TABLE `dolls` (`name` blob)"]
|
|
64
58
|
end
|
|
65
|
-
|
|
59
|
+
|
|
66
60
|
specify "should respect the size option for File type" do
|
|
67
61
|
@db.create_table(:dolls) do
|
|
68
62
|
File :n1
|
|
@@ -82,42 +76,41 @@ describe "MySQL", '#create_table' do
|
|
|
82
76
|
end
|
|
83
77
|
@db.schema(:dolls).map{|k, v| v[:auto_increment]}.should == [nil, nil, true]
|
|
84
78
|
end
|
|
85
|
-
end
|
|
86
79
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
specify "should handle the creation and dropping of an InnoDB table with foreign keys" do
|
|
93
|
-
proc{MYSQL_DB.create_table!(:test_innodb, :engine=>:InnoDB){primary_key :id; foreign_key :fk, :test_innodb, :key=>:id}}.should_not raise_error
|
|
80
|
+
specify "should support collate with various other column options" do
|
|
81
|
+
@db.create_table!(:dolls){ String :name, :size=>128, :collate=>:utf8_bin, :default=>'foo', :null=>false, :unique=>true}
|
|
82
|
+
@db[:dolls].insert
|
|
83
|
+
@db[:dolls].select_map(:name).should == ["foo"]
|
|
94
84
|
end
|
|
95
|
-
|
|
96
|
-
specify "should
|
|
97
|
-
|
|
85
|
+
|
|
86
|
+
specify "should be able to parse the default value for set and enum types" do
|
|
87
|
+
@db.create_table!(:dolls){column :t, "set('a', 'b', 'c', 'd')", :default=>'a,b'}
|
|
88
|
+
@db.schema(:dolls).first.last[:ruby_default].should == 'a,b'
|
|
89
|
+
@db.create_table!(:dolls){column :t, "enum('a', 'b', 'c', 'd')", :default=>'b'}
|
|
90
|
+
@db.schema(:dolls).first.last[:ruby_default].should == 'b'
|
|
98
91
|
end
|
|
99
92
|
end
|
|
100
93
|
|
|
101
|
-
if MYSQL_DB.adapter_scheme
|
|
102
|
-
describe "Sequel::MySQL
|
|
94
|
+
if [:mysql, :mysql2].include?(MYSQL_DB.adapter_scheme)
|
|
95
|
+
describe "Sequel::MySQL::Database#convert_tinyint_to_bool" do
|
|
103
96
|
before do
|
|
104
97
|
@db = MYSQL_DB
|
|
105
98
|
@db.create_table(:booltest){column :b, 'tinyint(1)'; column :i, 'tinyint(4)'}
|
|
106
99
|
@ds = @db[:booltest]
|
|
107
100
|
end
|
|
108
101
|
after do
|
|
109
|
-
|
|
110
|
-
@db.drop_table(:booltest)
|
|
102
|
+
@db.convert_tinyint_to_bool = true
|
|
103
|
+
@db.drop_table?(:booltest)
|
|
111
104
|
end
|
|
112
|
-
|
|
105
|
+
|
|
113
106
|
specify "should consider tinyint(1) datatypes as boolean if set, but not larger tinyints" do
|
|
114
107
|
@db.schema(:booltest, :reload=>true).should == [[:b, {:type=>:boolean, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(1)"}, ], [:i, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}, ]]
|
|
115
|
-
|
|
108
|
+
@db.convert_tinyint_to_bool = false
|
|
116
109
|
@db.schema(:booltest, :reload=>true).should == [[:b, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(1)"}, ], [:i, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}, ]]
|
|
117
110
|
end
|
|
118
|
-
|
|
111
|
+
|
|
119
112
|
specify "should return tinyint(1)s as bools and tinyint(4)s as integers when set" do
|
|
120
|
-
|
|
113
|
+
@db.convert_tinyint_to_bool = true
|
|
121
114
|
@ds.delete
|
|
122
115
|
@ds << {:b=>true, :i=>10}
|
|
123
116
|
@ds.all.should == [{:b=>true, :i=>10}]
|
|
@@ -130,14 +123,14 @@ if MYSQL_DB.adapter_scheme == :mysql
|
|
|
130
123
|
end
|
|
131
124
|
|
|
132
125
|
specify "should return all tinyints as integers when unset" do
|
|
133
|
-
|
|
126
|
+
@db.convert_tinyint_to_bool = false
|
|
134
127
|
@ds.delete
|
|
135
128
|
@ds << {:b=>true, :i=>10}
|
|
136
129
|
@ds.all.should == [{:b=>1, :i=>10}]
|
|
137
130
|
@ds.delete
|
|
138
131
|
@ds << {:b=>false, :i=>0}
|
|
139
132
|
@ds.all.should == [{:b=>0, :i=>0}]
|
|
140
|
-
|
|
133
|
+
|
|
141
134
|
@ds.delete
|
|
142
135
|
@ds << {:b=>1, :i=>10}
|
|
143
136
|
@ds.all.should == [{:b=>1, :i=>10}]
|
|
@@ -145,6 +138,17 @@ if MYSQL_DB.adapter_scheme == :mysql
|
|
|
145
138
|
@ds << {:b=>0, :i=>0}
|
|
146
139
|
@ds.all.should == [{:b=>0, :i=>0}]
|
|
147
140
|
end
|
|
141
|
+
|
|
142
|
+
specify "should allow disabling the conversion on a per-dataset basis" do
|
|
143
|
+
@db.convert_tinyint_to_bool = true
|
|
144
|
+
ds = @ds.clone
|
|
145
|
+
ds.meta_def(:cast_tinyint_integer?){|f| true} # mysql
|
|
146
|
+
ds.meta_def(:convert_tinyint_to_bool?){false} # mysql2
|
|
147
|
+
ds.delete
|
|
148
|
+
ds << {:b=>true, :i=>10}
|
|
149
|
+
ds.all.should == [{:b=>1, :i=>10}]
|
|
150
|
+
@ds.all.should == [{:b=>true, :i=>10}]
|
|
151
|
+
end
|
|
148
152
|
end
|
|
149
153
|
end
|
|
150
154
|
|
|
@@ -155,106 +159,86 @@ describe "A MySQL dataset" do
|
|
|
155
159
|
MYSQL_DB.sqls.clear
|
|
156
160
|
end
|
|
157
161
|
after do
|
|
158
|
-
MYSQL_DB.drop_table(:items)
|
|
162
|
+
MYSQL_DB.drop_table?(:items)
|
|
159
163
|
end
|
|
160
|
-
|
|
164
|
+
|
|
161
165
|
specify "should quote columns and tables using back-ticks if quoting identifiers" do
|
|
162
166
|
@d.quote_identifiers = true
|
|
163
|
-
@d.select(:name).sql.should ==
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
@d.select(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
@d.select(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
@d.select(:
|
|
173
|
-
'SELECT
|
|
174
|
-
|
|
175
|
-
@d.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
@d.order(:name.desc).sql.should == \
|
|
179
|
-
'SELECT * FROM `items` ORDER BY `name` DESC'
|
|
180
|
-
|
|
181
|
-
@d.select('items.name AS item_name'.lit).sql.should == \
|
|
182
|
-
'SELECT items.name AS item_name FROM `items`'
|
|
183
|
-
|
|
184
|
-
@d.select('`name`'.lit).sql.should == \
|
|
185
|
-
'SELECT `name` FROM `items`'
|
|
186
|
-
|
|
187
|
-
@d.select('max(items.`name`) AS `max_name`'.lit).sql.should == \
|
|
188
|
-
'SELECT max(items.`name`) AS `max_name` FROM `items`'
|
|
189
|
-
|
|
190
|
-
@d.select(:test.sql_function(:abc, 'hello')).sql.should == \
|
|
191
|
-
"SELECT test(`abc`, 'hello') FROM `items`"
|
|
192
|
-
|
|
193
|
-
@d.select(:test.sql_function(:abc__def, 'hello')).sql.should == \
|
|
194
|
-
"SELECT test(`abc`.`def`, 'hello') FROM `items`"
|
|
195
|
-
|
|
196
|
-
@d.select(:test.sql_function(:abc__def, 'hello').as(:x2)).sql.should == \
|
|
197
|
-
"SELECT test(`abc`.`def`, 'hello') AS `x2` FROM `items`"
|
|
198
|
-
|
|
199
|
-
@d.insert_sql(:value => 333).should == \
|
|
200
|
-
'INSERT INTO `items` (`value`) VALUES (333)'
|
|
201
|
-
|
|
202
|
-
@d.insert_sql(:x => :y).should == \
|
|
203
|
-
'INSERT INTO `items` (`x`) VALUES (`y`)'
|
|
167
|
+
@d.select(:name).sql.should == 'SELECT `name` FROM `items`'
|
|
168
|
+
@d.select(Sequel.lit('COUNT(*)')).sql.should == 'SELECT COUNT(*) FROM `items`'
|
|
169
|
+
@d.select(Sequel.function(:max, :value)).sql.should == 'SELECT max(`value`) FROM `items`'
|
|
170
|
+
@d.select(Sequel.function(:NOW)).sql.should == 'SELECT NOW() FROM `items`'
|
|
171
|
+
@d.select(Sequel.function(:max, :items__value)).sql.should == 'SELECT max(`items`.`value`) FROM `items`'
|
|
172
|
+
@d.order(Sequel.expr(:name).desc).sql.should == 'SELECT * FROM `items` ORDER BY `name` DESC'
|
|
173
|
+
@d.select(Sequel.lit('items.name AS item_name')).sql.should == 'SELECT items.name AS item_name FROM `items`'
|
|
174
|
+
@d.select(Sequel.lit('`name`')).sql.should == 'SELECT `name` FROM `items`'
|
|
175
|
+
@d.select(Sequel.lit('max(items.`name`) AS `max_name`')).sql.should == 'SELECT max(items.`name`) AS `max_name` FROM `items`'
|
|
176
|
+
@d.select(Sequel.function(:test, :abc, 'hello')).sql.should == "SELECT test(`abc`, 'hello') FROM `items`"
|
|
177
|
+
@d.select(Sequel.function(:test, :abc__def, 'hello')).sql.should == "SELECT test(`abc`.`def`, 'hello') FROM `items`"
|
|
178
|
+
@d.select(Sequel.function(:test, :abc__def, 'hello').as(:x2)).sql.should == "SELECT test(`abc`.`def`, 'hello') AS `x2` FROM `items`"
|
|
179
|
+
@d.insert_sql(:value => 333).should == 'INSERT INTO `items` (`value`) VALUES (333)'
|
|
180
|
+
@d.insert_sql(:x => :y).should == 'INSERT INTO `items` (`x`) VALUES (`y`)'
|
|
204
181
|
end
|
|
205
|
-
|
|
182
|
+
|
|
206
183
|
specify "should quote fields correctly when reversing the order" do
|
|
207
184
|
@d.quote_identifiers = true
|
|
208
|
-
@d.reverse_order(:name).sql.should ==
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
@d.reverse_order(:name
|
|
212
|
-
'SELECT * FROM `items` ORDER BY `name` ASC'
|
|
213
|
-
|
|
214
|
-
@d.reverse_order(:name, :test.desc).sql.should == \
|
|
215
|
-
'SELECT * FROM `items` ORDER BY `name` DESC, `test` ASC'
|
|
216
|
-
|
|
217
|
-
@d.reverse_order(:name.desc, :test).sql.should == \
|
|
218
|
-
'SELECT * FROM `items` ORDER BY `name` ASC, `test` DESC'
|
|
185
|
+
@d.reverse_order(:name).sql.should == 'SELECT * FROM `items` ORDER BY `name` DESC'
|
|
186
|
+
@d.reverse_order(Sequel.desc(:name)).sql.should == 'SELECT * FROM `items` ORDER BY `name` ASC'
|
|
187
|
+
@d.reverse_order(:name, Sequel.desc(:test)).sql.should == 'SELECT * FROM `items` ORDER BY `name` DESC, `test` ASC'
|
|
188
|
+
@d.reverse_order(Sequel.desc(:name), :test).sql.should == 'SELECT * FROM `items` ORDER BY `name` ASC, `test` DESC'
|
|
219
189
|
end
|
|
220
|
-
|
|
190
|
+
|
|
221
191
|
specify "should support ORDER clause in UPDATE statements" do
|
|
222
|
-
@d.order(:name).update_sql(:value => 1).should ==
|
|
223
|
-
'UPDATE items SET value = 1 ORDER BY name'
|
|
192
|
+
@d.order(:name).update_sql(:value => 1).should == 'UPDATE `items` SET `value` = 1 ORDER BY `name`'
|
|
224
193
|
end
|
|
225
|
-
|
|
194
|
+
|
|
226
195
|
specify "should support LIMIT clause in UPDATE statements" do
|
|
227
|
-
@d.limit(10).update_sql(:value => 1).should ==
|
|
228
|
-
'UPDATE items SET value = 1 LIMIT 10'
|
|
196
|
+
@d.limit(10).update_sql(:value => 1).should == 'UPDATE `items` SET `value` = 1 LIMIT 10'
|
|
229
197
|
end
|
|
230
|
-
|
|
198
|
+
|
|
231
199
|
specify "should support regexps" do
|
|
232
200
|
@d << {:name => 'abc', :value => 1}
|
|
233
201
|
@d << {:name => 'bcd', :value => 2}
|
|
234
202
|
@d.filter(:name => /bc/).count.should == 2
|
|
235
203
|
@d.filter(:name => /^bc/).count.should == 1
|
|
236
204
|
end
|
|
237
|
-
|
|
205
|
+
|
|
206
|
+
specify "should have explain output" do
|
|
207
|
+
@d.explain.should be_a_kind_of(String)
|
|
208
|
+
@d.explain(:extended=>true).should be_a_kind_of(String)
|
|
209
|
+
@d.explain.should_not == @d.explain(:extended=>true)
|
|
210
|
+
end
|
|
211
|
+
|
|
238
212
|
specify "should correctly literalize strings with comment backslashes in them" do
|
|
239
213
|
@d.delete
|
|
240
214
|
proc {@d << {:name => ':\\'}}.should_not raise_error
|
|
241
|
-
|
|
215
|
+
|
|
242
216
|
@d.first[:name].should == ':\\'
|
|
243
217
|
end
|
|
218
|
+
|
|
219
|
+
specify "should handle prepared statements with on_duplicate_key_update" do
|
|
220
|
+
@d.db.add_index :items, :value, :unique=>true
|
|
221
|
+
ds = @d.on_duplicate_key_update
|
|
222
|
+
ps = ds.prepare(:insert, :insert_user_id_feature_name, :value => :$v, :name => :$n)
|
|
223
|
+
ps.call(:v => 1, :n => 'a')
|
|
224
|
+
ds.all.should == [{:value=>1, :name=>'a'}]
|
|
225
|
+
ps.call(:v => 1, :n => 'b')
|
|
226
|
+
ds.all.should == [{:value=>1, :name=>'b'}]
|
|
227
|
+
end
|
|
244
228
|
end
|
|
245
229
|
|
|
246
230
|
describe "MySQL datasets" do
|
|
247
231
|
before do
|
|
248
232
|
@d = MYSQL_DB[:orders]
|
|
249
233
|
end
|
|
250
|
-
|
|
234
|
+
|
|
251
235
|
specify "should correctly quote column references" do
|
|
252
236
|
@d.quote_identifiers = true
|
|
253
237
|
market = 'ICE'
|
|
254
238
|
ack_stamp = Time.now - 15 * 60 # 15 minutes ago
|
|
255
|
-
@d.select(:market, :minute.
|
|
256
|
-
where{
|
|
257
|
-
group_by(:minute.
|
|
239
|
+
@d.select(:market, Sequel.function(:minute, Sequel.function(:from_unixtime, :ack)).as(:minute)).
|
|
240
|
+
where{(ack > ack_stamp) & {:market => market}}.
|
|
241
|
+
group_by(Sequel.function(:minute, Sequel.function(:from_unixtime, :ack))).sql.should == \
|
|
258
242
|
"SELECT `market`, minute(from_unixtime(`ack`)) AS `minute` FROM `orders` WHERE ((`ack` > #{@d.literal(ack_stamp)}) AND (`market` = 'ICE')) GROUP BY minute(from_unixtime(`ack`))"
|
|
259
243
|
end
|
|
260
244
|
end
|
|
@@ -269,14 +253,14 @@ describe "Dataset#distinct" do
|
|
|
269
253
|
@ds = @db[:a]
|
|
270
254
|
end
|
|
271
255
|
after do
|
|
272
|
-
@db.drop_table(:a)
|
|
256
|
+
@db.drop_table?(:a)
|
|
273
257
|
end
|
|
274
|
-
|
|
258
|
+
|
|
275
259
|
it "#distinct with arguments should return results distinct on those arguments" do
|
|
276
260
|
@ds.insert(20, 10)
|
|
277
261
|
@ds.insert(30, 10)
|
|
278
262
|
@ds.order(:b, :a).distinct.map(:a).should == [20, 30]
|
|
279
|
-
@ds.order(:b, :a
|
|
263
|
+
@ds.order(:b, Sequel.desc(:a)).distinct.map(:a).should == [30, 20]
|
|
280
264
|
# MySQL doesn't respect orders when using the nonstandard GROUP BY
|
|
281
265
|
[[20], [30]].should include(@ds.order(:b, :a).distinct(:b).map(:a))
|
|
282
266
|
end
|
|
@@ -285,7 +269,6 @@ end
|
|
|
285
269
|
describe "MySQL join expressions" do
|
|
286
270
|
before do
|
|
287
271
|
@ds = MYSQL_DB[:nodes]
|
|
288
|
-
@ds.db.meta_def(:server_version) {50014}
|
|
289
272
|
end
|
|
290
273
|
|
|
291
274
|
specify "should raise error for :full_outer join requests." do
|
|
@@ -293,43 +276,43 @@ describe "MySQL join expressions" do
|
|
|
293
276
|
end
|
|
294
277
|
specify "should support natural left joins" do
|
|
295
278
|
@ds.join_table(:natural_left, :nodes).sql.should == \
|
|
296
|
-
'SELECT * FROM nodes NATURAL LEFT JOIN nodes'
|
|
279
|
+
'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
|
|
297
280
|
end
|
|
298
281
|
specify "should support natural right joins" do
|
|
299
282
|
@ds.join_table(:natural_right, :nodes).sql.should == \
|
|
300
|
-
'SELECT * FROM nodes NATURAL RIGHT JOIN nodes'
|
|
283
|
+
'SELECT * FROM `nodes` NATURAL RIGHT JOIN `nodes`'
|
|
301
284
|
end
|
|
302
285
|
specify "should support natural left outer joins" do
|
|
303
286
|
@ds.join_table(:natural_left_outer, :nodes).sql.should == \
|
|
304
|
-
'SELECT * FROM nodes NATURAL LEFT OUTER JOIN nodes'
|
|
287
|
+
'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN `nodes`'
|
|
305
288
|
end
|
|
306
289
|
specify "should support natural right outer joins" do
|
|
307
290
|
@ds.join_table(:natural_right_outer, :nodes).sql.should == \
|
|
308
|
-
'SELECT * FROM nodes NATURAL RIGHT OUTER JOIN nodes'
|
|
291
|
+
'SELECT * FROM `nodes` NATURAL RIGHT OUTER JOIN `nodes`'
|
|
309
292
|
end
|
|
310
293
|
specify "should support natural inner joins" do
|
|
311
294
|
@ds.join_table(:natural_inner, :nodes).sql.should == \
|
|
312
|
-
'SELECT * FROM nodes NATURAL LEFT JOIN nodes'
|
|
295
|
+
'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
|
|
313
296
|
end
|
|
314
297
|
specify "should support cross joins" do
|
|
315
298
|
@ds.join_table(:cross, :nodes).sql.should == \
|
|
316
|
-
'SELECT * FROM nodes CROSS JOIN nodes'
|
|
299
|
+
'SELECT * FROM `nodes` CROSS JOIN `nodes`'
|
|
317
300
|
end
|
|
318
301
|
specify "should support cross joins as inner joins if conditions are used" do
|
|
319
302
|
@ds.join_table(:cross, :nodes, :id=>:id).sql.should == \
|
|
320
|
-
'SELECT * FROM nodes INNER JOIN nodes ON (nodes
|
|
303
|
+
'SELECT * FROM `nodes` INNER JOIN `nodes` ON (`nodes`.`id` = `nodes`.`id`)'
|
|
321
304
|
end
|
|
322
305
|
specify "should support straight joins (force left table to be read before right)" do
|
|
323
306
|
@ds.join_table(:straight, :nodes).sql.should == \
|
|
324
|
-
'SELECT * FROM nodes STRAIGHT_JOIN nodes'
|
|
307
|
+
'SELECT * FROM `nodes` STRAIGHT_JOIN `nodes`'
|
|
325
308
|
end
|
|
326
309
|
specify "should support natural joins on multiple tables." do
|
|
327
310
|
@ds.join_table(:natural_left_outer, [:nodes, :branches]).sql.should == \
|
|
328
|
-
'SELECT * FROM nodes NATURAL LEFT OUTER JOIN (nodes
|
|
311
|
+
'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN (`nodes`, `branches`)'
|
|
329
312
|
end
|
|
330
313
|
specify "should support straight joins on multiple tables." do
|
|
331
314
|
@ds.join_table(:straight, [:nodes,:branches]).sql.should == \
|
|
332
|
-
'SELECT * FROM nodes STRAIGHT_JOIN (nodes
|
|
315
|
+
'SELECT * FROM `nodes` STRAIGHT_JOIN (`nodes`, `branches`)'
|
|
333
316
|
end
|
|
334
317
|
end
|
|
335
318
|
|
|
@@ -337,46 +320,79 @@ describe "Joined MySQL dataset" do
|
|
|
337
320
|
before do
|
|
338
321
|
@ds = MYSQL_DB[:nodes]
|
|
339
322
|
end
|
|
340
|
-
|
|
323
|
+
|
|
341
324
|
specify "should quote fields correctly" do
|
|
342
325
|
@ds.quote_identifiers = true
|
|
343
326
|
@ds.join(:attributes, :node_id => :id).sql.should == \
|
|
344
327
|
"SELECT * FROM `nodes` INNER JOIN `attributes` ON (`attributes`.`node_id` = `nodes`.`id`)"
|
|
345
328
|
end
|
|
346
|
-
|
|
329
|
+
|
|
347
330
|
specify "should allow a having clause on ungrouped datasets" do
|
|
348
331
|
proc {@ds.having('blah')}.should_not raise_error
|
|
349
332
|
|
|
350
333
|
@ds.having('blah').sql.should == \
|
|
351
|
-
"SELECT * FROM nodes HAVING (blah)"
|
|
334
|
+
"SELECT * FROM `nodes` HAVING (blah)"
|
|
352
335
|
end
|
|
353
|
-
|
|
336
|
+
|
|
354
337
|
specify "should put a having clause before an order by clause" do
|
|
355
338
|
@ds.order(:aaa).having(:bbb => :ccc).sql.should == \
|
|
356
|
-
"SELECT * FROM nodes HAVING (bbb = ccc) ORDER BY aaa"
|
|
339
|
+
"SELECT * FROM `nodes` HAVING (`bbb` = `ccc`) ORDER BY `aaa`"
|
|
357
340
|
end
|
|
358
341
|
end
|
|
359
342
|
|
|
360
343
|
describe "A MySQL database" do
|
|
361
|
-
|
|
344
|
+
after do
|
|
345
|
+
MYSQL_DB.drop_table?(:test_innodb)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
specify "should handle the creation and dropping of an InnoDB table with foreign keys" do
|
|
349
|
+
proc{MYSQL_DB.create_table!(:test_innodb, :engine=>:InnoDB){primary_key :id; foreign_key :fk, :test_innodb, :key=>:id}}.should_not raise_error
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
describe "A MySQL database" do
|
|
354
|
+
before(:all) do
|
|
362
355
|
@db = MYSQL_DB
|
|
356
|
+
@db.create_table! :test2 do
|
|
357
|
+
text :name
|
|
358
|
+
integer :value
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
after(:all) do
|
|
362
|
+
@db.drop_table?(:test2)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
specify "should provide the server version" do
|
|
366
|
+
@db.server_version.should >= 40000
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
specify "should cache the server version" do
|
|
370
|
+
# warm cache:
|
|
371
|
+
@db.server_version
|
|
372
|
+
@db.sqls.clear
|
|
373
|
+
3.times{@db.server_version}
|
|
374
|
+
@db.sqls.should be_empty
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
specify "should support for_share" do
|
|
378
|
+
@db.transaction{@db[:test2].for_share.all.should == []}
|
|
363
379
|
end
|
|
364
380
|
|
|
365
381
|
specify "should support add_column operations" do
|
|
366
382
|
@db.add_column :test2, :xyz, :text
|
|
367
|
-
|
|
383
|
+
|
|
368
384
|
@db[:test2].columns.should == [:name, :value, :xyz]
|
|
369
385
|
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => '000'}
|
|
370
386
|
@db[:test2].first[:xyz].should == '000'
|
|
371
387
|
end
|
|
372
|
-
|
|
388
|
+
|
|
373
389
|
specify "should support drop_column operations" do
|
|
374
390
|
@db[:test2].columns.should == [:name, :value, :xyz]
|
|
375
391
|
@db.drop_column :test2, :xyz
|
|
376
|
-
|
|
392
|
+
|
|
377
393
|
@db[:test2].columns.should == [:name, :value]
|
|
378
394
|
end
|
|
379
|
-
|
|
395
|
+
|
|
380
396
|
specify "should support rename_column operations" do
|
|
381
397
|
@db[:test2].delete
|
|
382
398
|
@db.add_column :test2, :xyz, :text
|
|
@@ -387,7 +403,7 @@ describe "A MySQL database" do
|
|
|
387
403
|
@db[:test2].columns.should == [:name, :value, :zyx]
|
|
388
404
|
@db[:test2].first[:zyx].should == 'qqqq'
|
|
389
405
|
end
|
|
390
|
-
|
|
406
|
+
|
|
391
407
|
specify "should support rename_column operations with types like varchar(255)" do
|
|
392
408
|
@db[:test2].delete
|
|
393
409
|
@db.add_column :test2, :tre, :text
|
|
@@ -398,26 +414,27 @@ describe "A MySQL database" do
|
|
|
398
414
|
@db[:test2].columns.should == [:name, :value, :zyx, :ert]
|
|
399
415
|
@db[:test2].first[:ert].should == 'qqqq'
|
|
400
416
|
end
|
|
401
|
-
|
|
417
|
+
|
|
402
418
|
specify "should support set_column_type operations" do
|
|
403
419
|
@db.add_column :test2, :xyz, :float
|
|
404
420
|
@db[:test2].delete
|
|
405
421
|
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => 56.78}
|
|
406
422
|
@db.set_column_type :test2, :xyz, :integer
|
|
407
|
-
|
|
423
|
+
|
|
408
424
|
@db[:test2].first[:xyz].should == 57
|
|
409
425
|
end
|
|
410
|
-
|
|
426
|
+
|
|
411
427
|
specify "should support add_index" do
|
|
412
428
|
@db.add_index :test2, :value
|
|
413
429
|
end
|
|
414
|
-
|
|
430
|
+
|
|
415
431
|
specify "should support drop_index" do
|
|
416
432
|
@db.drop_index :test2, :value
|
|
417
433
|
end
|
|
418
|
-
|
|
434
|
+
|
|
419
435
|
specify "should support add_foreign_key" do
|
|
420
436
|
@db.alter_table :test2 do
|
|
437
|
+
add_index :value, :unique=>true
|
|
421
438
|
add_foreign_key :value2, :test2, :key=>:value
|
|
422
439
|
end
|
|
423
440
|
@db[:test2].columns.should == [:name, :value, :zyx, :ert, :xyz, :value2]
|
|
@@ -427,79 +444,82 @@ end
|
|
|
427
444
|
describe "A MySQL database with table options" do
|
|
428
445
|
before do
|
|
429
446
|
@options = {:engine=>'MyISAM', :charset=>'latin1', :collate => 'latin1_swedish_ci'}
|
|
430
|
-
|
|
447
|
+
|
|
431
448
|
Sequel::MySQL.default_engine = 'InnoDB'
|
|
432
449
|
Sequel::MySQL.default_charset = 'utf8'
|
|
433
450
|
Sequel::MySQL.default_collate = 'utf8_general_ci'
|
|
434
|
-
|
|
451
|
+
|
|
435
452
|
@db = MYSQL_DB
|
|
436
|
-
@db.drop_table(:items)
|
|
437
|
-
|
|
453
|
+
@db.drop_table?(:items)
|
|
454
|
+
|
|
438
455
|
MYSQL_DB.sqls.clear
|
|
439
456
|
end
|
|
440
457
|
after do
|
|
441
|
-
@db.drop_table(:items)
|
|
458
|
+
@db.drop_table?(:items)
|
|
442
459
|
|
|
443
460
|
Sequel::MySQL.default_engine = nil
|
|
444
461
|
Sequel::MySQL.default_charset = nil
|
|
445
462
|
Sequel::MySQL.default_collate = nil
|
|
446
463
|
end
|
|
447
|
-
|
|
464
|
+
|
|
448
465
|
specify "should allow to pass custom options (engine, charset, collate) for table creation" do
|
|
449
466
|
@db.create_table(:items, @options){Integer :size; text :name}
|
|
450
|
-
@db.sqls.should == ["CREATE TABLE items (size integer, name text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
|
|
467
|
+
@db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
|
|
451
468
|
end
|
|
452
|
-
|
|
469
|
+
|
|
453
470
|
specify "should use default options if specified (engine, charset, collate) for table creation" do
|
|
454
471
|
@db.create_table(:items){Integer :size; text :name}
|
|
455
|
-
@db.sqls.should == ["CREATE TABLE items (size integer, name text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
|
|
472
|
+
@db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
|
|
456
473
|
end
|
|
457
|
-
|
|
474
|
+
|
|
458
475
|
specify "should not use default if option has a nil value" do
|
|
459
476
|
@db.create_table(:items, :engine=>nil, :charset=>nil, :collate=>nil){Integer :size; text :name}
|
|
460
|
-
@db.sqls.should == ["CREATE TABLE items (size integer, name text)"]
|
|
477
|
+
@db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text)"]
|
|
461
478
|
end
|
|
462
479
|
end
|
|
463
480
|
|
|
464
481
|
describe "A MySQL database" do
|
|
465
482
|
before do
|
|
466
483
|
@db = MYSQL_DB
|
|
467
|
-
@db.drop_table(:items)
|
|
484
|
+
@db.drop_table?(:items)
|
|
468
485
|
MYSQL_DB.sqls.clear
|
|
469
486
|
end
|
|
470
487
|
after do
|
|
471
|
-
@db.drop_table(:items)
|
|
488
|
+
@db.drop_table?(:items, :users)
|
|
472
489
|
end
|
|
473
|
-
|
|
490
|
+
|
|
474
491
|
specify "should support defaults for boolean columns" do
|
|
475
492
|
@db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
|
|
476
|
-
@db.sqls.should == ["CREATE TABLE items (active1 tinyint(1) DEFAULT 1, active2 tinyint(1) DEFAULT 0)"]
|
|
493
|
+
@db.sqls.should == ["CREATE TABLE `items` (`active1` tinyint(1) DEFAULT 1, `active2` tinyint(1) DEFAULT 0)"]
|
|
477
494
|
end
|
|
478
|
-
|
|
495
|
+
|
|
479
496
|
specify "should correctly format CREATE TABLE statements with foreign keys" do
|
|
480
|
-
@db.create_table(:items){
|
|
481
|
-
@db.sqls.should == ["CREATE TABLE items (id integer, p_id integer NOT NULL, FOREIGN KEY (p_id) REFERENCES items(id) ON DELETE CASCADE)"]
|
|
497
|
+
@db.create_table(:items){primary_key :id; foreign_key :p_id, :items, :key => :id, :null => false, :on_delete => :cascade}
|
|
498
|
+
@db.sqls.should == ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `p_id` integer NOT NULL, UNIQUE (`id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`id`) ON DELETE CASCADE)"]
|
|
482
499
|
end
|
|
483
|
-
|
|
500
|
+
|
|
484
501
|
specify "should correctly format ALTER TABLE statements with foreign keys" do
|
|
485
502
|
@db.create_table(:items){Integer :id}
|
|
503
|
+
@db.create_table(:users){primary_key :id}
|
|
486
504
|
@db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade}
|
|
487
|
-
@db.sqls.should == ["CREATE TABLE items (id integer)",
|
|
505
|
+
@db.sqls.should == ["CREATE TABLE `items` (`id` integer)",
|
|
506
|
+
"CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
|
|
507
|
+
"ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
|
|
488
508
|
end
|
|
489
|
-
|
|
509
|
+
|
|
490
510
|
specify "should have rename_column support keep existing options" do
|
|
491
511
|
@db.create_table(:items){String :id, :null=>false, :default=>'blah'}
|
|
492
512
|
@db.alter_table(:items){rename_column :id, :nid}
|
|
493
|
-
@db.sqls.should == ["CREATE TABLE items (id varchar(255) NOT NULL DEFAULT 'blah')", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id nid varchar(255) NOT NULL DEFAULT 'blah'"]
|
|
513
|
+
@db.sqls.should == ["CREATE TABLE `items` (`id` varchar(255) NOT NULL DEFAULT 'blah')", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `nid` varchar(255) NOT NULL DEFAULT 'blah'"]
|
|
494
514
|
@db[:items].insert
|
|
495
515
|
@db[:items].all.should == [{:nid=>'blah'}]
|
|
496
516
|
proc{@db[:items].insert(:nid=>nil)}.should raise_error(Sequel::DatabaseError)
|
|
497
517
|
end
|
|
498
|
-
|
|
518
|
+
|
|
499
519
|
specify "should have set_column_type support keep existing options" do
|
|
500
520
|
@db.create_table(:items){Integer :id, :null=>false, :default=>5}
|
|
501
521
|
@db.alter_table(:items){set_column_type :id, Bignum}
|
|
502
|
-
@db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id bigint NOT NULL DEFAULT 5"]
|
|
522
|
+
@db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` bigint NOT NULL DEFAULT 5"]
|
|
503
523
|
@db[:items].insert
|
|
504
524
|
@db[:items].all.should == [{:id=>5}]
|
|
505
525
|
proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
|
|
@@ -511,35 +531,35 @@ describe "A MySQL database" do
|
|
|
511
531
|
specify "should have set_column_type pass through options" do
|
|
512
532
|
@db.create_table(:items){integer :id; enum :list, :elements=>%w[one]}
|
|
513
533
|
@db.alter_table(:items){set_column_type :id, :int, :unsigned=>true, :size=>8; set_column_type :list, :enum, :elements=>%w[two]}
|
|
514
|
-
@db.sqls.should == ["CREATE TABLE items (id integer, list enum('one'))", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id int(8) UNSIGNED NULL
|
|
534
|
+
@db.sqls.should == ["CREATE TABLE `items` (`id` integer, `list` enum('one'))", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(8) UNSIGNED NULL, CHANGE COLUMN `list` `list` enum('two') NULL"]
|
|
515
535
|
end
|
|
516
|
-
|
|
536
|
+
|
|
517
537
|
specify "should have set_column_default support keep existing options" do
|
|
518
538
|
@db.create_table(:items){Integer :id, :null=>false, :default=>5}
|
|
519
539
|
@db.alter_table(:items){set_column_default :id, 6}
|
|
520
|
-
@db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id int(11) NOT NULL DEFAULT 6"]
|
|
540
|
+
@db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NOT NULL DEFAULT 6"]
|
|
521
541
|
@db[:items].insert
|
|
522
542
|
@db[:items].all.should == [{:id=>6}]
|
|
523
543
|
proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
|
|
524
544
|
end
|
|
525
|
-
|
|
545
|
+
|
|
526
546
|
specify "should have set_column_allow_null support keep existing options" do
|
|
527
547
|
@db.create_table(:items){Integer :id, :null=>false, :default=>5}
|
|
528
548
|
@db.alter_table(:items){set_column_allow_null :id, true}
|
|
529
|
-
@db.sqls.should == ["CREATE TABLE items (id integer NOT NULL DEFAULT 5)", "DESCRIBE items", "ALTER TABLE items CHANGE COLUMN id id int(11) NULL DEFAULT 5"]
|
|
549
|
+
@db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NULL DEFAULT 5"]
|
|
530
550
|
@db[:items].insert
|
|
531
551
|
@db[:items].all.should == [{:id=>5}]
|
|
532
552
|
proc{@db[:items].insert(:id=>nil)}.should_not
|
|
533
553
|
end
|
|
534
|
-
|
|
554
|
+
|
|
535
555
|
specify "should accept repeated raw sql statements using Database#<<" do
|
|
536
556
|
@db.create_table(:items){String :name; Integer :value}
|
|
537
557
|
@db << 'DELETE FROM items'
|
|
538
558
|
@db[:items].count.should == 0
|
|
539
|
-
|
|
559
|
+
|
|
540
560
|
@db << "INSERT INTO items (name, value) VALUES ('tutu', 1234)"
|
|
541
561
|
@db[:items].first.should == {:name => 'tutu', :value => 1234}
|
|
542
|
-
|
|
562
|
+
|
|
543
563
|
@db << 'DELETE FROM items'
|
|
544
564
|
@db[:items].first.should == nil
|
|
545
565
|
end
|
|
@@ -552,12 +572,12 @@ if %w'localhost 127.0.0.1 ::1'.include?(MYSQL_URI.host) and MYSQL_DB.adapter_sch
|
|
|
552
572
|
db = Sequel.mysql(MYSQL_DB.opts[:database], :host => 'localhost', :user => MYSQL_DB.opts[:user], :password => MYSQL_DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
|
|
553
573
|
proc {db.test_connection}.should_not raise_error
|
|
554
574
|
end
|
|
555
|
-
|
|
575
|
+
|
|
556
576
|
specify "should accept a socket option without host option" do
|
|
557
577
|
db = Sequel.mysql(MYSQL_DB.opts[:database], :user => MYSQL_DB.opts[:user], :password => MYSQL_DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
|
|
558
578
|
proc {db.test_connection}.should_not raise_error
|
|
559
579
|
end
|
|
560
|
-
|
|
580
|
+
|
|
561
581
|
specify "should fail to connect with invalid socket" do
|
|
562
582
|
db = Sequel.mysql(MYSQL_DB.opts[:database], :user => MYSQL_DB.opts[:user], :password => MYSQL_DB.opts[:password], :socket =>'blah')
|
|
563
583
|
proc {db.test_connection}.should raise_error
|
|
@@ -577,9 +597,58 @@ describe "A MySQL database" do
|
|
|
577
597
|
end
|
|
578
598
|
end
|
|
579
599
|
|
|
600
|
+
describe "MySQL foreign key support" do
|
|
601
|
+
after do
|
|
602
|
+
MYSQL_DB.drop_table?(:testfk, :testpk)
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
specify "should create table without :key" do
|
|
606
|
+
MYSQL_DB.create_table!(:testpk){primary_key :id}
|
|
607
|
+
MYSQL_DB.create_table!(:testfk){foreign_key :fk, :testpk}
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
specify "should create table with composite keys without :key" do
|
|
611
|
+
MYSQL_DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
|
|
612
|
+
MYSQL_DB.create_table!(:testfk){Integer :fk; Integer :fk2; foreign_key([:fk, :fk2], :testpk)}
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
specify "should create table with self referential without :key" do
|
|
616
|
+
MYSQL_DB.create_table!(:testfk){primary_key :id; foreign_key :fk, :testfk}
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
specify "should create table with self referential with composite keys without :key" do
|
|
620
|
+
MYSQL_DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2]); foreign_key([:fk, :fk2], :testfk)}
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
specify "should alter table without :key" do
|
|
624
|
+
MYSQL_DB.create_table!(:testpk){primary_key :id}
|
|
625
|
+
MYSQL_DB.create_table!(:testfk){Integer :id}
|
|
626
|
+
MYSQL_DB.alter_table(:testfk){add_foreign_key :fk, :testpk}
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
specify "should alter table with composite keys without :key" do
|
|
630
|
+
MYSQL_DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
|
|
631
|
+
MYSQL_DB.create_table!(:testfk){Integer :fk; Integer :fk2}
|
|
632
|
+
MYSQL_DB.alter_table(:testfk){add_foreign_key([:fk, :fk2], :testpk)}
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
specify "should alter table with self referential without :key" do
|
|
636
|
+
MYSQL_DB.create_table!(:testfk){primary_key :id}
|
|
637
|
+
MYSQL_DB.alter_table(:testfk){add_foreign_key :fk, :testfk}
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
specify "should alter table with self referential with composite keys without :key" do
|
|
641
|
+
MYSQL_DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2])}
|
|
642
|
+
MYSQL_DB.alter_table(:testfk){add_foreign_key [:fk, :fk2], :testfk}
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
|
|
580
646
|
describe "A grouped MySQL dataset" do
|
|
581
647
|
before do
|
|
582
|
-
MYSQL_DB
|
|
648
|
+
MYSQL_DB.create_table! :test2 do
|
|
649
|
+
text :name
|
|
650
|
+
integer :value
|
|
651
|
+
end
|
|
583
652
|
MYSQL_DB[:test2] << {:name => '11', :value => 10}
|
|
584
653
|
MYSQL_DB[:test2] << {:name => '11', :value => 20}
|
|
585
654
|
MYSQL_DB[:test2] << {:name => '11', :value => 30}
|
|
@@ -587,12 +656,15 @@ describe "A grouped MySQL dataset" do
|
|
|
587
656
|
MYSQL_DB[:test2] << {:name => '12', :value => 20}
|
|
588
657
|
MYSQL_DB[:test2] << {:name => '13', :value => 10}
|
|
589
658
|
end
|
|
590
|
-
|
|
659
|
+
after do
|
|
660
|
+
MYSQL_DB.drop_table?(:test2)
|
|
661
|
+
end
|
|
662
|
+
|
|
591
663
|
specify "should return the correct count for raw sql query" do
|
|
592
664
|
ds = MYSQL_DB["select name FROM test2 WHERE name = '11' GROUP BY name"]
|
|
593
665
|
ds.count.should == 1
|
|
594
666
|
end
|
|
595
|
-
|
|
667
|
+
|
|
596
668
|
specify "should return the correct count for a normal dataset" do
|
|
597
669
|
ds = MYSQL_DB[:test2].select(:name).where(:name => '11').group(:name)
|
|
598
670
|
ds.count.should == 1
|
|
@@ -602,21 +674,21 @@ end
|
|
|
602
674
|
describe "A MySQL database" do
|
|
603
675
|
before do
|
|
604
676
|
@db = MYSQL_DB
|
|
605
|
-
@db.drop_table(:posts)
|
|
677
|
+
@db.drop_table?(:posts)
|
|
606
678
|
@db.sqls.clear
|
|
607
679
|
end
|
|
608
680
|
after do
|
|
609
|
-
@db.drop_table(:posts)
|
|
681
|
+
@db.drop_table?(:posts)
|
|
610
682
|
end
|
|
611
|
-
|
|
683
|
+
|
|
612
684
|
specify "should support fulltext indexes and full_text_search" do
|
|
613
|
-
@db.create_table(:posts){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
|
|
685
|
+
@db.create_table(:posts, :engine=>:MyISAM){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
|
|
614
686
|
@db.sqls.should == [
|
|
615
|
-
"CREATE TABLE posts (title text, body text)",
|
|
616
|
-
"CREATE FULLTEXT INDEX posts_title_index ON posts (title)",
|
|
617
|
-
"CREATE FULLTEXT INDEX posts_title_body_index ON posts (title
|
|
687
|
+
"CREATE TABLE `posts` (`title` text, `body` text) ENGINE=MyISAM",
|
|
688
|
+
"CREATE FULLTEXT INDEX `posts_title_index` ON `posts` (`title`)",
|
|
689
|
+
"CREATE FULLTEXT INDEX `posts_title_body_index` ON `posts` (`title`, `body`)"
|
|
618
690
|
]
|
|
619
|
-
|
|
691
|
+
|
|
620
692
|
@db[:posts].insert(:title=>'ruby rails', :body=>'y')
|
|
621
693
|
@db[:posts].insert(:title=>'sequel', :body=>'ruby')
|
|
622
694
|
@db[:posts].insert(:title=>'ruby scooby', :body=>'x')
|
|
@@ -626,32 +698,35 @@ describe "A MySQL database" do
|
|
|
626
698
|
@db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.should == [{:title=>'sequel', :body=>'ruby'}]
|
|
627
699
|
@db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.should == [{:title=>'ruby scooby', :body=>'x'}]
|
|
628
700
|
@db.sqls.should == [
|
|
629
|
-
"SELECT * FROM posts WHERE (MATCH (title) AGAINST ('rails'))",
|
|
630
|
-
"SELECT * FROM posts WHERE (MATCH (title
|
|
631
|
-
"SELECT * FROM posts WHERE (MATCH (title) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
|
|
701
|
+
"SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('rails'))",
|
|
702
|
+
"SELECT * FROM `posts` WHERE (MATCH (`title`, `body`) AGAINST ('sequel ruby'))",
|
|
703
|
+
"SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
|
|
704
|
+
|
|
705
|
+
@db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
|
|
706
|
+
@db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
|
|
632
707
|
end
|
|
633
708
|
|
|
634
709
|
specify "should support spatial indexes" do
|
|
635
|
-
@db.create_table(:posts){point :geom, :null=>false; spatial_index [:geom]}
|
|
710
|
+
@db.create_table(:posts, :engine=>:MyISAM){point :geom, :null=>false; spatial_index [:geom]}
|
|
636
711
|
@db.sqls.should == [
|
|
637
|
-
"CREATE TABLE posts (geom point NOT NULL)",
|
|
638
|
-
"CREATE SPATIAL INDEX posts_geom_index ON posts (geom)"
|
|
712
|
+
"CREATE TABLE `posts` (`geom` point NOT NULL) ENGINE=MyISAM",
|
|
713
|
+
"CREATE SPATIAL INDEX `posts_geom_index` ON `posts` (`geom`)"
|
|
639
714
|
]
|
|
640
715
|
end
|
|
641
716
|
|
|
642
717
|
specify "should support indexes with index type" do
|
|
643
718
|
@db.create_table(:posts){Integer :id; index :id, :type => :btree}
|
|
644
719
|
@db.sqls.should == [
|
|
645
|
-
"CREATE TABLE posts (id integer)",
|
|
646
|
-
"CREATE INDEX posts_id_index USING btree ON posts (id)"
|
|
720
|
+
"CREATE TABLE `posts` (`id` integer)",
|
|
721
|
+
"CREATE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
|
|
647
722
|
]
|
|
648
723
|
end
|
|
649
724
|
|
|
650
725
|
specify "should support unique indexes with index type" do
|
|
651
726
|
@db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
|
|
652
727
|
@db.sqls.should == [
|
|
653
|
-
"CREATE TABLE posts (id integer)",
|
|
654
|
-
"CREATE UNIQUE INDEX posts_id_index USING btree ON posts (id)"
|
|
728
|
+
"CREATE TABLE `posts` (`id` integer)",
|
|
729
|
+
"CREATE UNIQUE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
|
|
655
730
|
]
|
|
656
731
|
end
|
|
657
732
|
|
|
@@ -675,43 +750,25 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
675
750
|
MYSQL_DB.sqls.clear
|
|
676
751
|
end
|
|
677
752
|
after do
|
|
678
|
-
MYSQL_DB.drop_table(:items)
|
|
753
|
+
MYSQL_DB.drop_table?(:items)
|
|
679
754
|
end
|
|
680
755
|
|
|
681
756
|
specify "#insert should insert record with default values when no arguments given" do
|
|
682
757
|
@d.insert
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
"INSERT INTO items () VALUES ()"
|
|
686
|
-
]
|
|
687
|
-
|
|
688
|
-
@d.all.should == [
|
|
689
|
-
{:name => nil, :value => nil}
|
|
690
|
-
]
|
|
758
|
+
MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
|
|
759
|
+
@d.all.should == [{:name => nil, :value => nil}]
|
|
691
760
|
end
|
|
692
761
|
|
|
693
762
|
specify "#insert should insert record with default values when empty hash given" do
|
|
694
763
|
@d.insert({})
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
"INSERT INTO items () VALUES ()"
|
|
698
|
-
]
|
|
699
|
-
|
|
700
|
-
@d.all.should == [
|
|
701
|
-
{:name => nil, :value => nil}
|
|
702
|
-
]
|
|
764
|
+
MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
|
|
765
|
+
@d.all.should == [{:name => nil, :value => nil}]
|
|
703
766
|
end
|
|
704
767
|
|
|
705
768
|
specify "#insert should insert record with default values when empty array given" do
|
|
706
769
|
@d.insert []
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
"INSERT INTO items () VALUES ()"
|
|
710
|
-
]
|
|
711
|
-
|
|
712
|
-
@d.all.should == [
|
|
713
|
-
{:name => nil, :value => nil}
|
|
714
|
-
]
|
|
770
|
+
MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
|
|
771
|
+
@d.all.should == [{:name => nil, :value => nil}]
|
|
715
772
|
end
|
|
716
773
|
|
|
717
774
|
specify "#on_duplicate_key_update should work with regular inserts" do
|
|
@@ -722,19 +779,75 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
722
779
|
@d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'def', :value => 2)
|
|
723
780
|
|
|
724
781
|
MYSQL_DB.sqls.length.should == 3
|
|
725
|
-
MYSQL_DB.sqls[0].should =~ /\AINSERT INTO items \((name|value)
|
|
726
|
-
MYSQL_DB.sqls[1].should =~ /\AINSERT INTO items \((name|value)
|
|
727
|
-
MYSQL_DB.sqls[2].should =~ /\AINSERT INTO items \((name|value)
|
|
782
|
+
MYSQL_DB.sqls[0].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\)\z/
|
|
783
|
+
MYSQL_DB.sqls[1].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/
|
|
784
|
+
MYSQL_DB.sqls[2].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('def'|2), (2|'def')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/
|
|
728
785
|
|
|
729
786
|
@d.all.should == [{:name => 'abc', :value => 6}, {:name => 'def', :value => 2}]
|
|
730
787
|
end
|
|
731
788
|
|
|
789
|
+
specify "#multi_replace should insert multiple records in a single statement" do
|
|
790
|
+
@d.multi_replace([{:name => 'abc'}, {:name => 'def'}])
|
|
791
|
+
|
|
792
|
+
MYSQL_DB.sqls.should == [
|
|
793
|
+
SQL_BEGIN,
|
|
794
|
+
"REPLACE INTO `items` (`name`) VALUES ('abc'), ('def')",
|
|
795
|
+
SQL_COMMIT
|
|
796
|
+
]
|
|
797
|
+
|
|
798
|
+
@d.all.should == [
|
|
799
|
+
{:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
|
|
800
|
+
]
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
specify "#multi_replace should split the list of records into batches if :commit_every option is given" do
|
|
804
|
+
@d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
|
|
805
|
+
:commit_every => 2)
|
|
806
|
+
|
|
807
|
+
MYSQL_DB.sqls.should == [
|
|
808
|
+
SQL_BEGIN,
|
|
809
|
+
"REPLACE INTO `items` (`value`) VALUES (1), (2)",
|
|
810
|
+
SQL_COMMIT,
|
|
811
|
+
SQL_BEGIN,
|
|
812
|
+
"REPLACE INTO `items` (`value`) VALUES (3), (4)",
|
|
813
|
+
SQL_COMMIT
|
|
814
|
+
]
|
|
815
|
+
|
|
816
|
+
@d.all.should == [
|
|
817
|
+
{:name => nil, :value => 1},
|
|
818
|
+
{:name => nil, :value => 2},
|
|
819
|
+
{:name => nil, :value => 3},
|
|
820
|
+
{:name => nil, :value => 4}
|
|
821
|
+
]
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
specify "#multi_replace should split the list of records into batches if :slice option is given" do
|
|
825
|
+
@d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
|
|
826
|
+
:slice => 2)
|
|
827
|
+
|
|
828
|
+
MYSQL_DB.sqls.should == [
|
|
829
|
+
SQL_BEGIN,
|
|
830
|
+
"REPLACE INTO `items` (`value`) VALUES (1), (2)",
|
|
831
|
+
SQL_COMMIT,
|
|
832
|
+
SQL_BEGIN,
|
|
833
|
+
"REPLACE INTO `items` (`value`) VALUES (3), (4)",
|
|
834
|
+
SQL_COMMIT
|
|
835
|
+
]
|
|
836
|
+
|
|
837
|
+
@d.all.should == [
|
|
838
|
+
{:name => nil, :value => 1},
|
|
839
|
+
{:name => nil, :value => 2},
|
|
840
|
+
{:name => nil, :value => 3},
|
|
841
|
+
{:name => nil, :value => 4}
|
|
842
|
+
]
|
|
843
|
+
end
|
|
844
|
+
|
|
732
845
|
specify "#multi_insert should insert multiple records in a single statement" do
|
|
733
846
|
@d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
|
|
734
|
-
|
|
847
|
+
|
|
735
848
|
MYSQL_DB.sqls.should == [
|
|
736
849
|
SQL_BEGIN,
|
|
737
|
-
"INSERT INTO items (name) VALUES ('abc'), ('def')",
|
|
850
|
+
"INSERT INTO `items` (`name`) VALUES ('abc'), ('def')",
|
|
738
851
|
SQL_COMMIT
|
|
739
852
|
]
|
|
740
853
|
|
|
@@ -749,13 +862,13 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
749
862
|
|
|
750
863
|
MYSQL_DB.sqls.should == [
|
|
751
864
|
SQL_BEGIN,
|
|
752
|
-
"INSERT INTO items (value) VALUES (1), (2)",
|
|
865
|
+
"INSERT INTO `items` (`value`) VALUES (1), (2)",
|
|
753
866
|
SQL_COMMIT,
|
|
754
867
|
SQL_BEGIN,
|
|
755
|
-
"INSERT INTO items (value) VALUES (3), (4)",
|
|
868
|
+
"INSERT INTO `items` (`value`) VALUES (3), (4)",
|
|
756
869
|
SQL_COMMIT
|
|
757
870
|
]
|
|
758
|
-
|
|
871
|
+
|
|
759
872
|
@d.all.should == [
|
|
760
873
|
{:name => nil, :value => 1},
|
|
761
874
|
{:name => nil, :value => 2},
|
|
@@ -770,13 +883,13 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
770
883
|
|
|
771
884
|
MYSQL_DB.sqls.should == [
|
|
772
885
|
SQL_BEGIN,
|
|
773
|
-
"INSERT INTO items (value) VALUES (1), (2)",
|
|
886
|
+
"INSERT INTO `items` (`value`) VALUES (1), (2)",
|
|
774
887
|
SQL_COMMIT,
|
|
775
888
|
SQL_BEGIN,
|
|
776
|
-
"INSERT INTO items (value) VALUES (3), (4)",
|
|
889
|
+
"INSERT INTO `items` (`value`) VALUES (3), (4)",
|
|
777
890
|
SQL_COMMIT
|
|
778
891
|
]
|
|
779
|
-
|
|
892
|
+
|
|
780
893
|
@d.all.should == [
|
|
781
894
|
{:name => nil, :value => 1},
|
|
782
895
|
{:name => nil, :value => 2},
|
|
@@ -784,28 +897,28 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
784
897
|
{:name => nil, :value => 4}
|
|
785
898
|
]
|
|
786
899
|
end
|
|
787
|
-
|
|
900
|
+
|
|
788
901
|
specify "#import should support inserting using columns and values arrays" do
|
|
789
902
|
@d.import([:name, :value], [['abc', 1], ['def', 2]])
|
|
790
903
|
|
|
791
904
|
MYSQL_DB.sqls.should == [
|
|
792
905
|
SQL_BEGIN,
|
|
793
|
-
"INSERT INTO items (name
|
|
906
|
+
"INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2)",
|
|
794
907
|
SQL_COMMIT
|
|
795
908
|
]
|
|
796
|
-
|
|
909
|
+
|
|
797
910
|
@d.all.should == [
|
|
798
911
|
{:name => 'abc', :value => 1},
|
|
799
912
|
{:name => 'def', :value => 2}
|
|
800
913
|
]
|
|
801
914
|
end
|
|
802
|
-
|
|
915
|
+
|
|
803
916
|
specify "#insert_ignore should add the IGNORE keyword when inserting" do
|
|
804
917
|
@d.insert_ignore.multi_insert([{:name => 'abc'}, {:name => 'def'}])
|
|
805
|
-
|
|
918
|
+
|
|
806
919
|
MYSQL_DB.sqls.should == [
|
|
807
920
|
SQL_BEGIN,
|
|
808
|
-
"INSERT IGNORE INTO items (name) VALUES ('abc'), ('def')",
|
|
921
|
+
"INSERT IGNORE INTO `items` (`name`) VALUES ('abc'), ('def')",
|
|
809
922
|
SQL_COMMIT
|
|
810
923
|
]
|
|
811
924
|
|
|
@@ -813,20 +926,20 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
813
926
|
{:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
|
|
814
927
|
]
|
|
815
928
|
end
|
|
816
|
-
|
|
929
|
+
|
|
817
930
|
specify "#insert_ignore should add the IGNORE keyword for single inserts" do
|
|
818
931
|
@d.insert_ignore.insert(:name => 'ghi')
|
|
819
|
-
MYSQL_DB.sqls.should == ["INSERT IGNORE INTO items (name) VALUES ('ghi')"]
|
|
932
|
+
MYSQL_DB.sqls.should == ["INSERT IGNORE INTO `items` (`name`) VALUES ('ghi')"]
|
|
820
933
|
@d.all.should == [{:name => 'ghi', :value => nil}]
|
|
821
934
|
end
|
|
822
|
-
|
|
935
|
+
|
|
823
936
|
specify "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and ALL columns when no args given" do
|
|
824
937
|
@d.on_duplicate_key_update.import([:name,:value], [['abc', 1], ['def',2]])
|
|
825
|
-
|
|
938
|
+
|
|
826
939
|
MYSQL_DB.sqls.should == [
|
|
827
|
-
"SELECT * FROM items LIMIT 1",
|
|
940
|
+
"SELECT * FROM `items` LIMIT 1",
|
|
828
941
|
SQL_BEGIN,
|
|
829
|
-
"INSERT INTO items (name
|
|
942
|
+
"INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `value`=VALUES(`value`)",
|
|
830
943
|
SQL_COMMIT
|
|
831
944
|
]
|
|
832
945
|
|
|
@@ -834,15 +947,15 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
834
947
|
{:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
|
|
835
948
|
]
|
|
836
949
|
end
|
|
837
|
-
|
|
950
|
+
|
|
838
951
|
specify "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and columns specified when args are given" do
|
|
839
952
|
@d.on_duplicate_key_update(:value).import([:name,:value],
|
|
840
953
|
[['abc', 1], ['def',2]]
|
|
841
954
|
)
|
|
842
|
-
|
|
955
|
+
|
|
843
956
|
MYSQL_DB.sqls.should == [
|
|
844
957
|
SQL_BEGIN,
|
|
845
|
-
"INSERT INTO items (name
|
|
958
|
+
"INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)",
|
|
846
959
|
SQL_COMMIT
|
|
847
960
|
]
|
|
848
961
|
|
|
@@ -850,7 +963,27 @@ describe "MySQL::Dataset#insert and related methods" do
|
|
|
850
963
|
{:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
|
|
851
964
|
]
|
|
852
965
|
end
|
|
853
|
-
|
|
966
|
+
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
describe "MySQL::Dataset#update and related methods" do
|
|
970
|
+
before do
|
|
971
|
+
MYSQL_DB.create_table(:items){String :name; Integer :value; index :name, :unique=>true}
|
|
972
|
+
@d = MYSQL_DB[:items]
|
|
973
|
+
end
|
|
974
|
+
after do
|
|
975
|
+
MYSQL_DB.drop_table?(:items)
|
|
976
|
+
end
|
|
977
|
+
|
|
978
|
+
specify "#update_ignore should not raise error where normal update would fail" do
|
|
979
|
+
@d.insert(:name => 'cow', :value => 0)
|
|
980
|
+
@d.insert(:name => 'cat', :value => 1)
|
|
981
|
+
proc{@d.where(:value => 1).update(:name => 'cow')}.should raise_error(Sequel::DatabaseError)
|
|
982
|
+
MYSQL_DB.sqls.clear
|
|
983
|
+
@d.update_ignore.where(:value => 1).update(:name => 'cow')
|
|
984
|
+
MYSQL_DB.sqls.should == ["UPDATE IGNORE `items` SET `name` = 'cow' WHERE (`value` = 1)"]
|
|
985
|
+
@d.order(:name).all.should == [{:name => 'cat', :value => 1}, {:name => 'cow', :value => 0}]
|
|
986
|
+
end
|
|
854
987
|
end
|
|
855
988
|
|
|
856
989
|
describe "MySQL::Dataset#replace" do
|
|
@@ -860,9 +993,9 @@ describe "MySQL::Dataset#replace" do
|
|
|
860
993
|
MYSQL_DB.sqls.clear
|
|
861
994
|
end
|
|
862
995
|
after do
|
|
863
|
-
MYSQL_DB.drop_table(:items)
|
|
996
|
+
MYSQL_DB.drop_table?(:items)
|
|
864
997
|
end
|
|
865
|
-
|
|
998
|
+
|
|
866
999
|
specify "should use default values if they exist" do
|
|
867
1000
|
MYSQL_DB.alter_table(:items){set_column_default :id, 1; set_column_default :value, 2}
|
|
868
1001
|
@d.replace
|
|
@@ -872,7 +1005,7 @@ describe "MySQL::Dataset#replace" do
|
|
|
872
1005
|
@d.replace({})
|
|
873
1006
|
@d.all.should == [{:id=>1, :value=>2}]
|
|
874
1007
|
end
|
|
875
|
-
|
|
1008
|
+
|
|
876
1009
|
specify "should use support arrays, datasets, and multiple values" do
|
|
877
1010
|
@d.replace([1, 2])
|
|
878
1011
|
@d.all.should == [{:id=>1, :value=>2}]
|
|
@@ -881,12 +1014,12 @@ describe "MySQL::Dataset#replace" do
|
|
|
881
1014
|
@d.replace(@d)
|
|
882
1015
|
@d.all.should == [{:id=>1, :value=>2}]
|
|
883
1016
|
end
|
|
884
|
-
|
|
1017
|
+
|
|
885
1018
|
specify "should create a record if the condition is not met" do
|
|
886
1019
|
@d.replace(:id => 111, :value => 333)
|
|
887
1020
|
@d.all.should == [{:id => 111, :value => 333}]
|
|
888
1021
|
end
|
|
889
|
-
|
|
1022
|
+
|
|
890
1023
|
specify "should update a record if the condition is met" do
|
|
891
1024
|
@d << {:id => 111}
|
|
892
1025
|
@d.all.should == [{:id => 111, :value => nil}]
|
|
@@ -901,25 +1034,25 @@ describe "MySQL::Dataset#complex_expression_sql" do
|
|
|
901
1034
|
end
|
|
902
1035
|
|
|
903
1036
|
specify "should handle pattern matches correctly" do
|
|
904
|
-
@d.literal(:x.like('a')).should == "(x LIKE BINARY 'a')"
|
|
905
|
-
@d.literal(
|
|
906
|
-
@d.literal(:x.ilike('a')).should == "(x LIKE 'a')"
|
|
907
|
-
@d.literal(
|
|
908
|
-
@d.literal(:x.like(/a/)).should == "(x REGEXP BINARY 'a')"
|
|
909
|
-
@d.literal(
|
|
910
|
-
@d.literal(:x.like(/a/i)).should == "(x REGEXP 'a')"
|
|
911
|
-
@d.literal(
|
|
1037
|
+
@d.literal(Sequel.expr(:x).like('a')).should == "(`x` LIKE BINARY 'a')"
|
|
1038
|
+
@d.literal(~Sequel.expr(:x).like('a')).should == "(`x` NOT LIKE BINARY 'a')"
|
|
1039
|
+
@d.literal(Sequel.expr(:x).ilike('a')).should == "(`x` LIKE 'a')"
|
|
1040
|
+
@d.literal(~Sequel.expr(:x).ilike('a')).should == "(`x` NOT LIKE 'a')"
|
|
1041
|
+
@d.literal(Sequel.expr(:x).like(/a/)).should == "(`x` REGEXP BINARY 'a')"
|
|
1042
|
+
@d.literal(~Sequel.expr(:x).like(/a/)).should == "(`x` NOT REGEXP BINARY 'a')"
|
|
1043
|
+
@d.literal(Sequel.expr(:x).like(/a/i)).should == "(`x` REGEXP 'a')"
|
|
1044
|
+
@d.literal(~Sequel.expr(:x).like(/a/i)).should == "(`x` NOT REGEXP 'a')"
|
|
912
1045
|
end
|
|
913
1046
|
|
|
914
1047
|
specify "should handle string concatenation with CONCAT if more than one record" do
|
|
915
|
-
@d.literal([:x, :y]
|
|
916
|
-
@d.literal([:x, :y]
|
|
917
|
-
@d.literal([
|
|
1048
|
+
@d.literal(Sequel.join([:x, :y])).should == "CONCAT(`x`, `y`)"
|
|
1049
|
+
@d.literal(Sequel.join([:x, :y], ' ')).should == "CONCAT(`x`, ' ', `y`)"
|
|
1050
|
+
@d.literal(Sequel.join([Sequel.function(:x, :y), 1, Sequel.lit('z')], Sequel.subscript(:y, 1))).should == "CONCAT(x(`y`), `y`[1], '1', `y`[1], z)"
|
|
918
1051
|
end
|
|
919
1052
|
|
|
920
1053
|
specify "should handle string concatenation as simple string if just one record" do
|
|
921
|
-
@d.literal([:x]
|
|
922
|
-
@d.literal([:x]
|
|
1054
|
+
@d.literal(Sequel.join([:x])).should == "`x`"
|
|
1055
|
+
@d.literal(Sequel.join([:x], ' ')).should == "`x`"
|
|
923
1056
|
end
|
|
924
1057
|
end
|
|
925
1058
|
|
|
@@ -928,12 +1061,12 @@ describe "MySQL::Dataset#calc_found_rows" do
|
|
|
928
1061
|
MYSQL_DB.create_table!(:items){Integer :a}
|
|
929
1062
|
end
|
|
930
1063
|
after do
|
|
931
|
-
MYSQL_DB.drop_table(:items)
|
|
1064
|
+
MYSQL_DB.drop_table?(:items)
|
|
932
1065
|
end
|
|
933
1066
|
|
|
934
1067
|
specify "should add the SQL_CALC_FOUND_ROWS keyword when selecting" do
|
|
935
1068
|
MYSQL_DB[:items].select(:a).calc_found_rows.limit(1).sql.should == \
|
|
936
|
-
'SELECT SQL_CALC_FOUND_ROWS a FROM items LIMIT 1'
|
|
1069
|
+
'SELECT SQL_CALC_FOUND_ROWS `a` FROM `items` LIMIT 1'
|
|
937
1070
|
end
|
|
938
1071
|
|
|
939
1072
|
specify "should count matching rows disregarding LIMIT clause" do
|
|
@@ -941,16 +1074,16 @@ describe "MySQL::Dataset#calc_found_rows" do
|
|
|
941
1074
|
MYSQL_DB.sqls.clear
|
|
942
1075
|
|
|
943
1076
|
MYSQL_DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.should == [{:a => 1}]
|
|
944
|
-
MYSQL_DB.dataset.select(:FOUND_ROWS.
|
|
1077
|
+
MYSQL_DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.should == [{:rows => 2 }]
|
|
945
1078
|
|
|
946
1079
|
MYSQL_DB.sqls.should == [
|
|
947
|
-
'SELECT SQL_CALC_FOUND_ROWS * FROM items WHERE (a = 1) LIMIT 1',
|
|
948
|
-
'SELECT FOUND_ROWS() AS rows',
|
|
1080
|
+
'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',
|
|
1081
|
+
'SELECT FOUND_ROWS() AS `rows`',
|
|
949
1082
|
]
|
|
950
1083
|
end
|
|
951
1084
|
end
|
|
952
1085
|
|
|
953
|
-
if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
|
|
1086
|
+
if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc or MYSQL_DB.adapter_scheme == :mysql2
|
|
954
1087
|
describe "MySQL Stored Procedures" do
|
|
955
1088
|
before do
|
|
956
1089
|
MYSQL_DB.create_table(:items){Integer :id; Integer :value}
|
|
@@ -958,10 +1091,10 @@ if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
|
|
|
958
1091
|
MYSQL_DB.sqls.clear
|
|
959
1092
|
end
|
|
960
1093
|
after do
|
|
961
|
-
MYSQL_DB.drop_table(:items)
|
|
1094
|
+
MYSQL_DB.drop_table?(:items)
|
|
962
1095
|
MYSQL_DB.execute('DROP PROCEDURE test_sproc')
|
|
963
1096
|
end
|
|
964
|
-
|
|
1097
|
+
|
|
965
1098
|
specify "should be callable on the database object" do
|
|
966
1099
|
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc() BEGIN DELETE FROM items; END')
|
|
967
1100
|
MYSQL_DB[:items].delete
|
|
@@ -970,27 +1103,38 @@ if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
|
|
|
970
1103
|
MYSQL_DB.call_sproc(:test_sproc)
|
|
971
1104
|
MYSQL_DB[:items].count.should == 0
|
|
972
1105
|
end
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1106
|
+
|
|
1107
|
+
# Mysql2 doesn't support stored procedures that return result sets, probably because
|
|
1108
|
+
# CLIENT_MULTI_RESULTS is not set.
|
|
1109
|
+
unless MYSQL_DB.adapter_scheme == :mysql2
|
|
1110
|
+
specify "should be callable on the dataset object" do
|
|
1111
|
+
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
|
|
1112
|
+
MYSQL_DB[:items].delete
|
|
1113
|
+
@d = MYSQL_DB[:items]
|
|
1114
|
+
@d.call_sproc(:select, :test_sproc, 3).should == []
|
|
1115
|
+
@d.insert(:value=>1)
|
|
1116
|
+
@d.call_sproc(:select, :test_sproc, 4).should == [{:id=>nil, :value=>1, :b=>4}]
|
|
1117
|
+
@d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
|
|
1118
|
+
@d.call_sproc(:select, :test_sproc, 3).should == [{:id=>nil, :value=>2, :b=>6}]
|
|
1119
|
+
end
|
|
1120
|
+
|
|
1121
|
+
specify "should be callable on the dataset object with multiple arguments" do
|
|
1122
|
+
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
|
|
1123
|
+
MYSQL_DB[:items].delete
|
|
1124
|
+
@d = MYSQL_DB[:items]
|
|
1125
|
+
@d.call_sproc(:select, :test_sproc, 3, 4).should == []
|
|
1126
|
+
@d.insert(:value=>1)
|
|
1127
|
+
@d.call_sproc(:select, :test_sproc, 4, 5).should == [{:id=>nil, :value=>1, :b=>4, :d=>5}]
|
|
1128
|
+
@d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
|
|
1129
|
+
@d.call_sproc(:select, :test_sproc, 3, 4).should == [{:id=>nil, :value=>2, :b=>6, :d => 8}]
|
|
1130
|
+
end
|
|
983
1131
|
end
|
|
984
|
-
|
|
985
|
-
specify "should
|
|
986
|
-
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(
|
|
1132
|
+
|
|
1133
|
+
specify "should deal with nil values" do
|
|
1134
|
+
MYSQL_DB.execute_ddl('CREATE PROCEDURE test_sproc(i INTEGER, v INTEGER) BEGIN INSERT INTO items VALUES (i, v); END')
|
|
987
1135
|
MYSQL_DB[:items].delete
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
@d.insert(:value=>1)
|
|
991
|
-
@d.call_sproc(:select, :test_sproc, 4, 5).should == [{:id=>nil, :value=>1, :b=>4, :d=>5}]
|
|
992
|
-
@d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
|
|
993
|
-
@d.call_sproc(:select, :test_sproc, 3, 4).should == [{:id=>nil, :value=>2, :b=>6, :d => 8}]
|
|
1136
|
+
MYSQL_DB.call_sproc(:test_sproc, :args=>[1, nil])
|
|
1137
|
+
MYSQL_DB[:items].all.should == [{:id=>1, :value=>nil}]
|
|
994
1138
|
end
|
|
995
1139
|
end
|
|
996
1140
|
end
|
|
@@ -998,35 +1142,35 @@ end
|
|
|
998
1142
|
if MYSQL_DB.adapter_scheme == :mysql
|
|
999
1143
|
describe "MySQL bad date/time conversions" do
|
|
1000
1144
|
after do
|
|
1001
|
-
|
|
1145
|
+
MYSQL_DB.convert_invalid_date_time = false
|
|
1002
1146
|
end
|
|
1003
|
-
|
|
1147
|
+
|
|
1004
1148
|
specify "should raise an exception when a bad date/time is used and convert_invalid_date_time is false" do
|
|
1005
|
-
|
|
1149
|
+
MYSQL_DB.convert_invalid_date_time = false
|
|
1006
1150
|
proc{MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value}.should raise_error(Sequel::InvalidValue)
|
|
1007
1151
|
proc{MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.should raise_error(Sequel::InvalidValue)
|
|
1008
1152
|
proc{MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value}.should raise_error(Sequel::InvalidValue)
|
|
1009
1153
|
end
|
|
1010
|
-
|
|
1154
|
+
|
|
1011
1155
|
specify "should not use a nil value bad date/time is used and convert_invalid_date_time is nil or :nil" do
|
|
1012
|
-
|
|
1156
|
+
MYSQL_DB.convert_invalid_date_time = nil
|
|
1013
1157
|
MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == nil
|
|
1014
1158
|
MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == nil
|
|
1015
1159
|
MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == nil
|
|
1016
|
-
|
|
1160
|
+
MYSQL_DB.convert_invalid_date_time = :nil
|
|
1017
1161
|
MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == nil
|
|
1018
1162
|
MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == nil
|
|
1019
1163
|
MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == nil
|
|
1020
1164
|
end
|
|
1021
|
-
|
|
1165
|
+
|
|
1022
1166
|
specify "should not use a nil value bad date/time is used and convert_invalid_date_time is :string" do
|
|
1023
|
-
|
|
1167
|
+
MYSQL_DB.convert_invalid_date_time = :string
|
|
1024
1168
|
MYSQL_DB["SELECT CAST('0000-00-00' AS date)"].single_value.should == '0000-00-00'
|
|
1025
1169
|
MYSQL_DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.should == '0000-00-00 00:00:00'
|
|
1026
1170
|
MYSQL_DB["SELECT CAST('25:00:00' AS time)"].single_value.should == '25:00:00'
|
|
1027
1171
|
end
|
|
1028
1172
|
end
|
|
1029
|
-
|
|
1173
|
+
|
|
1030
1174
|
describe "MySQL multiple result sets" do
|
|
1031
1175
|
before do
|
|
1032
1176
|
MYSQL_DB.create_table!(:a){Integer :a}
|
|
@@ -1038,43 +1182,68 @@ if MYSQL_DB.adapter_scheme == :mysql
|
|
|
1038
1182
|
MYSQL_DB[:b].insert(25)
|
|
1039
1183
|
end
|
|
1040
1184
|
after do
|
|
1041
|
-
MYSQL_DB.drop_table(:a, :b)
|
|
1185
|
+
MYSQL_DB.drop_table?(:a, :b)
|
|
1042
1186
|
end
|
|
1043
|
-
|
|
1187
|
+
|
|
1044
1188
|
specify "should combine all results by default" do
|
|
1045
1189
|
@ds.all.should == [{:a=>10}, {:a=>15}, {:b=>20}, {:b=>25}]
|
|
1046
1190
|
end
|
|
1047
|
-
|
|
1191
|
+
|
|
1048
1192
|
specify "should work with Database#run" do
|
|
1049
1193
|
proc{MYSQL_DB.run('SELECT * FROM a; SELECT * FROM b')}.should_not raise_error
|
|
1050
1194
|
proc{MYSQL_DB.run('SELECT * FROM a; SELECT * FROM b')}.should_not raise_error
|
|
1051
1195
|
end
|
|
1052
|
-
|
|
1196
|
+
|
|
1053
1197
|
specify "should work with Database#run and other statements" do
|
|
1054
1198
|
proc{MYSQL_DB.run('UPDATE a SET a = 1; SELECT * FROM a; DELETE FROM b')}.should_not raise_error
|
|
1055
1199
|
MYSQL_DB[:a].select_order_map(:a).should == [1, 1]
|
|
1056
1200
|
MYSQL_DB[:b].all.should == []
|
|
1057
1201
|
end
|
|
1058
|
-
|
|
1202
|
+
|
|
1059
1203
|
specify "should split results returned into arrays if split_multiple_result_sets is used" do
|
|
1060
1204
|
@ds.split_multiple_result_sets.all.should == [[{:a=>10}, {:a=>15}], [{:b=>20}, {:b=>25}]]
|
|
1061
1205
|
end
|
|
1062
|
-
|
|
1206
|
+
|
|
1063
1207
|
specify "should have regular row_procs work when splitting multiple result sets" do
|
|
1064
1208
|
@ds.row_proc = proc{|x| x[x.keys.first] *= 2; x}
|
|
1065
1209
|
@ds.split_multiple_result_sets.all.should == [[{:a=>20}, {:a=>30}], [{:b=>40}, {:b=>50}]]
|
|
1066
1210
|
end
|
|
1067
|
-
|
|
1211
|
+
|
|
1068
1212
|
specify "should use the columns from the first result set when splitting result sets" do
|
|
1069
1213
|
@ds.split_multiple_result_sets.columns.should == [:a]
|
|
1070
1214
|
end
|
|
1071
|
-
|
|
1215
|
+
|
|
1072
1216
|
specify "should not allow graphing a dataset that splits multiple statements" do
|
|
1073
1217
|
proc{@ds.split_multiple_result_sets.graph(:b, :b=>:a)}.should raise_error(Sequel::Error)
|
|
1074
1218
|
end
|
|
1075
|
-
|
|
1219
|
+
|
|
1076
1220
|
specify "should not allow splitting a graphed dataset" do
|
|
1077
1221
|
proc{MYSQL_DB[:a].graph(:b, :b=>:a).split_multiple_result_sets}.should raise_error(Sequel::Error)
|
|
1078
1222
|
end
|
|
1079
1223
|
end
|
|
1080
1224
|
end
|
|
1225
|
+
|
|
1226
|
+
if MYSQL_DB.adapter_scheme == :mysql2
|
|
1227
|
+
describe "Mysql2 streaming" do
|
|
1228
|
+
before(:all) do
|
|
1229
|
+
MYSQL_DB.create_table!(:a){Integer :a}
|
|
1230
|
+
MYSQL_DB.transaction do
|
|
1231
|
+
1000.times do |i|
|
|
1232
|
+
MYSQL_DB[:a].insert(i)
|
|
1233
|
+
end
|
|
1234
|
+
end
|
|
1235
|
+
@ds = MYSQL_DB[:a].stream.order(:a)
|
|
1236
|
+
end
|
|
1237
|
+
after(:all) do
|
|
1238
|
+
MYSQL_DB.drop_table?(:a)
|
|
1239
|
+
end
|
|
1240
|
+
|
|
1241
|
+
specify "should correctly stream results" do
|
|
1242
|
+
@ds.map(:a).should == (0...1000).to_a
|
|
1243
|
+
end
|
|
1244
|
+
|
|
1245
|
+
specify "should correctly handle early returning when streaming results" do
|
|
1246
|
+
3.times{@ds.each{|r| break r[:a]}.should == 0}
|
|
1247
|
+
end
|
|
1248
|
+
end if false
|
|
1249
|
+
end
|