Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gosqlite
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gosqlite
Commits
dd7e497c
Commit
dd7e497c
authored
Oct 20, 2011
by
gwenn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Another try with Scan but bad stuff.
parent
0f1bd89b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
130 additions
and
123 deletions
+130
-123
Makefile
Makefile
+1
-2
README
README
+1
-8
sqlite.go
sqlite.go
+128
-30
value.go
value.go
+0
-83
No files found.
Makefile
View file @
dd7e497c
...
@@ -11,8 +11,7 @@ CGOFILES=\
...
@@ -11,8 +11,7 @@ CGOFILES=\
backup.go
\
backup.go
\
meta.go
\
meta.go
\
trace.go
\
trace.go
\
blob.go
\
blob.go
value.go
GOFILES
=
\
GOFILES
=
\
date.go
date.go
...
...
README
View file @
dd7e497c
...
@@ -23,14 +23,7 @@ Using the native sqlite3_column_x implies:
...
@@ -23,14 +23,7 @@ Using the native sqlite3_column_x implies:
- loosy conversion when types mismatch (select cast('M' as int); --> 0),
- loosy conversion when types mismatch (select cast('M' as int); --> 0),
- NULL value cannot be returned, default value (0, false, "") is returned instead.
- NULL value cannot be returned, default value (0, false, "") is returned instead.
Maybe we should let the caller do the conversion:
Maybe we should let the caller do the conversion.
- she gives the Scan method a pointer/context (interface{}) and a callback function with this signature:
func (data interface{}, c *Converter) os.Error
- the Converter gives access to:
* the number of columns,
* the type of a column (by name or index),
* the bool/byte/[]byte/int/int64/float/string value of a column (by name or index).
- for each row, the callback is invoked.
Misc:
Misc:
Conn#EnableFkey/IsFKeyEnabled
Conn#EnableFkey/IsFKeyEnabled
...
...
sqlite.go
View file @
dd7e497c
...
@@ -342,6 +342,10 @@ type Stmt struct {
...
@@ -342,6 +342,10 @@ type Stmt struct {
stmt
*
C
.
sqlite3_stmt
stmt
*
C
.
sqlite3_stmt
tail
string
tail
string
cols
map
[
string
]
int
// cached columns index by name
cols
map
[
string
]
int
// cached columns index by name
// Enable NULL value check in Scan methods
CheckNull
bool
// Enable type check in Scan methods
CheckTypeMismatch
bool
}
}
// Calls sqlite3_prepare_v2 and sqlite3_bind_*
// Calls sqlite3_prepare_v2 and sqlite3_bind_*
...
@@ -362,7 +366,7 @@ func (c *Conn) Prepare(cmd string, args ...interface{}) (*Stmt, os.Error) {
...
@@ -362,7 +366,7 @@ func (c *Conn) Prepare(cmd string, args ...interface{}) (*Stmt, os.Error) {
if
tail
!=
nil
&&
C
.
strlen
(
tail
)
>
0
{
if
tail
!=
nil
&&
C
.
strlen
(
tail
)
>
0
{
t
=
C
.
GoString
(
tail
)
t
=
C
.
GoString
(
tail
)
}
}
s
:=
&
Stmt
{
c
:
c
,
stmt
:
stmt
,
tail
:
t
}
s
:=
&
Stmt
{
c
:
c
,
stmt
:
stmt
,
tail
:
t
,
CheckNull
:
true
,
CheckTypeMismatch
:
true
}
if
len
(
args
)
>
0
{
if
len
(
args
)
>
0
{
err
:=
s
.
Bind
(
args
...
)
err
:=
s
.
Bind
(
args
...
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -576,7 +580,7 @@ func (s *Stmt) NamedScan(args ...interface{}) os.Error {
...
@@ -576,7 +580,7 @@ func (s *Stmt) NamedScan(args ...interface{}) os.Error {
return
err
return
err
}
}
ptr
:=
args
[
i
+
1
]
ptr
:=
args
[
i
+
1
]
_
,
err
=
s
.
ScanColumn
(
index
,
ptr
/*, false*/
)
_
,
err
=
s
.
ScanColumn
(
index
,
ptr
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -595,7 +599,7 @@ func (s *Stmt) Scan(args ...interface{}) os.Error {
...
@@ -595,7 +599,7 @@ func (s *Stmt) Scan(args ...interface{}) os.Error {
}
}
for
i
,
v
:=
range
args
{
for
i
,
v
:=
range
args
{
_
,
err
:=
s
.
ScanColumn
(
i
,
v
/*, false*/
)
_
,
err
:=
s
.
ScanColumn
(
i
,
v
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -627,7 +631,7 @@ func (s *Stmt) ColumnIndex(name string) (int, os.Error) {
...
@@ -627,7 +631,7 @@ func (s *Stmt) ColumnIndex(name string) (int, os.Error) {
}
}
// Set nullable to false to skip NULL type test.
// Set nullable to false to skip NULL type test.
// Returns true when column is null.
// Returns true when column is null
and Stmt.CheckNull is activated
.
// Calls sqlite3_column_count, sqlite3_column_name and sqlite3_column_(blob|double|int|int64|text) depending on args type.
// Calls sqlite3_column_count, sqlite3_column_name and sqlite3_column_(blob|double|int|int64|text) depending on args type.
// http://sqlite.org/c3ref/column_blob.html
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
NamedScanColumn
(
name
string
,
value
interface
{})
(
bool
,
os
.
Error
)
{
func
(
s
*
Stmt
)
NamedScanColumn
(
name
string
,
value
interface
{})
(
bool
,
os
.
Error
)
{
...
@@ -639,38 +643,64 @@ func (s *Stmt) NamedScanColumn(name string, value interface{}) (bool, os.Error)
...
@@ -639,38 +643,64 @@ func (s *Stmt) NamedScanColumn(name string, value interface{}) (bool, os.Error)
}
}
// The leftmost column/index is number 0.
// The leftmost column/index is number 0.
// Returns true when column is null.
// Returns true when column is null
and Stmt.CheckNull is activated
.
// Calls sqlite3_column_(blob|double|int|int64|text) depending on args type.
// Calls sqlite3_column_(blob|double|int|int64|text) depending on args type.
// http://sqlite.org/c3ref/column_blob.html
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanColumn
(
index
int
,
value
interface
{})
(
bool
,
os
.
Error
)
{
func
(
s
*
Stmt
)
ScanColumn
(
index
int
,
value
interface
{})
(
bool
,
os
.
Error
)
{
var
isNull
bool
var
isNull
bool
var
err
os
.
Error
switch
value
:=
value
.
(
type
)
{
switch
value
:=
value
.
(
type
)
{
case
nil
:
case
nil
:
case
*
string
:
case
*
string
:
*
value
,
isNull
=
s
.
ScanText
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanText
(
index
)
case
*
int
:
case
*
int
:
*
value
,
isNull
=
s
.
ScanInt
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanInt
(
index
)
case
*
int64
:
case
*
int64
:
*
value
,
isNull
=
s
.
ScanInt64
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanInt64
(
index
)
case
*
byte
:
case
*
byte
:
*
value
,
isNull
=
s
.
ScanByte
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanByte
(
index
)
case
*
bool
:
case
*
bool
:
*
value
,
isNull
=
s
.
ScanBool
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanBool
(
index
)
case
*
float64
:
case
*
float64
:
*
value
,
isNull
=
s
.
ScanFloat64
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanFloat64
(
index
)
case
*
[]
byte
:
case
*
[]
byte
:
*
value
,
isNull
=
s
.
ScanBlob
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanBlob
(
index
)
default
:
default
:
return
false
,
os
.
NewError
(
"unsupported type in Scan: "
+
reflect
.
TypeOf
(
value
)
.
String
())
return
false
,
os
.
NewError
(
"unsupported type in Scan: "
+
reflect
.
TypeOf
(
value
)
.
String
())
}
}
return
isNull
,
nil
return
isNull
,
err
}
// The leftmost column/index is number 0.
// Calls sqlite3_column_(blob|double|int|int64|text) depending on columns type.
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanValue
(
index
int
)
(
value
interface
{})
{
switch
s
.
ColumnType
(
index
)
{
case
Null
:
value
=
nil
case
Text
:
p
:=
C
.
sqlite3_column_text
(
s
.
stmt
,
C
.
int
(
index
))
n
:=
C
.
sqlite3_column_bytes
(
s
.
stmt
,
C
.
int
(
index
))
value
=
C
.
GoStringN
((
*
C
.
char
)(
unsafe
.
Pointer
(
p
)),
n
)
case
Integer
:
value
=
int64
(
C
.
sqlite3_column_int64
(
s
.
stmt
,
C
.
int
(
index
)))
case
Float
:
value
=
float64
(
C
.
sqlite3_column_double
(
s
.
stmt
,
C
.
int
(
index
)))
case
Blob
:
p
:=
C
.
sqlite3_column_blob
(
s
.
stmt
,
C
.
int
(
index
))
n
:=
C
.
sqlite3_column_bytes
(
s
.
stmt
,
C
.
int
(
index
))
value
=
(
*
[
1
<<
30
]
byte
)(
unsafe
.
Pointer
(
p
))[
0
:
n
]
default
:
panic
(
"The column type is not one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL"
)
}
return
}
}
// The leftmost column/index is number 0.
// The leftmost column/index is number 0.
// Returns true when column is null.
// Returns true when column is null.
// Calls sqlite3_column_text.
// Calls sqlite3_column_text.
// http://sqlite.org/c3ref/column_blob.html
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanText
(
index
int
)
(
value
string
,
isNull
bool
)
{
func
(
s
*
Stmt
)
ScanText
(
index
int
)
(
value
string
,
isNull
bool
,
err
os
.
Error
)
{
p
:=
C
.
sqlite3_column_text
(
s
.
stmt
,
C
.
int
(
index
))
p
:=
C
.
sqlite3_column_text
(
s
.
stmt
,
C
.
int
(
index
))
if
p
==
nil
{
if
p
==
nil
{
isNull
=
true
isNull
=
true
...
@@ -682,65 +712,110 @@ func (s *Stmt) ScanText(index int) (value string, isNull bool) {
...
@@ -682,65 +712,110 @@ func (s *Stmt) ScanText(index int) (value string, isNull bool) {
}
}
// The leftmost column/index is number 0.
// The leftmost column/index is number 0.
// Returns true when column is null.
// Returns true when column is null
and Stmt.CheckNull is activated
.
// Calls sqlite3_column_int.
// Calls sqlite3_column_int.
// http://sqlite.org/c3ref/column_blob.html
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanInt
(
index
int
)
(
value
int
,
isNull
bool
)
{
func
(
s
*
Stmt
)
ScanInt
(
index
int
)
(
value
int
,
isNull
bool
,
err
os
.
Error
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test for not nullable column or when it doesn't care
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
isNull
=
true
}
else
{
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Integer
);
err
!=
nil
{
return
}
}
value
=
int
(
C
.
sqlite3_column_int
(
s
.
stmt
,
C
.
int
(
index
)))
value
=
int
(
C
.
sqlite3_column_int
(
s
.
stmt
,
C
.
int
(
index
)))
}
}
return
return
}
}
// The leftmost column/index is number 0.
// The leftmost column/index is number 0.
// Returns true when column is null.
// Returns true when column is null
and Stmt.CheckNull is activated
.
// Calls sqlite3_column_int64.
// Calls sqlite3_column_int64.
// http://sqlite.org/c3ref/column_blob.html
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanInt64
(
index
int
)
(
value
int64
,
isNull
bool
)
{
func
(
s
*
Stmt
)
ScanInt64
(
index
int
)
(
value
int64
,
isNull
bool
,
err
os
.
Error
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test ...
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
isNull
=
true
}
else
{
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Integer
);
err
!=
nil
{
return
}
}
value
=
int64
(
C
.
sqlite3_column_int64
(
s
.
stmt
,
C
.
int
(
index
)))
value
=
int64
(
C
.
sqlite3_column_int64
(
s
.
stmt
,
C
.
int
(
index
)))
}
}
return
return
}
}
// The leftmost column/index is number 0.
// The leftmost column/index is number 0.
// Returns true when column is null.
// Returns true when column is null
and Stmt.CheckNull is activated
.
// Calls sqlite3_column_int.
// Calls sqlite3_column_int.
// http://sqlite.org/c3ref/column_blob.html
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanByte
(
index
int
)
(
value
byte
,
isNull
bool
)
{
func
(
s
*
Stmt
)
ScanByte
(
index
int
)
(
value
byte
,
isNull
bool
,
err
os
.
Error
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test ...
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
isNull
=
true
}
else
{
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Integer
);
err
!=
nil
{
return
}
}
value
=
byte
(
C
.
sqlite3_column_int
(
s
.
stmt
,
C
.
int
(
index
)))
value
=
byte
(
C
.
sqlite3_column_int
(
s
.
stmt
,
C
.
int
(
index
)))
}
}
return
return
}
}
// The leftmost column/index is number 0.
// The leftmost column/index is number 0.
// Returns true when column is null.
// Returns true when column is null
and Stmt.CheckNull is activated
.
// Calls sqlite3_column_int.
// Calls sqlite3_column_int.
// http://sqlite.org/c3ref/column_blob.html
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanBool
(
index
int
)
(
value
bool
,
isNull
bool
)
{
func
(
s
*
Stmt
)
ScanBool
(
index
int
)
(
value
bool
,
isNull
bool
,
err
os
.
Error
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test ...
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
isNull
=
true
}
else
{
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Integer
);
err
!=
nil
{
return
}
}
value
=
C
.
sqlite3_column_int
(
s
.
stmt
,
C
.
int
(
index
))
==
1
value
=
C
.
sqlite3_column_int
(
s
.
stmt
,
C
.
int
(
index
))
==
1
}
}
return
return
}
}
// The leftmost column/index is number 0.
// The leftmost column/index is number 0.
// Returns true when column is null.
// Returns true when column is null
and Stmt.CheckNull is activated
.
// Calls sqlite3_column_double.
// Calls sqlite3_column_double.
// http://sqlite.org/c3ref/column_blob.html
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanFloat64
(
index
int
)
(
value
float64
,
isNull
bool
)
{
func
(
s
*
Stmt
)
ScanFloat64
(
index
int
)
(
value
float64
,
isNull
bool
,
err
os
.
Error
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test ...
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
isNull
=
true
}
else
{
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Float
);
err
!=
nil
{
return
}
}
value
=
float64
(
C
.
sqlite3_column_double
(
s
.
stmt
,
C
.
int
(
index
)))
value
=
float64
(
C
.
sqlite3_column_double
(
s
.
stmt
,
C
.
int
(
index
)))
}
}
return
return
...
@@ -750,7 +825,7 @@ func (s *Stmt) ScanFloat64(index int) (value float64, isNull bool) {
...
@@ -750,7 +825,7 @@ func (s *Stmt) ScanFloat64(index int) (value float64, isNull bool) {
// Returns true when column is null.
// Returns true when column is null.
// Calls sqlite3_column_bytes.
// Calls sqlite3_column_bytes.
// http://sqlite.org/c3ref/column_blob.html
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanBlob
(
index
int
)
(
value
[]
byte
,
isNull
bool
)
{
func
(
s
*
Stmt
)
ScanBlob
(
index
int
)
(
value
[]
byte
,
isNull
bool
,
err
os
.
Error
)
{
p
:=
C
.
sqlite3_column_blob
(
s
.
stmt
,
C
.
int
(
index
))
p
:=
C
.
sqlite3_column_blob
(
s
.
stmt
,
C
.
int
(
index
))
if
p
==
nil
{
if
p
==
nil
{
isNull
=
true
isNull
=
true
...
@@ -761,6 +836,29 @@ func (s *Stmt) ScanBlob(index int) (value []byte, isNull bool) {
...
@@ -761,6 +836,29 @@ func (s *Stmt) ScanBlob(index int) (value []byte, isNull bool) {
return
return
}
}
// Only lossy conversion is reported as error.
func
(
s
*
Stmt
)
checkTypeMismatch
(
source
,
target
Type
)
os
.
Error
{
switch
target
{
case
Integer
:
switch
source
{
case
Float
:
fallthrough
case
Text
:
fallthrough
case
Blob
:
return
s
.
c
.
error
(
20
)
}
case
Float
:
switch
source
{
case
Text
:
fallthrough
case
Blob
:
return
s
.
c
.
error
(
20
)
}
}
return
nil
}
// Calls http://sqlite.org/c3ref/finalize.html
// Calls http://sqlite.org/c3ref/finalize.html
func
(
s
*
Stmt
)
Finalize
()
os
.
Error
{
func
(
s
*
Stmt
)
Finalize
()
os
.
Error
{
rv
:=
C
.
sqlite3_finalize
(
s
.
stmt
)
rv
:=
C
.
sqlite3_finalize
(
s
.
stmt
)
...
...
value.go
deleted
100644 → 0
View file @
0f1bd89b
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package sqlite provides access to the SQLite library, version 3.
package
sqlite
/*
#include <sqlite3.h>
#include <stdlib.h>
*/
import
"C"
/*
import (
"fmt"
"os"
"unsafe"
)
*/
// Calls sqlite3_column_count and sqlite3_column_(blob|double|int|int64|text) depending on columns type.
// http://sqlite.org/c3ref/column_blob.html
/*
func (s *Stmt) ScanNamedValues(values ...NamedValue) os.Error {
n := s.ColumnCount()
if n != len(values) { // What happens when the number of arguments is less than the number of columns?
return os.NewError(fmt.Sprintf("incorrect argument count for Stmt.ScanValues: have %d want %d", len(values), n))
}
for _, v := range values {
index, err := s.ColumnIndex(v.Name()) // How to look up only once for one statement ?
if err != nil {
return err
}
s.ScanValue(index, v)
}
return nil
}
*/
// Calls sqlite3_column_count and sqlite3_column_(blob|double|int|int64|text) depending on columns type.
// http://sqlite.org/c3ref/column_blob.html
/*
func (s *Stmt) ScanValues(values ...Value) os.Error {
n := s.ColumnCount()
if n != len(values) { // What happens when the number of arguments is less than the number of columns?
return os.NewError(fmt.Sprintf("incorrect argument count for Stmt.ScanValues: have %d want %d", len(values), n))
}
for i, v := range values {
s.ScanValue(i, v)
}
return nil
}
*/
// The leftmost column/index is number 0.
// Calls sqlite3_column_(blob|double|int|int64|text) depending on columns type.
// http://sqlite.org/c3ref/column_blob.html
/*
func (s *Stmt) ScanValue(index int) {
switch s.columnType(index) {
case C.SQLITE_NULL:
value.setNull(true)
case C.SQLITE_TEXT:
p := C.sqlite3_column_text(s.stmt, C.int(index))
n := C.sqlite3_column_bytes(s.stmt, C.int(index))
value.setText(C.GoStringN((*C.char)(unsafe.Pointer(p)), n))
case C.SQLITE_INTEGER:
value.setInt(int64(C.sqlite3_column_int64(s.stmt, C.int(index))))
case C.SQLITE_FLOAT:
value.setFloat(float64(C.sqlite3_column_double(s.stmt, C.int(index))))
case C.SQLITE_BLOB:
p := C.sqlite3_column_blob(s.stmt, C.int(index))
n := C.sqlite3_column_bytes(s.stmt, C.int(index))
value.setBlob((*[1 << 30]byte)(unsafe.Pointer(p))[0:n])
default:
panic("The column type is not one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL")
}
}
*/
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment