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

added decimal type #54

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name = "JDBC"
uuid = "6042db11-3c3d-5e84-8dba-9cbf74c9ba48"
version = "0.5.0"
version = "0.5.1"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Decimals = "abce61dc-4473-55a0-ba07-351d65e31d42"
JavaCall = "494afd89-becb-516b-aafa-70d2670c0337"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"

Expand Down
37 changes: 30 additions & 7 deletions src/JDBC.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#This file is part of JDBC.jl. License is MIT.
module JDBC
using JavaCall
using Dates
using Dates, Decimals

export DriverManager, createStatement, prepareStatement, prepareCall, executeQuery, setFetchSize,
getInt, getFloat, getString, getShort, getByte, getTime, getTimestamp, getDate,
getBoolean, getNString, getURL, setInt, setFloat, setString, setShort, setByte, setBoolean,
getMetaData, getColumnCount, getColumnType, getColumnName, executeUpdate, execute, commit,
getBoolean, getNString, getURL, getBigDecimal, setInt, setFloat, setString, setShort, setByte, setBoolean,
setBigDecimal, getMetaData, getColumnCount, getColumnType, getColumnName, executeUpdate, execute, commit,
rollback, setAutoCommit, getResultSet


Expand All @@ -32,6 +32,7 @@ const JStatement = @jimport java.sql.Statement
const JPreparedStatement = @jimport java.sql.PreparedStatement
const JCallableStatement = @jimport java.sql.CallableStatement
const JConnection = @jimport java.sql.Connection
const JBigDecimal = @jimport java.math.BigDecimal

const COLUMN_NO_NULLS = 0
const COLUMN_NULLABLE = 1
Expand All @@ -40,6 +41,10 @@ const COLUMN_NULLABLE_UNKNOWN = 2
init() = JavaCall.init()
destroy() = JavaCall.destroy()


JBigDecimal(x::Decimal) = JBigDecimal((JString,), string(x))
Decimals.Decimal(x::JBigDecimal) = decimal(jcall(x, "toPlainString", JString, ()))

