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=\
backup.go
\
meta.go
\
trace.go
\
blob.go
\
value.go
blob.go
GOFILES
=
\
date.go
...
...
README
View file @
dd7e497c
...
...
@@ -23,14 +23,7 @@ Using the native sqlite3_column_x implies:
- loosy conversion when types mismatch (select cast('M' as int); --> 0),
- NULL value cannot be returned, default value (0, false, "") is returned instead.
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.
Maybe we should let the caller do the conversion.
Misc:
Conn#EnableFkey/IsFKeyEnabled
...
...
sqlite.go
View file @
dd7e497c
...
...
@@ -342,6 +342,10 @@ type Stmt struct {
stmt
*
C
.
sqlite3_stmt
tail
string
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_*
...
...
@@ -362,7 +366,7 @@ func (c *Conn) Prepare(cmd string, args ...interface{}) (*Stmt, os.Error) {
if
tail
!=
nil
&&
C
.
strlen
(
tail
)
>
0
{
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
{
err
:=
s
.
Bind
(
args
...
)
if
err
!=
nil
{
...
...
@@ -576,7 +580,7 @@ func (s *Stmt) NamedScan(args ...interface{}) os.Error {
return
err
}
ptr
:=
args
[
i
+
1
]
_
,
err
=
s
.
ScanColumn
(
index
,
ptr
/*, false*/
)
_
,
err
=
s
.
ScanColumn
(
index
,
ptr
)
if
err
!=
nil
{
return
err
}
...
...
@@ -595,7 +599,7 @@ func (s *Stmt) Scan(args ...interface{}) os.Error {
}
for
i
,
v
:=
range
args
{
_
,
err
:=
s
.
ScanColumn
(
i
,
v
/*, false*/
)
_
,
err
:=
s
.
ScanColumn
(
i
,
v
)
if
err
!=
nil
{
return
err
}
...
...
@@ -627,7 +631,7 @@ func (s *Stmt) ColumnIndex(name string) (int, os.Error) {
}
// 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.
// http://sqlite.org/c3ref/column_blob.html
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.
// 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.
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanColumn
(
index
int
,
value
interface
{})
(
bool
,
os
.
Error
)
{
var
isNull
bool
var
err
os
.
Error
switch
value
:=
value
.
(
type
)
{
case
nil
:
case
*
string
:
*
value
,
isNull
=
s
.
ScanText
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanText
(
index
)
case
*
int
:
*
value
,
isNull
=
s
.
ScanInt
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanInt
(
index
)
case
*
int64
:
*
value
,
isNull
=
s
.
ScanInt64
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanInt64
(
index
)
case
*
byte
:
*
value
,
isNull
=
s
.
ScanByte
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanByte
(
index
)
case
*
bool
:
*
value
,
isNull
=
s
.
ScanBool
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanBool
(
index
)
case
*
float64
:
*
value
,
isNull
=
s
.
ScanFloat64
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanFloat64
(
index
)
case
*
[]
byte
:
*
value
,
isNull
=
s
.
ScanBlob
(
index
)
*
value
,
isNull
,
err
=
s
.
ScanBlob
(
index
)
default
:
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.
// Returns true when column is null.
// Calls sqlite3_column_text.
// 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
))
if
p
==
nil
{
isNull
=
true
...
...
@@ -682,65 +712,110 @@ func (s *Stmt) ScanText(index int) (value string, isNull bool) {
}
// 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.
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanInt
(
index
int
)
(
value
int
,
isNull
bool
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test for not nullable column or when it doesn't care
func
(
s
*
Stmt
)
ScanInt
(
index
int
)
(
value
int
,
isNull
bool
,
err
os
.
Error
)
{
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Integer
);
err
!=
nil
{
return
}
}
value
=
int
(
C
.
sqlite3_column_int
(
s
.
stmt
,
C
.
int
(
index
)))
}
return
}
// 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.
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanInt64
(
index
int
)
(
value
int64
,
isNull
bool
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test ...
func
(
s
*
Stmt
)
ScanInt64
(
index
int
)
(
value
int64
,
isNull
bool
,
err
os
.
Error
)
{
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Integer
);
err
!=
nil
{
return
}
}
value
=
int64
(
C
.
sqlite3_column_int64
(
s
.
stmt
,
C
.
int
(
index
)))
}
return
}
// 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.
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanByte
(
index
int
)
(
value
byte
,
isNull
bool
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test ...
func
(
s
*
Stmt
)
ScanByte
(
index
int
)
(
value
byte
,
isNull
bool
,
err
os
.
Error
)
{
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Integer
);
err
!=
nil
{
return
}
}
value
=
byte
(
C
.
sqlite3_column_int
(
s
.
stmt
,
C
.
int
(
index
)))
}
return
}
// 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.
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanBool
(
index
int
)
(
value
bool
,
isNull
bool
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test ...
func
(
s
*
Stmt
)
ScanBool
(
index
int
)
(
value
bool
,
isNull
bool
,
err
os
.
Error
)
{
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Integer
);
err
!=
nil
{
return
}
}
value
=
C
.
sqlite3_column_int
(
s
.
stmt
,
C
.
int
(
index
))
==
1
}
return
}
// 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.
// http://sqlite.org/c3ref/column_blob.html
func
(
s
*
Stmt
)
ScanFloat64
(
index
int
)
(
value
float64
,
isNull
bool
)
{
if
s
.
ColumnType
(
index
)
==
Null
{
// TODO How to avoid this test ...
func
(
s
*
Stmt
)
ScanFloat64
(
index
int
)
(
value
float64
,
isNull
bool
,
err
os
.
Error
)
{
var
ctype
Type
if
s
.
CheckNull
||
s
.
CheckTypeMismatch
{
ctype
=
s
.
ColumnType
(
index
)
}
if
s
.
CheckNull
&&
ctype
==
Null
{
isNull
=
true
}
else
{
if
s
.
CheckTypeMismatch
{
if
err
=
s
.
checkTypeMismatch
(
ctype
,
Float
);
err
!=
nil
{
return
}
}
value
=
float64
(
C
.
sqlite3_column_double
(
s
.
stmt
,
C
.
int
(
index
)))
}
return
...
...
@@ -750,7 +825,7 @@ func (s *Stmt) ScanFloat64(index int) (value float64, isNull bool) {
// Returns true when column is null.
// Calls sqlite3_column_bytes.
// 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
))
if
p
==
nil
{
isNull
=
true
...
...
@@ -761,6 +836,29 @@ func (s *Stmt) ScanBlob(index int) (value []byte, isNull bool) {
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
func
(
s
*
Stmt
)
Finalize
()
os
.
Error
{
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