dbd-sqlanywhere 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,6 +1,12 @@
1
1
  =CHANGE LOG
2
2
 
3
+ =====0.1.1 -- 2008/11/06
4
+ - Changed file permissions on archives
5
+ - Changed archives to be specific to platform (.zip on windows, .tar.gz
6
+ otherwise)
7
+ - Removed the default rake task
8
+
3
9
  =====0.1.0 -- 2008/10/29
4
10
  - Initial Release
5
- - Wraps DBCAPI funcationality
11
+ - Wraps DBCAPI functionality
6
12
  - Tested against DBI 0.4
data/README CHANGED
@@ -29,7 +29,7 @@ The connection string takes the general form:
29
29
  where,
30
30
  [DB_NAME] is the name of the database you wish to connect to
31
31
  [USER_NAME] is the username
32
- [PASSWORD] is the correspoding password for the username
32
+ [PASSWORD] is the corresponding password for the username
33
33
 
34
34
  [OPTIONS] is a hash of additional options for the connection.
35
35
 
@@ -37,6 +37,12 @@ For example, to start with named connection called 'ruby_dbi' you can use:
37
37
 
38
38
  dbh = DBI.connect('DBI:SQLAnywhere:Test', 'dba', 'sql', {:CON => "ruby_dbi"})
39
39
 
40
+ ==Running Test Suite
41
+
42
+ For information on running the Ruby/DBI DBD Tests, please see
43
+
44
+ test/DBD_TESTS
45
+
40
46
  ==Driver-Specific Features
41
47
 
42
48
  At the time of this writing, there was no standard way to handle INOUT and OUT parameters
@@ -91,7 +97,7 @@ to retrieve the output value using the :name supplied at binding time.
91
97
  buffer = "-some_string-"
92
98
  prefix = "PREFIX"
93
99
 
94
- # preparing the statment
100
+ # preparing the statement
95
101
  sth = dbh.prepare("call foo( ?, ?, ?, ? )")
96
102
 
97
103
  # Binding buffer column as :buf, and str_len column as :len
@@ -37,7 +37,7 @@ module DBI
37
37
  module DBD
38
38
  module SQLAnywhere
39
39
 
40
- VERSION = "0.1.0"
40
+ VERSION = "0.1.1"
41
41
 
42
42
  def self.driver_name
43
43
  "SQLAnywhere"
@@ -98,7 +98,7 @@ module SQLAnywhere
98
98
  end
99
99
 
100
100
 
101
- # This module provides funcationality that is used by all the DBD classes
101
+ # This module provides functionality that is used by all the DBD classes
102
102
  module Utility
103
103
 
104
104
  NO_DIRECTION = 0
@@ -170,6 +170,6 @@ end # module SQLAnywhere
170
170
  end # module DBD
171
171
  end # module DBI
172
172
 
