dbd-sqlanywhere 0.1.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +21 -12
- data/LICENSE +23 -23
- data/README +150 -150
- data/lib/dbd/SQLAnywhere.rb +176 -176
- data/lib/dbd/sqlanywhere/database.rb +266 -255
- data/lib/dbd/sqlanywhere/driver.rb +108 -102
- data/lib/dbd/sqlanywhere/statement.rb +216 -211
- data/test/dbd/sqlanywhere/base.rb +26 -26
- data/test/dbd/sqlanywhere/down.sql +19 -19
- data/test/dbd/sqlanywhere/up.sql +28 -28
- metadata +77 -67
- data/test/DBD_TESTS +0 -48
- data/test/dbd/general/test_database.rb +0 -157
- data/test/dbd/general/test_statement.rb +0 -249
- data/test/dbd/general/test_types.rb +0 -253
- data/test/ts_dbd.rb +0 -118
data/CHANGELOG
CHANGED
@@ -1,12 +1,21 @@
|
|
1
|
-
=CHANGE LOG
|
2
|
-
|
3
|
-
=====0.
|
4
|
-
- Changed
|
5
|
-
- Changed
|
6
|
-
|
7
|
-
-
|
8
|
-
|
9
|
-
=====0.1.
|
10
|
-
-
|
11
|
-
|
12
|
-
|
1
|
+
=CHANGE LOG
|
2
|
+
|
3
|
+
=====1.0.0 -- 2012/08/29
|
4
|
+
- Changed to have each row element to be stored as String object by "default" so that dbh.convert_types = false would return the String element properly.
|
5
|
+
- Changed sth.column_info not to assign any value "precision" and "scale" for the datatype that does not specify the precision or length.
|
6
|
+
- Changed sth.rows to return proper value for the number of the affected rows
|
7
|
+
- Changed rakefile to use rdoc/task instead of rake/rdoctask(deprecated)
|
8
|
+
|
9
|
+
=====0.1.2 -- 2009/03/27
|
10
|
+
- Changed the order and type of parameter for connection
|
11
|
+
|
12
|
+
=====0.1.1 -- 2008/11/06
|
13
|
+
- Changed file permissions on archives
|
14
|
+
- Changed archives to be specific to platform (.zip on windows, .tar.gz
|
15
|
+
otherwise)
|
16
|
+
- Removed the default rake task
|
17
|
+
|
18
|
+
=====0.1.0 -- 2008/10/29
|
19
|
+
- Initial Release
|
20
|
+
- Wraps DBCAPI functionality
|
21
|
+
- Tested against DBI 0.4
|
data/LICENSE
CHANGED
@@ -1,23 +1,23 @@
|
|
1
|
-
/*====================================================
|
2
|
-
*
|
3
|
-
* Copyright
|
4
|
-
*
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
* you may not use this file except in compliance with the License.
|
7
|
-
* You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
*
|
10
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
*
|
12
|
-
* Unless required by applicable law or agreed to in writing, software
|
13
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
*
|
16
|
-
* See the License for the specific language governing permissions and
|
17
|
-
* limitations under the License.
|
18
|
-
*
|
19
|
-
* While not a requirement of the license, if you do modify this file, we
|
20
|
-
* would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
|
21
|
-
*
|
22
|
-
*
|
23
|
-
*====================================================*/
|
1
|
+
/*====================================================
|
2
|
+
*
|
3
|
+
* Copyright 2012 iAnywhere Solutions, Inc.
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
*
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
*
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
*
|
16
|
+
* See the License for the specific language governing permissions and
|
17
|
+
* limitations under the License.
|
18
|
+
*
|
19
|
+
* While not a requirement of the license, if you do modify this file, we
|
20
|
+
* would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
|
21
|
+
*
|
22
|
+
*
|
23
|
+
*====================================================*/
|
data/README
CHANGED
@@ -1,150 +1,150 @@
|
|
1
|
-
=SQL Anywhere DBD Driver for Ruby-DBI
|
2
|
-
|
3
|
-
This is a SQL Anywhere driver for Ruby DBI (http://ruby-dbi.rubyforge.org/). This driver requires the
|
4
|
-
native SQL Anywhere Ruby driver. To get the native driver, use:
|
5
|
-
|
6
|
-
gem install sqlanywhere
|
7
|
-
|
8
|
-
This driver is designed for use with DBI 0.4 and greater.
|
9
|
-
|
10
|
-
This driver is licensed under the Apache License, Version 2.
|
11
|
-
|
12
|
-
The official code repository is located on GitHub. The repository can be cloned with:
|
13
|
-
|
14
|
-
git clone git://github.com/sqlanywhere/dbd-sqlanywhere.git
|
15
|
-
|
16
|
-
==Making a Connection
|
17
|
-
|
18
|
-
The following code is a sample database configuration object that connects
|
19
|
-
to a database called 'Test'.
|
20
|
-
|
21
|
-
require 'dbi'
|
22
|
-
|
23
|
-
DBI.connect('DBI:SQLAnywhere:Test') do | dbh |
|
24
|
-
if dbh.ping
|
25
|
-
print "Successfully Connected"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
The connection function takes the general form:
|
30
|
-
|
31
|
-
dbh = DBI.connect(DBNAME, [USER_NAME], [PASSWORD])
|
32
|
-
|
33
|
-
The DBNAME string can be specified in the following forms:
|
34
|
-
|
35
|
-
"DBI:SQLAnywhere:"
|
36
|
-
"DBI:SQLAnywhere:{ENG}"
|
37
|
-
"DBI:SQLAnywhere:{ENG}:{DBN}"
|
38
|
-
"DBI:SQLAnywhere:{CONNECTION_STRING}" # where CONNECTION_STRING ~= "key1=val1;key2=val2;..."
|
39
|
-
|
40
|
-
For the first form, nothing will be added to the connection string. With the second and third forms
|
41
|
-
the driver will add ENG and DBN to the connection string accordingly. The fourth form will pass
|
42
|
-
the supplied connection string through unmolested.
|
43
|
-
|
44
|
-
The USER_NAME and PASSWORD can be passed into the function and they will be automatically appended to the
|
45
|
-
connection string. Since Ruby DBI will automatically fill in the username and password with defaults if they are omitted,
|
46
|
-
you should NEVER include a "UID=" or "PWD=" in your connection string or an exception will be thrown.
|
47
|
-
|
48
|
-
Examples:
|
49
|
-
|
50
|
-
Function Call ==> Generated Connection String
|
51
|
-
==============================================================================================
|
52
|
-
DBI.connect("DBI:SQLAnywhere:") ==> "uid=dba;pwd=sql"
|
53
|
-
DBI.connect("DBI:SQLAnywhere:Demo") ==> "eng=Demo;uid=dba;pwd=sql"
|
54
|
-
DBI.connect("DBI:SQLAnywhere:Demo:Test") ==> "eng=Demo;dbn=Test;uid=dba;pwd=sql"
|
55
|
-
DBI.connect("DBI:SQLAnywhere:Demo:Test", 'john', 'doe') ==> "eng=Demo;dbn=Test;uid=john;pwd=doe"
|
56
|
-
DBI.connect("DBI:SQLAnywhere:eng=Demo;dbn=Test") ==> "eng=Demo;dbn=Test;uid=dba;pwd=sql"
|
57
|
-
DBI.connect("DBI:SQLAnywhere:eng=Demo;dbn=Test;uid=john") ==> EXCEPTION! UID cannot be specified in the connection string
|
58
|
-
DBI.connect("DBI:SQLAnywhere:CommLinks=tcpip(port=2638)") ==> "CommLinks=tcpip(port=2638);uid=dba;pwd=sql"
|
59
|
-
|
60
|
-
|
61
|
-
==Running Test Suite
|
62
|
-
|
63
|
-
For information on running the Ruby/DBI DBD Tests, please see
|
64
|
-
|
65
|
-
test/DBD_TESTS
|
66
|
-
|
67
|
-
==Driver-Specific Features
|
68
|
-
|
69
|
-
At the time of this writing, there was no standard way to handle INOUT and OUT parameters
|
70
|
-
from stored procedures in DBI.
|
71
|
-
|
72
|
-
When binding to an OUT parameter, you must bind a hash that contains a key called
|
73
|
-
:name. This :name will be used to retrieve the OUT value after execution. If the
|
74
|
-
OUT column is of string or binary type, you must also pass a key called :length
|
75
|
-
with the expected maximum length of the OUT parameter.
|
76
|
-
|
77
|
-
In the case of an INOUT parameter, the :name and :length keys are the same as for
|
78
|
-
OUT parameters, but an additional :value parameter holds the value to be passed
|
79
|
-
into the stored procedure.
|
80
|
-
|
81
|
-
After execution, you can use the statement-specific function :bound_param
|
82
|
-
to retrieve the output value using the :name supplied at binding time.
|
83
|
-
|
84
|
-
===Example of using OUT and INOUT parameters
|
85
|
-
|
86
|
-
# The result that should be printed to console is:
|
87
|
-
# Complete string is PREFIX-some_string-SUFFIX and is 25 chars long
|
88
|
-
# Complete string is PREFIXPREFIX-some_string-SUFFIXSUFFIX and is 37 chars long
|
89
|
-
|
90
|
-
require 'dbi'
|
91
|
-
|
92
|
-
begin
|
93
|
-
DBI.connect("DBI:SQLAnywhere:test") do |dbh|
|
94
|
-
|
95
|
-
sql = <<SQL
|
96
|
-
IF EXISTS(SELECT * FROM SYS.SYSPROCEDURE where proc_name = 'foo') THEN
|
97
|
-
DROP PROCEDURE foo;
|
98
|
-
END IF
|
99
|
-
SQL
|
100
|
-
|
101
|
-
dbh.do(sql);
|
102
|
-
|
103
|
-
sql = <<SQL
|
104
|
-
create procedure foo
|
105
|
-
( IN prefix char(10),
|
106
|
-
INOUT buffer varchar(256),
|
107
|
-
OUT str_len int,
|
108
|
-
IN suffix char(10)
|
109
|
-
)
|
110
|
-
begin
|
111
|
-
set buffer = prefix || buffer || suffix;
|
112
|
-
select length( buffer ) into str_len;
|
113
|
-
end
|
114
|
-
SQL
|
115
|
-
|
116
|
-
dbh.do(sql);
|
117
|
-
|
118
|
-
buffer = "-some_string-"
|
119
|
-
prefix = "PREFIX"
|
120
|
-
|
121
|
-
# preparing the statement
|
122
|
-
sth = dbh.prepare("call foo( ?, ?, ?, ? )")
|
123
|
-
|
124
|
-
# Binding buffer column as :buf, and str_len column as :len
|
125
|
-
# Note that we must supply a :value for :buf since it is an INOUT
|
126
|
-
# And we must supply a :length for :buf since it is a string column
|
127
|
-
sth.execute( prefix, {:name => :buf, :value => buffer, :length => 255}, {:name => :len}, "SUFFIX")
|
128
|
-
|
129
|
-
# Retrieve the OUT value from buffer
|
130
|
-
new_buffer = sth.func(:bound_param, :buf)
|
131
|
-
|
132
|
-
# Retrieve the OUT value from str_len
|
133
|
-
length = sth.func(:bound_param, :len)
|
134
|
-
puts "Complete string is #{new_buffer} and is #{length} chars long"
|
135
|
-
|
136
|
-
# Add the results back into the string, and re-execute
|
137
|
-
sth.execute("PREFIX", {:name => :buf, :value => new_buffer, :length => 255}, {:name => :len}, "SUFFIX")
|
138
|
-
new_buffer = sth.func(:bound_param, :buf)
|
139
|
-
length = sth.func(:bound_param, :len)
|
140
|
-
puts "Complete string is #{new_buffer} and is #{length} chars long"
|
141
|
-
end
|
142
|
-
|
143
|
-
rescue DBI::DatabaseError => e
|
144
|
-
puts "An error occurred"
|
145
|
-
puts "Error code: #{e.err}"
|
146
|
-
puts "Error message: #{e.errstr}"
|
147
|
-
puts "Error SQLSTATE: #{e.state}"
|
148
|
-
ensure
|
149
|
-
DBI.disconnect_all
|
150
|
-
end
|
1
|
+
=SQL Anywhere DBD Driver for Ruby-DBI
|
2
|
+
|
3
|
+
This is a SQL Anywhere driver for Ruby DBI (http://ruby-dbi.rubyforge.org/). This driver requires the
|
4
|
+
native SQL Anywhere Ruby driver. To get the native driver, use:
|
5
|
+
|
6
|
+
gem install sqlanywhere
|
7
|
+
|
8
|
+
This driver is designed for use with DBI 0.4 and greater.
|
9
|
+
|
10
|
+
This driver is licensed under the Apache License, Version 2.
|
11
|
+
|
12
|
+
The official code repository is located on GitHub. The repository can be cloned with:
|
13
|
+
|
14
|
+
git clone git://github.com/sqlanywhere/dbd-sqlanywhere.git
|
15
|
+
|
16
|
+
==Making a Connection
|
17
|
+
|
18
|
+
The following code is a sample database configuration object that connects
|
19
|
+
to a database called 'Test'.
|
20
|
+
|
21
|
+
require 'dbi'
|
22
|
+
|
23
|
+
DBI.connect('DBI:SQLAnywhere:Test') do | dbh |
|
24
|
+
if dbh.ping
|
25
|
+
print "Successfully Connected"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
The connection function takes the general form:
|
30
|
+
|
31
|
+
dbh = DBI.connect(DBNAME, [USER_NAME], [PASSWORD])
|
32
|
+
|
33
|
+
The DBNAME string can be specified in the following forms:
|
34
|
+
|
35
|
+
"DBI:SQLAnywhere:"
|
36
|
+
"DBI:SQLAnywhere:{ENG}"
|
37
|
+
"DBI:SQLAnywhere:{ENG}:{DBN}"
|
38
|
+
"DBI:SQLAnywhere:{CONNECTION_STRING}" # where CONNECTION_STRING ~= "key1=val1;key2=val2;..."
|
39
|
+
|
40
|
+
For the first form, nothing will be added to the connection string. With the second and third forms
|
41
|
+
the driver will add ENG and DBN to the connection string accordingly. The fourth form will pass
|
42
|
+
the supplied connection string through unmolested.
|
43
|
+
|
44
|
+
The USER_NAME and PASSWORD can be passed into the function and they will be automatically appended to the
|
45
|
+
connection string. Since Ruby DBI will automatically fill in the username and password with defaults if they are omitted,
|
46
|
+
you should NEVER include a "UID=" or "PWD=" in your connection string or an exception will be thrown.
|
47
|
+
|
48
|
+
Examples:
|
49
|
+
|
50
|
+
Function Call ==> Generated Connection String
|
51
|
+
==============================================================================================
|
52
|
+
DBI.connect("DBI:SQLAnywhere:") ==> "uid=dba;pwd=sql"
|
53
|
+
DBI.connect("DBI:SQLAnywhere:Demo") ==> "eng=Demo;uid=dba;pwd=sql"
|
54
|
+
DBI.connect("DBI:SQLAnywhere:Demo:Test") ==> "eng=Demo;dbn=Test;uid=dba;pwd=sql"
|
55
|
+
DBI.connect("DBI:SQLAnywhere:Demo:Test", 'john', 'doe') ==> "eng=Demo;dbn=Test;uid=john;pwd=doe"
|
56
|
+
DBI.connect("DBI:SQLAnywhere:eng=Demo;dbn=Test") ==> "eng=Demo;dbn=Test;uid=dba;pwd=sql"
|
57
|
+
DBI.connect("DBI:SQLAnywhere:eng=Demo;dbn=Test;uid=john") ==> EXCEPTION! UID cannot be specified in the connection string
|
58
|
+
DBI.connect("DBI:SQLAnywhere:CommLinks=tcpip(port=2638)") ==> "CommLinks=tcpip(port=2638);uid=dba;pwd=sql"
|
59
|
+
|
60
|
+
|
61
|
+
==Running Test Suite
|
62
|
+
|
63
|
+
For information on running the Ruby/DBI DBD Tests, please see
|
64
|
+
|
65
|
+
test/DBD_TESTS
|
66
|
+
|
67
|
+
==Driver-Specific Features
|
68
|
+
|
69
|
+
At the time of this writing, there was no standard way to handle INOUT and OUT parameters
|
70
|
+
from stored procedures in DBI.
|
71
|
+
|
72
|
+
When binding to an OUT parameter, you must bind a hash that contains a key called
|
73
|
+
:name. This :name will be used to retrieve the OUT value after execution. If the
|
74
|
+
OUT column is of string or binary type, you must also pass a key called :length
|
75
|
+
with the expected maximum length of the OUT parameter.
|
76
|
+
|
77
|
+
In the case of an INOUT parameter, the :name and :length keys are the same as for
|
78
|
+
OUT parameters, but an additional :value parameter holds the value to be passed
|
79
|
+
into the stored procedure.
|
80
|
+
|
81
|
+
After execution, you can use the statement-specific function :bound_param
|
82
|
+
to retrieve the output value using the :name supplied at binding time.
|
83
|
+
|
84
|
+
===Example of using OUT and INOUT parameters
|
85
|
+
|
86
|
+
# The result that should be printed to console is:
|
87
|
+
# Complete string is PREFIX-some_string-SUFFIX and is 25 chars long
|
88
|
+
# Complete string is PREFIXPREFIX-some_string-SUFFIXSUFFIX and is 37 chars long
|
89
|
+
|
90
|
+
require 'dbi'
|
91
|
+
|
92
|
+
begin
|
93
|
+
DBI.connect("DBI:SQLAnywhere:test") do |dbh|
|
94
|
+
|
95
|
+
sql = <<SQL
|
96
|
+
IF EXISTS(SELECT * FROM SYS.SYSPROCEDURE where proc_name = 'foo') THEN
|
97
|
+
DROP PROCEDURE foo;
|
98
|
+
END IF
|
99
|
+
SQL
|
100
|
+
|
101
|
+
dbh.do(sql);
|
102
|
+
|
103
|
+
sql = <<SQL
|
104
|
+
create procedure foo
|
105
|
+
( IN prefix char(10),
|
106
|
+
INOUT buffer varchar(256),
|
107
|
+
OUT str_len int,
|
108
|
+
IN suffix char(10)
|
109
|
+
)
|
110
|
+
begin
|
111
|
+
set buffer = prefix || buffer || suffix;
|
112
|
+
select length( buffer ) into str_len;
|
113
|
+
end
|
114
|
+
SQL
|
115
|
+
|
116
|
+
dbh.do(sql);
|
117
|
+
|
118
|
+
buffer = "-some_string-"
|
119
|
+
prefix = "PREFIX"
|
120
|
+
|
121
|
+
# preparing the statement
|
122
|
+
sth = dbh.prepare("call foo( ?, ?, ?, ? )")
|
123
|
+
|
124
|
+
# Binding buffer column as :buf, and str_len column as :len
|
125
|
+
# Note that we must supply a :value for :buf since it is an INOUT
|
126
|
+
# And we must supply a :length for :buf since it is a string column
|
127
|
+
sth.execute( prefix, {:name => :buf, :value => buffer, :length => 255}, {:name => :len}, "SUFFIX")
|
128
|
+
|
129
|
+
# Retrieve the OUT value from buffer
|
130
|
+
new_buffer = sth.func(:bound_param, :buf)
|
131
|
+
|
132
|
+
# Retrieve the OUT value from str_len
|
133
|
+
length = sth.func(:bound_param, :len)
|
134
|
+
puts "Complete string is #{new_buffer} and is #{length} chars long"
|
135
|
+
|
136
|
+
# Add the results back into the string, and re-execute
|
137
|
+
sth.execute("PREFIX", {:name => :buf, :value => new_buffer, :length => 255}, {:name => :len}, "SUFFIX")
|
138
|
+
new_buffer = sth.func(:bound_param, :buf)
|
139
|
+
length = sth.func(:bound_param, :len)
|
140
|
+
puts "Complete string is #{new_buffer} and is #{length} chars long"
|
141
|
+
end
|
142
|
+
|
143
|
+
rescue DBI::DatabaseError => e
|
144
|
+
puts "An error occurred"
|
145
|
+
puts "Error code: #{e.err}"
|
146
|
+
puts "Error message: #{e.errstr}"
|
147
|
+
puts "Error SQLSTATE: #{e.state}"
|
148
|
+
ensure
|
149
|
+
DBI.disconnect_all
|
150
|
+
end
|
data/lib/dbd/SQLAnywhere.rb
CHANGED
@@ -1,176 +1,176 @@
|
|
1
|
-
#====================================================
|
2
|
-
#
|
3
|
-
# Copyright
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
#
|
16
|
-
# See the License for the specific language governing permissions and
|
17
|
-
# limitations under the License.
|
18
|
-
#
|
19
|
-
# While not a requirement of the license, if you do modify this file, we
|
20
|
-
# would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#====================================================
|
24
|
-
|
25
|
-
begin
|
26
|
-
require 'rubygems'
|
27
|
-
gem 'sqlanywhere'
|
28
|
-
gem 'dbi'
|
29
|
-
rescue LoadError => e
|
30
|
-
end
|
31
|
-
|
32
|
-
require 'dbi'
|
33
|
-
require 'dbi/typeutil'
|
34
|
-
require 'sqlanywhere'
|
35
|
-
require 'singleton'
|
36
|
-
|
37
|
-
module DBI
|
38
|
-
module DBD
|
39
|
-
module SQLAnywhere
|
40
|
-
|
41
|
-
VERSION = "0.
|
42
|
-
|
43
|
-
def self.driver_name
|
44
|
-
"SQLAnywhere"
|
45
|
-
end
|
46
|
-
|
47
|
-
class SA
|
48
|
-
include Singleton
|
49
|
-
attr_accessor :api
|
50
|
-
|
51
|
-
def initialize
|
52
|
-
unless defined? SQLAnywhere
|
53
|
-
require 'sqlanywhere'
|
54
|
-
end
|
55
|
-
|
56
|
-
@api = ::SQLAnywhere::SQLAnywhereInterface.new()
|
57
|
-
result = ::SQLAnywhere::API.sqlany_initialize_interface( @api )
|
58
|
-
if result == 0
|
59
|
-
raise LoadError, "Could not load SQLAnywhere DLL"
|
60
|
-
end
|
61
|
-
result = @api.sqlany_init()
|
62
|
-
if result == 0
|
63
|
-
raise LoadError, "Could not initialize SQLAnywhere DLL"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def free_api
|
68
|
-
::SQLAnywhere::API.sqlany_finalize_interface( @api );
|
69
|
-
@api = nil
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
DBI::TypeUtil.register_conversion(driver_name) do |obj|
|
75
|
-
case obj
|
76
|
-
when DBI::Binary # these need to be handled specially by the driver
|
77
|
-
obj.to_s
|
78
|
-
when ::NilClass
|
79
|
-
nil
|
80
|
-
when ::TrueClass
|
81
|
-
1
|
82
|
-
when ::FalseClass
|
83
|
-
0
|
84
|
-
when ::Time
|
85
|
-
obj.strftime("%H:%M:%S")
|
86
|
-
when ::Date
|
87
|
-
obj.strftime("%Y/%m/%d")
|
88
|
-
when ::DateTime, DBI::Timestamp
|
89
|
-
DateTime.parse(obj.to_s).strftime("%Y/%m/%d %H:%M:%S")
|
90
|
-
when ::String
|
91
|
-
obj
|
92
|
-
when ::BigDecimal
|
93
|
-
obj.to_s("F")
|
94
|
-
when ::Numeric
|
95
|
-
obj.to_s
|
96
|
-
else
|
97
|
-
obj
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
# This module provides functionality that is used by all the DBD classes
|
103
|
-
module Utility
|
104
|
-
|
105
|
-
NO_DIRECTION = 0
|
106
|
-
INPUT_ONLY = 1
|
107
|
-
OUTPUT_ONLY = 2
|
108
|
-
INPUT_OUTPUT = 3
|
109
|
-
|
110
|
-
# do_bind takes the following arguments:
|
111
|
-
# * +prep_stmt+ : a handle the prepared Statement object
|
112
|
-
# * +param+ : the parameter to bound, obtained by sqlany_describe_bind_param
|
113
|
-
# * +bindvar+ : the actual value to bind the the parameter. Can be a +VALUE+, or a +HASH+.
|
114
|
-
# * +i+ : the parameter number to bind. Should be the same as used in sqlany_describe_bind_param
|
115
|
-
# * +bound+ : hash used to track INOUT, and OUT parameters
|
116
|
-
#
|
117
|
-
# +IN+ parameters will be bound once with +INPUT_ONLY+.
|
118
|
-
# +OUT+ parameters will be bound once with +OUTPUT_ONLY+.
|
119
|
-
# +INOUT+ parameters will be be bound twice, once as +INPUT_ONLY+, and once as +OUTPUT_ONLY+. +INOUT+ parameters
|
120
|
-
# will use *different* buffers to pass the input and output values to the DLL.
|
121
|
-
#
|
122
|
-
# If the parameter to be bound is +INPUT_ONLY+, +bindvar+ *must* be a regular value type such as
|
123
|
-
# Bignum, Fixnum, String, etc. This value will be bound to the input parameter
|
124
|
-
#
|
125
|
-
# If the parameter to be bound is +OUTPUT_ONLY+, +bindvar+ *must* be a hash with keys:
|
126
|
-
# ::name => This is the name that you will be used later to retrieve the output value
|
127
|
-
# ::length => If the output will be a string or binary, the expected length must be stated. If this length is exceeded
|
128
|
-
# a DatabaseError (truncation) will be raised.
|
129
|
-
#
|
130
|
-
# If the parameter to be bound is +INPUT_OUTPUT+, +bindvar+ *must* be a hash with keys:
|
131
|
-
# ::name => This is the name that you will be used later to retrieve the output value
|
132
|
-
# ::value => The value to bind to the input.
|
133
|
-
# ::length => If the output will be a string or binary, the expected length must be stated. If this length is exceeded
|
134
|
-
# a DatabaseError (truncation) will be raised.
|
135
|
-
#
|
136
|
-
def do_bind!(prep_stmt, param, bindvar, i, bound)
|
137
|
-
# Get the direction
|
138
|
-
orig_direction = param.get_direction;
|
139
|
-
|
140
|
-
# Bind INPUT
|
141
|
-
if orig_direction == INPUT_ONLY or orig_direction == INPUT_OUTPUT
|
142
|
-
param.set_direction(INPUT_ONLY)
|
143
|
-
# Obtain the value out of the hash if neccessary
|
144
|
-
if bindvar.class == Hash
|
145
|
-
raise DBI::ProgrammingError.new("Parameter hash must contain :value key") if !bindvar.has_key?(:value)
|
146
|
-
param.set_value(bindvar[:value])
|
147
|
-
else
|
148
|
-
param.set_value(bindvar)
|
149
|
-
end
|
150
|
-
raise error() if SA.instance.api.sqlany_bind_param(prep_stmt, i, param) == 0
|
151
|
-
end
|
152
|
-
|
153
|
-
# Bind OUTPUT
|
154
|
-
if orig_direction == OUTPUT_ONLY or orig_direction == INPUT_OUTPUT
|
155
|
-
param.set_direction(OUTPUT_ONLY)
|
156
|
-
# Add the +::name+ to the +bound+ hash so its output value can be retrieved later
|
157
|
-
raise DBI::ProgrammingError.new("Parameter hash must contain :name key") if !bindvar.has_key?(:name)
|
158
|
-
bound[bindvar[:name]] = i if !bound.nil?
|
159
|
-
# set the buffer length if appropriate
|
160
|
-
if bindvar.has_key?(:length)
|
161
|
-
param.set_buffer_size(bindvar[:length])
|
162
|
-
end
|
163
|
-
# +set_value+ sets up the receiveing buffer
|
164
|
-
param.set_value(nil)
|
165
|
-
raise error() if SA.instance.api.sqlany_bind_param(prep_stmt, i, param) == 0
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
end # module SQLAnywhere
|
171
|
-
end # module DBD
|
172
|
-
end # module DBI
|
173
|
-
|
174
|
-
require 'dbd/sqlanywhere/driver'
|
175
|
-
require 'dbd/sqlanywhere/database'
|
176
|
-
require 'dbd/sqlanywhere/statement'
|
1
|
+
#====================================================
|
2
|
+
#
|
3
|
+
# Copyright 2012 iAnywhere Solutions, Inc.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
#
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
# While not a requirement of the license, if you do modify this file, we
|
20
|
+
# would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
|
21
|
+
#
|
22
|
+
#
|
23
|
+
#====================================================
|
24
|
+
|
25
|
+
begin
|
26
|
+
require 'rubygems'
|
27
|
+
gem 'sqlanywhere'
|
28
|
+
gem 'dbi'
|
29
|
+
rescue LoadError => e
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'dbi'
|
33
|
+
require 'dbi/typeutil'
|
34
|
+
require 'sqlanywhere'
|
35
|
+
require 'singleton'
|
36
|
+
|
37
|
+
module DBI
|
38
|
+
module DBD
|
39
|
+
module SQLAnywhere
|
40
|
+
|
41
|
+
VERSION = "1.0.0"
|
42
|
+
|
43
|
+
def self.driver_name
|
44
|
+
"SQLAnywhere"
|
45
|
+
end
|
46
|
+
|
47
|
+
class SA
|
48
|
+
include Singleton
|
49
|
+
attr_accessor :api
|
50
|
+
|
51
|
+
def initialize
|
52
|
+
unless defined? SQLAnywhere
|
53
|
+
require 'sqlanywhere'
|
54
|
+
end
|
55
|
+
|
56
|
+
@api = ::SQLAnywhere::SQLAnywhereInterface.new()
|
57
|
+
result = ::SQLAnywhere::API.sqlany_initialize_interface( @api )
|
58
|
+
if result == 0
|
59
|
+
raise LoadError, "Could not load SQLAnywhere DLL"
|
60
|
+
end
|
61
|
+
result = @api.sqlany_init()
|
62
|
+
if result == 0
|
63
|
+
raise LoadError, "Could not initialize SQLAnywhere DLL"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def free_api
|
68
|
+
::SQLAnywhere::API.sqlany_finalize_interface( @api );
|
69
|
+
@api = nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
DBI::TypeUtil.register_conversion(driver_name) do |obj|
|
75
|
+
case obj
|
76
|
+
when DBI::Binary # these need to be handled specially by the driver
|
77
|
+
obj.to_s
|
78
|
+
when ::NilClass
|
79
|
+
nil
|
80
|
+
when ::TrueClass
|
81
|
+
1
|
82
|
+
when ::FalseClass
|
83
|
+
0
|
84
|
+
when ::Time
|
85
|
+
obj.strftime("%H:%M:%S")
|
86
|
+
when ::Date
|
87
|
+
obj.strftime("%Y/%m/%d")
|
88
|
+
when ::DateTime, DBI::Timestamp
|
89
|
+
DateTime.parse(obj.to_s).strftime("%Y/%m/%d %H:%M:%S")
|
90
|
+
when ::String
|
91
|
+
obj
|
92
|
+
when ::BigDecimal
|
93
|
+
obj.to_s("F")
|
94
|
+
when ::Numeric
|
95
|
+
obj.to_s
|
96
|
+
else
|
97
|
+
obj
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# This module provides functionality that is used by all the DBD classes
|
103
|
+
module Utility
|
104
|
+
|
105
|
+
NO_DIRECTION = 0
|
106
|
+
INPUT_ONLY = 1
|
107
|
+
OUTPUT_ONLY = 2
|
108
|
+
INPUT_OUTPUT = 3
|
109
|
+
|
110
|
+
# do_bind takes the following arguments:
|
111
|
+
# * +prep_stmt+ : a handle the prepared Statement object
|
112
|
+
# * +param+ : the parameter to bound, obtained by sqlany_describe_bind_param
|
113
|
+
# * +bindvar+ : the actual value to bind the the parameter. Can be a +VALUE+, or a +HASH+.
|
114
|
+
# * +i+ : the parameter number to bind. Should be the same as used in sqlany_describe_bind_param
|
115
|
+
# * +bound+ : hash used to track INOUT, and OUT parameters
|
116
|
+
#
|
117
|
+
# +IN+ parameters will be bound once with +INPUT_ONLY+.
|
118
|
+
# +OUT+ parameters will be bound once with +OUTPUT_ONLY+.
|
119
|
+
# +INOUT+ parameters will be be bound twice, once as +INPUT_ONLY+, and once as +OUTPUT_ONLY+. +INOUT+ parameters
|
120
|
+
# will use *different* buffers to pass the input and output values to the DLL.
|
121
|
+
#
|
122
|
+
# If the parameter to be bound is +INPUT_ONLY+, +bindvar+ *must* be a regular value type such as
|
123
|
+
# Bignum, Fixnum, String, etc. This value will be bound to the input parameter
|
124
|
+
#
|
125
|
+
# If the parameter to be bound is +OUTPUT_ONLY+, +bindvar+ *must* be a hash with keys:
|
126
|
+
# ::name => This is the name that you will be used later to retrieve the output value
|
127
|
+
# ::length => If the output will be a string or binary, the expected length must be stated. If this length is exceeded
|
128
|
+
# a DatabaseError (truncation) will be raised.
|
129
|
+
#
|
130
|
+
# If the parameter to be bound is +INPUT_OUTPUT+, +bindvar+ *must* be a hash with keys:
|
131
|
+
# ::name => This is the name that you will be used later to retrieve the output value
|
132
|
+
# ::value => The value to bind to the input.
|
133
|
+
# ::length => If the output will be a string or binary, the expected length must be stated. If this length is exceeded
|
134
|
+
# a DatabaseError (truncation) will be raised.
|
135
|
+
#
|
136
|
+
def do_bind!(prep_stmt, param, bindvar, i, bound)
|
137
|
+
# Get the direction
|
138
|
+
orig_direction = param.get_direction;
|
139
|
+
|
140
|
+
# Bind INPUT
|
141
|
+
if orig_direction == INPUT_ONLY or orig_direction == INPUT_OUTPUT
|
142
|
+
param.set_direction(INPUT_ONLY)
|
143
|
+
# Obtain the value out of the hash if neccessary
|
144
|
+
if bindvar.class == Hash
|
145
|
+
raise DBI::ProgrammingError.new("Parameter hash must contain :value key") if !bindvar.has_key?(:value)
|
146
|
+
param.set_value(bindvar[:value])
|
147
|
+
else
|
148
|
+
param.set_value(bindvar)
|
149
|
+
end
|
150
|
+
raise error() if SA.instance.api.sqlany_bind_param(prep_stmt, i, param) == 0
|
151
|
+
end
|
152
|
+
|
153
|
+
# Bind OUTPUT
|
154
|
+
if orig_direction == OUTPUT_ONLY or orig_direction == INPUT_OUTPUT
|
155
|
+
param.set_direction(OUTPUT_ONLY)
|
156
|
+
# Add the +::name+ to the +bound+ hash so its output value can be retrieved later
|
157
|
+
raise DBI::ProgrammingError.new("Parameter hash must contain :name key") if !bindvar.has_key?(:name)
|
158
|
+
bound[bindvar[:name]] = i if !bound.nil?
|
159
|
+
# set the buffer length if appropriate
|
160
|
+
if bindvar.has_key?(:length)
|
161
|
+
param.set_buffer_size(bindvar[:length])
|
162
|
+
end
|
163
|
+
# +set_value+ sets up the receiveing buffer
|
164
|
+
param.set_value(nil)
|
165
|
+
raise error() if SA.instance.api.sqlany_bind_param(prep_stmt, i, param) == 0
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
end # module SQLAnywhere
|
171
|
+
end # module DBD
|
172
|
+
end # module DBI
|
173
|
+
|
174
|
+
require 'dbd/sqlanywhere/driver'
|
175
|
+
require 'dbd/sqlanywhere/database'
|
176
|
+
require 'dbd/sqlanywhere/statement'
|