sqlanywhere-ffi 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +34 -0
- data/Gemfile +3 -0
- data/LICENSE +23 -0
- data/README.md +102 -0
- data/lib/api.rb +8 -0
- data/lib/bind_param.rb +92 -0
- data/lib/bind_param_info.rb +12 -0
- data/lib/bool.rb +13 -0
- data/lib/column_info.rb +18 -0
- data/lib/data_info.rb +12 -0
- data/lib/data_value.rb +60 -0
- data/lib/sql_anywhere_interface.rb +113 -0
- data/lib/sqlanywhere.rb +126 -0
- data/sqlanywhere-ffi.gemspec +15 -0
- data/test/sqlanywhere_test.rb +430 -0
- data/test/test.sql +92 -0
- data/test/test_iq.sql +92 -0
- metadata +106 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
=CHANGE LOG
|
2
|
+
|
3
|
+
=====0.1.5 -- 2010/01/25
|
4
|
+
- Updated library to use DBCAPI 2.0
|
5
|
+
- Changed test suite to correctly test BIT and TINYINT types
|
6
|
+
- Added support for Ruby 1.9.1
|
7
|
+
|
8
|
+
=====0.1.4 -- 2009/03/25
|
9
|
+
- Changed Rakefile to automatically create lib directory
|
10
|
+
- Fixed bug that tried to build native extensions on binary distsributions
|
11
|
+
|
12
|
+
=====0.1.3 -- 2008/12/31
|
13
|
+
- Removed 'hint file' in lib directory
|
14
|
+
- Added extensions to gemspec to force a local compile
|
15
|
+
|
16
|
+
=====0.1.2 -- 2008/12/18
|
17
|
+
- Fixed bug when trying to read input value from OUTPUT parameter
|
18
|
+
- Added error checking to C2RB
|
19
|
+
- Fixed Rake to handle .bundle on OSX
|
20
|
+
|
21
|
+
=====0.1.1 -- 2008/11/06
|
22
|
+
- Created a source gem rake task
|
23
|
+
- Created a 'hint' file if the source gem is used directly
|
24
|
+
- Changed file permissions on archives
|
25
|
+
- Changed archives to be specific to platform (.zip on windows, .tar.gz
|
26
|
+
otherwise)
|
27
|
+
- Changed default rake task to only build library, not gem
|
28
|
+
- Added a gem rake task
|
29
|
+
|
30
|
+
=====0.1.0 -- 2008/10/15
|
31
|
+
- Initial Release
|
32
|
+
- Wraps DBCAPI functionality
|
33
|
+
- Includes a simple unit test suite
|
34
|
+
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,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.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
SQL Anywhere Ruby Driver
|
2
|
+
------------------------
|
3
|
+
This is a native SQL Anywhere driver for Ruby. This library wraps the
|
4
|
+
functionality provided by the SQL Anywhere DBCAPI library. This driver
|
5
|
+
is intended to be a base-level library to be used by interface libraries
|
6
|
+
such as Ruby-DBI and ActiveRecord.
|
7
|
+
|
8
|
+
This driver can be used with SQL Anywhere 10 and later versions.
|
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/sqlanywhere.git
|
15
|
+
|
16
|
+
==Running Unit Tests==
|
17
|
+
|
18
|
+
1. Change to the the <tt>test</tt> directory
|
19
|
+
|
20
|
+
cd test
|
21
|
+
|
22
|
+
2. Create a testing database:
|
23
|
+
|
24
|
+
dbinit test
|
25
|
+
|
26
|
+
3. Start the testing database:
|
27
|
+
|
28
|
+
dbeng12 test.db
|
29
|
+
|
30
|
+
4. Create the test schema:
|
31
|
+
|
32
|
+
dbisql -c "eng=test;uid=dba;pwd=sql" test.sql
|
33
|
+
|
34
|
+
5. Run the unit tests:
|
35
|
+
|
36
|
+
ruby sqlanywhere_test.rb
|
37
|
+
|
38
|
+
<b>If the tests fail to run, make sure you have set up the SQL Anywhere environment variables correctly.</b> For more information,
|
39
|
+
review the online documentation here [http://dcx.sybase.com/index.html#1200/en/dbadmin/da-envvar.html].
|
40
|
+
|
41
|
+
Sample
|
42
|
+
------
|
43
|
+
|
44
|
+
This script makes a connection, prints <tt>Successful Ruby Connection</tt> to the SQL
|
45
|
+
Anywhere console, then disconnects.
|
46
|
+
|
47
|
+
# load the SQLAnywhere gem
|
48
|
+
|
49
|
+
begin
|
50
|
+
|
51
|
+
require 'rubygems'
|
52
|
+
|
53
|
+
gem 'sqlanywhere'
|
54
|
+
|
55
|
+
unless defined? SQLAnywhere
|
56
|
+
|
57
|
+
require 'sqlanywhere'
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# create an interface
|
64
|
+
|
65
|
+
api = SQLAnywhere::SQLAnywhereInterface.new()
|
66
|
+
|
67
|
+
# initialize the interface (loads the DLL/SO)
|
68
|
+
|
69
|
+
SQLAnywhere::API.sqlany_initialize_interface( api )
|
70
|
+
|
71
|
+
# initialize our api object
|
72
|
+
|
73
|
+
api.sqlany_init()
|
74
|
+
|
75
|
+
# create a connection
|
76
|
+
|
77
|
+
conn = api.sqlany_new_connection()
|
78
|
+
|
79
|
+
# establish a connection
|
80
|
+
|
81
|
+
api.sqlany_connect(conn, "uid=dba;pwd=sql")
|
82
|
+
|
83
|
+
# execute a query without a result set
|
84
|
+
|
85
|
+
api.sqlany_execute_immediate(conn, "MESSAGE 'Successful Ruby Connection'")
|
86
|
+
|
87
|
+
# disconnect from the database
|
88
|
+
|
89
|
+
api.sqlany_disconnect(conn)
|
90
|
+
|
91
|
+
# free the connection resources
|
92
|
+
|
93
|
+
api.sqlany_free_connection(conn)
|
94
|
+
|
95
|
+
# free resources the api object uses
|
96
|
+
|
97
|
+
api.sqlany_fini()
|
98
|
+
|
99
|
+
# close the interface
|
100
|
+
|
101
|
+
SQLAnywhere::API.sqlany_finalize_interface( api )
|
102
|
+
|
data/lib/api.rb
ADDED
data/lib/bind_param.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
class SQLAnywhere::BindParam < FFI::Struct
|
4
|
+
|
5
|
+
layout(
|
6
|
+
:direction, SQLAnywhere::DataDirection,
|
7
|
+
:value, SQLAnywhere::DataValue,
|
8
|
+
:name, :string,
|
9
|
+
)
|
10
|
+
|
11
|
+
def get_name
|
12
|
+
self[:name]
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_direction
|
16
|
+
self[:direction]
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_direction d
|
20
|
+
self[:direction] = d
|
21
|
+
end
|
22
|
+
|
23
|
+
def inspect
|
24
|
+
"<#{self.class} direction: #{self[:direction]}, name: #{self[:name]}, value: #{self[:value].inspect}>"
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_value(value)
|
28
|
+
|
29
|
+
self[:value][:is_null] = FFI::MemoryPointer.new(SQLAnywhere::Bool, 1, true)
|
30
|
+
|
31
|
+
if self[:direction] == :input
|
32
|
+
|
33
|
+
case value
|
34
|
+
when String
|
35
|
+
self[:value][:length] = FFI::MemoryPointer.new(SQLAnywhere::SIZE_T, 1, false)
|
36
|
+
length = value.bytesize
|
37
|
+
SQLAnywhere.write_size_t(self[:value][:length], length)
|
38
|
+
self[:value][:buffer] = FFI::MemoryPointer.new(:char, length + 1, false)
|
39
|
+
|
40
|
+
self[:value][:buffer].put_string(0, value)
|
41
|
+
self[:value][:type] = :string
|
42
|
+
when Fixnum
|
43
|
+
self[:value][:buffer] = FFI::MemoryPointer.new(:long, 1, false)
|
44
|
+
self[:value][:type] = :val64
|
45
|
+
byte_array = [value].pack('q')
|
46
|
+
byte_array.each_byte.each_with_index do |b, offset|
|
47
|
+
self[:value][:buffer].put_char(offset, b)
|
48
|
+
end
|
49
|
+
when Bignum
|
50
|
+
self[:value][:buffer] = FFI::MemoryPointer.new(:long_long, 1, false)
|
51
|
+
self[:value][:type] = :val64
|
52
|
+
byte_array = [value].pack('Q')
|
53
|
+
byte_array.each_byte.each_with_index do |b, offset|
|
54
|
+
self[:value][:buffer].put_char(offset, b)
|
55
|
+
end
|
56
|
+
when Float
|
57
|
+
self[:value][:buffer] = FFI::MemoryPointer.new(:double, 1, false)
|
58
|
+
self[:value][:buffer].write_double(value)
|
59
|
+
self[:value][:type] = :double
|
60
|
+
when nil
|
61
|
+
self[:value][:is_null].write_int(1)
|
62
|
+
self[:value][:buffer] = FFI::MemoryPointer.new(:int, 1, false)
|
63
|
+
self[:value][:type] = :val32
|
64
|
+
else
|
65
|
+
raise "Cannot convert type (#{value.class}). Must be STRING, FIXNUM, BIGNUM, FLOAT, or NIL"
|
66
|
+
end
|
67
|
+
|
68
|
+
else
|
69
|
+
self[:value][:buffer] = FFI::MemoryPointer.new(:char,
|
70
|
+
case self[:value][:type]
|
71
|
+
when :string
|
72
|
+
self[:value][:buffer_size]
|
73
|
+
when :double
|
74
|
+
FFI::Type::FLOAT.size # Is this right? it's what the old code does
|
75
|
+
when :val64, :uval64
|
76
|
+
FFI::Type::LONG_LONG.size
|
77
|
+
when :val32, :uval32
|
78
|
+
FFI::Type::INT.size
|
79
|
+
when :val16, :uval16
|
80
|
+
FFI::Type::SHORT.size
|
81
|
+
when :val8, :uval8
|
82
|
+
FFI::Type::CHAR.size
|
83
|
+
else
|
84
|
+
raise "Type unknown (#{self[:value][:type]})"
|
85
|
+
end
|
86
|
+
)
|
87
|
+
|
88
|
+
end
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-a-sqlany-bind-param-info-str.html
|
4
|
+
class SQLAnywhere::BindParamInfo < FFI::Struct
|
5
|
+
|
6
|
+
layout(
|
7
|
+
:name, :string,
|
8
|
+
:direction, SQLAnywhere::DataDirection,
|
9
|
+
:input_value, SQLAnywhere::DataValue,
|
10
|
+
:output_value, SQLAnywhere::DataValue,
|
11
|
+
)
|
12
|
+
end
|
data/lib/bool.rb
ADDED
data/lib/column_info.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-a-sqlany-column-info-str.html
|
4
|
+
class SQLAnywhere::ColumnInfo < FFI::Struct
|
5
|
+
|
6
|
+
layout(
|
7
|
+
# The name of the column (null-terminated).
|
8
|
+
# The string can be referenced as long as the result set object is not freed.
|
9
|
+
:name, :string,
|
10
|
+
:type, SQLAnywhere::DataType,
|
11
|
+
:native_type, SQLAnywhere::NativeType,
|
12
|
+
:precision, :ushort,
|
13
|
+
:scale, :ushort,
|
14
|
+
:max_size, SQLAnywhere::SIZE_T,
|
15
|
+
:nullable, SQLAnywhere::Bool,
|
16
|
+
)
|
17
|
+
|
18
|
+
end
|
data/lib/data_info.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-a-sqlany-data-info-str.html
|
4
|
+
class SQLAnywhere::DataInfo < FFI::Struct
|
5
|
+
|
6
|
+
layout(
|
7
|
+
:type, SQLAnywhere::DataType,
|
8
|
+
:is_null, SQLAnywhere::Bool,
|
9
|
+
:data_size, SQLAnywhere::SIZE_T,
|
10
|
+
)
|
11
|
+
|
12
|
+
end
|
data/lib/data_value.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
#
|
4
|
+
class SQLAnywhere::DataValue < FFI::Struct
|
5
|
+
|
6
|
+
layout(
|
7
|
+
:buffer, :pointer, # deliberately not a string
|
8
|
+
:buffer_size, SQLAnywhere::SIZE_T,
|
9
|
+
:length, :pointer,
|
10
|
+
:type, SQLAnywhere::DataType,
|
11
|
+
:is_null, :pointer,
|
12
|
+
)
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
"<#{self.class} value: #{self.value}, buffer_size: #{self[:buffer_size]}, is_null: #{self.is_null?}, length: #{self.length}, type: #{self[:type]}, buffer: #{self[:buffer]}, length_pointer: #{self[:length]}>"
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def is_null?
|
20
|
+
return nil if self[:is_null].null?
|
21
|
+
self[:is_null].read_uint == 1
|
22
|
+
end
|
23
|
+
|
24
|
+
def length
|
25
|
+
return nil if self[:length].null?
|
26
|
+
self[:length].read_uint
|
27
|
+
end
|
28
|
+
|
29
|
+
def value
|
30
|
+
return nil if is_null?
|
31
|
+
|
32
|
+
case self[:type]
|
33
|
+
#when :invalid_type
|
34
|
+
when :binary, :string
|
35
|
+
self[:buffer].get_string(0, length)
|
36
|
+
when :double
|
37
|
+
self[:buffer].read_double
|
38
|
+
when :val64 # 64 bit integer
|
39
|
+
self[:buffer].read_long_long
|
40
|
+
when :unsigned_val64 # 64 bit unsigned integer
|
41
|
+
self[:buffer].read_ulong_long
|
42
|
+
when :val32
|
43
|
+
self[:buffer].read_int
|
44
|
+
when :unsigned_val32
|
45
|
+
self[:buffer].read_uint
|
46
|
+
when :val16
|
47
|
+
self[:buffer].read_short
|
48
|
+
when :unsigned_val16
|
49
|
+
self[:buffer].read_ushort
|
50
|
+
when :val8
|
51
|
+
self[:buffer].read_char
|
52
|
+
when :unsigned_val8
|
53
|
+
self[:buffer].read_uchar
|
54
|
+
else
|
55
|
+
raise "Type not yet implemented #{self[:type]}"
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
class SQLAnywhere::SQLAnywhereInterface
|
4
|
+
|
5
|
+
extend FFI::Library
|
6
|
+
ffi_lib 'dbcapi'
|
7
|
+
|
8
|
+
def sqlany_init(app_name = "RUBY", api_version = SQLAnywhere::API_VERSION_2, version_available = FFI::MemoryPointer.new(:int, 1, false))
|
9
|
+
sqlany_init_ app_name, api_version, version_available
|
10
|
+
end
|
11
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-init-met.html
|
12
|
+
attach_function :sqlany_init_, :sqlany_init, [:string, :uint, :pointer], :int
|
13
|
+
|
14
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-new-connection-met.html
|
15
|
+
attach_function :sqlany_new_connection, [], :pointer
|
16
|
+
|
17
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-connect-met.html
|
18
|
+
attach_function :sqlany_connect, [:pointer, :string], :int
|
19
|
+
|
20
|
+
def sqlany_error(connection)
|
21
|
+
size = 255
|
22
|
+
buffer = FFI::MemoryPointer.new(:char, size, false)
|
23
|
+
code = sqlany_error_ connection, buffer, size
|
24
|
+
return code, buffer.read_string
|
25
|
+
end
|
26
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-error-met.html
|
27
|
+
attach_function :sqlany_error_, :sqlany_error, [:pointer, :pointer, SQLAnywhere::SIZE_T], :int
|
28
|
+
|
29
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-execute-direct-met.html
|
30
|
+
attach_function :sqlany_execute_direct, [:pointer, :string], :pointer
|
31
|
+
|
32
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-fetch-next-met.html
|
33
|
+
attach_function :sqlany_fetch_next, [:pointer], :int
|
34
|
+
|
35
|
+
def sqlany_get_column(statement, column_number)
|
36
|
+
buffer = SQLAnywhere::DataValue.new
|
37
|
+
result = sqlany_get_column_(statement, column_number, buffer)
|
38
|
+
return [0, nil] if result == 0
|
39
|
+
[result, buffer.value]
|
40
|
+
end
|
41
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-get-column-met.html
|
42
|
+
attach_function :sqlany_get_column_, :sqlany_get_column, [:pointer, :uint32, :pointer], :int
|
43
|
+
|
44
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-free-stmt-met.html
|
45
|
+
attach_function :sqlany_free_stmt, [:pointer], :void
|
46
|
+
|
47
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-execute-immediate-met.html
|
48
|
+
attach_function :sqlany_execute_immediate, [:pointer, :string], :int
|
49
|
+
|
50
|
+
def sqlany_disconnect(connection)
|
51
|
+
sqlany_disconnect_(connection)
|
52
|
+
return nil
|
53
|
+
end
|
54
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-disconnect-met.html
|
55
|
+
attach_function :sqlany_disconnect_, :sqlany_disconnect, [:pointer], :int
|
56
|
+
|
57
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-free-connection-met.html
|
58
|
+
attach_function :sqlany_free_connection, [:pointer], :void
|
59
|
+
|
60
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-fini-met.html
|
61
|
+
attach_function :sqlany_fini, [], :void
|
62
|
+
|
63
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-prepare-met.html
|
64
|
+
attach_function :sqlany_prepare, [:pointer, :string], :pointer
|
65
|
+
|
66
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-num-cols-met.html
|
67
|
+
attach_function :sqlany_num_cols, [:pointer], :int
|
68
|
+
|
69
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-commit-met.html
|
70
|
+
attach_function :sqlany_commit, [:pointer], :int
|
71
|
+
|
72
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-execute-met.html
|
73
|
+
attach_function :sqlany_execute, [:pointer], :int
|
74
|
+
|
75
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-rollback-met.html
|
76
|
+
attach_function :sqlany_rollback, [:pointer], :int
|
77
|
+
|
78
|
+
def sqlany_describe_bind_param(statement, index)
|
79
|
+
bind_parameter = SQLAnywhere::BindParam.new
|
80
|
+
result = sqlany_describe_bind_param_(statement, index, bind_parameter)
|
81
|
+
[result, bind_parameter]
|
82
|
+
end
|
83
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-describe-bind-param-met.html
|
84
|
+
attach_function :sqlany_describe_bind_param_, :sqlany_describe_bind_param, [:pointer, :uint32, :pointer], :int
|
85
|
+
|
86
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-bind-param-met.html
|
87
|
+
attach_function :sqlany_bind_param, [:pointer, :uint, :pointer], :int
|
88
|
+
|
89
|
+
def sqlany_get_column_info(statement, column_number)
|
90
|
+
|
91
|
+
info = SQLAnywhere::ColumnInfo.new
|
92
|
+
|
93
|
+
result = sqlany_get_column_info_(statement, column_number, info)
|
94
|
+
[result, column_number, info[:name], info[:type], info[:native_type], info[:precision], info[:scale], info[:max_size], info[:nullable].read]
|
95
|
+
end
|
96
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-get-column-info-met.html
|
97
|
+
attach_function :sqlany_get_column_info_, :sqlany_get_column_info, [:pointer, :uint, :pointer], :int
|
98
|
+
|
99
|
+
def sqlany_sqlstate(connection)
|
100
|
+
size = 255
|
101
|
+
buffer = FFI::MemoryPointer.new(:char, size, false)
|
102
|
+
used = sqlany_sqlstate_(connection, buffer, size)
|
103
|
+
buffer.read_string(used)
|
104
|
+
end
|
105
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-sqlstate-met.html
|
106
|
+
attach_function :sqlany_sqlstate_, :sqlany_sqlstate, [:pointer, :pointer, SQLAnywhere::SIZE_T], SQLAnywhere::SIZE_T
|
107
|
+
|
108
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-clear-error-met.html
|
109
|
+
attach_function :sqlany_clear_error, [:pointer], :void
|
110
|
+
|
111
|
+
# http://dcx.sybase.com/1200/en/dbprogramming/programming-sacpp-sacapi-h-fil-sqlany-num-params-met.html
|
112
|
+
attach_function :sqlany_num_params, [:pointer], :int
|
113
|
+
end
|