Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sql decimal to crystal big decimal #4

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/odbc/result_set.cr
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require "big"

class ODBC::ResultSet < DB::ResultSet
def initialize(@statement, @stmt_handle : LibODBC::Sqlhandle)
super(@statement)
Expand All @@ -18,13 +20,14 @@ class ODBC::ResultSet < DB::ResultSet

def read
col = @column_index
@column_index += 1

# Get the type of the column
check LibODBC.sql_col_attribute_w(@stmt_handle, col, LibODBC::SQL_DESC_CONCISE_TYPE, nil, 0, nil, out col_type)

# Query the data from the column
ind_ptr = 0_i64
val = case col_type
case col_type
when LibODBC::SQL_BIT
bit = uninitialized UInt8
check LibODBC.sql_get_data(@stmt_handle, col, LibODBC::SQL_C_BIT, pointerof(bit), 0, pointerof(ind_ptr))
Expand All @@ -39,10 +42,25 @@ class ODBC::ResultSet < DB::ResultSet
ival = uninitialized Int64
check LibODBC.sql_get_data(@stmt_handle, col, LibODBC::SQL_C_SBIGINT, pointerof(ival), 0, pointerof(ind_ptr))
ind_ptr == LibODBC::SQL_NULL_DATA ? nil : ival
when LibODBC::SQL_REAL, LibODBC::SQL_FLOAT, LibODBC::SQL_DOUBLE, LibODBC::SQL_NUMERIC, LibODBC::SQL_DECIMAL
when LibODBC::SQL_REAL, LibODBC::SQL_FLOAT, LibODBC::SQL_DOUBLE
fval = uninitialized Float64
check LibODBC.sql_get_data(@stmt_handle, col, LibODBC::SQL_C_DOUBLE, pointerof(fval), 0, pointerof(ind_ptr))
ind_ptr == LibODBC::SQL_NULL_DATA ? nil : fval
when LibODBC::SQL_NUMERIC, LibODBC::SQL_DECIMAL
check LibODBC.sql_col_attribute_w(@stmt_handle, col, LibODBC::SQL_DESC_PRECISION, nil, 0, nil, out precision)
check LibODBC.sql_col_attribute_w(@stmt_handle, col, LibODBC::SQL_DESC_SCALE, nil, 0, nil, out scale)
if scale < 0
sbuf = Bytes.new(precision - scale + 4) #Careful with scientific notation and - sign which could take up to 4 supplementary chars
elsif scale > precision
sbuf = Bytes.new(scale + 3)
else
sbuf = Bytes.new(precision + 2)
end
check LibODBC.sql_get_data(@stmt_handle, col, LibODBC::SQL_C_CHAR, sbuf.to_unsafe, sbuf.size, pointerof(ind_ptr))
return nil if ind_ptr == LibODBC::SQL_NULL_DATA
slen = [ind_ptr, sbuf.size].min
str = String.new(sbuf[...slen])
BigDecimal.new(str)
when LibODBC::SQL_CHAR, LibODBC::SQL_VARCHAR, LibODBC::SQL_LONGVARCHAR
dummy = Bytes.new(1)
check LibODBC.sql_get_data(@stmt_handle, col, LibODBC::SQL_C_CHAR, dummy.to_unsafe, 0, pointerof(ind_ptr))
Expand Down Expand Up @@ -96,8 +114,6 @@ class ODBC::ResultSet < DB::ResultSet
else
nil
end
@column_index += 1
val
end

def read(t : Int32.class) : Int32
Expand Down