dbd-sqlanywhere 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG 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