lib/dbd/sqlanywhere/statement.rb in dbd-sqlanywhere-0.1.2 vs lib/dbd/sqlanywhere/statement.rb in dbd-sqlanywhere-1.0.0
- old
+ new
@@ -1,211 +1,216 @@
-#====================================================
-#
-# Copyright 2008-2009 iAnywhere Solutions, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# While not a requirement of the license, if you do modify this file, we
-# would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
-#
-#
-#====================================================
-
-module DBI::DBD::SQLAnywhere
- class Statement < DBI::BaseStatement
- include Utility
-
-
- # Conversion table between SQL Anywhere E-SQL types and DBI SQL Types
- SQLANY_NATIVE_TYPES = {
- 0 => DBI::SQL_LONGVARCHAR,
- 384 => DBI::SQL_DATE,
- 388 => DBI::SQL_TIME,
- 392 => DBI::SQL_TIMESTAMP,
- 448 => DBI::SQL_VARCHAR,
- 452 => DBI::SQL_CHAR,
- 456 => DBI::SQL_LONGVARCHAR,
- 460 => DBI::SQL_LONGVARCHAR,
- 480 => DBI::SQL_DOUBLE,
- 482 => DBI::SQL_FLOAT,
- 484 => DBI::SQL_DECIMAL,
- 496 => DBI::SQL_INTEGER,
- 500 => DBI::SQL_SMALLINT,
- 524 => DBI::SQL_BINARY,
- 528 => DBI::SQL_LONGVARBINARY,
- 604 => DBI::SQL_TINYINT,
- 608 => DBI::SQL_BIGINT,
- 612 => DBI::SQL_INTEGER,
- 616 => DBI::SQL_SMALLINT,
- 620 => DBI::SQL_BIGINT,
- 624 => DBI::SQL_BIT,
- 640 => DBI::SQL_LONGVARCHAR
- }
-
- def initialize(handle, conn, bound = {} )
- @handle = handle
- @conn = conn
- @arr = []
- @bound = bound
- @offset = -1
- end
-
- def __bound_param(name)
- if !@bound[name].nil?
- res, param = SA.instance.api.sqlany_get_bind_param_info(@handle, @bound[name])
- raise error() if res == 0
- return param.get_output()
- end
- end
-
- # Although SQL Anywhere allows multiple result sets,
- # the @fetchable variable disallows there use
- #
- #def __next_resultset
- # return SA.instance.api.sqlany_get_next_result(@handle)
- #end
-
- def bind_param(param, value, attribs)
- param -= 1
- res, param_description = SA.instance.api.sqlany_describe_bind_param(@handle, param)
- raise error() if res == 0 or param_description.nil?
- do_bind!(@handle, param_description, value, param, @bound)
- param_description.finish
- end
-
- def execute()
- res = SA.instance.api.sqlany_execute(@handle)
- raise error() if res == 0
- end
-
- def fetch()
- return fetch_scroll(DBI::SQL_FETCH_NEXT, 1)
- end
-
- def fetch_all()
- rows = []
- loop {
- new_row = self.fetch_scroll(DBI::SQL_FETCH_NEXT, 1)
- break if new_row.nil?
- rows << new_row.clone
- }
- return rows
- end
-
- def fetch_scroll(direction, offset)
- res = 0
- new_offset = @offset
-
- case direction
- when DBI::SQL_FETCH_NEXT
- res = SA.instance.api.sqlany_fetch_next(@handle)
- new_offset += 1
- when DBI::SQL_FETCH_PRIOR
- res = SA.instance.api.sqlany_fetch_absolute(@handle, @offset)
- new_offset -= 1
- when DBI::SQL_FETCH_FIRST
- res = SA.instance.api.sqlany_fetch_absolute(@handle, 1)
- new_offset = 0
- when DBI::SQL_FETCH_LAST
- res = SA.instance.api.sqlany_fetch_absolute(@handle, -1)
- new_offset = self.rows() - 1
- when DBI::SQL_FETCH_ABSOLUTE
- res = SA.instance.api.sqlany_fetch_absolute(@handle, offset)
- if offset <= 0
- new_offset = self.rows() + offset
- else
- new_offset = offset - 1
- end
- when DBI::SQL_FETCH_RELATIVE
- res = SA.instance.api.sqlany_fetch_absolute(@handle, @offset + offset + 1)
- new_offset += offset
- end
-
- if (res == 1)
- retrieve_row_data()
- @offset = new_offset
- return @arr
- else
- return nil
- end
- end
-
- def column_info
- columns = []
- if !@handle.nil?
- max_cols = SA.instance.api.sqlany_num_cols(@handle)
- raise error() if max_cols == -1
- max_cols.times do |cols|
- columns << {}
- res, holder, col_name, type, native_type, precision, scale, max_size, nullable = SA.instance.api.sqlany_get_column_info(@handle, cols)
- raise error() if res == 0 or col_name.nil?
- columns[cols]["name"] = col_name
- sql_type = SQLANY_NATIVE_TYPES[native_type]
- columns[cols]["sql_type"] = sql_type
- columns[cols]["type_name"] = DBI::SQL_TYPE_NAMES[sql_type]
- precision = max_size if precision == 0 and max_size != 0
- columns[cols]["precision"] = precision
- columns[cols]["scale"] = scale
- columns[cols]["nullable"] = (nullable == 0)
-
- columns[cols]["dbi_type"] = DBI::Type::Boolean if sql_type == DBI::SQL_BIT
- end
- end
- return columns
- end
-
- def rows
- if @handle.nil?
- res = SA.instance.api.sqlany_affected_rows(@handle)
- raise error() if res == -1
- return res
- else
- 0
- end
- end
-
- def finish
- if !@handle.nil?
- SA.instance.api.sqlany_free_stmt(@handle);
- @handle = nil
- end
- end
-
- def cancel
- end
-
- protected
- def error(*custom_msg)
- code, msg = SA.instance.api.sqlany_error(@conn)
- state = SA.instance.api.sqlany_sqlstate(@conn)
- SA.instance.api.sqlany_clear_error(@conn)
- if !custom_msg.nil?
- if custom_msg.length != 0
- msg = "#{custom_msg}. #{msg}"
- end
- end
- return DBI::DatabaseError.new(msg, code, state)
- end
-
- def retrieve_row_data
- max_cols = SA.instance.api.sqlany_num_cols(@handle)
- raise error() if max_cols == -1
- max_cols.times do |cols|
- res, col_val = SA.instance.api.sqlany_get_column(@handle, cols)
- raise error() if res == 0
- @arr[cols] = col_val
- end
- end
- end
-end
+#====================================================
+#
+# Copyright 2012 iAnywhere Solutions, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# While not a requirement of the license, if you do modify this file, we
+# would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
+#
+#
+#====================================================
+
+module DBI::DBD::SQLAnywhere
+ class Statement < DBI::BaseStatement
+ include Utility
+
+
+ # Conversion table between SQL Anywhere E-SQL types and DBI SQL Types
+ SQLANY_NATIVE_TYPES = {
+ 0 => DBI::SQL_LONGVARCHAR,
+ 384 => DBI::SQL_DATE,
+ 388 => DBI::SQL_TIME,
+ 392 => DBI::SQL_TIMESTAMP,
+ 448 => DBI::SQL_VARCHAR,
+ 452 => DBI::SQL_CHAR,
+ 456 => DBI::SQL_LONGVARCHAR,
+ 460 => DBI::SQL_LONGVARCHAR,
+ 480 => DBI::SQL_DOUBLE,
+ 482 => DBI::SQL_FLOAT,
+ 484 => DBI::SQL_DECIMAL,
+ 496 => DBI::SQL_INTEGER,
+ 500 => DBI::SQL_SMALLINT,
+ 524 => DBI::SQL_BINARY,
+ 528 => DBI::SQL_LONGVARBINARY,
+ 604 => DBI::SQL_TINYINT,
+ 608 => DBI::SQL_BIGINT,
+ 612 => DBI::SQL_INTEGER,
+ 616 => DBI::SQL_SMALLINT,
+ 620 => DBI::SQL_BIGINT,
+ 624 => DBI::SQL_BIT,
+ 640 => DBI::SQL_LONGVARCHAR
+ }
+
+ def initialize(handle, conn, bound = {} )
+ @handle = handle
+ @conn = conn
+ @arr = []
+ @bound = bound
+ @offset = -1
+ end
+
+ def __bound_param(name)
+ if !@bound[name].nil?
+ res, param = SA.instance.api.sqlany_get_bind_param_info(@handle, @bound[name])
+ raise error() if res == 0
+ return param.get_output()
+ end
+ end
+
+ # Although SQL Anywhere allows multiple result sets,
+ # the @fetchable variable disallows there use
+ #
+ #def __next_resultset
+ # return SA.instance.api.sqlany_get_next_result(@handle)
+ #end
+
+ def bind_param(param, value, attribs)
+ param -= 1
+ res, param_description = SA.instance.api.sqlany_describe_bind_param(@handle, param)
+ raise error() if res == 0 or param_description.nil?
+ do_bind!(@handle, param_description, value, param, @bound)
+ param_description.finish
+ end
+
+ def execute()
+ res = SA.instance.api.sqlany_execute(@handle)
+ raise error() if res == 0
+ end
+
+ def fetch()
+ return fetch_scroll(DBI::SQL_FETCH_NEXT, 1)
+ end
+
+ def fetch_all()
+ rows = []
+ loop {
+ new_row = self.fetch_scroll(DBI::SQL_FETCH_NEXT, 1)
+ break if new_row.nil?
+ rows << new_row.clone
+ }
+ return rows
+ end
+
+ def fetch_scroll(direction, offset)
+ res = 0
+ new_offset = @offset
+
+ case direction
+ when DBI::SQL_FETCH_NEXT
+ res = SA.instance.api.sqlany_fetch_next(@handle)
+ new_offset += 1
+ when DBI::SQL_FETCH_PRIOR
+ res = SA.instance.api.sqlany_fetch_absolute(@handle, @offset)
+ new_offset -= 1
+ when DBI::SQL_FETCH_FIRST
+ res = SA.instance.api.sqlany_fetch_absolute(@handle, 1)
+ new_offset = 0
+ when DBI::SQL_FETCH_LAST
+ res = SA.instance.api.sqlany_fetch_absolute(@handle, -1)
+ new_offset = self.rows() - 1
+ when DBI::SQL_FETCH_ABSOLUTE
+ res = SA.instance.api.sqlany_fetch_absolute(@handle, offset)
+ if offset <= 0
+ new_offset = self.rows() + offset
+ else
+ new_offset = offset - 1
+ end
+ when DBI::SQL_FETCH_RELATIVE
+ res = SA.instance.api.sqlany_fetch_absolute(@handle, @offset + offset + 1)
+ new_offset += offset
+ end
+
+ if (res == 1)
+ retrieve_row_data()
+ @offset = new_offset
+ return @arr
+ else
+ return nil
+ end
+ end
+
+ def column_info
+ columns = []
+ if !@handle.nil?
+ max_cols = SA.instance.api.sqlany_num_cols(@handle)
+ raise error() if max_cols == -1
+ max_cols.times do |cols|
+ columns << {}
+ res, holder, col_name, type, native_type, precision, scale, max_size, nullable = SA.instance.api.sqlany_get_column_info(@handle, cols)
+ raise error() if res == 0 or col_name.nil?
+ columns[cols]["name"] = col_name
+ sql_type = SQLANY_NATIVE_TYPES[native_type]
+ columns[cols]["sql_type"] = sql_type
+ columns[cols]["type_name"] = DBI::SQL_TYPE_NAMES[sql_type]
+ if [ DBI::SQL_CHAR, DBI::SQL_VARCHAR,
+ DBI::SQL_BINARY, DBI::SQL_VARBINARY ].include?(sql_type)
+ precision = max_size
+ end
+ if precision != 0 or scale != 0
+ columns[cols]["precision"] = precision
+ columns[cols]["scale"] = scale
+ end
+ columns[cols]["nullable"] = (nullable == 0)
+
+ columns[cols]["dbi_type"] = DBI::Type::Boolean if sql_type == DBI::SQL_BIT
+ end
+ end
+ return columns
+ end
+
+ def rows
+ if !@handle.nil?
+ res = SA.instance.api.sqlany_affected_rows(@handle)
+ raise error() if res == -1
+ return res
+ else
+ 0
+ end
+ end
+
+ def finish
+ if !@handle.nil?
+ SA.instance.api.sqlany_free_stmt(@handle);
+ @handle = nil
+ end
+ end
+
+ def cancel
+ end
+
+ protected
+ def error(*custom_msg)
+ code, msg = SA.instance.api.sqlany_error(@conn)
+ state = SA.instance.api.sqlany_sqlstate(@conn)
+ SA.instance.api.sqlany_clear_error(@conn)
+ if !custom_msg.nil?
+ if custom_msg.length != 0
+ msg = "#{custom_msg}. #{msg}"
+ end
+ end
+ return DBI::DatabaseError.new(msg, code, state)
+ end
+
+ def retrieve_row_data
+ max_cols = SA.instance.api.sqlany_num_cols(@handle)
+ raise error() if max_cols == -1
+ max_cols.times do |cols|
+ res, col_val = SA.instance.api.sqlany_get_column(@handle, cols)
+ raise error() if res == 0
+ @arr[cols] = ( col_val ? col_val.to_s : nil )
+ end
+ end
+ end
+end