173
- require 'dbd/SQLAnywhere/driver'
174
- require 'dbd/SQLAnywhere/database'
175
- require 'dbd/SQLAnywhere/statement'
173
+ require 'dbd/sqlanywhere/driver'
174
+ require 'dbd/sqlanywhere/database'
175
+ require 'dbd/sqlanywhere/statement'
data/test/DBD_TESTS ADDED
@@ -0,0 +1,48 @@
1
+ ================================================================================
2
+ Using DBD tests
3
+ ================================================================================
4
+
5
+ Create a YAML file named .ruby-dbi.test-config.yaml in your home directory.
6
+
7
+ This file is a hash of keys that determine what you want to test and how you
8
+ access the databases related to those tests.
9
+
10
+ The key 'dbtypes' is an array which determines what tests you want to run. They
11
+ *do not* correspond to the driver names, they correspond to the test
12
+ directories that were made for them.
13
+
14
+ Each 'dbtype' has a key that contains a hash of values:
15
+ - username: the username of your account
16
+ - password: the password for your account
17
+ - dbname: the name of the database to connect to
18
+
19
+ NOTE that tests expect to connect to a database on localhost currently. This
20
+ may be fixed in the future, especially when we start writing Oracle and
21
+ SQLServer tests.
22
+
23
+ Each DBD test relies on database semantics which may not match up entirely with
24
+ this configuration. For instance, the postgresql tests expect you to be able to
25
+ work with the database directly via the `psql' client. This is something which
26
+ will eventually be remedied as time and ability allows.
27
+
28
+ Here is a sample configuration to get you started with the postgresql tests:
29
+
30
+ ################################################################################
31
+
32
+ ---
33
+ dbtypes:
34
+ - postgresql
35
+ postgresql:
36
+ username: erikh
37
+ password: monkeys
38
+ dbname: rubytest
39
+
40
+ ################################################################################
41
+
42
+ NOTE the --- is part of the file and is not a separator.
43
+
44
+ ================================================================================
45
+ Writing DBD tests
46
+ ================================================================================
47
+
48
+ Coming soon.
@@ -0,0 +1,157 @@
1
+ @class = Class.new(DBDConfig.testbase(DBDConfig.current_dbtype)) do
2
+ def test_ping
3
+ assert @dbh.ping
4
+ # XXX if it isn't obvious, this should be tested better. Not sure what
5
+ # good behavior is yet.
6
+ end
7
+
8
+ def test_columns
9
+ assert_nothing_raised do
10
+ cols = @dbh.columns("precision_test")
11
+
12
+ assert(cols)
13
+ assert_kind_of(Array, cols)
14
+ assert_equal(2, cols.length)
15
+
16
+ # the first column should always be "text_field" and have the following
17
+ # properties:
18
+ assert_equal("text_field", cols[0]["name"])
19
+ assert(!cols[0]["nullable"])
20
+
21
+ assert_equal(20, cols[0]["precision"])
22
+ # scale can be either nil or 0 for character types.
23
+ case cols[0]["scale"]
24
+ when nil
25
+ assert_equal(nil, cols[0]["scale"])
26
+ when 0
27
+ assert_equal(0, cols[0]["scale"])
28
+ else
29
+ flunk "scale can be either 0 or nil for character types"
30
+ end
31
+
32
+ assert_equal(
33
+ DBI::Type::Varchar,
34
+ DBI::TypeUtil.type_name_to_module(cols[0]["type_name"])
35
+ )
36
+
37
+ # the second column should always be "integer_field" and have the following
38
+ # properties:
39
+ assert_equal("integer_field", cols[1]["name"])
40
+ assert(cols[1]["nullable"])
41
+ assert_equal(1, cols[1]["scale"])
42
+ assert_equal(2, cols[1]["precision"])
43
+ assert_equal(
44
+ DBI::Type::Decimal,
45
+ DBI::TypeUtil.type_name_to_module(cols[1]["type_name"])
46
+ )
47
+
48
+ # finally, we ensure that every column in the array is a ColumnInfo
49
+ # object
50
+ cols.each { |col| assert_kind_of(DBI::ColumnInfo, col) }
51
+ end
52
+ end
53
+
54
+ def test_prepare
55
+ @sth = @dbh.prepare('select * from names')
56
+
57
+ assert @sth
58
+ assert_kind_of DBI::StatementHandle, @sth
59
+
60
+ @sth.finish
61
+ end
62
+
63
+ def test_do
64
+ assert_equal 1, @dbh.do("insert into names (name, age) values (?, ?)", "Billy", 21)
65
+ @sth = @dbh.prepare("select * from names where name = ?")
66
+ @sth.execute("Billy")
67
+ assert_equal ["Billy", 21], @sth.fetch
68
+ @sth.finish
69
+ end
70
+
71
+ def test_tables
72
+ tables = @dbh.tables.sort
73
+
74
+ # since this is a general test, let's prune the system tables
75
+ # FIXME not so sure if this should be a general test anymore.
76
+ if dbtype == "odbc"
77
+ tables -= [
78
+ "administrable_role_authorizations",
79
+ "applicable_roles",
80
+ "attributes",
81
+ "check_constraint_routine_usage",
82
+ "check_constraints",
83
+ "column_domain_usage",
84
+ "column_privileges",
85
+ "column_udt_usage",
86
+ "columns",
87
+ "constraint_column_usage",
88
+ "constraint_table_usage",
89
+ "data_type_privileges",
90
+ "domain_constraints",
91
+ "domain_udt_usage",
92
+ "domains",
93
+ "element_types",
94
+ "enabled_roles",
95
+ "information_schema_catalog_name",
96
+ "key_column_usage",
97
+ "parameters",
98
+ "referential_constraints",
99
+ "role_column_grants",
100
+ "role_routine_grants",
101
+ "role_table_grants",
102
+ "role_usage_grants",
103
+ "routine_privileges",
104
+ "routines",
105
+ "schemata",
106
+ "sequences",
107
+ "sql_features",
108
+ "sql_implementation_info",
109
+ "sql_languages",
110
+ "sql_packages",
111
+ "sql_parts",
112
+ "sql_sizing",
113
+ "sql_sizing_profiles",
114
+ "table_constraints",
115
+ "table_privileges",
116
+ "tables",
117
+ "triggered_update_columns",
118
+ "triggers",
119
+ "usage_privileges",
120
+ "view_column_usage",
121
+ "view_routine_usage",
122
+ "view_table_usage",
123
+ "views"
124
+ ]
125
+ end
126
+
127
+ case dbtype
128
+ when "postgresql"
129
+ tables.reject! { |x| x =~ /^pg_/ }
130
+ assert_equal %w(array_test bit_test blob_test boolean_test bytea_test db_specific_types_test field_types_test names precision_test time_test timestamp_test view_names), tables
131
+ else
132
+ assert_equal %w(bit_test blob_test boolean_test db_specific_types_test field_types_test names precision_test time_test timestamp_test view_names), tables
133
+ end
134
+ end
135
+
136
+ def test_attrs
137
+ # test defaults
138
+ assert @dbh["AutoCommit"] # should be true
139
+
140
+ # test setting
141
+ assert !(@dbh["AutoCommit"] = false)
142
+ assert !@dbh["AutoCommit"]
143
+
144
+ # test committing an outstanding transaction
145
+
146
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
147
+ @sth.execute("Billy", 22)
148
+ @sth.finish
149
+
150
+ assert @dbh["AutoCommit"] = true # should commit at this point
151
+
152
+ @sth = @dbh.prepare("select * from names where name = ?")
153
+ @sth.execute("Billy")
154
+ assert_equal [ "Billy", 22 ], @sth.fetch
155
+ @sth.finish
156
+ end
157
+ end
@@ -0,0 +1,249 @@
1
+ @class = Class.new(DBDConfig.testbase(DBDConfig.current_dbtype)) do
2
+
3
+ def test_execute
4
+ assert_nothing_raised do
5
+ @dbh.execute("select * from names order by age") do |sth|
6
+ assert_equal([["Joe", 19], ["Bob", 21], ["Jim", 30]], sth.fetch_all)
7
+ end
8
+ end
9
+ end
10
+
11
+ def test_quoting # FIXME breaks sqlite-ruby to a segfault - research
12
+ @sth = nil
13
+
14
+ assert_nothing_raised do
15
+ if dbtype == "postgresql"
16
+ @sth = @dbh.prepare('select E\'\\\\\'')
17
+ else
18
+ @sth = @dbh.prepare('select \'\\\\\'')
19
+ end
20
+ @sth.execute
21
+ row = @sth.fetch
22
+ assert_equal ['\\'], row
23
+ @sth.finish
24
+ end
25
+ end
26
+
27
+ def test_duplicate_columns
28
+ assert_nothing_raised do
29
+ @sth = @dbh.prepare("select name, name from names where name = ?")
30
+ @sth.execute("Bob")
31
+ assert_equal [["Bob", "Bob"]], @sth.fetch_all
32
+ @sth.finish
33
+ end
34
+ end
35
+
36
+ def test_columninfo
37
+ @sth = nil
38
+
39
+ assert_nothing_raised do
40
+ @sth = @dbh.prepare("select * from precision_test")
41
+ @sth.execute
42
+
43
+ cols = @sth.column_info
44
+
45
+ assert(cols)
46
+ assert_kind_of(Array, cols)
47
+ assert_equal(2, cols.length)
48
+
49
+ # the first column should always be "text_field" and have the following
50
+ # properties:
51
+ assert_equal("text_field", cols[0]["name"])
52
+ assert_equal(20, cols[0]["precision"])
53
+ # scale can be either nil or 0 for character types.
54
+ case cols[0]["scale"]
55
+ when nil
56
+ assert_equal(nil, cols[0]["scale"])
57
+ when 0
58
+ assert_equal(0, cols[0]["scale"])
59
+ else
60
+ flunk "scale can be either 0 or nil for character types"
61
+ end
62
+
63
+ assert_equal(
64
+ DBI::Type::Varchar,
65
+ DBI::TypeUtil.type_name_to_module(cols[0]["type_name"])
66
+ )
67
+
68
+ # the second column should always be "integer_field" and have the following
69
+ # properties:
70
+ assert_equal("integer_field", cols[1]["name"])
71
+ assert_equal(1, cols[1]["scale"])
72
+ assert_equal(2, cols[1]["precision"])
73
+ assert_equal(
74
+ DBI::Type::Decimal,
75
+ DBI::TypeUtil.type_name_to_module(cols[1]["type_name"])
76
+ )
77
+
78
+ cols.each { |col| assert_kind_of(DBI::ColumnInfo, col) }
79
+ @sth.finish
80
+ end
81
+ end
82
+
83
+ def test_duplicate_columns
84
+ assert_nothing_raised do
85
+ @sth = @dbh.prepare("select name, name from names where name = ?")
86
+ @sth.execute("Bob")
87
+ assert_equal [["Bob", "Bob"]], @sth.fetch_all
88
+ @sth.finish
89
+ end
90
+ end
91
+
92
+ def test_rows
93
+ @sth = nil
94
+
95
+ assert_nothing_raised do
96
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
97
+ @sth.execute("Bill", 22);
98
+ end
99
+
100
+ assert 1, @sth.rows
101
+
102
+ @sth.finish
103
+ @sth = nil
104
+
105
+ assert_nothing_raised do
106
+ @sth = @dbh.prepare("delete from names where name = ?")
107
+ @sth.execute("Bill");
108
+ end
109
+
110
+ assert 1, @sth.rows
111
+
112
+ @sth.finish
113
+
114
+ assert_nothing_raised do
115
+ @sth = @dbh.prepare("select * from names")
116
+ @sth.execute
117
+ end
118
+
119
+ assert_equal 0, @sth.rows
120
+ assert @sth.fetchable?
121
+ assert @sth.any?
122
+ assert @sth.rows.zero?
123
+ @sth.finish
124
+ end
125
+
126
+ def test_prepare_execute
127
+ assert_nothing_raised do
128
+ @sth = @dbh.prepare("select * from names")
129
+ @sth.execute
130
+ @sth.finish
131
+ end
132
+
133
+ assert_nothing_raised do
134
+ @sth = @dbh.prepare("select * from names where name = ?")
135
+ @sth.execute("Bob")
136
+ @sth.finish
137
+ end
138
+
139
+ assert_nothing_raised do
140
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
141
+ @sth.execute("Bill", 22);
142
+ @sth.finish
143
+ end
144
+ end
145
+
146
+ def test_prepare_execute_with_transactions
147
+ @dbh["AutoCommit"] = false
148
+ config = DBDConfig.get_config['sqlite3']
149
+
150
+ # rollback 1 (the right way)
151
+ @sth = nil
152
+ @sth2 = nil
153
+
154
+ assert_nothing_raised do
155
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
156
+ @sth.execute("Billy", 23)
157
+ @sth2 = @dbh.prepare("select * from names where name = ?")
158
+ @sth2.execute("Billy")
159
+ end
160
+ assert_equal ["Billy", 23 ], @sth2.fetch
161
+ @sth2.finish
162
+ @sth.finish
163
+ assert_nothing_raised { @dbh.rollback }
164
+
165
+ @sth = @dbh.prepare("select * from names where name = ?")
166
+ @sth.execute("Billy")
167
+ assert_nil @sth.fetch
168
+ @sth.finish
169
+
170
+ # rollback 2 (without closing statements first)
171
+
172
+ @sth = nil
173
+ @sth2 = nil
174
+
175
+ assert_nothing_raised do
176
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
177
+ @sth.execute("Billy", 23)
178
+ @sth2 = @dbh.prepare("select * from names where name = ?")
179
+ @sth2.execute("Billy")
180
+ end
181
+
182
+ assert_equal ["Billy", 23], @sth2.fetch
183
+
184
+ # FIXME some throw here, some don't. we should probably normalize this
185
+ @dbh.rollback rescue true
186
+
187
+ @sth2.finish
188
+ @sth.finish
189
+ assert_nothing_raised { @dbh.rollback }
190
+
191
+ @sth = @dbh.prepare("select * from names where name = ?")
192
+ @sth.execute("Billy")
193
+ assert_nil @sth.fetch
194
+ @sth.finish
195
+
196
+ # commit
197
+
198
+ @sth = nil
199
+ @sth2 = nil
200
+
201
+ assert_nothing_raised do
202
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
203
+ @sth.execute("Billy", 23)
204
+ @sth2 = @dbh.prepare("select * from names where name = ?")
205
+ @sth2.execute("Billy")
206
+ end
207
+ assert_equal ["Billy", 23 ], @sth2.fetch
208
+ @sth2.finish
209
+ @sth.finish
210
+ assert_nothing_raised { @dbh.commit }
211
+
212
+ @sth = @dbh.prepare("select * from names where name = ?")
213
+ @sth.execute("Billy")
214
+ assert_equal ["Billy", 23 ], @sth.fetch
215
+ @sth.finish
216
+ end
217
+
218
+ def test_fetch
219
+ @sth = nil
220
+ assert_nothing_raised do
221
+ @sth = @dbh.prepare("select * from names order by age")
222
+ @sth.execute
223
+ end
224
+
225
+ # this tests that we're getting the rows in the right order,
226
+ # and that the types are being converted.
227
+ assert_equal ["Joe", 19], @sth.fetch
228
+ assert_equal ["Bob", 21], @sth.fetch
229
+ assert_equal ["Jim", 30], @sth.fetch
230
+ assert_nil @sth.fetch
231
+
232
+ @sth.finish
233
+ end
234
+
235
+ def test_transaction_block
236
+ @dbh["AutoCommit"] = false
237
+ # this transaction should not fail because it called return early
238
+ @dbh.transaction do |dbh|
239
+ dbh.do('INSERT INTO names (name, age) VALUES (?, ?)', "Cooter", 69)
240
+ return 42
241
+ end
242
+ @sth = @dbh.prepare("select * from names where name = ?")
243
+ @sth.execute("Cooter")
244
+ row = @sth.fetch
245
+ assert row
246
+ assert_equal ["Cooter", 69], row
247
+ @sth.finish
248
+ end
249
+ end
@@ -0,0 +1,253 @@
1
+ @class = Class.new(DBDConfig.testbase(DBDConfig.current_dbtype)) do
2
+ def skip_bit
3
+ # FIXME this test fails because DBI's type system blows goats.
4
+ @sth = nil
5
+
6
+ assert_nothing_raised do
7
+ @sth = @dbh.prepare("insert into bit_test (mybit) values (?)")
8
+ @sth.bind_param(1, 0, DBI::SQL_TINYINT)
9
+ @sth.execute
10
+ # if dbtype == "postgresql"
11
+ # @sth.execute("0")
12
+ # else
13
+ # @sth.execute(0)
14
+ # end
15
+ @sth.finish
16
+ end
17
+
18
+ assert_nothing_raised do
19
+ @sth = @dbh.prepare("select * from bit_test")
20
+ @sth.execute
21
+ row = @sth.fetch
22
+ @sth.finish
23
+
24
+ assert_equal [0], row
25
+ end
26
+ end
27
+
28
+ # FIXME
29
+ # Ideally, this test should be split across the DBI tests and DBD, but for
30
+ # now testing against the DBDs really doesn't cost us anything other than
31
+ # debugging time if something breaks.
32
+ def test_bind_coltype
33
+ # ensure type conv didn't get turned off somewhere.
34
+ assert(DBI.convert_types)
35
+ assert(@dbh.convert_types)
36
+
37
+ assert_nothing_raised do
38
+ @sth = @dbh.prepare("select name, age from names order by age")
39
+ assert(@sth.convert_types) # again
40
+ @sth.execute
41
+ @sth.bind_coltype(2, DBI::Type::Varchar)
42
+ assert_equal(
43
+ [
44
+ ["Joe", "19"],
45
+ ["Bob", "21"],
46
+ ["Jim", "30"],
47
+ ], @sth.fetch_all
48
+ )
49
+ @sth.finish
50
+ end
51
+
52
+ # just to be sure..
53
+ assert_nothing_raised do
54
+ @sth = @dbh.prepare("select name, age from names order by age")
55
+ @sth.execute
56
+ @sth.bind_coltype(2, DBI::Type::Float)
57
+ @sth.fetch_all.collect { |x| assert_kind_of(Float, x[1]) }
58
+ @sth.finish
59
+ end
60
+
61
+ # now, let's check some failure cases
62
+ @sth = @dbh.prepare("select name, age from names order by age")
63
+
64
+ # can't bind_coltype before execute
65
+ assert_raise(DBI::InterfaceError) { @sth.bind_coltype(1, DBI::Type::Float) }
66
+ # can't index < 1
67
+ assert_raise(DBI::InterfaceError) { @sth.bind_coltype(0, DBI::Type::Float) }
68
+ end
69
+
70
+ def test_noconv
71
+ # XXX this test will fail the whole test suite miserably if it fails at any point.
72
+ assert(DBI.convert_types)
73
+
74
+ DBI.convert_types = false
75
+ @sth.finish rescue nil
76
+ @dbh.disconnect
77
+ set_base_dbh
78
+
79
+ assert(!@dbh.convert_types)
80
+
81
+ assert_nothing_raised do
82
+ @sth = @dbh.prepare("select * from names order by age")
83
+ assert(!@sth.convert_types)
84
+ @sth.execute
85
+ assert_equal(
86
+ [
87
+ ["Joe", "19"],
88
+ ["Bob", "21"],
89
+ ["Jim", "30"],
90
+ ], @sth.fetch_all
91
+ )
92
+ @sth.finish
93
+ end
94
+
95
+ DBI.convert_types = true
96
+ @sth.finish rescue nil
97
+ @dbh.disconnect
98
+ set_base_dbh
99
+
100
+ assert(DBI.convert_types)
101
+ assert(@dbh.convert_types)
102
+
103
+ assert_nothing_raised do
104
+ @sth = @dbh.prepare("select * from names order by age")
105
+ assert(@sth.convert_types)
106
+ @sth.execute
107
+ assert_equal(
108
+ [
109
+ ["Joe", 19],
110
+ ["Bob", 21],
111
+ ["Jim", 30],
112
+ ], @sth.fetch_all
113
+ )
114
+ @sth.finish
115
+ end
116
+
117
+ @dbh.convert_types = false
118
+
119
+ assert_nothing_raised do
120
+ @sth = @dbh.prepare("select * from names order by age")
121
+ assert(!@sth.convert_types)
122
+ @sth.execute
123
+ assert_equal(
124
+ [
125
+ ["Joe", "19"],
126
+ ["Bob", "21"],
127
+ ["Jim", "30"],
128
+ ], @sth.fetch_all
129
+ )
130
+ @sth.finish
131
+ end
132
+
133
+ @dbh.convert_types = true
134
+
135
+ assert_nothing_raised do
136
+ @sth = @dbh.prepare("select * from names order by age")
137
+ assert(@sth.convert_types)
138
+ @sth.convert_types = false
139
+ @sth.execute
140
+ assert_equal(
141
+ [
142
+ ["Joe", "19"],
143
+ ["Bob", "21"],
144
+ ["Jim", "30"],
145
+ ], @sth.fetch_all
146
+ )
147
+ @sth.finish
148
+ end
149
+ rescue Exception => e
150
+ DBI.convert_types = true
151
+ @sth.finish
152
+ @dbh.disconnect
153
+ set_base_dbh
154
+ raise e
155
+ end
156
+
157
+ def test_null
158
+ assert_nothing_raised do
159
+ @sth = @dbh.prepare('insert into names (name, age) values (?, ?)')
160
+ @sth.execute("'NULL'", 201)
161
+ @sth.execute(nil, 202)
162
+ @sth.execute("NULL", 203)
163
+ @sth.finish
164
+ end
165
+
166
+ assert_nothing_raised do
167
+ @sth = @dbh.prepare('select * from names where age > 200 order by age')
168
+ @sth.execute
169
+ assert_equal(["'NULL'", 201], @sth.fetch)
170
+ assert_equal([nil, 202], @sth.fetch)
171
+ assert_equal(["NULL", 203], @sth.fetch)
172
+ @sth.finish
173
+ end
174
+ end
175
+
176
+ def test_time
177
+ @sth = nil
178
+ t = nil
179
+ assert_nothing_raised do
180
+ @sth = @dbh.prepare("insert into time_test (mytime) values (?)")
181
+ t = Time.now
182
+ @sth.execute(t)
183
+ @sth.finish
184
+ end
185
+
186
+ assert_nothing_raised do
187
+ @sth = @dbh.prepare("select * from time_test")
188
+ @sth.execute
189
+ row = @sth.fetch
190
+ assert_kind_of DateTime, row[0]
191
+ assert_equal t.hour, row[0].hour
192
+ assert_equal t.min, row[0].min
193
+ assert_equal t.sec, row[0].sec
194
+ @sth.finish
195
+ end
196
+ end
197
+
198
+ def test_timestamp
199
+ @sth = nil
200
+ # We omit fractional second testing here -- timestamp precision
201
+ # is a very slippery, dependent on driver and driver version.
202
+ t = DBI::Timestamp.new(2008, 3, 8, 10, 39, 1)
203
+ assert_nothing_raised do
204
+ @sth = @dbh.prepare("insert into timestamp_test (mytimestamp) values (?)")
205
+ @sth.execute(t)
206
+ @sth.finish
207
+ end
208
+
209
+ assert_nothing_raised do
210
+ @sth = @dbh.prepare("select * from timestamp_test")
211
+ @sth.execute
212
+ row = @sth.fetch
213
+ assert_kind_of DateTime, row[0]
214
+ assert_equal t.year, row[0].year
215
+ assert_equal t.month, row[0].month
216
+ assert_equal t.day, row[0].day
217
+ assert_equal t.hour, row[0].hour
218
+ assert_equal t.min, row[0].min
219
+ assert_equal t.sec, row[0].sec
220
+ # omit fractional tests
221
+ @sth.finish
222
+ end
223
+ end
224
+
225
+ def test_boolean_return
226
+ @sth = nil
227
+
228
+ unless dbtype == "odbc" # ODBC has no boolean type
229
+ assert_nothing_raised do
230
+ @sth = @dbh.prepare("insert into boolean_test (num, mybool) values (?, ?)")
231
+ @sth.execute(1, true)
232
+ @sth.execute(2, false)
233
+ @sth.finish
234
+ end
235
+
236
+ assert_nothing_raised do
237
+ @sth = @dbh.prepare("select * from boolean_test order by num")
238
+ @sth.execute
239
+
240
+ pairs = @sth.fetch_all
241
+
242
+ assert_equal(
243
+ [
244
+ [1, true],
245
+ [2, false],
246
+ ], pairs
247
+ )
248
+
249
+ @sth.finish
250
+ end
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,26 @@
1
+ DBDConfig.set_testbase(:sqlanywhere, Class.new(Test::Unit::TestCase) do
2
+ def dbtype
3
+ "sqlanywhere"
4
+ end
5
+
6
+ def test_base
7
+ assert_equal(@dbh.driver_name, "SQLAnywhere")
8
+ assert_kind_of(DBI::DBD::SQLAnywhere::Database, @dbh.instance_variable_get(:@handle))
9
+ end
10
+
11
+ def set_base_dbh
12
+ config = DBDConfig.get_config["sqlanywhere"]
13
+ @dbh = DBI.connect("dbi:SQLAnywhere:"+config["dbname"], config["username"], config["password"], { })
14
+ end
15
+
16
+ def setup
17
+ set_base_dbh
18
+ DBDConfig.inject_sql(@dbh, dbtype, "dbd/sqlanywhere/up.sql")
19
+ end
20
+
21
+ def teardown
22
+ DBDConfig.inject_sql(@dbh, dbtype, "dbd/sqlanywhere/down.sql")
23
+ @dbh.disconnect
24
+ end
25
+ end
26
+ )
@@ -0,0 +1,19 @@
1
+ drop view view_names;
2
+ ---
3
+ drop table names;
4
+ ---
5
+ drop table blob_test;
6
+ ---
7
+ drop table boolean_test;
8
+ ---
9
+ drop table time_test;
10
+ ---
11
+ drop table timestamp_test;
12
+ ---
13
+ drop table bit_test;
14
+ ---
15
+ drop table field_types_test;
16
+ ---
17
+ drop table db_specific_types_test;
18
+ ---
19
+ drop table precision_test;
@@ -0,0 +1,28 @@
1
+ create table names (
2
+ name varchar(255),
3
+ age integer
4
+ );
5
+ ---
6
+ insert into names (name, age) values ('Joe', 19);
7
+ ---
8
+ insert into names (name, age) values ('Jim', 30);
9
+ ---
10
+ insert into names (name, age) values ('Bob', 21);
11
+ ---
12
+ create table precision_test (text_field varchar(20) primary key not null, integer_field decimal(2,1));
13
+ ---
14
+ CREATE TABLE blob_test (name VARCHAR(30), data long binary);
15
+ ---
16
+ create view view_names as select * from names;
17
+ ---
18
+ create table boolean_test (num integer, mybool bit);
19
+ ---
20
+ create table time_test (mytime time);
21
+ ---
22
+ create table timestamp_test (mytimestamp timestamp);
23
+ ---
24
+ create table bit_test (mybit bit);
25
+ ---
26
+ create table field_types_test (foo integer not null primary key default 1);
27
+ ---
28
+ create table db_specific_types_test (ts timestamp, dt date);
data/test/ts_dbd.rb ADDED
@@ -0,0 +1,118 @@
1
+ # figure out what tests to run
2
+ require 'yaml'
3
+ require 'test/unit/testsuite'
4
+ require 'test/unit/ui/console/testrunner'
5
+
6
+ if File.basename(Dir.pwd) == "test"
7
+ $:.unshift('../lib')
8
+ else
9
+ $:.unshift('lib')
10
+ end
11
+
12
+ module Test::Unit::Assertions
13
+ def build_message(head, template=nil, *arguments)
14
+ template += "\n" + "DATABASE: " + dbtype
15
+ template &&= template.chomp
16
+ return AssertionMessage.new(head, template, arguments)
17
+ end
18
+ end
19
+
20
+ module DBDConfig
21
+ @testbase = { }
22
+ @current_dbtype = nil
23
+
24
+ def self.get_config
25
+ config = nil
26
+
27
+ begin
28
+ config = YAML.load_file(File.join(ENV["HOME"], ".ruby-dbi.test-config.yaml"))
29
+ rescue Exception => e
30
+ config = { }
31
+ config["dbtypes"] = [ ]
32
+ end
33
+
34
+ return config
35
+ end
36
+
37
+ def self.inject_sql(dbh, dbtype, file)
38
+ # splits by --- in the file, strips newlines and the semicolons.
39
+ # this way we can still manually import the file, but use it with our
40
+ # drivers for client-independent injection.
41
+ File.open(file).read.split(/\n*---\n*/, -1).collect { |x| x.gsub!(/\n/, ''); x.sub(/;\z/, '') }.each do |stmt|
42
+ tmp = STDERR.dup
43
+ STDERR.reopen('sql.log', 'a')
44
+ begin
45
+ dbh.commit rescue nil
46
+ dbh["AutoCommit"] = true rescue nil
47
+ dbh.do(stmt)
48
+ dbh.commit unless dbtype == 'sqlite3'
49
+ rescue Exception => e
50
+ tmp.puts "Error injecting '#{stmt}' for db #{dbtype}"
51
+ tmp.puts "Error: #{e.message}"
52
+ end
53
+ STDERR.reopen(tmp)
54
+ end
55
+ end
56
+
57
+ def self.current_dbtype
58
+ @current_dbtype
59
+ end
60
+
61
+ def self.current_dbtype=(setting)
62
+ @current_dbtype = setting
63
+ end
64
+
65
+ def self.testbase(klass_name)
66
+ return @testbase[klass_name]
67
+ end
68
+
69
+ def self.set_testbase(klass_name, klass)
70
+ @testbase[klass_name] = klass
71
+ end
72
+
73
+ def self.suite
74
+ @suite ||= []
75
+ end
76
+ end
77
+
78
+ if __FILE__ == $0
79
+ Dir.chdir("..") if File.basename(Dir.pwd) == "test"
80
+ $LOAD_PATH.unshift(File.join(Dir.pwd, "lib"))
81
+ Dir.chdir("test") rescue nil
82
+
83
+ begin
84
+ require 'dbi'
85
+ rescue LoadError => e
86
+ begin
87
+ require 'rubygems'
88
+ gem 'dbi'
89
+ require 'dbi'
90
+ rescue LoadError => e
91
+ abort "DBI must already be installed or must come with this package for tests to work."
92
+ end
93
+ end
94
+
95
+ Deprecate.set_action(proc { })
96
+
97
+ config = DBDConfig.get_config
98
+
99
+ config["dbtypes"] = ENV["DBTYPES"].split(/\s+/) if ENV["DBTYPES"]
100
+
101
+ if config and config["dbtypes"]
102
+ config["dbtypes"].each do |dbtype|
103
+ unless config[dbtype]
104
+ warn "#{dbtype} is selected for testing but not configured; see test/DBD_TESTS"
105
+ next
106
+ end
107
+
108
+ # base.rb is special, see DBD_TESTS
109
+ require "dbd/#{dbtype}/base.rb"
110
+ Dir["dbd/#{dbtype}/test*.rb"].each { |file| require file }
111
+ # run the general tests
112
+ DBDConfig.current_dbtype = dbtype.to_sym
113
+ Dir["dbd/general/test*.rb"].each { |file| load file; DBDConfig.suite << @class }
114
+ end
115
+ elsif !config["dbtypes"]
116
+ warn "Please see test/DBD_TESTS for information on configuring DBD tests."
117
+ end
118
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: dbd-sqlanywhere
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
7
- date: 2008-11-03 00:00:00 -05:00
6
+ version: 0.1.1
7
+ date: 2008-11-07 00:00:00 -05:00
8
8
  summary: Ruby DBI driver (DBD) for SQL Anywhere
9
9
  require_paths:
10
10
  - lib
@@ -29,10 +29,21 @@ post_install_message:
29
29
  authors:
30
30
  - Eric Farrar
31
31
  files:
32
- - lib/dbd/SQLAnywhere.rb
33
- - lib/dbd/sqlanywhere/statement.rb
34
- - lib/dbd/sqlanywhere/driver.rb
35
32
  - lib/dbd/sqlanywhere/database.rb
33
+ - lib/dbd/sqlanywhere/driver.rb
34
+ - lib/dbd/sqlanywhere/statement.rb
35
+ - lib/dbd/SQLAnywhere.rb
36
+ - test/dbd
37
+ - test/dbd/general
38
+ - test/dbd/general/test_database.rb
39
+ - test/dbd/general/test_statement.rb
40
+ - test/dbd/general/test_types.rb
41
+ - test/dbd/sqlanywhere
42
+ - test/dbd/sqlanywhere/base.rb
43
+ - test/dbd/sqlanywhere/down.sql
44
+ - test/dbd/sqlanywhere/up.sql
45
+ - test/DBD_TESTS
46
+ - test/ts_dbd.rb
36
47
  - README
37
48
  - CHANGELOG
38
49
  - LICENSE