sequel_impala 1.1.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 +7 -0
- data/CHANGELOG.md +50 -0
- data/LICENSE +463 -0
- data/README.md +45 -0
- data/Rakefile +39 -0
- data/lib/driver/commons-collections-3.2.1.jar +0 -0
- data/lib/driver/commons-configuration-1.10.jar +0 -0
- data/lib/driver/commons-logging-1.2.jar +0 -0
- data/lib/driver/hadoop-auth-2.9.0.jar +0 -0
- data/lib/driver/hadoop-common-2.9.0.jar +0 -0
- data/lib/driver/hadoop-core-2.6.0.jar +0 -0
- data/lib/driver/hive-exec-1.1.0.jar +0 -0
- data/lib/driver/hive-jdbc-1.1.0.jar +0 -0
- data/lib/driver/hive-metastore-1.1.0.jar +0 -0
- data/lib/driver/hive-service-1.1.0.jar +0 -0
- data/lib/driver/httpclient-4.3.jar +0 -0
- data/lib/driver/httpcore-4.3.jar +0 -0
- data/lib/driver/libfb303-0.9.0.jar +0 -0
- data/lib/driver/log4j-1.2.17.jar +0 -0
- data/lib/driver/slf4j-api-1.7.5.jar +0 -0
- data/lib/driver/stax2-api-3.1.4.jar +0 -0
- data/lib/driver/woodstox-core-asl-4.4.1.jar +0 -0
- data/lib/impala.rb +55 -0
- data/lib/impala/connection.rb +180 -0
- data/lib/impala/cursor.rb +200 -0
- data/lib/impala/progress_reporter.rb +40 -0
- data/lib/impala/protocol.rb +8 -0
- data/lib/impala/protocol/beeswax_constants.rb +15 -0
- data/lib/impala/protocol/beeswax_service.rb +747 -0
- data/lib/impala/protocol/beeswax_types.rb +193 -0
- data/lib/impala/protocol/exec_stats_constants.rb +13 -0
- data/lib/impala/protocol/exec_stats_types.rb +133 -0
- data/lib/impala/protocol/facebook_service.rb +706 -0
- data/lib/impala/protocol/fb303_constants.rb +15 -0
- data/lib/impala/protocol/fb303_types.rb +25 -0
- data/lib/impala/protocol/hive_metastore_constants.rb +53 -0
- data/lib/impala/protocol/hive_metastore_types.rb +698 -0
- data/lib/impala/protocol/impala_hive_server2_service.rb +137 -0
- data/lib/impala/protocol/impala_service.rb +443 -0
- data/lib/impala/protocol/impala_service_constants.rb +13 -0
- data/lib/impala/protocol/impala_service_types.rb +192 -0
- data/lib/impala/protocol/status_constants.rb +13 -0
- data/lib/impala/protocol/status_types.rb +46 -0
- data/lib/impala/protocol/t_c_l_i_service.rb +1108 -0
- data/lib/impala/protocol/t_c_l_i_service_constants.rb +72 -0
- data/lib/impala/protocol/t_c_l_i_service_types.rb +1802 -0
- data/lib/impala/protocol/thrift_hive_metastore.rb +4707 -0
- data/lib/impala/protocol/types_constants.rb +13 -0
- data/lib/impala/protocol/types_types.rb +332 -0
- data/lib/impala/sasl_transport.rb +117 -0
- data/lib/impala/thrift_patch.rb +31 -0
- data/lib/impala/version.rb +3 -0
- data/lib/jdbc/hive2.rb +52 -0
- data/lib/jdbc/impala.rb +50 -0
- data/lib/rbhive.rb +8 -0
- data/lib/rbhive/connection.rb +150 -0
- data/lib/rbhive/explain_result.rb +46 -0
- data/lib/rbhive/result_set.rb +37 -0
- data/lib/rbhive/schema_definition.rb +86 -0
- data/lib/rbhive/t_c_l_i_connection.rb +466 -0
- data/lib/rbhive/t_c_l_i_result_set.rb +3 -0
- data/lib/rbhive/t_c_l_i_schema_definition.rb +87 -0
- data/lib/rbhive/table_schema.rb +122 -0
- data/lib/rbhive/version.rb +3 -0
- data/lib/sequel/adapters/impala.rb +220 -0
- data/lib/sequel/adapters/jdbc/hive2.rb +36 -0
- data/lib/sequel/adapters/jdbc/impala.rb +38 -0
- data/lib/sequel/adapters/rbhive.rb +177 -0
- data/lib/sequel/adapters/shared/impala.rb +808 -0
- data/lib/sequel/extensions/csv_to_parquet.rb +166 -0
- data/lib/thrift/facebook_service.rb +700 -0
- data/lib/thrift/fb303_constants.rb +9 -0
- data/lib/thrift/fb303_types.rb +19 -0
- data/lib/thrift/hive_metastore_constants.rb +41 -0
- data/lib/thrift/hive_metastore_types.rb +630 -0
- data/lib/thrift/hive_service_constants.rb +13 -0
- data/lib/thrift/hive_service_types.rb +72 -0
- data/lib/thrift/queryplan_constants.rb +13 -0
- data/lib/thrift/queryplan_types.rb +261 -0
- data/lib/thrift/sasl_client_transport.rb +161 -0
- data/lib/thrift/serde_constants.rb +92 -0
- data/lib/thrift/serde_types.rb +7 -0
- data/lib/thrift/t_c_l_i_service.rb +1054 -0
- data/lib/thrift/t_c_l_i_service_constants.rb +72 -0
- data/lib/thrift/t_c_l_i_service_types.rb +1768 -0
- data/lib/thrift/thrift_hive.rb +508 -0
- data/lib/thrift/thrift_hive_metastore.rb +3856 -0
- data/spec/database_test.rb +56 -0
- data/spec/dataset_test.rb +1268 -0
- data/spec/files/bad_down_migration/001_create_alt_basic.rb +4 -0
- data/spec/files/bad_down_migration/002_create_alt_advanced.rb +4 -0
- data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +9 -0
- data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +9 -0
- data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +3 -0
- data/spec/files/bad_up_migration/001_create_alt_basic.rb +4 -0
- data/spec/files/bad_up_migration/002_create_alt_advanced.rb +3 -0
- data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +9 -0
- data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +9 -0
- data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +4 -0
- data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +9 -0
- data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +9 -0
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +9 -0
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +9 -0
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +4 -0
- data/spec/files/integer_migrations/001_create_sessions.rb +9 -0
- data/spec/files/integer_migrations/002_create_nodes.rb +9 -0
- data/spec/files/integer_migrations/003_3_create_users.rb +4 -0
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +9 -0
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +9 -0
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +9 -0
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +9 -0
- data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +4 -0
- data/spec/files/reversible_migrations/001_reversible.rb +5 -0
- data/spec/files/reversible_migrations/002_reversible.rb +5 -0
- data/spec/files/reversible_migrations/003_reversible.rb +5 -0
- data/spec/files/reversible_migrations/004_reversible.rb +5 -0
- data/spec/files/reversible_migrations/005_reversible.rb +10 -0
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +9 -0
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +9 -0
- data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +4 -0
- data/spec/impala_test.rb +290 -0
- data/spec/migrator_test.rb +240 -0
- data/spec/plugin_test.rb +91 -0
- data/spec/prepared_statement_test.rb +327 -0
- data/spec/schema_test.rb +356 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/timezone_test.rb +86 -0
- data/spec/type_test.rb +99 -0
- metadata +294 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
2
|
+
|
|
3
|
+
Sequel.extension :migration
|
|
4
|
+
describe Sequel::Migrator do
|
|
5
|
+
before do
|
|
6
|
+
@db = DB
|
|
7
|
+
@m = Sequel::Migrator
|
|
8
|
+
end
|
|
9
|
+
after do
|
|
10
|
+
@db.drop_table?(:schema_info, :schema_migrations, :sm1111, :sm1122, :sm2222, :sm2233, :sm3333, :sm11111, :sm22222)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should be able to migrate up and down all the way successfully" do
|
|
14
|
+
@dir = 'spec/files/integer_migrations'
|
|
15
|
+
@m.apply(@db, @dir)
|
|
16
|
+
[:schema_info, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal true}
|
|
17
|
+
@db[:schema_info].get(:version).must_equal 3
|
|
18
|
+
@m.apply(@db, @dir, 0)
|
|
19
|
+
[:sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
|
20
|
+
@db[:schema_info].get(:version).must_equal 0
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should be able to migrate up and down to specific versions successfully" do
|
|
24
|
+
@dir = 'spec/files/integer_migrations'
|
|
25
|
+
@m.apply(@db, @dir, 2)
|
|
26
|
+
[:schema_info, :sm1111, :sm2222].each{|n| @db.table_exists?(n).must_equal true}
|
|
27
|
+
@db.table_exists?(:sm3333).must_equal false
|
|
28
|
+
@db[:schema_info].get(:version).must_equal 2
|
|
29
|
+
@m.apply(@db, @dir, 1)
|
|
30
|
+
[:sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
|
31
|
+
@db.table_exists?(:sm1111).must_equal true
|
|
32
|
+
@db[:schema_info].get(:version).must_equal 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should correctly set migration version to the last successful migration if the migration raises an error when migrating up" do
|
|
36
|
+
@dir = 'spec/files/bad_up_migration'
|
|
37
|
+
proc{@m.apply(@db, @dir)}.must_raise Sequel::DatabaseError
|
|
38
|
+
[:schema_info, :sm11111].each{|n| @db.table_exists?(n).must_equal true}
|
|
39
|
+
@db.table_exists?(:sm22222).must_equal false
|
|
40
|
+
@db[:schema_info].get(:version).must_equal 1
|
|
41
|
+
@m.apply(@db, @dir, 0)
|
|
42
|
+
[:sm11111, :sm22222].each{|n| @db.table_exists?(n).must_equal false}
|
|
43
|
+
@db[:schema_info].get(:version).must_equal 0
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should correctly set migration version to the last successful migration if the migration raises an error when migrating down" do
|
|
47
|
+
@dir = 'spec/files/bad_down_migration'
|
|
48
|
+
@m.apply(@db, @dir)
|
|
49
|
+
[:schema_info, :sm11111, :sm22222].each{|n| @db.table_exists?(n).must_equal true}
|
|
50
|
+
@db[:schema_info].get(:version).must_equal 2
|
|
51
|
+
proc{@m.apply(@db, @dir, 0)}.must_raise Sequel::DatabaseError
|
|
52
|
+
[:sm22222].each{|n| @db.table_exists?(n).must_equal false}
|
|
53
|
+
@db.table_exists?(:sm11111).must_equal true
|
|
54
|
+
@db[:schema_info].get(:version).must_equal 1
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "should handle migrating up or down all the way with timestamped migrations" do
|
|
58
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
59
|
+
@m.apply(@db, @dir)
|
|
60
|
+
[:schema_migrations, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal true}
|
|
61
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb 1273253853_3_create_users.rb'
|
|
62
|
+
@m.apply(@db, @dir, 0)
|
|
63
|
+
[:sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
|
64
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal []
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should handle migrating up or down to specific timestamps with timestamped migrations" do
|
|
68
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
69
|
+
@m.apply(@db, @dir, 1273253851)
|
|
70
|
+
[:schema_migrations, :sm1111, :sm2222].each{|n| @db.table_exists?(n).must_equal true}
|
|
71
|
+
@db.table_exists?(:sm3333).must_equal false
|
|
72
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb'
|
|
73
|
+
@m.apply(@db, @dir, 1273253849)
|
|
74
|
+
[:sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
|
75
|
+
@db.table_exists?(:sm1111).must_equal true
|
|
76
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should apply all missing files when migrating up with timestamped migrations" do
|
|
80
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
81
|
+
@m.apply(@db, @dir)
|
|
82
|
+
@dir = 'spec/files/interleaved_timestamped_migrations'
|
|
83
|
+
@m.apply(@db, @dir)
|
|
84
|
+
[:schema_migrations, :sm1111, :sm1122, :sm2222, :sm2233, :sm3333].each{|n| @db.table_exists?(n).must_equal true}
|
|
85
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb 1273253850_create_artists.rb 1273253851_create_nodes.rb 1273253852_create_albums.rb 1273253853_3_create_users.rb'
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should not apply down action to migrations where up action hasn't been applied" do
|
|
89
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
90
|
+
@m.apply(@db, @dir)
|
|
91
|
+
@dir = 'spec/files/interleaved_timestamped_migrations'
|
|
92
|
+
@m.apply(@db, @dir, 0)
|
|
93
|
+
[:sm1111, :sm1122, :sm2222, :sm2233, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
|
94
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal []
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should handle updating to a specific timestamp when interleaving migrations with timestamps" do
|
|
98
|
+
@dir = 'spec/files/timestamped_migrations'
|
|
99
|
+
@m.apply(@db, @dir)
|
|
100
|
+
@dir = 'spec/files/interleaved_timestamped_migrations'
|
|
101
|
+
@m.apply(@db, @dir, 1273253851)
|
|
102
|
+
[:schema_migrations, :sm1111, :sm1122, :sm2222].each{|n| @db.table_exists?(n).must_equal true}
|
|
103
|
+
[:sm2233, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
|
104
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb 1273253850_create_artists.rb 1273253851_create_nodes.rb'
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should correctly update schema_migrations table when an error occurs when migrating up or down using timestamped migrations" do
|
|
108
|
+
@dir = 'spec/files/bad_timestamped_migrations'
|
|
109
|
+
proc{@m.apply(@db, @dir)}.must_raise Sequel::DatabaseError
|
|
110
|
+
[:schema_migrations, :sm1111, :sm2222].each{|n| @db.table_exists?(n).must_equal true}
|
|
111
|
+
@db.table_exists?(:sm3333).must_equal false
|
|
112
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb'
|
|
113
|
+
proc{@m.apply(@db, @dir, 0)}.must_raise Sequel::DatabaseError
|
|
114
|
+
[:sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
|
115
|
+
@db.table_exists?(:sm1111).must_equal true
|
|
116
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb'
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should handle multiple migrations with the same timestamp correctly" do
|
|
120
|
+
@dir = 'spec/files/duplicate_timestamped_migrations'
|
|
121
|
+
@m.apply(@db, @dir)
|
|
122
|
+
[:schema_migrations, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal true}
|
|
123
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb 1273253853_create_nodes.rb 1273253853_create_users.rb'
|
|
124
|
+
@m.apply(@db, @dir, 1273253853)
|
|
125
|
+
[:sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal true}
|
|
126
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb 1273253853_create_nodes.rb 1273253853_create_users.rb'
|
|
127
|
+
@m.apply(@db, @dir, 1273253849)
|
|
128
|
+
[:sm1111].each{|n| @db.table_exists?(n).must_equal true}
|
|
129
|
+
[:sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
|
130
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'1273253849_create_sessions.rb'
|
|
131
|
+
@m.apply(@db, @dir, 1273253848)
|
|
132
|
+
[:sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
|
133
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal []
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "should convert schema_info table to schema_migrations table" do
|
|
137
|
+
@dir = 'spec/files/integer_migrations'
|
|
138
|
+
@m.apply(@db, @dir)
|
|
139
|
+
[:schema_info, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal true}
|
|
140
|
+
[:schema_migrations, :sm1122, :sm2233].each{|n| @db.table_exists?(n).must_equal false}
|
|
141
|
+
|
|
142
|
+
@dir = 'spec/files/convert_to_timestamp_migrations'
|
|
143
|
+
@m.apply(@db, @dir)
|
|
144
|
+
[:schema_info, :sm1111, :sm2222, :sm3333, :schema_migrations, :sm1122, :sm2233].each{|n| @db.table_exists?(n).must_equal true}
|
|
145
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'001_create_sessions.rb 002_create_nodes.rb 003_3_create_users.rb 1273253850_create_artists.rb 1273253852_create_albums.rb'
|
|
146
|
+
|
|
147
|
+
@m.apply(@db, @dir, 4)
|
|
148
|
+
[:schema_info, :schema_migrations, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal true}
|
|
149
|
+
[:sm1122, :sm2233].each{|n| @db.table_exists?(n).must_equal false}
|
|
150
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'001_create_sessions.rb 002_create_nodes.rb 003_3_create_users.rb'
|
|
151
|
+
|
|
152
|
+
@m.apply(@db, @dir, 0)
|
|
153
|
+
[:schema_info, :schema_migrations].each{|n| @db.table_exists?(n).must_equal true}
|
|
154
|
+
[:sm1111, :sm2222, :sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).must_equal false}
|
|
155
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal []
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "should handle unapplied migrations when migrating schema_info table to schema_migrations table" do
|
|
159
|
+
@dir = 'spec/files/integer_migrations'
|
|
160
|
+
@m.apply(@db, @dir, 2)
|
|
161
|
+
[:schema_info, :sm1111, :sm2222].each{|n| @db.table_exists?(n).must_equal true}
|
|
162
|
+
[:schema_migrations, :sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).must_equal false}
|
|
163
|
+
|
|
164
|
+
@dir = 'spec/files/convert_to_timestamp_migrations'
|
|
165
|
+
@m.apply(@db, @dir, 1273253850)
|
|
166
|
+
[:schema_info, :sm1111, :sm2222, :sm3333, :schema_migrations, :sm1122].each{|n| @db.table_exists?(n).must_equal true}
|
|
167
|
+
[:sm2233].each{|n| @db.table_exists?(n).must_equal false}
|
|
168
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'001_create_sessions.rb 002_create_nodes.rb 003_3_create_users.rb 1273253850_create_artists.rb'
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "should handle unapplied migrations when migrating schema_info table to schema_migrations table and target is less than last integer migration version" do
|
|
172
|
+
@dir = 'spec/files/integer_migrations'
|
|
173
|
+
@m.apply(@db, @dir, 1)
|
|
174
|
+
[:schema_info, :sm1111].each{|n| @db.table_exists?(n).must_equal true}
|
|
175
|
+
[:schema_migrations, :sm2222, :sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).must_equal false}
|
|
176
|
+
|
|
177
|
+
@dir = 'spec/files/convert_to_timestamp_migrations'
|
|
178
|
+
@m.apply(@db, @dir, 2)
|
|
179
|
+
[:schema_info, :sm1111, :sm2222, :schema_migrations].each{|n| @db.table_exists?(n).must_equal true}
|
|
180
|
+
[:sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).must_equal false}
|
|
181
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'001_create_sessions.rb 002_create_nodes.rb'
|
|
182
|
+
|
|
183
|
+
@m.apply(@db, @dir)
|
|
184
|
+
[:schema_info, :sm1111, :sm2222, :schema_migrations, :sm3333, :sm1122, :sm2233].each{|n| @db.table_exists?(n).must_equal true}
|
|
185
|
+
@db[:schema_migrations].select_order_map(:filename).must_equal %w'001_create_sessions.rb 002_create_nodes.rb 003_3_create_users.rb 1273253850_create_artists.rb 1273253852_create_albums.rb'
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it "should handle reversible migrations" do
|
|
189
|
+
@dir = 'spec/files/reversible_migrations'
|
|
190
|
+
@db.drop_table?(:a, :b)
|
|
191
|
+
@m.apply(@db, @dir, 1)
|
|
192
|
+
[:schema_info, :a].each{|n| @db.table_exists?(n).must_equal true}
|
|
193
|
+
[:schema_migrations, :b].each{|n| @db.table_exists?(n).must_equal false}
|
|
194
|
+
@db[:a].columns.must_equal [:a]
|
|
195
|
+
|
|
196
|
+
@m.apply(@db, @dir, 2)
|
|
197
|
+
[:schema_info, :a].each{|n| @db.table_exists?(n).must_equal true}
|
|
198
|
+
[:schema_migrations, :b].each{|n| @db.table_exists?(n).must_equal false}
|
|
199
|
+
@db[:a].columns.must_equal [:a, :b]
|
|
200
|
+
|
|
201
|
+
@m.apply(@db, @dir, 3)
|
|
202
|
+
[:schema_info, :a].each{|n| @db.table_exists?(n).must_equal true}
|
|
203
|
+
[:schema_migrations, :b].each{|n| @db.table_exists?(n).must_equal false}
|
|
204
|
+
@db[:a].columns.must_equal [:a, :c]
|
|
205
|
+
|
|
206
|
+
@m.apply(@db, @dir, 4)
|
|
207
|
+
[:schema_info, :b].each{|n| @db.table_exists?(n).must_equal true}
|
|
208
|
+
[:schema_migrations, :a].each{|n| @db.table_exists?(n).must_equal false}
|
|
209
|
+
@db[:b].columns.must_equal [:a, :c]
|
|
210
|
+
|
|
211
|
+
@m.apply(@db, @dir, 5)
|
|
212
|
+
[:schema_info, :b].each{|n| @db.table_exists?(n).must_equal true}
|
|
213
|
+
[:schema_migrations, :a].each{|n| @db.table_exists?(n).must_equal false}
|
|
214
|
+
@db[:b].columns.must_equal [:a, :c, :e]
|
|
215
|
+
|
|
216
|
+
@m.apply(@db, @dir, 4)
|
|
217
|
+
[:schema_info, :b].each{|n| @db.table_exists?(n).must_equal true}
|
|
218
|
+
[:schema_migrations, :a].each{|n| @db.table_exists?(n).must_equal false}
|
|
219
|
+
@db[:b].columns.must_equal [:a, :c]
|
|
220
|
+
|
|
221
|
+
@m.apply(@db, @dir, 3)
|
|
222
|
+
[:schema_info, :a].each{|n| @db.table_exists?(n).must_equal true}
|
|
223
|
+
[:schema_migrations, :b].each{|n| @db.table_exists?(n).must_equal false}
|
|
224
|
+
@db[:a].columns.must_equal [:a, :c]
|
|
225
|
+
|
|
226
|
+
@m.apply(@db, @dir, 2)
|
|
227
|
+
[:schema_info, :a].each{|n| @db.table_exists?(n).must_equal true}
|
|
228
|
+
[:schema_migrations, :b].each{|n| @db.table_exists?(n).must_equal false}
|
|
229
|
+
@db[:a].columns.must_equal [:a, :b]
|
|
230
|
+
|
|
231
|
+
@m.apply(@db, @dir, 1)
|
|
232
|
+
[:schema_info, :a].each{|n| @db.table_exists?(n).must_equal true}
|
|
233
|
+
[:schema_migrations, :b].each{|n| @db.table_exists?(n).must_equal false}
|
|
234
|
+
@db[:a].columns.must_equal [:a]
|
|
235
|
+
|
|
236
|
+
@m.apply(@db, @dir, 0)
|
|
237
|
+
[:schema_info].each{|n| @db.table_exists?(n).must_equal true}
|
|
238
|
+
[:schema_migrations, :a, :b].each{|n| @db.table_exists?(n).must_equal false}
|
|
239
|
+
end
|
|
240
|
+
end
|
data/spec/plugin_test.rb
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
2
|
+
|
|
3
|
+
describe "date_arithmetic extension" do
|
|
4
|
+
asd = begin
|
|
5
|
+
require 'active_support/duration'
|
|
6
|
+
require 'active_support/inflector'
|
|
7
|
+
require 'active_support/core_ext/string/inflections'
|
|
8
|
+
true
|
|
9
|
+
rescue LoadError
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
before(:all) do
|
|
14
|
+
@db = DB
|
|
15
|
+
@db.extension(:date_arithmetic)
|
|
16
|
+
if @db.database_type == :sqlite
|
|
17
|
+
@db.use_timestamp_timezones = false
|
|
18
|
+
end
|
|
19
|
+
@date = Date.civil(2010, 7, 12)
|
|
20
|
+
@dt = Time.local(2010, 7, 12)
|
|
21
|
+
if asd
|
|
22
|
+
@d0 = ActiveSupport::Duration.new(0, [[:days, 0]])
|
|
23
|
+
@d1 = ActiveSupport::Duration.new(1, [[:days, 1]])
|
|
24
|
+
@d2 = ActiveSupport::Duration.new(1, [[:years, 1], [:months, 1], [:days, 1], [:minutes, 61], [:seconds, 1]])
|
|
25
|
+
end
|
|
26
|
+
@h0 = {:days=>0}
|
|
27
|
+
@h1 = {:days=>1, :years=>nil, :hours=>0}
|
|
28
|
+
@h2 = {:years=>1, :months=>1, :days=>1, :hours=>1, :minutes=>1, :seconds=>1}
|
|
29
|
+
@a1 = Time.local(2010, 7, 13)
|
|
30
|
+
@a2 = Time.local(2011, 8, 13, 1, 1, 1)
|
|
31
|
+
@s1 = Time.local(2010, 7, 11)
|
|
32
|
+
@s2 = Time.local(2009, 6, 10, 22, 58, 59)
|
|
33
|
+
@check = lambda do |meth, in_date, in_interval, should|
|
|
34
|
+
output = @db.get(Sequel.send(meth, in_date, in_interval))
|
|
35
|
+
output = Time.parse(output.to_s) unless output.is_a?(Time) || output.is_a?(DateTime)
|
|
36
|
+
output.year.must_equal should.year
|
|
37
|
+
output.month.must_equal should.month
|
|
38
|
+
output.day.must_equal should.day
|
|
39
|
+
output.hour.must_equal should.hour
|
|
40
|
+
output.min.must_equal should.min
|
|
41
|
+
output.sec.must_equal should.sec
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
after(:all) do
|
|
45
|
+
if @db.database_type == :sqlite
|
|
46
|
+
@db.use_timestamp_timezones = true
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if asd
|
|
51
|
+
it "be able to use Sequel.date_add to add ActiveSupport::Duration objects to dates and datetimes" do
|
|
52
|
+
@check.call(:date_add, @date, @d0, @dt)
|
|
53
|
+
@check.call(:date_add, @date, @d1, @a1)
|
|
54
|
+
@check.call(:date_add, @date, @d2, @a2)
|
|
55
|
+
|
|
56
|
+
@check.call(:date_add, @dt, @d0, @dt)
|
|
57
|
+
@check.call(:date_add, @dt, @d1, @a1)
|
|
58
|
+
@check.call(:date_add, @dt, @d2, @a2)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "be able to use Sequel.date_sub to subtract ActiveSupport::Duration objects from dates and datetimes" do
|
|
62
|
+
@check.call(:date_sub, @date, @d0, @dt)
|
|
63
|
+
@check.call(:date_sub, @date, @d1, @s1)
|
|
64
|
+
@check.call(:date_sub, @date, @d2, @s2)
|
|
65
|
+
|
|
66
|
+
@check.call(:date_sub, @dt, @d0, @dt)
|
|
67
|
+
@check.call(:date_sub, @dt, @d1, @s1)
|
|
68
|
+
@check.call(:date_sub, @dt, @d2, @s2)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "be able to use Sequel.date_add to add interval hashes to dates and datetimes" do
|
|
73
|
+
@check.call(:date_add, @date, @h0, @dt)
|
|
74
|
+
@check.call(:date_add, @date, @h1, @a1)
|
|
75
|
+
@check.call(:date_add, @date, @h2, @a2)
|
|
76
|
+
|
|
77
|
+
@check.call(:date_add, @dt, @h0, @dt)
|
|
78
|
+
@check.call(:date_add, @dt, @h1, @a1)
|
|
79
|
+
@check.call(:date_add, @dt, @h2, @a2)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "be able to use Sequel.date_sub to subtract interval hashes from dates and datetimes" do
|
|
83
|
+
@check.call(:date_sub, @date, @h0, @dt)
|
|
84
|
+
@check.call(:date_sub, @date, @h1, @s1)
|
|
85
|
+
@check.call(:date_sub, @date, @h2, @s2)
|
|
86
|
+
|
|
87
|
+
@check.call(:date_sub, @dt, @h0, @dt)
|
|
88
|
+
@check.call(:date_sub, @dt, @h1, @s1)
|
|
89
|
+
@check.call(:date_sub, @dt, @h2, @s2)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
2
|
+
|
|
3
|
+
describe "Prepared Statements and Bound Arguments" do
|
|
4
|
+
before do
|
|
5
|
+
@db = DB
|
|
6
|
+
@db.create_table!(:items) do
|
|
7
|
+
primary_key :id
|
|
8
|
+
integer :numb
|
|
9
|
+
end
|
|
10
|
+
@c = Class.new(Sequel::Model(:items))
|
|
11
|
+
@ds = @db[:items]
|
|
12
|
+
@ds.insert(:id=>1, :numb=>10)
|
|
13
|
+
@pr = @ds.requires_placeholder_type_specifiers? ? proc{|i| :"#{i}__integer"} : proc{|i| i}
|
|
14
|
+
end
|
|
15
|
+
after do
|
|
16
|
+
@db.drop_table?(:items)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should support bound variables when selecting" do
|
|
20
|
+
@ds.filter(:numb=>:$n).call(:each, :n=>10){|h| h.must_equal(:id=>1, :numb=>10)}
|
|
21
|
+
@ds.filter(:numb=>:$n).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
22
|
+
@ds.filter(:numb=>:$n).call(:all, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
23
|
+
@ds.filter(:numb=>:$n).call(:first, :n=>10).must_equal(:id=>1, :numb=>10)
|
|
24
|
+
@ds.filter(:numb=>:$n).call([:map, :numb], :n=>10).must_equal [10]
|
|
25
|
+
@ds.filter(:numb=>:$n).call([:to_hash, :id, :numb], :n=>10).must_equal(1=>10)
|
|
26
|
+
@ds.filter(:numb=>:$n).call([:to_hash_groups, :id, :numb], :n=>10).must_equal(1=>[10])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should support blocks for each, select, all, and map when using bound variables" do
|
|
30
|
+
a = []
|
|
31
|
+
@ds.filter(:numb=>:$n).call(:each, :n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
|
|
32
|
+
@ds.filter(:numb=>:$n).call(:select, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
|
|
33
|
+
@ds.filter(:numb=>:$n).call(:all, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
|
|
34
|
+
@ds.filter(:numb=>:$n).call([:map], :n=>10){|r| r[:numb] * 2}.must_equal [20]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should support binding variables before the call with #bind" do
|
|
38
|
+
@ds.filter(:numb=>:$n).bind(:n=>10).call(:select).must_equal [{:id=>1, :numb=>10}]
|
|
39
|
+
@ds.filter(:numb=>:$n).bind(:n=>10).call(:all).must_equal [{:id=>1, :numb=>10}]
|
|
40
|
+
@ds.filter(:numb=>:$n).bind(:n=>10).call(:first).must_equal(:id=>1, :numb=>10)
|
|
41
|
+
|
|
42
|
+
@ds.bind(:n=>10).filter(:numb=>:$n).call(:select).must_equal [{:id=>1, :numb=>10}]
|
|
43
|
+
@ds.bind(:n=>10).filter(:numb=>:$n).call(:all).must_equal [{:id=>1, :numb=>10}]
|
|
44
|
+
@ds.bind(:n=>10).filter(:numb=>:$n).call(:first).must_equal(:id=>1, :numb=>10)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should allow overriding variables specified with #bind" do
|
|
48
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
49
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).call(:all, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
50
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).call(:first, :n=>10).must_equal(:id=>1, :numb=>10)
|
|
51
|
+
|
|
52
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:select).must_equal [{:id=>1, :numb=>10}]
|
|
53
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:all).must_equal [{:id=>1, :numb=>10}]
|
|
54
|
+
@ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:first).must_equal(:id=>1, :numb=>10)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "should support placeholder literal strings with call" do
|
|
58
|
+
@ds.filter("numb = ?", :$n).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should support named placeholder literal strings and handle multiple named placeholders correctly with call" do
|
|
62
|
+
@ds.filter("numb = :n", :n=>:$n).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
63
|
+
@ds.insert(:id=>2, :numb=>20)
|
|
64
|
+
@ds.insert(:id=>3, :numb=>30)
|
|
65
|
+
@ds.filter("numb > :n1 AND numb < :n2 AND numb = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1).call(:select, :n3=>20, :n2=>30, :n1=>10).must_equal [{:id=>2, :numb=>20}]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should support datasets with static sql and placeholders with call" do
|
|
69
|
+
@db["SELECT * FROM items WHERE numb = ?", :$n].call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should support subselects with call" do
|
|
73
|
+
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n)).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should support subselects with exists with call" do
|
|
77
|
+
@ds.filter(:id=>:$i).filter(@ds.select(:numb).filter(:numb=>:$n).exists).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should support subselects with literal strings with call" do
|
|
81
|
+
@ds.filter(:id=>:$i, :numb=>@ds.select(:numb).filter("numb = ?", :$n)).call(:select, :n=>10, :i=>1).must_equal [{:id=>1, :numb=>10}]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should support subselects with static sql and placeholders with call" do
|
|
85
|
+
@ds.filter(:id=>:$i, :numb=>@db["SELECT numb FROM items WHERE numb = ?", :$n]).call(:select, :n=>10, :i=>1).must_equal [{:id=>1, :numb=>10}]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should support subselects of subselects with call" do
|
|
89
|
+
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should support using a bound variable for a limit and offset" do
|
|
93
|
+
@ds.insert(:id=>2, :numb=>20)
|
|
94
|
+
ds = @ds.limit(:$n, :$n2).order(:id)
|
|
95
|
+
ds.call(:select, :n=>1, :n2=>0).must_equal [{:id=>1, :numb=>10}]
|
|
96
|
+
ds.call(:select, :n=>1, :n2=>1).must_equal [{:id=>2, :numb=>20}]
|
|
97
|
+
ds.call(:select, :n=>1, :n2=>2).must_equal []
|
|
98
|
+
ds.call(:select, :n=>2, :n2=>0).must_equal [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
|
|
99
|
+
ds.call(:select, :n=>2, :n2=>1).must_equal [{:id=>2, :numb=>20}]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should support bound variables with insert" do
|
|
103
|
+
@ds.call(:insert, {:n=>20}, :numb=>:$n)
|
|
104
|
+
@ds.count.must_equal 2
|
|
105
|
+
@ds.order(:id).map(:numb).must_equal [10, 20]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "should have insert return primary key value when using bound arguments" do
|
|
109
|
+
assert_nil(@ds.call(:insert, {:n=>20}, :numb=>:$n, :id=>2))
|
|
110
|
+
@ds.filter(:id=>2).first[:numb].must_equal 20
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should support bound variables with delete" do
|
|
114
|
+
assert_nil(@ds.filter(:numb=>:$n).call(:delete, :n=>10))
|
|
115
|
+
@ds.count.must_equal 0
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "should support prepared statements when selecting" do
|
|
119
|
+
@ds.filter(:numb=>:$n).prepare(:each, :select_n)
|
|
120
|
+
@db.call(:select_n, :n=>10){|h| h.must_equal(:id=>1, :numb=>10)}
|
|
121
|
+
@ds.filter(:numb=>:$n).prepare(:select, :select_n)
|
|
122
|
+
@db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
123
|
+
@ds.filter(:numb=>:$n).prepare(:all, :select_n)
|
|
124
|
+
@db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
125
|
+
@ds.filter(:numb=>:$n).prepare(:first, :select_n)
|
|
126
|
+
@db.call(:select_n, :n=>10).must_equal(:id=>1, :numb=>10)
|
|
127
|
+
@ds.filter(:numb=>:$n).prepare([:map, :numb], :select_n)
|
|
128
|
+
@db.call(:select_n, :n=>10).must_equal [10]
|
|
129
|
+
@ds.filter(:numb=>:$n).prepare([:to_hash, :id, :numb], :select_n)
|
|
130
|
+
@db.call(:select_n, :n=>10).must_equal(1=>10)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "should support blocks for each, select, all, and map when using prepared statements" do
|
|
134
|
+
a = []
|
|
135
|
+
@ds.filter(:numb=>:$n).prepare(:each, :select_n).call(:n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
|
|
136
|
+
a = []
|
|
137
|
+
@db.call(:select_n, :n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
|
|
138
|
+
@ds.filter(:numb=>:$n).prepare(:select, :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
|
|
139
|
+
@db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
|
|
140
|
+
@ds.filter(:numb=>:$n).prepare(:all, :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
|
|
141
|
+
@db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
|
|
142
|
+
@ds.filter(:numb=>:$n).prepare([:map], :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [20]
|
|
143
|
+
@db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [20]
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "should support prepared statements being called multiple times with different arguments" do
|
|
147
|
+
@ds.filter(:numb=>:$n).prepare(:select, :select_n)
|
|
148
|
+
@db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
149
|
+
@db.call(:select_n, :n=>0).must_equal []
|
|
150
|
+
@db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should support placeholder literal strings with prepare" do
|
|
154
|
+
@ds.filter("numb = ?", :$n).prepare(:select, :seq_select).call(:n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should support named placeholder literal strings and handle multiple named placeholders correctly with prepare" do
|
|
158
|
+
@ds.filter("numb = :n", :n=>:$n).prepare(:select, :seq_select).call(:n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
159
|
+
@ds.insert(:id=>2, :numb=>20)
|
|
160
|
+
@ds.insert(:id=>3, :numb=>30)
|
|
161
|
+
@ds.filter("numb > :n1 AND numb < :n2 AND numb = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1).call(:select, :n3=>20, :n2=>30, :n1=>10).must_equal [{:id=>2, :numb=>20}]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "should support datasets with static sql and placeholders with prepare" do
|
|
165
|
+
@db["SELECT * FROM items WHERE numb = ?", :$n].prepare(:select, :seq_select).call(:n=>10).must_equal [{:id=>1, :numb=>10}]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "should support subselects with prepare" do
|
|
169
|
+
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n)).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "should support subselects with exists with prepare" do
|
|
173
|
+
@ds.filter(:id=>:$i).filter(@ds.select(:numb).filter(:numb=>:$n).exists).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "should support subselects with literal strings with prepare" do
|
|
177
|
+
@ds.filter(:id=>:$i, :numb=>@ds.select(:numb).filter("numb = ?", :$n)).prepare(:select, :seq_select).call(:n=>10, :i=>1).must_equal [{:id=>1, :numb=>10}]
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "should support subselects with static sql and placeholders with prepare" do
|
|
181
|
+
@ds.filter(:id=>:$i, :numb=>@db["SELECT numb FROM items WHERE numb = ?", :$n]).prepare(:select, :seq_select).call(:n=>10, :i=>1).must_equal [{:id=>1, :numb=>10}]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should support subselects of subselects with prepare" do
|
|
185
|
+
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it "should support using a prepared_statement for a limit and offset" do
|
|
189
|
+
@ds.insert(:id=>2, :numb=>20)
|
|
190
|
+
ps = @ds.limit(:$n, :$n2).order(:id).prepare(:select, :seq_select)
|
|
191
|
+
ps.call(:n=>1, :n2=>0).must_equal [{:id=>1, :numb=>10}]
|
|
192
|
+
ps.call(:n=>1, :n2=>1).must_equal [{:id=>2, :numb=>20}]
|
|
193
|
+
ps.call(:n=>1, :n2=>2).must_equal []
|
|
194
|
+
ps.call(:n=>2, :n2=>0).must_equal [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
|
|
195
|
+
ps.call(:n=>2, :n2=>1).must_equal [{:id=>2, :numb=>20}]
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "should support prepared statements with insert" do
|
|
199
|
+
@ds.prepare(:insert, :insert_n, :numb=>:$n)
|
|
200
|
+
@db.call(:insert_n, :n=>20)
|
|
201
|
+
@ds.count.must_equal 2
|
|
202
|
+
@ds.order(:id).map(:numb).must_equal [10, 20]
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it "should have insert return primary key value when using prepared statements" do
|
|
206
|
+
@ds.prepare(:insert, :insert_n, :numb=>:$n, :id=>2)
|
|
207
|
+
assert_nil(@db.call(:insert_n, :id=>2, :n=>20))
|
|
208
|
+
@ds.filter(:id=>2).first[:numb].must_equal 20
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "should support prepared statements with delete" do
|
|
212
|
+
@ds.filter(:numb=>:$n).prepare(:delete, :delete_n)
|
|
213
|
+
assert_nil(@db.call(:delete_n, :n=>10))
|
|
214
|
+
@ds.count.must_equal 0
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "model datasets should return model instances when using select, all, and first with bound variables" do
|
|
218
|
+
@c.filter(:numb=>:$n).call(:select, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
|
|
219
|
+
@c.filter(:numb=>:$n).call(:all, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
|
|
220
|
+
@c.filter(:numb=>:$n).call(:first, :n=>10).must_equal @c.load(:id=>1, :numb=>10)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "model datasets should return model instances when using select, all, and first with prepared statements" do
|
|
224
|
+
@c.filter(:numb=>:$n).prepare(:select, :select_n1)
|
|
225
|
+
@db.call(:select_n1, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
|
|
226
|
+
@c.filter(:numb=>:$n).prepare(:all, :select_n1)
|
|
227
|
+
@db.call(:select_n1, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
|
|
228
|
+
@c.filter(:numb=>:$n).prepare(:first, :select_n1)
|
|
229
|
+
@db.call(:select_n1, :n=>10).must_equal @c.load(:id=>1, :numb=>10)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
describe "Bound Argument Types" do
|
|
234
|
+
before do
|
|
235
|
+
@db = DB
|
|
236
|
+
@db.create_table!(:items) do
|
|
237
|
+
primary_key :id
|
|
238
|
+
DateTime :dt
|
|
239
|
+
String :s
|
|
240
|
+
Time :t
|
|
241
|
+
Float :f
|
|
242
|
+
TrueClass :b
|
|
243
|
+
end
|
|
244
|
+
@ds = @db[:items]
|
|
245
|
+
@vs = {:id=>1, :dt=>DateTime.civil(2010, 10, 12, 13, 14, 15), :f=>1.0, :s=>'str', :t=>Time.at(20101010), :b=>true}
|
|
246
|
+
@ds.insert(@vs)
|
|
247
|
+
end
|
|
248
|
+
after do
|
|
249
|
+
@db.drop_table?(:items)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "should handle float type" do
|
|
253
|
+
@ds.filter(:f=>:$x).prepare(:first, :ps_float).call(:x=>@vs[:f])[:f].must_equal @vs[:f]
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it "should handle string type" do
|
|
257
|
+
@ds.filter(:s=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:s])[:s].must_equal @vs[:s]
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it "should handle boolean type" do
|
|
261
|
+
@ds.filter(:b=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:b])[:b].must_equal @vs[:b]
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
describe "Dataset#unbind" do
|
|
266
|
+
before do
|
|
267
|
+
@ds = ds = DB[:items]
|
|
268
|
+
@ct = proc do |t, v|
|
|
269
|
+
DB.create_table!(:items) do
|
|
270
|
+
column :c, t
|
|
271
|
+
end
|
|
272
|
+
ds.insert(:c=>v)
|
|
273
|
+
end
|
|
274
|
+
@u = proc{|ds1| ds2, bv = ds1.unbind; ds2.call(:first, bv)}
|
|
275
|
+
end
|
|
276
|
+
after do
|
|
277
|
+
DB.drop_table?(:items)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it "should unbind values assigned to equality and inequality statements" do
|
|
281
|
+
@ct[Integer, 10]
|
|
282
|
+
@u[@ds.filter(:c=>10)].must_equal(:c=>10)
|
|
283
|
+
assert_nil(@u[@ds.exclude(:c=>10)])
|
|
284
|
+
assert_nil(@u[@ds.filter{c < 10}])
|
|
285
|
+
@u[@ds.filter{c <= 10}].must_equal(:c=>10)
|
|
286
|
+
assert_nil(@u[@ds.filter{c > 10}])
|
|
287
|
+
@u[@ds.filter{c >= 10}].must_equal(:c=>10)
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
it "should handle numerics and strings" do
|
|
291
|
+
@ct[Integer, 10]
|
|
292
|
+
@u[@ds.filter(:c=>10)].must_equal(:c=>10)
|
|
293
|
+
@ct[Float, 0.0]
|
|
294
|
+
@u[@ds.filter{c < 1}].must_equal(:c=>0.0)
|
|
295
|
+
@ct[String, 'foo']
|
|
296
|
+
@u[@ds.filter(:c=>'foo')].must_equal(:c=>'foo')
|
|
297
|
+
|
|
298
|
+
DB.create_table!(:items) do
|
|
299
|
+
BigDecimal :c, :size=>[15,2]
|
|
300
|
+
end
|
|
301
|
+
@ds.insert(:c=>BigDecimal.new('1.1'))
|
|
302
|
+
@u[@ds.filter{c > 0}].must_equal(:c=>BigDecimal.new('1.1'))
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
it "should handle QualifiedIdentifiers" do
|
|
306
|
+
@ct[Integer, 10]
|
|
307
|
+
@u[@ds.filter{items__c > 1}].must_equal(:c=>10)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
it "should handle deep nesting" do
|
|
311
|
+
DB.create_table!(:items) do
|
|
312
|
+
Integer :a
|
|
313
|
+
Integer :b
|
|
314
|
+
Integer :c
|
|
315
|
+
Integer :d
|
|
316
|
+
end
|
|
317
|
+
@ds.insert(:a=>2, :b=>0, :c=>3, :d=>5)
|
|
318
|
+
@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and(Sequel.case({~Sequel.expr(:d=>4)=>1}, 0) => 1)].must_equal(:a=>2, :b=>0, :c=>3, :d=>5)
|
|
319
|
+
assert_nil(@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and(Sequel.case({~Sequel.expr(:d=>5)=>1}, 0) => 1)])
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it "should handle case where the same variable has the same value in multiple places " do
|
|
323
|
+
@ct[Integer, 1]
|
|
324
|
+
@u[@ds.filter{c > 1}.or{c < 1}.invert].must_equal(:c=>1)
|
|
325
|
+
assert_nil(@u[@ds.filter{c > 1}.or{c < 1}])
|
|
326
|
+
end
|
|
327
|
+
end
|