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
6b4ec960
Commit
6b4ec960
authored
Sep 07, 2011
by
gwenn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce ScanColumn and NamedScanColumn as the less ugly way (i can see) to known if
a column is null.
parent
cbd9900c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
114 additions
and
11 deletions
+114
-11
sqlite.go
sqlite.go
+24
-5
sqlite_test.go
sqlite_test.go
+87
-3
trace.go
trace.go
+3
-3
No files found.
sqlite.go
View file @
6b4ec960
...
...
@@ -469,12 +469,12 @@ func (s *Stmt) NamedScan(args ...interface{}) os.Error {
if
!
ok
{
return
os
.
NewError
(
"non-string field name field"
)
}
index
,
err
:=
s
.
field
Index
(
name
)
// How to look up only once for one statement ?
index
,
err
:=
s
.
Column
Index
(
name
)
// How to look up only once for one statement ?
if
err
!=
nil
{
return
err
}
ptr
:=
args
[
i
+
1
]
_
,
err
=
s
.
scanField
(
index
,
ptr
,
false
)
_
,
err
=
s
.
ScanColumn
(
index
,
ptr
,
false
)
if
err
!=
nil
{
return
err
}
...
...
@@ -493,7 +493,7 @@ func (s *Stmt) Scan(args ...interface{}) os.Error {
}
for
i
,
v
:=
range
args
{
_
,
err
:=
s
.
scanField
(
i
,
v
,
false
)
_
,
err
:=
s
.
ScanColumn
(
i
,
v
,
false
)
if
err
!=
nil
{
return
err
}
...
...
@@ -506,7 +506,10 @@ func (s *Stmt) SQL() string {
return
C
.
GoString
(
C
.
sqlite3_sql
(
s
.
stmt
))
}
func
(
s
*
Stmt
)
fieldIndex
(
name
string
)
(
int
,
os
.
Error
)
{
// Must scan all columns (but result is cached).
// Calls sqlite3_column_count, sqlite3_column_name
// http://sqlite.org/c3ref/column_name.html
func
(
s
*
Stmt
)
ColumnIndex
(
name
string
)
(
int
,
os
.
Error
)
{
if
s
.
cols
==
nil
{
count
:=
s
.
ColumnCount
()
s
.
cols
=
make
(
map
[
string
]
int
,
count
)
...
...
@@ -523,7 +526,23 @@ func (s *Stmt) fieldIndex(name string) (int, os.Error) {
// Set nullable to false to skip NULL type test.
// Returns true when nullable is true and field is null.
func
(
s
*
Stmt
)
scanField
(
index
int
,
value
interface
{},
nullable
bool
)
(
bool
,
os
.
Error
)
{
// 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
{},
nullable
bool
)
(
bool
,
os
.
Error
)
{
index
,
err
:=
s
.
ColumnIndex
(
name
)
if
err
!=
nil
{
return
false
,
err
}
return
s
.
ScanColumn
(
index
,
value
,
true
)
}
// The leftmost column is number 0.
// Index starts at 0.
// Set nullable to false to skip NULL type test.
// Returns true when nullable is true and field is null.
// 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
{},
nullable
bool
)
(
bool
,
os
.
Error
)
{
var
isNull
bool
switch
value
:=
value
.
(
type
)
{
case
*
string
:
...
...
sqlite_test.go
View file @
6b4ec960
...
...
@@ -216,10 +216,10 @@ func TestInsertWithStatement(t *testing.T) {
t
.
Errorf
(
"column name error: %s <> 'int_num'"
,
secondColumnName
)
}
var
fnum
float64
var
inum
int64
var
sstr
string
if
ok
,
_
:=
rs
.
Next
();
ok
{
var
fnum
float64
var
inum
int64
var
sstr
string
rs
.
Scan
(
&
fnum
,
&
inum
,
&
sstr
)
if
fnum
!=
0
{
t
.
Errorf
(
"Expected 0 <> %f
\n
"
,
fnum
)
...
...
@@ -376,6 +376,90 @@ func TestBlob(t *testing.T) {
br
.
Close
()
}
func
testScanColumn
(
t
*
testing
.
T
)
{
db
:=
open
(
t
)
defer
db
.
Close
()
s
,
err
:=
db
.
Prepare
(
"select 1, null, 0"
)
if
err
!=
nil
{
t
.
Fatalf
(
"prepare error: %s"
,
err
)
}
defer
s
.
Finalize
()
if
ok
,
err
:=
s
.
Next
();
!
ok
{
if
err
!=
nil
{
t
.
Fatalf
(
"error preparing count: %s"
,
err
)
}
t
.
Fatal
(
"no result for count"
)
}
var
i1
,
i2
,
i3
int
null
,
err
:=
s
.
ScanColumn
(
0
,
&
i1
,
true
)
if
err
!=
nil
{
t
.
Errorf
(
"scan error: %s
\n
"
,
err
)
}
else
if
null
{
t
.
Errorf
(
"Expected not null value"
)
}
else
if
i1
!=
1
{
t
.
Errorf
(
"Expected 1 <> %d
\n
"
,
i1
)
}
null
,
err
=
s
.
ScanColumn
(
1
,
&
i2
,
true
)
if
err
!=
nil
{
t
.
Errorf
(
"scan error: %s
\n
"
,
err
)
}
else
if
!
null
{
t
.
Errorf
(
"Expected null value"
)
}
else
if
i2
!=
0
{
t
.
Errorf
(
"Expected 0 <> %d
\n
"
,
i2
)
}
null
,
err
=
s
.
ScanColumn
(
2
,
&
i3
,
true
)
if
err
!=
nil
{
t
.
Errorf
(
"scan error: %s
\n
"
,
err
)
}
else
if
null
{
t
.
Errorf
(
"Expected not null value"
)
}
else
if
i3
!=
0
{
t
.
Errorf
(
"Expected 0 <> %d
\n
"
,
i3
)
}
}
func
testNamedScanColumn
(
t
*
testing
.
T
)
{
db
:=
open
(
t
)
defer
db
.
Close
()
s
,
err
:=
db
.
Prepare
(
"select 1 as i1, null as i2, 0 as i3"
)
if
err
!=
nil
{
t
.
Fatalf
(
"prepare error: %s"
,
err
)
}
defer
s
.
Finalize
()
if
ok
,
err
:=
s
.
Next
();
!
ok
{
if
err
!=
nil
{
t
.
Fatalf
(
"error preparing count: %s"
,
err
)
}
t
.
Fatal
(
"no result for count"
)
}
var
i1
,
i2
,
i3
int
null
,
err
:=
s
.
NamedScanColumn
(
"i1"
,
&
i1
,
true
)
if
err
!=
nil
{
t
.
Errorf
(
"scan error: %s
\n
"
,
err
)
}
else
if
null
{
t
.
Errorf
(
"Expected not null value"
)
}
else
if
i1
!=
1
{
t
.
Errorf
(
"Expected 1 <> %d
\n
"
,
i1
)
}
null
,
err
=
s
.
NamedScanColumn
(
"i2"
,
&
i2
,
true
)
if
err
!=
nil
{
t
.
Errorf
(
"scan error: %s
\n
"
,
err
)
}
else
if
!
null
{
t
.
Errorf
(
"Expected null value"
)
}
else
if
i2
!=
0
{
t
.
Errorf
(
"Expected 0 <> %d
\n
"
,
i2
)
}
null
,
err
=
s
.
NamedScanColumn
(
"i3"
,
&
i3
,
true
)
if
err
!=
nil
{
t
.
Errorf
(
"scan error: %s
\n
"
,
err
)
}
else
if
null
{
t
.
Errorf
(
"Expected not null value"
)
}
else
if
i3
!=
0
{
t
.
Errorf
(
"Expected 0 <> %d
\n
"
,
i3
)
}
}
func
BenchmarkScan
(
b
*
testing
.
B
)
{
b
.
StopTimer
()
db
,
_
:=
Open
(
""
)
...
...
trace.go
View file @
6b4ec960
...
...
@@ -223,9 +223,9 @@ func (c *Conn) ProgressHandler(f ProgressHandler, freq int, arg interface{}) {
type
StmtStatus
int
const
(
STMTSTATUS_FULLSCAN_STEP
StmtStatus
=
C
.
SQLITE_STMTSTATUS_FULLSCAN_STEP
STMTSTATUS_SORT
StmtStatus
=
C
.
SQLITE_STMTSTATUS_SORT
STMTSTATUS_AUTOINDEX
StmtStatus
=
C
.
SQLITE_STMTSTATUS_AUTOINDEX
STMTSTATUS_FULLSCAN_STEP
StmtStatus
=
C
.
SQLITE_STMTSTATUS_FULLSCAN_STEP
STMTSTATUS_SORT
StmtStatus
=
C
.
SQLITE_STMTSTATUS_SORT
STMTSTATUS_AUTOINDEX
StmtStatus
=
C
.
SQLITE_STMTSTATUS_AUTOINDEX
)
// Calls http://sqlite.org/c3ref/stmt_status.html
...
...
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