sequel 4.22.0 → 4.23.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.
- checksums.yaml +4 -4
- data/CHANGELOG +22 -0
- data/README.rdoc +6 -0
- data/Rakefile +59 -81
- data/doc/migration.rdoc +2 -0
- data/doc/release_notes/4.23.0.txt +65 -0
- data/doc/sharding.rdoc +16 -14
- data/doc/testing.rdoc +61 -77
- data/lib/sequel/adapters/jdbc.rb +1 -0
- data/lib/sequel/adapters/mock.rb +0 -1
- data/lib/sequel/adapters/postgres.rb +1 -0
- data/lib/sequel/adapters/postgresql.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +3 -3
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +9 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/transactions.rb +2 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +12 -12
- data/lib/sequel/extensions/date_arithmetic.rb +0 -4
- data/lib/sequel/extensions/pagination.rb +14 -2
- data/lib/sequel/extensions/pg_enum.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -0
- data/lib/sequel/plugins/delay_add_association.rb +50 -0
- data/lib/sequel/plugins/list.rb +2 -2
- data/lib/sequel/plugins/nested_attributes.rb +8 -28
- data/lib/sequel/plugins/update_refresh.rb +50 -0
- data/lib/sequel/plugins/validate_associated.rb +55 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +29 -29
- data/spec/adapters/firebird_spec.rb +97 -103
- data/spec/adapters/informix_spec.rb +25 -25
- data/spec/adapters/mssql_spec.rb +156 -172
- data/spec/adapters/mysql_spec.rb +334 -359
- data/spec/adapters/oracle_spec.rb +67 -69
- data/spec/adapters/postgres_spec.rb +1298 -1249
- data/spec/adapters/spec_helper.rb +2 -35
- data/spec/adapters/sqlanywhere_spec.rb +39 -39
- data/spec/adapters/sqlite_spec.rb +203 -200
- data/spec/bin_spec.rb +57 -59
- data/spec/core/connection_pool_spec.rb +402 -401
- data/spec/core/database_spec.rb +953 -944
- data/spec/core/dataset_spec.rb +2178 -2168
- data/spec/core/deprecated_spec.rb +19 -19
- data/spec/core/expression_filters_spec.rb +415 -415
- data/spec/core/mock_adapter_spec.rb +212 -212
- data/spec/core/object_graph_spec.rb +73 -73
- data/spec/core/placeholder_literalizer_spec.rb +71 -71
- data/spec/core/schema_generator_spec.rb +44 -44
- data/spec/core/schema_spec.rb +470 -472
- data/spec/core/spec_helper.rb +5 -20
- data/spec/core/version_spec.rb +2 -2
- data/spec/core_extensions_spec.rb +320 -320
- data/spec/extensions/accessed_columns_spec.rb +12 -12
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +2 -2
- data/spec/extensions/arbitrary_servers_spec.rb +23 -23
- data/spec/extensions/association_dependencies_spec.rb +34 -34
- data/spec/extensions/association_pks_spec.rb +98 -98
- data/spec/extensions/association_proxies_spec.rb +33 -33
- data/spec/extensions/auto_validations_spec.rb +46 -46
- data/spec/extensions/blacklist_security_spec.rb +19 -18
- data/spec/extensions/blank_spec.rb +36 -36
- data/spec/extensions/boolean_readers_spec.rb +36 -36
- data/spec/extensions/caching_spec.rb +82 -82
- data/spec/extensions/class_table_inheritance_spec.rb +72 -72
- data/spec/extensions/column_conflicts_spec.rb +19 -14
- data/spec/extensions/column_select_spec.rb +19 -19
- data/spec/extensions/columns_introspection_spec.rb +43 -43
- data/spec/extensions/composition_spec.rb +64 -64
- data/spec/extensions/connection_validator_spec.rb +92 -90
- data/spec/extensions/constraint_validations_plugin_spec.rb +92 -92
- data/spec/extensions/constraint_validations_spec.rb +80 -80
- data/spec/extensions/core_refinements_spec.rb +220 -220
- data/spec/extensions/csv_serializer_spec.rb +44 -44
- data/spec/extensions/current_datetime_timestamp_spec.rb +8 -8
- data/spec/extensions/dataset_associations_spec.rb +65 -65
- data/spec/extensions/dataset_source_alias_spec.rb +16 -16
- data/spec/extensions/date_arithmetic_spec.rb +51 -58
- data/spec/extensions/defaults_setter_spec.rb +19 -19
- data/spec/extensions/delay_add_association_spec.rb +52 -0
- data/spec/extensions/dirty_spec.rb +51 -51
- data/spec/extensions/eager_each_spec.rb +8 -8
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +10 -10
- data/spec/extensions/error_splitter_spec.rb +2 -2
- data/spec/extensions/error_sql_spec.rb +4 -4
- data/spec/extensions/eval_inspect_spec.rb +3 -3
- data/spec/extensions/filter_having_spec.rb +8 -8
- data/spec/extensions/force_encoding_spec.rb +30 -30
- data/spec/extensions/from_block_spec.rb +7 -7
- data/spec/extensions/graph_each_spec.rb +19 -19
- data/spec/extensions/hash_aliases_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +100 -100
- data/spec/extensions/inflector_spec.rb +54 -54
- data/spec/extensions/input_transformer_spec.rb +10 -10
- data/spec/extensions/insert_returning_select_spec.rb +8 -8
- data/spec/extensions/instance_filters_spec.rb +26 -26
- data/spec/extensions/instance_hooks_spec.rb +85 -85
- data/spec/extensions/json_serializer_spec.rb +68 -68
- data/spec/extensions/lazy_attributes_spec.rb +49 -49
- data/spec/extensions/list_spec.rb +77 -75
- data/spec/extensions/looser_typecasting_spec.rb +16 -16
- data/spec/extensions/many_through_many_spec.rb +627 -627
- data/spec/extensions/meta_def_spec.rb +7 -7
- data/spec/extensions/migration_spec.rb +217 -217
- data/spec/extensions/modification_detection_spec.rb +20 -20
- data/spec/extensions/mssql_optimistic_locking_spec.rb +21 -21
- data/spec/extensions/named_timezones_spec.rb +18 -18
- data/spec/extensions/nested_attributes_spec.rb +107 -107
- data/spec/extensions/null_dataset_spec.rb +24 -24
- data/spec/extensions/optimistic_locking_spec.rb +21 -21
- data/spec/extensions/pagination_spec.rb +52 -52
- data/spec/extensions/pg_array_associations_spec.rb +273 -273
- data/spec/extensions/pg_array_ops_spec.rb +52 -52
- data/spec/extensions/pg_array_spec.rb +152 -152
- data/spec/extensions/pg_enum_spec.rb +13 -13
- data/spec/extensions/pg_hstore_ops_spec.rb +63 -63
- data/spec/extensions/pg_hstore_spec.rb +84 -84
- data/spec/extensions/pg_inet_spec.rb +15 -15
- data/spec/extensions/pg_interval_spec.rb +29 -29
- data/spec/extensions/pg_json_ops_spec.rb +86 -84
- data/spec/extensions/pg_json_spec.rb +104 -104
- data/spec/extensions/pg_loose_count_spec.rb +6 -6
- data/spec/extensions/pg_range_ops_spec.rb +24 -24
- data/spec/extensions/pg_range_spec.rb +143 -143
- data/spec/extensions/pg_row_ops_spec.rb +14 -14
- data/spec/extensions/pg_row_plugin_spec.rb +12 -12
- data/spec/extensions/pg_row_spec.rb +118 -118
- data/spec/extensions/pg_static_cache_updater_spec.rb +28 -28
- data/spec/extensions/pg_typecast_on_load_spec.rb +21 -21
- data/spec/extensions/prepared_statements_associations_spec.rb +42 -42
- data/spec/extensions/prepared_statements_safe_spec.rb +18 -18
- data/spec/extensions/prepared_statements_spec.rb +28 -28
- data/spec/extensions/prepared_statements_with_pk_spec.rb +11 -11
- data/spec/extensions/pretty_table_spec.rb +16 -16
- data/spec/extensions/query_literals_spec.rb +37 -37
- data/spec/extensions/query_spec.rb +32 -32
- data/spec/extensions/rcte_tree_spec.rb +141 -141
- data/spec/extensions/round_timestamps_spec.rb +21 -21
- data/spec/extensions/schema_caching_spec.rb +8 -8
- data/spec/extensions/schema_dumper_spec.rb +78 -78
- data/spec/extensions/schema_spec.rb +31 -27
- data/spec/extensions/scissors_spec.rb +3 -3
- data/spec/extensions/select_remove_spec.rb +14 -14
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +28 -28
- data/spec/extensions/serialization_modification_detection_spec.rb +33 -33
- data/spec/extensions/serialization_spec.rb +79 -78
- data/spec/extensions/server_block_spec.rb +17 -17
- data/spec/extensions/set_overrides_spec.rb +30 -30
- data/spec/extensions/sharding_spec.rb +65 -65
- data/spec/extensions/shared_caching_spec.rb +29 -29
- data/spec/extensions/single_table_inheritance_spec.rb +79 -79
- data/spec/extensions/skip_create_refresh_spec.rb +3 -3
- data/spec/extensions/spec_helper.rb +4 -29
- data/spec/extensions/split_array_nil_spec.rb +9 -9
- data/spec/extensions/split_values_spec.rb +7 -7
- data/spec/extensions/sql_expr_spec.rb +32 -32
- data/spec/extensions/static_cache_spec.rb +123 -123
- data/spec/extensions/string_date_time_spec.rb +34 -34
- data/spec/extensions/string_stripper_spec.rb +15 -15
- data/spec/extensions/subclasses_spec.rb +31 -31
- data/spec/extensions/table_select_spec.rb +15 -15
- data/spec/extensions/tactical_eager_loading_spec.rb +23 -23
- data/spec/extensions/thread_local_timezones_spec.rb +13 -13
- data/spec/extensions/timestamps_spec.rb +40 -40
- data/spec/extensions/to_dot_spec.rb +34 -34
- data/spec/extensions/touch_spec.rb +52 -52
- data/spec/extensions/tree_spec.rb +72 -72
- data/spec/extensions/typecast_on_load_spec.rb +25 -25
- data/spec/extensions/unlimited_update_spec.rb +2 -2
- data/spec/extensions/update_or_create_spec.rb +36 -36
- data/spec/extensions/update_primary_key_spec.rb +35 -35
- data/spec/extensions/update_refresh_spec.rb +41 -0
- data/spec/extensions/validate_associated_spec.rb +52 -0
- data/spec/extensions/validation_class_methods_spec.rb +314 -317
- data/spec/extensions/validation_helpers_spec.rb +195 -195
- data/spec/extensions/xml_serializer_spec.rb +48 -48
- data/spec/guards_helper.rb +55 -0
- data/spec/integration/associations_test.rb +1089 -1088
- data/spec/integration/database_test.rb +29 -29
- data/spec/integration/dataset_test.rb +661 -661
- data/spec/integration/eager_loader_test.rb +147 -147
- data/spec/integration/migrator_test.rb +122 -122
- data/spec/integration/model_test.rb +70 -70
- data/spec/integration/plugin_test.rb +682 -640
- data/spec/integration/prepared_statement_test.rb +172 -172
- data/spec/integration/schema_test.rb +245 -245
- data/spec/integration/spec_helper.rb +1 -64
- data/spec/integration/timezone_test.rb +17 -17
- data/spec/integration/transaction_test.rb +87 -87
- data/spec/integration/type_test.rb +33 -33
- data/spec/model/association_reflection_spec.rb +130 -121
- data/spec/model/associations_spec.rb +1112 -1113
- data/spec/model/base_spec.rb +197 -196
- data/spec/model/class_dataset_methods_spec.rb +118 -118
- data/spec/model/dataset_methods_spec.rb +49 -49
- data/spec/model/eager_loading_spec.rb +705 -702
- data/spec/model/hooks_spec.rb +169 -168
- data/spec/model/inflector_spec.rb +5 -5
- data/spec/model/model_spec.rb +287 -297
- data/spec/model/plugins_spec.rb +47 -47
- data/spec/model/record_spec.rb +534 -535
- data/spec/model/spec_helper.rb +3 -21
- data/spec/model/validations_spec.rb +72 -70
- data/spec/spec_config.rb +8 -0
- metadata +41 -9
- data/lib/sequel/adapters/fdbsql.rb +0 -286
- data/lib/sequel/adapters/jdbc/fdbsql.rb +0 -66
- data/lib/sequel/adapters/openbase.rb +0 -54
- data/lib/sequel/adapters/shared/fdbsql.rb +0 -550
- data/spec/adapters/fdbsql_spec.rb +0 -429
- data/spec/rspec_helper.rb +0 -22
|
@@ -9,135 +9,135 @@ describe "Sequel::Postgres::ArrayOp" do
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
it "should support the standard mathematical operators" do
|
|
12
|
-
@db.literal(@a < @a).
|
|
13
|
-
@db.literal(@a <= @a).
|
|
14
|
-
@db.literal(@a > @a).
|
|
15
|
-
@db.literal(@a >= @a).
|
|
12
|
+
@db.literal(@a < @a).must_equal "(a < a)"
|
|
13
|
+
@db.literal(@a <= @a).must_equal "(a <= a)"
|
|
14
|
+
@db.literal(@a > @a).must_equal "(a > a)"
|
|
15
|
+
@db.literal(@a >= @a).must_equal "(a >= a)"
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it "#[] should support subscript access" do
|
|
19
|
-
@db.literal(@a[1]).
|
|
20
|
-
@db.literal(@a[1][2]).
|
|
19
|
+
@db.literal(@a[1]).must_equal "a[1]"
|
|
20
|
+
@db.literal(@a[1][2]).must_equal "a[1][2]"
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it "#[] with a range should return an ArrayOp" do
|
|
24
|
-
@db.literal(@a[1..2].any).
|
|
24
|
+
@db.literal(@a[1..2].any).must_equal "ANY(a[1:2])"
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it "#any should use the ANY method" do
|
|
28
|
-
@db.literal(1=>@a.any).
|
|
28
|
+
@db.literal(1=>@a.any).must_equal "(1 = ANY(a))"
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
it "#all should use the ALL method" do
|
|
32
|
-
@db.literal(1=>@a.all).
|
|
32
|
+
@db.literal(1=>@a.all).must_equal "(1 = ALL(a))"
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "#contains should use the @> operator" do
|
|
36
|
-
@db.literal(@a.contains(:b)).
|
|
36
|
+
@db.literal(@a.contains(:b)).must_equal "(a @> b)"
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
it "#contained_by should use the <@ operator" do
|
|
40
|
-
@db.literal(@a.contained_by(:b)).
|
|
40
|
+
@db.literal(@a.contained_by(:b)).must_equal "(a <@ b)"
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it "#overlaps should use the && operator" do
|
|
44
|
-
@db.literal(@a.overlaps(:b)).
|
|
44
|
+
@db.literal(@a.overlaps(:b)).must_equal "(a && b)"
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it "#push/concat should use the || operator in append mode" do
|
|
48
|
-
@db.literal(@a.push(:b)).
|
|
49
|
-
@db.literal(@a.concat(:b)).
|
|
48
|
+
@db.literal(@a.push(:b)).must_equal "(a || b)"
|
|
49
|
+
@db.literal(@a.concat(:b)).must_equal "(a || b)"
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it "#remove should remove the element from the array" do
|
|
53
|
-
@db.literal(@a.remove(1)).
|
|
54
|
-
@db.literal(@a.remove(1)[2]).
|
|
53
|
+
@db.literal(@a.remove(1)).must_equal "array_remove(a, 1)"
|
|
54
|
+
@db.literal(@a.remove(1)[2]).must_equal "array_remove(a, 1)[2]"
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
it "#remove should replace the element in the array with another" do
|
|
58
|
-
@db.literal(@a.replace(1, 2)).
|
|
59
|
-
@db.literal(@a.replace(1, 2)[3]).
|
|
58
|
+
@db.literal(@a.replace(1, 2)).must_equal "array_replace(a, 1, 2)"
|
|
59
|
+
@db.literal(@a.replace(1, 2)[3]).must_equal "array_replace(a, 1, 2)[3]"
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
it "#unshift should use the || operator in prepend mode" do
|
|
63
|
-
@db.literal(@a.unshift(:b)).
|
|
63
|
+
@db.literal(@a.unshift(:b)).must_equal "(b || a)"
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it "#cardinality should use the cardinality function" do
|
|
67
|
-
@db.literal(@a.cardinality).
|
|
67
|
+
@db.literal(@a.cardinality).must_equal "cardinality(a)"
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
it "#dims should use the array_dims function" do
|
|
71
|
-
@db.literal(@a.dims).
|
|
71
|
+
@db.literal(@a.dims).must_equal "array_dims(a)"
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
it "#length should use the array_length function" do
|
|
75
|
-
@db.literal(@a.length).
|
|
76
|
-
@db.literal(@a.length(2)).
|
|
75
|
+
@db.literal(@a.length).must_equal "array_length(a, 1)"
|
|
76
|
+
@db.literal(@a.length(2)).must_equal "array_length(a, 2)"
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
it "#length should use the array_lower function" do
|
|
80
|
-
@db.literal(@a.lower).
|
|
81
|
-
@db.literal(@a.lower(2)).
|
|
80
|
+
@db.literal(@a.lower).must_equal "array_lower(a, 1)"
|
|
81
|
+
@db.literal(@a.lower(2)).must_equal "array_lower(a, 2)"
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
it "#to_string/join should use the array_to_string function" do
|
|
85
|
-
@db.literal(@a.to_string).
|
|
86
|
-
@db.literal(@a.join).
|
|
87
|
-
@db.literal(@a.join(':')).
|
|
88
|
-
@db.literal(@a.join(':', '*')).
|
|
85
|
+
@db.literal(@a.to_string).must_equal "array_to_string(a, '', NULL)"
|
|
86
|
+
@db.literal(@a.join).must_equal "array_to_string(a, '', NULL)"
|
|
87
|
+
@db.literal(@a.join(':')).must_equal "array_to_string(a, ':', NULL)"
|
|
88
|
+
@db.literal(@a.join(':', '*')).must_equal "array_to_string(a, ':', '*')"
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
it "#hstore should convert the item to an hstore using the hstore function" do
|
|
92
|
-
@db.literal(@a.hstore).
|
|
93
|
-
@db.literal(@a.hstore['a']).
|
|
94
|
-
@db.literal(@a.hstore(:b)).
|
|
95
|
-
@db.literal(@a.hstore(:b)['a']).
|
|
96
|
-
@db.literal(@a.hstore(%w'1')).
|
|
97
|
-
@db.literal(@a.hstore(%w'1')['a']).
|
|
92
|
+
@db.literal(@a.hstore).must_equal "hstore(a)"
|
|
93
|
+
@db.literal(@a.hstore['a']).must_equal "(hstore(a) -> 'a')"
|
|
94
|
+
@db.literal(@a.hstore(:b)).must_equal "hstore(a, b)"
|
|
95
|
+
@db.literal(@a.hstore(:b)['a']).must_equal "(hstore(a, b) -> 'a')"
|
|
96
|
+
@db.literal(@a.hstore(%w'1')).must_equal "hstore(a, ARRAY['1'])"
|
|
97
|
+
@db.literal(@a.hstore(%w'1')['a']).must_equal "(hstore(a, ARRAY['1']) -> 'a')"
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
it "#unnest should use the unnest function" do
|
|
101
|
-
@db.literal(@a.unnest).
|
|
102
|
-
@db.literal(@a.unnest(:b, :c)).
|
|
103
|
-
@db.literal(@a.unnest([1])).
|
|
101
|
+
@db.literal(@a.unnest).must_equal "unnest(a)"
|
|
102
|
+
@db.literal(@a.unnest(:b, :c)).must_equal "unnest(a, b, c)"
|
|
103
|
+
@db.literal(@a.unnest([1])).must_equal "unnest(a, ARRAY[1])"
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
it "#pg_array should return self" do
|
|
107
|
-
@a.pg_array.
|
|
107
|
+
@a.pg_array.must_be_same_as(@a)
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
it "Sequel.pg_array_op should return arg for ArrayOp" do
|
|
111
|
-
Sequel.pg_array_op(@a).
|
|
111
|
+
Sequel.pg_array_op(@a).must_be_same_as(@a)
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
it "should be able to turn expressions into array ops using pg_array" do
|
|
115
|
-
@db.literal(Sequel.qualify(:b, :a).pg_array.push(3)).
|
|
116
|
-
@db.literal(Sequel.function(:a, :b).pg_array.push(3)).
|
|
115
|
+
@db.literal(Sequel.qualify(:b, :a).pg_array.push(3)).must_equal "(b.a || 3)"
|
|
116
|
+
@db.literal(Sequel.function(:a, :b).pg_array.push(3)).must_equal "(a(b) || 3)"
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
it "should be able to turn literal strings into array ops using pg_array" do
|
|
120
|
-
@db.literal(Sequel.lit('a').pg_array.unnest).
|
|
120
|
+
@db.literal(Sequel.lit('a').pg_array.unnest).must_equal "unnest(a)"
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
it "should be able to turn symbols into array ops using Sequel.pg_array_op" do
|
|
124
|
-
@db.literal(Sequel.pg_array_op(:a).unnest).
|
|
124
|
+
@db.literal(Sequel.pg_array_op(:a).unnest).must_equal "unnest(a)"
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
it "should be able to turn symbols into array ops using Sequel.pg_array" do
|
|
128
|
-
@db.literal(Sequel.pg_array(:a).unnest).
|
|
128
|
+
@db.literal(Sequel.pg_array(:a).unnest).must_equal "unnest(a)"
|
|
129
129
|
end
|
|
130
130
|
|
|
131
131
|
it "should allow transforming PGArray instances into ArrayOp instances" do
|
|
132
|
-
@db.literal(Sequel.pg_array([1,2]).op.push(3)).
|
|
132
|
+
@db.literal(Sequel.pg_array([1,2]).op.push(3)).must_equal "(ARRAY[1,2] || 3)"
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
it "should wrap array arguments in PGArrays" do
|
|
136
|
-
@db.literal(@a.contains([1, 2])).
|
|
137
|
-
@db.literal(@a.contained_by([1, 2])).
|
|
138
|
-
@db.literal(@a.overlaps([1, 2])).
|
|
139
|
-
@db.literal(@a.push([1, 2])).
|
|
140
|
-
@db.literal(@a.concat([1, 2])).
|
|
141
|
-
@db.literal(@a.unshift([1, 2])).
|
|
136
|
+
@db.literal(@a.contains([1, 2])).must_equal "(a @> ARRAY[1,2])"
|
|
137
|
+
@db.literal(@a.contained_by([1, 2])).must_equal "(a <@ ARRAY[1,2])"
|
|
138
|
+
@db.literal(@a.overlaps([1, 2])).must_equal "(a && ARRAY[1,2])"
|
|
139
|
+
@db.literal(@a.push([1, 2])).must_equal "(a || ARRAY[1,2])"
|
|
140
|
+
@db.literal(@a.concat([1, 2])).must_equal "(a || ARRAY[1,2])"
|
|
141
|
+
@db.literal(@a.unshift([1, 2])).must_equal "(ARRAY[1,2] || a)"
|
|
142
142
|
end
|
|
143
143
|
end
|
|
@@ -22,188 +22,188 @@ describe "pg_array extension" do
|
|
|
22
22
|
|
|
23
23
|
it "should parse single dimensional text arrays" do
|
|
24
24
|
c = @converter[1009]
|
|
25
|
-
c.call("{a}").to_a.first.
|
|
26
|
-
c.call("{}").to_a.
|
|
27
|
-
c.call('{""}').to_a.
|
|
28
|
-
c.call('{"",""}').to_a.
|
|
29
|
-
c.call('{"","",""}').to_a.
|
|
30
|
-
c.call("{a}").to_a.
|
|
31
|
-
c.call('{"a b"}').to_a.
|
|
32
|
-
c.call('{a,b}').to_a.
|
|
25
|
+
c.call("{a}").to_a.first.must_be_kind_of(String)
|
|
26
|
+
c.call("{}").to_a.must_equal []
|
|
27
|
+
c.call('{""}').to_a.must_equal [""]
|
|
28
|
+
c.call('{"",""}').to_a.must_equal ["",""]
|
|
29
|
+
c.call('{"","",""}').to_a.must_equal ["","",""]
|
|
30
|
+
c.call("{a}").to_a.must_equal ['a']
|
|
31
|
+
c.call('{"a b"}').to_a.must_equal ['a b']
|
|
32
|
+
c.call('{a,b}').to_a.must_equal ['a', 'b']
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "should parse multi-dimensional text arrays" do
|
|
36
36
|
c = @converter[1009]
|
|
37
|
-
c.call("{{}}").to_a.
|
|
38
|
-
c.call("{{a},{b}}").to_a.
|
|
39
|
-
c.call('{{"a b"},{c}}').to_a.
|
|
40
|
-
c.call('{{{a},{b}},{{c},{d}}}').to_a.
|
|
41
|
-
c.call('{{{a,e},{b,f}},{{c,g},{d,h}}}').to_a.
|
|
37
|
+
c.call("{{}}").to_a.must_equal [[]]
|
|
38
|
+
c.call("{{a},{b}}").to_a.must_equal [['a'], ['b']]
|
|
39
|
+
c.call('{{"a b"},{c}}').to_a.must_equal [['a b'], ['c']]
|
|
40
|
+
c.call('{{{a},{b}},{{c},{d}}}').to_a.must_equal [[['a'], ['b']], [['c'], ['d']]]
|
|
41
|
+
c.call('{{{a,e},{b,f}},{{c,g},{d,h}}}').to_a.must_equal [[['a', 'e'], ['b', 'f']], [['c', 'g'], ['d', 'h']]]
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it "should parse text arrays with embedded deliminaters" do
|
|
45
45
|
c = @converter[1009]
|
|
46
|
-
c.call('{{"{},","\\",\\,\\\\\\"\\""}}').to_a.
|
|
46
|
+
c.call('{{"{},","\\",\\,\\\\\\"\\""}}').to_a.must_equal [['{},', '",,\\""']]
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
it "should parse single dimensional integer arrays" do
|
|
50
50
|
c = @converter[1007]
|
|
51
|
-
c.call("{1}").to_a.first.
|
|
52
|
-
c.call("{}").to_a.
|
|
53
|
-
c.call("{1}").to_a.
|
|
54
|
-
c.call('{2,3}').to_a.
|
|
55
|
-
c.call('{3,4,5}').to_a.
|
|
51
|
+
c.call("{1}").to_a.first.must_be_kind_of(Integer)
|
|
52
|
+
c.call("{}").to_a.must_equal []
|
|
53
|
+
c.call("{1}").to_a.must_equal [1]
|
|
54
|
+
c.call('{2,3}').to_a.must_equal [2, 3]
|
|
55
|
+
c.call('{3,4,5}').to_a.must_equal [3, 4, 5]
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it "should parse multiple dimensional integer arrays" do
|
|
59
59
|
c = @converter[1007]
|
|
60
|
-
c.call("{{}}").to_a.
|
|
61
|
-
c.call("{{1}}").to_a.
|
|
62
|
-
c.call('{{2},{3}}').to_a.
|
|
63
|
-
c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.
|
|
60
|
+
c.call("{{}}").to_a.must_equal [[]]
|
|
61
|
+
c.call("{{1}}").to_a.must_equal [[1]]
|
|
62
|
+
c.call('{{2},{3}}').to_a.must_equal [[2], [3]]
|
|
63
|
+
c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.must_equal [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it "should parse single dimensional float arrays" do
|
|
67
67
|
c = @converter[1022]
|
|
68
|
-
c.call("{}").to_a.
|
|
69
|
-
c.call("{1.5}").to_a.
|
|
70
|
-
c.call('{2.5,3.5}').to_a.
|
|
71
|
-
c.call('{3.5,4.5,5.5}').to_a.
|
|
68
|
+
c.call("{}").to_a.must_equal []
|
|
69
|
+
c.call("{1.5}").to_a.must_equal [1.5]
|
|
70
|
+
c.call('{2.5,3.5}').to_a.must_equal [2.5, 3.5]
|
|
71
|
+
c.call('{3.5,4.5,5.5}').to_a.must_equal [3.5, 4.5, 5.5]
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
it "should parse multiple dimensional float arrays" do
|
|
75
75
|
c = @converter[1022]
|
|
76
|
-
c.call("{{}}").to_a.
|
|
77
|
-
c.call("{{1.5}}").to_a.
|
|
78
|
-
c.call('{{2.5},{3.5}}').to_a.
|
|
79
|
-
c.call('{{{1.5,2.5},{3.5,4.5}},{{5.5,6.5},{7.5,8.5}}}').to_a.
|
|
76
|
+
c.call("{{}}").to_a.must_equal [[]]
|
|
77
|
+
c.call("{{1.5}}").to_a.must_equal [[1.5]]
|
|
78
|
+
c.call('{{2.5},{3.5}}').to_a.must_equal [[2.5], [3.5]]
|
|
79
|
+
c.call('{{{1.5,2.5},{3.5,4.5}},{{5.5,6.5},{7.5,8.5}}}').to_a.must_equal [[[1.5, 2.5], [3.5, 4.5]], [[5.5, 6.5], [7.5, 8.5]]]
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
it "should parse integers in float arrays as floats" do
|
|
83
83
|
c = @converter[1022]
|
|
84
|
-
c.call("{1}").to_a.first.
|
|
85
|
-
c.call("{1}").to_a.
|
|
86
|
-
c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.
|
|
84
|
+
c.call("{1}").to_a.first.must_be_kind_of(Float)
|
|
85
|
+
c.call("{1}").to_a.must_equal [1.0]
|
|
86
|
+
c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.must_equal [[[1.0, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]]
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
it "should parse single dimensional decimal arrays" do
|
|
90
90
|
c = @converter[1231]
|
|
91
|
-
c.call("{}").to_a.
|
|
92
|
-
c.call("{1.5}").to_a.
|
|
93
|
-
c.call('{2.5,3.5}').to_a.
|
|
94
|
-
c.call('{3.5,4.5,5.5}').to_a.
|
|
91
|
+
c.call("{}").to_a.must_equal []
|
|
92
|
+
c.call("{1.5}").to_a.must_equal [BigDecimal.new('1.5')]
|
|
93
|
+
c.call('{2.5,3.5}').to_a.must_equal [BigDecimal.new('2.5'), BigDecimal.new('3.5')]
|
|
94
|
+
c.call('{3.5,4.5,5.5}').to_a.must_equal [BigDecimal.new('3.5'), BigDecimal.new('4.5'), BigDecimal.new('5.5')]
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
it "should parse multiple dimensional decimal arrays" do
|
|
98
98
|
c = @converter[1231]
|
|
99
|
-
c.call("{{}}").to_a.
|
|
100
|
-
c.call("{{1.5}}").to_a.
|
|
101
|
-
c.call('{{2.5},{3.5}}').to_a.
|
|
102
|
-
c.call('{{{1.5,2.5},{3.5,4.5}},{{5.5,6.5},{7.5,8.5}}}').to_a.
|
|
99
|
+
c.call("{{}}").to_a.must_equal [[]]
|
|
100
|
+
c.call("{{1.5}}").to_a.must_equal [[BigDecimal.new('1.5')]]
|
|
101
|
+
c.call('{{2.5},{3.5}}').to_a.must_equal [[BigDecimal.new('2.5')], [BigDecimal.new('3.5')]]
|
|
102
|
+
c.call('{{{1.5,2.5},{3.5,4.5}},{{5.5,6.5},{7.5,8.5}}}').to_a.must_equal [[[BigDecimal.new('1.5'), BigDecimal.new('2.5')], [BigDecimal.new('3.5'), BigDecimal.new('4.5')]], [[BigDecimal.new('5.5'), BigDecimal.new('6.5')], [BigDecimal.new('7.5'), BigDecimal.new('8.5')]]]
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
it "should parse decimal values with arbitrary precision" do
|
|
106
106
|
c = @converter[1231]
|
|
107
|
-
c.call("{1.000000000000000000005}").to_a.
|
|
108
|
-
c.call("{{1.000000000000000000005,2.000000000000000000005},{3.000000000000000000005,4.000000000000000000005}}").to_a.
|
|
107
|
+
c.call("{1.000000000000000000005}").to_a.must_equal [BigDecimal.new('1.000000000000000000005')]
|
|
108
|
+
c.call("{{1.000000000000000000005,2.000000000000000000005},{3.000000000000000000005,4.000000000000000000005}}").to_a.must_equal [[BigDecimal.new('1.000000000000000000005'), BigDecimal.new('2.000000000000000000005')], [BigDecimal.new('3.000000000000000000005'), BigDecimal.new('4.000000000000000000005')]]
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
it "should parse integers in decimal arrays as BigDecimals" do
|
|
112
112
|
c = @converter[1231]
|
|
113
|
-
c.call("{1}").to_a.first.
|
|
114
|
-
c.call("{1}").to_a.
|
|
115
|
-
c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.
|
|
113
|
+
c.call("{1}").to_a.first.must_be_kind_of(BigDecimal)
|
|
114
|
+
c.call("{1}").to_a.must_equal [BigDecimal.new('1')]
|
|
115
|
+
c.call('{{{1,2},{3,4}},{{5,6},{7,8}}}').to_a.must_equal [[[BigDecimal.new('1'), BigDecimal.new('2')], [BigDecimal.new('3'), BigDecimal.new('4')]], [[BigDecimal.new('5'), BigDecimal.new('6')], [BigDecimal.new('7'), BigDecimal.new('8')]]]
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
it "should parse arrays with NULL values" do
|
|
119
119
|
@converter.values_at(1007, 1009, 1022, 1231).each do |c|
|
|
120
|
-
c.call("{NULL}").
|
|
121
|
-
c.call("{NULL,NULL}").
|
|
122
|
-
c.call("{{NULL,NULL},{NULL,NULL}}").
|
|
120
|
+
c.call("{NULL}").must_equal [nil]
|
|
121
|
+
c.call("{NULL,NULL}").must_equal [nil,nil]
|
|
122
|
+
c.call("{{NULL,NULL},{NULL,NULL}}").must_equal [[nil,nil],[nil,nil]]
|
|
123
123
|
end
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
it 'should parse arrays with "NULL" values' do
|
|
127
127
|
c = @converter[1009]
|
|
128
|
-
c.call('{NULL,"NULL",NULL}').to_a.
|
|
129
|
-
c.call('{NULLA,"NULL",NULL}').to_a.
|
|
128
|
+
c.call('{NULL,"NULL",NULL}').to_a.must_equal [nil, "NULL", nil]
|
|
129
|
+
c.call('{NULLA,"NULL",NULL}').to_a.must_equal ["NULLA", "NULL", nil]
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
it "should raise errors when for certain recognized invalid arrays" do
|
|
133
133
|
c = @converter[1009]
|
|
134
|
-
proc{c.call('')}.
|
|
135
|
-
proc{c.call('}')}.
|
|
136
|
-
proc{c.call('{{}')}.
|
|
137
|
-
proc{c.call('{}}')}.
|
|
138
|
-
proc{c.call('{a""}')}.
|
|
139
|
-
proc{c.call('{a{}}')}.
|
|
140
|
-
proc{c.call('{""a}')}.
|
|
134
|
+
proc{c.call('')}.must_raise(Sequel::Error)
|
|
135
|
+
proc{c.call('}')}.must_raise(Sequel::Error)
|
|
136
|
+
proc{c.call('{{}')}.must_raise(Sequel::Error)
|
|
137
|
+
proc{c.call('{}}')}.must_raise(Sequel::Error)
|
|
138
|
+
proc{c.call('{a""}')}.must_raise(Sequel::Error)
|
|
139
|
+
proc{c.call('{a{}}')}.must_raise(Sequel::Error)
|
|
140
|
+
proc{c.call('{""a}')}.must_raise(Sequel::Error)
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it "should literalize arrays without types correctly" do
|
|
144
|
-
@db.literal(@m::PGArray.new([])).
|
|
145
|
-
@db.literal(@m::PGArray.new([1])).
|
|
146
|
-
@db.literal(@m::PGArray.new([nil])).
|
|
147
|
-
@db.literal(@m::PGArray.new([nil, 1])).
|
|
148
|
-
@db.literal(@m::PGArray.new([1.0, 2.5])).
|
|
149
|
-
@db.literal(@m::PGArray.new([BigDecimal.new('1'), BigDecimal.new('2.000000000000000000005')])).
|
|
150
|
-
@db.literal(@m::PGArray.new([nil, "NULL"])).
|
|
151
|
-
@db.literal(@m::PGArray.new([nil, "{},[]'\""])).
|
|
144
|
+
@db.literal(@m::PGArray.new([])).must_equal 'ARRAY[]'
|
|
145
|
+
@db.literal(@m::PGArray.new([1])).must_equal 'ARRAY[1]'
|
|
146
|
+
@db.literal(@m::PGArray.new([nil])).must_equal 'ARRAY[NULL]'
|
|
147
|
+
@db.literal(@m::PGArray.new([nil, 1])).must_equal 'ARRAY[NULL,1]'
|
|
148
|
+
@db.literal(@m::PGArray.new([1.0, 2.5])).must_equal 'ARRAY[1.0,2.5]'
|
|
149
|
+
@db.literal(@m::PGArray.new([BigDecimal.new('1'), BigDecimal.new('2.000000000000000000005')])).must_equal 'ARRAY[1.0,2.000000000000000000005]'
|
|
150
|
+
@db.literal(@m::PGArray.new([nil, "NULL"])).must_equal "ARRAY[NULL,'NULL']"
|
|
151
|
+
@db.literal(@m::PGArray.new([nil, "{},[]'\""])).must_equal "ARRAY[NULL,'{},[]''\"']"
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
it "should literalize multidimensional arrays correctly" do
|
|
155
|
-
@db.literal(@m::PGArray.new([[]])).
|
|
156
|
-
@db.literal(@m::PGArray.new([[1, 2]])).
|
|
157
|
-
@db.literal(@m::PGArray.new([[3], [5]])).
|
|
158
|
-
@db.literal(@m::PGArray.new([[[1.0]], [[2.5]]])).
|
|
159
|
-
@db.literal(@m::PGArray.new([[[["NULL"]]]])).
|
|
160
|
-
@db.literal(@m::PGArray.new([["a", "b"], ["{},[]'\"", nil]])).
|
|
155
|
+
@db.literal(@m::PGArray.new([[]])).must_equal 'ARRAY[[]]'
|
|
156
|
+
@db.literal(@m::PGArray.new([[1, 2]])).must_equal 'ARRAY[[1,2]]'
|
|
157
|
+
@db.literal(@m::PGArray.new([[3], [5]])).must_equal 'ARRAY[[3],[5]]'
|
|
158
|
+
@db.literal(@m::PGArray.new([[[1.0]], [[2.5]]])).must_equal 'ARRAY[[[1.0]],[[2.5]]]'
|
|
159
|
+
@db.literal(@m::PGArray.new([[[["NULL"]]]])).must_equal "ARRAY[[[['NULL']]]]"
|
|
160
|
+
@db.literal(@m::PGArray.new([["a", "b"], ["{},[]'\"", nil]])).must_equal "ARRAY[['a','b'],['{},[]''\"',NULL]]"
|
|
161
161
|
end
|
|
162
162
|
|
|
163
163
|
it "should literalize with types correctly" do
|
|
164
|
-
@db.literal(@m::PGArray.new([], :int4)).
|
|
165
|
-
@db.literal(@m::PGArray.new([1], :int4)).
|
|
166
|
-
@db.literal(@m::PGArray.new([nil], :text)).
|
|
167
|
-
@db.literal(@m::PGArray.new([nil, 1], :int8)).
|
|
168
|
-
@db.literal(@m::PGArray.new([1.0, 2.5], :real)).
|
|
169
|
-
@db.literal(@m::PGArray.new([BigDecimal.new('1'), BigDecimal.new('2.000000000000000000005')], :decimal)).
|
|
170
|
-
@db.literal(@m::PGArray.new([nil, "NULL"], :varchar)).
|
|
171
|
-
@db.literal(@m::PGArray.new([nil, "{},[]'\""], :"varchar(255)")).
|
|
164
|
+
@db.literal(@m::PGArray.new([], :int4)).must_equal "'{}'::int4[]"
|
|
165
|
+
@db.literal(@m::PGArray.new([1], :int4)).must_equal 'ARRAY[1]::int4[]'
|
|
166
|
+
@db.literal(@m::PGArray.new([nil], :text)).must_equal 'ARRAY[NULL]::text[]'
|
|
167
|
+
@db.literal(@m::PGArray.new([nil, 1], :int8)).must_equal 'ARRAY[NULL,1]::int8[]'
|
|
168
|
+
@db.literal(@m::PGArray.new([1.0, 2.5], :real)).must_equal 'ARRAY[1.0,2.5]::real[]'
|
|
169
|
+
@db.literal(@m::PGArray.new([BigDecimal.new('1'), BigDecimal.new('2.000000000000000000005')], :decimal)).must_equal 'ARRAY[1.0,2.000000000000000000005]::decimal[]'
|
|
170
|
+
@db.literal(@m::PGArray.new([nil, "NULL"], :varchar)).must_equal "ARRAY[NULL,'NULL']::varchar[]"
|
|
171
|
+
@db.literal(@m::PGArray.new([nil, "{},[]'\""], :"varchar(255)")).must_equal "ARRAY[NULL,'{},[]''\"']::varchar(255)[]"
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
it "should have Sequel.pg_array method for easy PGArray creation" do
|
|
175
|
-
@db.literal(Sequel.pg_array([1])).
|
|
176
|
-
@db.literal(Sequel.pg_array([1, 2], :int4)).
|
|
177
|
-
@db.literal(Sequel.pg_array([[[1], [2]], [[3], [4]]], :real)).
|
|
175
|
+
@db.literal(Sequel.pg_array([1])).must_equal 'ARRAY[1]'
|
|
176
|
+
@db.literal(Sequel.pg_array([1, 2], :int4)).must_equal 'ARRAY[1,2]::int4[]'
|
|
177
|
+
@db.literal(Sequel.pg_array([[[1], [2]], [[3], [4]]], :real)).must_equal 'ARRAY[[[1],[2]],[[3],[4]]]::real[]'
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
it "should have Sequel.pg_array return existing PGArrays as-is" do
|
|
181
181
|
a = Sequel.pg_array([1])
|
|
182
|
-
Sequel.pg_array(a).
|
|
182
|
+
Sequel.pg_array(a).object_id.must_equal(a.object_id)
|
|
183
183
|
end
|
|
184
184
|
|
|
185
185
|
it "should have Sequel.pg_array create a new PGArrays if type of existing does not match" do
|
|
186
186
|
a = Sequel.pg_array([1], :int4)
|
|
187
187
|
b = Sequel.pg_array(a, :int8)
|
|
188
|
-
a.
|
|
189
|
-
a.
|
|
190
|
-
a.array_type.
|
|
191
|
-
b.array_type.
|
|
188
|
+
a.must_equal b
|
|
189
|
+
a.wont_be_same_as(b)
|
|
190
|
+
a.array_type.must_equal :int4
|
|
191
|
+
b.array_type.must_equal :int8
|
|
192
192
|
end
|
|
193
193
|
|
|
194
194
|
it "should support using arrays as bound variables" do
|
|
195
|
-
@db.bound_variable_arg(1, nil).
|
|
196
|
-
@db.bound_variable_arg(Sequel.pg_array([1,2]), nil).
|
|
197
|
-
@db.bound_variable_arg([1,2], nil).
|
|
198
|
-
@db.bound_variable_arg([[1,2]], nil).
|
|
199
|
-
@db.bound_variable_arg([1.0,2.0], nil).
|
|
200
|
-
@db.bound_variable_arg([Sequel.lit('a'), Sequel.blob("a\0'\"")], nil).
|
|
201
|
-
@db.bound_variable_arg(["\\ \"", 'NULL', nil], nil).
|
|
195
|
+
@db.bound_variable_arg(1, nil).must_equal 1
|
|
196
|
+
@db.bound_variable_arg(Sequel.pg_array([1,2]), nil).must_equal '{1,2}'
|
|
197
|
+
@db.bound_variable_arg([1,2], nil).must_equal '{1,2}'
|
|
198
|
+
@db.bound_variable_arg([[1,2]], nil).must_equal '{{1,2}}'
|
|
199
|
+
@db.bound_variable_arg([1.0,2.0], nil).must_equal '{1.0,2.0}'
|
|
200
|
+
@db.bound_variable_arg([Sequel.lit('a'), Sequel.blob("a\0'\"")], nil).must_equal '{a,"a\\\\000\\\\047\\""}'
|
|
201
|
+
@db.bound_variable_arg(["\\ \"", 'NULL', nil], nil).must_equal '{"\\\\ \\"","NULL",NULL}'
|
|
202
202
|
end
|
|
203
203
|
|
|
204
204
|
it "should parse array types from the schema correctly" do
|
|
205
205
|
@db.fetch = [{:name=>'id', :db_type=>'integer'}, {:name=>'i', :db_type=>'integer[]'}, {:name=>'f', :db_type=>'real[]'}, {:name=>'d', :db_type=>'numeric[]'}, {:name=>'t', :db_type=>'text[]'}]
|
|
206
|
-
@db.schema(:items).map{|e| e[1][:type]}.
|
|
206
|
+
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:integer, :integer_array, :real_array, :decimal_array, :string_array]
|
|
207
207
|
end
|
|
208
208
|
|
|
209
209
|
it "should support typecasting of the various array types" do
|
|
@@ -228,147 +228,147 @@ describe "pg_array extension" do
|
|
|
228
228
|
|
|
229
229
|
[[array_in]].each do |input|
|
|
230
230
|
v = @db.typecast_value(meth, input)
|
|
231
|
-
v.
|
|
232
|
-
v.first.
|
|
233
|
-
v.array_type.
|
|
234
|
-
@db.typecast_value(meth, Sequel.pg_array([value])).
|
|
235
|
-
@db.typecast_value(meth, v).
|
|
231
|
+
v.must_equal [value]
|
|
232
|
+
v.first.must_be_kind_of(klass)
|
|
233
|
+
v.array_type.wont_equal nil
|
|
234
|
+
@db.typecast_value(meth, Sequel.pg_array([value])).must_equal v
|
|
235
|
+
@db.typecast_value(meth, v).object_id.must_equal(v.object_id)
|
|
236
236
|
end
|
|
237
237
|
|
|
238
238
|
[[[array_in]]].each do |input|
|
|
239
239
|
v = @db.typecast_value(meth, input)
|
|
240
|
-
v.
|
|
241
|
-
v.first.first.
|
|
242
|
-
v.array_type.
|
|
243
|
-
@db.typecast_value(meth, Sequel.pg_array([[value]])).
|
|
244
|
-
@db.typecast_value(meth, v).
|
|
240
|
+
v.must_equal [[value]]
|
|
241
|
+
v.first.first.must_be_kind_of(klass)
|
|
242
|
+
v.array_type.wont_equal nil
|
|
243
|
+
@db.typecast_value(meth, Sequel.pg_array([[value]])).must_equal v
|
|
244
|
+
@db.typecast_value(meth, v).object_id.must_equal(v.object_id)
|
|
245
245
|
end
|
|
246
246
|
|
|
247
|
-
@db.literal(@db.typecast_value(meth, [array_in])).
|
|
248
|
-
@db.literal(@db.typecast_value(meth, [])).
|
|
247
|
+
@db.literal(@db.typecast_value(meth, [array_in])).must_equal "ARRAY[#{output}]::#{db_type}[]"
|
|
248
|
+
@db.literal(@db.typecast_value(meth, [])).must_equal "'{}'::#{db_type}[]"
|
|
249
249
|
end
|
|
250
|
-
proc{@db.typecast_value(:integer_array, {})}.
|
|
250
|
+
proc{@db.typecast_value(:integer_array, {})}.must_raise(Sequel::InvalidValue)
|
|
251
251
|
end
|
|
252
252
|
|
|
253
253
|
it "should support SQL::AliasMethods" do
|
|
254
|
-
@db.select(Sequel.pg_array([1], :integer).as(:col1)).sql.
|
|
254
|
+
@db.select(Sequel.pg_array([1], :integer).as(:col1)).sql.must_equal 'SELECT ARRAY[1]::integer[] AS col1'
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
it "should support registering custom array types" do
|
|
258
258
|
Sequel::Postgres::PGArray.register('foo')
|
|
259
|
-
@db.typecast_value(:foo_array, []).
|
|
259
|
+
@db.typecast_value(:foo_array, []).class.must_equal(Sequel::Postgres::PGArray)
|
|
260
260
|
@db.fetch = [{:name=>'id', :db_type=>'foo[]'}]
|
|
261
|
-
@db.schema(:items).map{|e| e[1][:type]}.
|
|
261
|
+
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:foo_array]
|
|
262
262
|
end
|
|
263
263
|
|
|
264
264
|
it "should support registering custom types with :type_symbol option" do
|
|
265
265
|
Sequel::Postgres::PGArray.register('foo', :type_symbol=>:bar)
|
|
266
|
-
@db.typecast_value(:bar_array, []).
|
|
266
|
+
@db.typecast_value(:bar_array, []).class.must_equal(Sequel::Postgres::PGArray)
|
|
267
267
|
@db.fetch = [{:name=>'id', :db_type=>'foo[]'}]
|
|
268
|
-
@db.schema(:items).map{|e| e[1][:type]}.
|
|
268
|
+
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:bar_array]
|
|
269
269
|
end
|
|
270
270
|
|
|
271
271
|
it "should support using a block as a custom conversion proc given as block" do
|
|
272
272
|
Sequel::Postgres::PGArray.register('foo', :oid=>1234){|s| (s*2).to_i}
|
|
273
|
-
@converter[1234].call('{1}').
|
|
273
|
+
@converter[1234].call('{1}').must_equal [11]
|
|
274
274
|
end
|
|
275
275
|
|
|
276
276
|
it "should support using a block as a custom conversion proc given as :converter option" do
|
|
277
277
|
Sequel::Postgres::PGArray.register('foo', :oid=>1234, :converter=>proc{|s| (s*2).to_i})
|
|
278
|
-
@converter[1234].call('{1}').
|
|
278
|
+
@converter[1234].call('{1}').must_equal [11]
|
|
279
279
|
end
|
|
280
280
|
|
|
281
281
|
it "should support using an existing scaler conversion proc via the :scalar_oid option" do
|
|
282
282
|
Sequel::Postgres::PGArray.register('foo', :oid=>1234, :scalar_oid=>16)
|
|
283
|
-
@converter[1234].call('{t}').
|
|
283
|
+
@converter[1234].call('{t}').must_equal [true]
|
|
284
284
|
end
|
|
285
285
|
|
|
286
286
|
it "should support using a given conversion procs hash via the :type_procs option" do
|
|
287
287
|
h = {16=>proc{|s| "!#{s}"}}
|
|
288
288
|
Sequel::Postgres::PGArray.register('foo', :oid=>1234, :scalar_oid=>16, :type_procs=>h)
|
|
289
|
-
h[1234].call('{t}').
|
|
289
|
+
h[1234].call('{t}').must_equal ["!t"]
|
|
290
290
|
end
|
|
291
291
|
|
|
292
292
|
it "should support adding methods to the given module via the :typecast_methods_module option" do
|
|
293
293
|
m = Module.new
|
|
294
294
|
Sequel::Postgres::PGArray.register('foo15', :scalar_typecast=>:boolean, :typecast_methods_module=>m)
|
|
295
|
-
@db.typecast_value(:foo15_array, ['t']).
|
|
295
|
+
@db.typecast_value(:foo15_array, ['t']).must_equal ['t']
|
|
296
296
|
@db.extend(m)
|
|
297
|
-
@db.typecast_value(:foo15_array, ['t']).
|
|
297
|
+
@db.typecast_value(:foo15_array, ['t']).must_equal [true]
|
|
298
298
|
end
|
|
299
299
|
|
|
300
300
|
it "should not raise an error if using :scalar_oid option with unexisting scalar conversion proc" do
|
|
301
301
|
h = {}
|
|
302
302
|
Sequel::Postgres::PGArray.register('foo', :oid=>1234, :scalar_oid=>0, :type_procs=>h)
|
|
303
|
-
h[1234].call('{t}').
|
|
303
|
+
h[1234].call('{t}').must_equal ["t"]
|
|
304
304
|
end
|
|
305
305
|
|
|
306
306
|
it "should raise an error if using :converter option and a block argument" do
|
|
307
|
-
proc{Sequel::Postgres::PGArray.register('foo', :converter=>proc{}){}}.
|
|
307
|
+
proc{Sequel::Postgres::PGArray.register('foo', :converter=>proc{}){}}.must_raise(Sequel::Error)
|
|
308
308
|
end
|
|
309
309
|
|
|
310
310
|
it "should raise an error if using :scalar_oid option and a block argument" do
|
|
311
|
-
proc{Sequel::Postgres::PGArray.register('foo', :scalar_oid=>16){}}.
|
|
311
|
+
proc{Sequel::Postgres::PGArray.register('foo', :scalar_oid=>16){}}.must_raise(Sequel::Error)
|
|
312
312
|
end
|
|
313
313
|
|
|
314
314
|
it "should support registering custom types with :oid option" do
|
|
315
315
|
Sequel::Postgres::PGArray.register('foo', :oid=>1)
|
|
316
|
-
Sequel::Postgres::PG_TYPES[1].call('{1}').
|
|
316
|
+
Sequel::Postgres::PG_TYPES[1].call('{1}').class.must_equal(Sequel::Postgres::PGArray)
|
|
317
317
|
end
|
|
318
318
|
|
|
319
319
|
it "should support registering custom types with :parser=>:json option" do
|
|
320
320
|
Sequel::Postgres::PGArray.register('foo', :oid=>2, :parser=>:json)
|
|
321
|
-
Sequel::Postgres::PG_TYPES[2].
|
|
321
|
+
Sequel::Postgres::PG_TYPES[2].must_be_kind_of(Sequel::Postgres::PGArray::JSONCreator)
|
|
322
322
|
end
|
|
323
323
|
|
|
324
324
|
it "should support registering converters with :parser=>:json option and blocks" do
|
|
325
325
|
Sequel::Postgres::PGArray.register('foo', :oid=>4, :parser=>:json){|s| s * 2}
|
|
326
|
-
Sequel::Postgres::PG_TYPES[4].call('{{1, 2}, {3, 4}}').
|
|
326
|
+
Sequel::Postgres::PG_TYPES[4].call('{{1, 2}, {3, 4}}').must_equal [[2, 4], [6, 8]]
|
|
327
327
|
end
|
|
328
328
|
|
|
329
329
|
it "should support registering custom types with :array_type option" do
|
|
330
330
|
Sequel::Postgres::PGArray.register('foo', :oid=>3, :array_type=>:blah)
|
|
331
|
-
@db.literal(Sequel::Postgres::PG_TYPES[3].call('{}')).
|
|
331
|
+
@db.literal(Sequel::Postgres::PG_TYPES[3].call('{}')).must_equal "'{}'::blah[]"
|
|
332
332
|
end
|
|
333
333
|
|
|
334
334
|
it "should support registering custom array types on a per-Database basis" do
|
|
335
335
|
@db.register_array_type('banana', :oid=>7865){|s| s}
|
|
336
|
-
@db.typecast_value(:banana_array, []).
|
|
336
|
+
@db.typecast_value(:banana_array, []).class.must_equal(Sequel::Postgres::PGArray)
|
|
337
337
|
@db.fetch = [{:name=>'id', :db_type=>'banana[]'}]
|
|
338
|
-
@db.schema(:items).map{|e| e[1][:type]}.
|
|
339
|
-
@db.conversion_procs.
|
|
340
|
-
@db.respond_to?(:typecast_value_banana_array, true).
|
|
338
|
+
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:banana_array]
|
|
339
|
+
@db.conversion_procs.must_include(7865)
|
|
340
|
+
@db.respond_to?(:typecast_value_banana_array, true).must_equal true
|
|
341
341
|
|
|
342
342
|
db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
|
|
343
343
|
db.extend_datasets(Module.new{def supports_timestamp_timezones?; false; end; def supports_timestamp_usecs?; false; end})
|
|
344
344
|
db.extension(:pg_array)
|
|
345
345
|
db.fetch = [{:name=>'id', :db_type=>'banana[]'}]
|
|
346
|
-
db.schema(:items).map{|e| e[1][:type]}.
|
|
347
|
-
db.conversion_procs.
|
|
348
|
-
db.respond_to?(:typecast_value_banana_array, true).
|
|
346
|
+
db.schema(:items).map{|e| e[1][:type]}.must_equal [nil]
|
|
347
|
+
db.conversion_procs.wont_include(7865)
|
|
348
|
+
db.respond_to?(:typecast_value_banana_array, true).must_equal false
|
|
349
349
|
end
|
|
350
350
|
|
|
351
351
|
it "should automatically look up the array and scalar oids when registering per-Database types" do
|
|
352
352
|
@db.fetch = [[{:oid=>21, :typarray=>7866}], [{:name=>'id', :db_type=>'banana[]'}]]
|
|
353
353
|
@db.register_array_type('banana', :scalar_typecast=>:integer)
|
|
354
|
-
@db.sqls.
|
|
355
|
-
@db.schema(:items).map{|e| e[1][:type]}.
|
|
356
|
-
@db.conversion_procs[7866].call("{1,2}").
|
|
357
|
-
@db.typecast_value(:banana_array, %w'1 2').
|
|
354
|
+
@db.sqls.must_equal ["SELECT typarray, oid FROM pg_type WHERE (typname = 'banana') LIMIT 1"]
|
|
355
|
+
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:banana_array]
|
|
356
|
+
@db.conversion_procs[7866].call("{1,2}").must_equal [1,2]
|
|
357
|
+
@db.typecast_value(:banana_array, %w'1 2').must_equal [1,2]
|
|
358
358
|
end
|
|
359
359
|
|
|
360
360
|
it "should not automatically look up oids if given both scalar and array oids" do
|
|
361
361
|
@db.register_array_type('banana', :oid=>7866, :scalar_oid=>21, :scalar_typecast=>:integer)
|
|
362
|
-
@db.sqls.
|
|
363
|
-
@db.conversion_procs[7866].call("{1,2}").
|
|
364
|
-
@db.typecast_value(:banana_array, %w'1 2').
|
|
362
|
+
@db.sqls.must_equal []
|
|
363
|
+
@db.conversion_procs[7866].call("{1,2}").must_equal [1,2]
|
|
364
|
+
@db.typecast_value(:banana_array, %w'1 2').must_equal [1,2]
|
|
365
365
|
end
|
|
366
366
|
|
|
367
367
|
it "should not automatically look up oids if given array oid and block" do
|
|
368
368
|
@db.register_array_type('banana', :oid=>7866, :scalar_typecast=>:integer){|s| s.to_i}
|
|
369
|
-
@db.sqls.
|
|
370
|
-
@db.conversion_procs[7866].call("{1,2}").
|
|
371
|
-
@db.typecast_value(:banana_array, %w'1 2').
|
|
369
|
+
@db.sqls.must_equal []
|
|
370
|
+
@db.conversion_procs[7866].call("{1,2}").must_equal [1,2]
|
|
371
|
+
@db.typecast_value(:banana_array, %w'1 2').must_equal [1,2]
|
|
372
372
|
end
|
|
373
373
|
|
|
374
374
|
it "should set appropriate timestamp conversion procs when resetting conversion procs" do
|
|
@@ -376,20 +376,20 @@ describe "pg_array extension" do
|
|
|
376
376
|
@db.fetch = [[{:oid=>2222, :typname=>'foo'}], [{:oid=>2222, :typarray=>2223, :typname=>'foo'}]]
|
|
377
377
|
@db.reset_conversion_procs
|
|
378
378
|
procs = @db.conversion_procs
|
|
379
|
-
procs[1185].call('{"2011-10-20 11:12:13"}').
|
|
380
|
-
procs[1115].call('{"2011-10-20 11:12:13"}').
|
|
381
|
-
procs[2222].call('1').
|
|
382
|
-
procs[2223].call('{"2"}').
|
|
379
|
+
procs[1185].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
|
|
380
|
+
procs[1115].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
|
|
381
|
+
procs[2222].call('1').must_equal '11'
|
|
382
|
+
procs[2223].call('{"2"}').must_equal ['22']
|
|
383
383
|
end
|
|
384
384
|
|
|
385
385
|
it "should return correct results for Database#schema_type_class" do
|
|
386
386
|
@db.register_array_type('banana', :oid=>7866, :scalar_typecast=>:integer){|s| s.to_i}
|
|
387
|
-
@db.schema_type_class(:banana_array).
|
|
388
|
-
@db.schema_type_class(:integer).
|
|
387
|
+
@db.schema_type_class(:banana_array).must_equal Sequel::Postgres::PGArray
|
|
388
|
+
@db.schema_type_class(:integer).must_equal Integer
|
|
389
389
|
end
|
|
390
390
|
|
|
391
391
|
it "should convert ruby arrays to pg arrays as :default option values" do
|
|
392
392
|
@db.create_table('a'){column :b, 'c[]', :default=>[]; Integer :d}
|
|
393
|
-
@db.sqls.
|
|
393
|
+
@db.sqls.must_equal ['CREATE TABLE a (b c[] DEFAULT (ARRAY[]::c[]), d integer)']
|
|
394
394
|
end
|
|
395
395
|
end
|