"""
```
createStatement(connection::JConnection)
Expand Down Expand Up @@ -283,8 +288,7 @@ for s in [("String", :JString),
("Float", :jfloat),
("Double", :jdouble),
("Byte", :jbyte),
("URL", :(@jimport(java.net.URL))),
("BigDecimal", :(@jimport(java.math.BigDecimal)))]
("URL", :(@jimport(java.net.URL)))]
m = Symbol(string("get", s[1]))
n = Symbol(string("set", s[1]))
v = quote
Expand All @@ -295,6 +299,25 @@ for s in [("String", :JString),
eval(v)
end

# this requires a special conversion
function getBigDecimal_raw(rs::Union{JResultSet, JCallableStatement}, fld::AbstractString)
jcall(rs, "getBigDecimal", JBigDecimal, (JString,), fld)
end
function getBigDecimal_raw(rs::Union{JResultSet, JCallableStatement}, fld::Integer)
jcall(rs, "getBigDecimal", JBigDecimal, (jint,), fld)
end
function setBigDecimal_raw(stmt::Union{JPreparedStatement, JCallableStatement}, idx::Integer, v)
jcall(stmt, "setBigDecimal", Nothing, (jint, JBigDecimal), idx, v)
end

getBigDecimal(rs::Union{JResultSet,JCallableStatement}, fld) = Decimal(getBigDecimal_raw(rs, fld))
function setBigDecimal(stmt::Union{JPreparedStatement,JCallableStatement}, idx::Integer, v::AbstractString)
setBigDecimal_raw(stmt, idx, JBigDecimal((JString,), v))
end
function setBigDecimal(stmt::Union{JPreparedStatement,JCallableStatement}, idx::Integer, v::Decimal)
setBigDecimal_raw(stmt, idx, JBigDecimal(v))
end

"""
```
getDate(rs::Union{JResultSet, JCallableStatement}, fld::AbstractString)
Expand Down Expand Up @@ -548,7 +571,7 @@ global const get_method_dict = Dict(
# JDBC_COLTYPE_CLOB => 2005,
# JDBC_COLTYPE_DATALINK => 70,
JDBC_COLTYPE_DATE => getDate,
JDBC_COLTYPE_DECIMAL => getFloat,
JDBC_COLTYPE_DECIMAL => getBigDecimal,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So one of the reasons I hadn't implemented this yet is the fear that doing things this way means every numeric field is now Decimal object, which is hundreds of time slower. Even columsn with small or low precision numbers. Should I not worry about that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was also concerned about just what the meaning was of NUMERIC. As far as I can tell, NUMERIC really does mean decimal, and not float, see here. Even if this is true, it doesn't mean there aren't lots of places where people have carelessly declared fields that should be floats as NUMERIC, but not much we can do about that I suppose.

# JDBC_COLTYPE_DISTINCT => 2001,
JDBC_COLTYPE_DOUBLE => getDouble,
JDBC_COLTYPE_FLOAT => getFloat,
Expand All @@ -560,7 +583,7 @@ global const get_method_dict = Dict(
JDBC_COLTYPE_NCHAR => getNString,
# JDBC_COLTYPE_NCLOB => 2011,
# JDBC_COLTYPE_NULL => 0,
JDBC_COLTYPE_NUMERIC => getDouble,
JDBC_COLTYPE_NUMERIC => getBigDecimal,
JDBC_COLTYPE_NVARCHAR => getNString,
# JDBC_COLTYPE_OTHER => 1111,
JDBC_COLTYPE_REAL => getFloat,
Expand Down
4 changes: 2 additions & 2 deletions src/tables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ const column_types = Dict(
JDBC_COLTYPE_BOOLEAN=>Bool,
JDBC_COLTYPE_CHAR=>String,
JDBC_COLTYPE_DATE=>Date,
JDBC_COLTYPE_DECIMAL=>Float64,
JDBC_COLTYPE_DECIMAL=>Decimal,
JDBC_COLTYPE_DOUBLE=>Float64,
JDBC_COLTYPE_FLOAT=>Float32,
JDBC_COLTYPE_INTEGER=>Int32,
JDBC_COLTYPE_LONGNVARCHAR=>String,
JDBC_COLTYPE_LONGVARCHAR=>String,
JDBC_COLTYPE_NCHAR=>String,
JDBC_COLTYPE_NUMERIC=>Float64,
JDBC_COLTYPE_NUMERIC=>Decimal,
JDBC_COLTYPE_NVARCHAR=>String,
JDBC_COLTYPE_REAL=>Float64,
JDBC_COLTYPE_ROWID=>Int64,
Expand Down
14 changes: 10 additions & 4 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ using JDBC
using DataFrames
using Test
using Dates
using Decimals
import Pkg

derby_driver_path = joinpath(dirname(pathof(JDBC)),"..","test","derby.jar")
Expand Down Expand Up @@ -94,23 +95,28 @@ stmt = createStatement(conn)

executeUpdate(stmt, "CREATE TABLE FIRSTTABLE
(ID INT PRIMARY KEY,
NAME VARCHAR(12))")
ppstmt = prepareStatement(conn, "insert into firsttable values (?, ?)")
NAME VARCHAR(12),
VALUE DECIMAL(5,2))")
ppstmt = prepareStatement(conn, "insert into firsttable values (?, ?, ?)")
setInt(ppstmt, 1,10)
setString(ppstmt, 2,"TEN")
setBigDecimal(ppstmt, 3, decimal("10.38"))
executeUpdate(ppstmt)
setInt(ppstmt, 1,20)
setString(ppstmt, 2,"TWENTY")
setBigDecimal(ppstmt, 3, decimal("-1.72e2"))
executeUpdate(ppstmt)
rs=executeQuery(stmt, "select * from FIRSTTABLE")
rs = executeQuery(stmt, "select * from FIRSTTABLE")
ft = JDBC.load(DataFrame, rs)

@testset "Query3" begin
@test size(ft) == (2,2)
@test size(ft) == (2,3)
@test ft[1, :ID] == 10
@test ft[1, :NAME] == "TEN"
@test ft[1, :VALUE] == decimal("10.38")
@test ft[2, :ID] == 20
@test ft[2, :NAME] == "TWENTY"
@test ft[2, :VALUE] == decimal("-1.72e2")
end

close(rs)
Expand Down