Commit 23b5fbc2 authored by gwenn's avatar gwenn

Fix scanning/binding of int on 64-bits machine.

parent 498b6a92
...@@ -32,7 +32,7 @@ type BlobReadWriter struct { ...@@ -32,7 +32,7 @@ type BlobReadWriter struct {
} }
// ZeroBlobLength is used to reserve space for a BLOB that is later written. // ZeroBlobLength is used to reserve space for a BLOB that is later written.
type ZeroBlobLength int type ZeroBlobLength int32
// NewBlobReader opens a BLOB for incremental I/O in read-only mode. // NewBlobReader opens a BLOB for incremental I/O in read-only mode.
// //
...@@ -117,6 +117,7 @@ func (r *BlobReader) Read(v []byte) (int, error) { ...@@ -117,6 +117,7 @@ func (r *BlobReader) Read(v []byte) (int, error) {
} }
// Seek sets the offset for the next Read or Write to offset. // Seek sets the offset for the next Read or Write to offset.
// SQLite is limited to 32-bits offset.
func (r *BlobReader) Seek(offset int64, whence int) (int64, error) { func (r *BlobReader) Seek(offset int64, whence int) (int64, error) {
switch whence { switch whence {
case 0: // SEEK_SET case 0: // SEEK_SET
......
...@@ -42,6 +42,10 @@ import ( ...@@ -42,6 +42,10 @@ import (
"unsafe" "unsafe"
) )
const (
i64 = unsafe.Sizeof(int(0)) > 4
)
type StmtError struct { type StmtError struct {
ConnError ConnError
s *Stmt s *Stmt
...@@ -341,6 +345,12 @@ func (s *Stmt) BindByIndex(index int, value interface{}) error { ...@@ -341,6 +345,12 @@ func (s *Stmt) BindByIndex(index int, value interface{}) error {
rv = C.my_bind_text(s.stmt, i, cs, l) rv = C.my_bind_text(s.stmt, i, cs, l)
} }
case int: case int:
if i64 {
rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value))
} else {
rv = C.sqlite3_bind_int(s.stmt, i, C.int(value))
}
case int32:
rv = C.sqlite3_bind_int(s.stmt, i, C.int(value)) rv = C.sqlite3_bind_int(s.stmt, i, C.int(value))
case int64: case int64:
rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value)) rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value))
...@@ -653,6 +663,18 @@ func (s *Stmt) ScanByIndex(index int, value interface{}) (bool, error) { ...@@ -653,6 +663,18 @@ func (s *Stmt) ScanByIndex(index int, value interface{}) (bool, error) {
**value = i **value = i
} }
} }
case *int32:
*value, isNull, err = s.ScanInt32(index)
case **int32:
var i int32
i, isNull, err = s.ScanInt32(index)
if err == nil {
if isNull {
*value = nil
} else {
**value = i
}
}
case *int64: case *int64:
*value, isNull, err = s.ScanInt64(index) *value, isNull, err = s.ScanInt64(index)
case **int64: case **int64:
...@@ -856,8 +878,30 @@ func (s *Stmt) ScanInt(index int) (value int, isNull bool, err error) { ...@@ -856,8 +878,30 @@ func (s *Stmt) ScanInt(index int) (value int, isNull bool, err error) {
if s.CheckTypeMismatch { if s.CheckTypeMismatch {
err = s.checkTypeMismatch(ctype, Integer) err = s.checkTypeMismatch(ctype, Integer)
} }
if i64 {
value = int(C.sqlite3_column_int64(s.stmt, C.int(index)))
} else {
value = int(C.sqlite3_column_int(s.stmt, C.int(index))) value = int(C.sqlite3_column_int(s.stmt, C.int(index)))
} }
}
return
}
// ScanInt32 scans result value from a query.
// The leftmost column/index is number 0.
// Returns true when column is null.
// (See sqlite3_column_int: http://sqlite.org/c3ref/column_blob.html)
// TODO Factorize with ScanByte, ScanBool
func (s *Stmt) ScanInt32(index int) (value int32, isNull bool, err error) {
ctype := s.ColumnType(index)
if ctype == Null {
isNull = true
} else {
if s.CheckTypeMismatch {
err = s.checkTypeMismatch(ctype, Integer)
}
value = int32(C.sqlite3_column_int(s.stmt, C.int(index)))
}
return return
} }
......
...@@ -7,9 +7,11 @@ package sqlite_test ...@@ -7,9 +7,11 @@ package sqlite_test
import ( import (
"github.com/bmizerany/assert" "github.com/bmizerany/assert"
. "github.com/gwenn/gosqlite" . "github.com/gwenn/gosqlite"
"math"
"reflect" "reflect"
"testing" "testing"
"time" "time"
"unsafe"
) )
func checkFinalize(s *Stmt, t *testing.T) { func checkFinalize(s *Stmt, t *testing.T) {
...@@ -469,3 +471,19 @@ func TestColumnType(t *testing.T) { ...@@ -469,3 +471,19 @@ func TestColumnType(t *testing.T) {
assert.Equal(t, Null, s.ColumnType(col), "column type") assert.Equal(t, Null, s.ColumnType(col), "column type")
} }
} }
func TestIntOnArch64(t *testing.T) {
db := open(t)
defer checkClose(db, t)
createTable(db, t)
if unsafe.Sizeof(int(0)) > 4 {
var i int = math.MaxInt64
err := db.Exec("INSERT INTO test (int_num) VALUES (?)", i)
checkNoError(t, err, "insert error: %s")
var r int
err = db.OneValue("SELECT int_num FROM test", &r)
checkNoError(t, err, "select error: %s")
assert.Equal(t, i, r, "int truncated")
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment