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
900f66f2
Commit
900f66f2
authored
Apr 12, 2015
by
gwenn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Panic if column index is out of range.
parent
4d9000a7
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
119 additions
and
219 deletions
+119
-219
csv.go
csv.go
+2
-3
csv_test.go
csv_test.go
+5
-10
driver.go
driver.go
+1
-3
meta.go
meta.go
+14
-23
meta_extra.go
meta_extra.go
+9
-9
meta_extra_test.go
meta_extra_test.go
+15
-30
meta_test.go
meta_test.go
+10
-30
stmt.go
stmt.go
+53
-88
stmt_test.go
stmt_test.go
+10
-23
No files found.
csv.go
View file @
900f66f2
...
...
@@ -331,9 +331,8 @@ func (s *Stmt) ExportToCSV(nullvalue string, headers bool, w *yacr.Writer) error
}
s
.
Select
(
func
(
s
*
Stmt
)
error
{
for
i
:=
0
;
i
<
s
.
ColumnCount
();
i
++
{
if
rb
,
null
,
err
:=
s
.
ScanRawBytes
(
i
);
err
!=
nil
{
return
err
}
else
if
null
{
rb
,
null
:=
s
.
ScanRawBytes
(
i
)
if
null
{
w
.
Write
([]
byte
(
nullvalue
))
}
else
{
w
.
Write
(
rb
)
...
...
csv_test.go
View file @
900f66f2
...
...
@@ -206,20 +206,15 @@ func TestImportAffinity(t *testing.T) {
err
:=
db
.
ImportCSV
(
r
,
ic
,
""
,
"test"
)
checkNoError
(
t
,
err
,
"error while importing CSV file: %s"
)
err
=
db
.
Select
(
"SELECT typeof(t), typeof(i), typeof(r), typeof(b), typeof(n) from test"
,
func
(
s
*
Stmt
)
error
{
tot
,
_
,
err
:=
s
.
ScanText
(
0
)
checkNoError
(
t
,
err
,
"error while scanning: %s"
)
tot
,
_
:=
s
.
ScanText
(
0
)
assert
.
Equal
(
t
,
"text"
,
tot
)
toi
,
_
,
err
:=
s
.
ScanText
(
1
)
checkNoError
(
t
,
err
,
"error while scanning: %s"
)
toi
,
_
:=
s
.
ScanText
(
1
)
assert
.
Equal
(
t
,
"integer"
,
toi
)
tor
,
_
,
err
:=
s
.
ScanText
(
2
)
checkNoError
(
t
,
err
,
"error while scanning: %s"
)
tor
,
_
:=
s
.
ScanText
(
2
)
assert
.
Equal
(
t
,
"real"
,
tor
)
tob
,
_
,
err
:=
s
.
ScanText
(
3
)
checkNoError
(
t
,
err
,
"error while scanning: %s"
)
tob
,
_
:=
s
.
ScanText
(
3
)
assert
.
Equal
(
t
,
"text"
,
tob
)
ton
,
_
,
err
:=
s
.
ScanText
(
4
)
checkNoError
(
t
,
err
,
"error while scanning: %s"
)
ton
,
_
:=
s
.
ScanText
(
4
)
assert
.
Equal
(
t
,
"integer"
,
ton
)
return
err
})
...
...
driver.go
View file @
900f66f2
...
...
@@ -229,9 +229,7 @@ func (r *rowsImpl) Next(dest []driver.Value) error {
return
io
.
EOF
}
for
i
:=
range
dest
{
if
dest
[
i
],
_
,
err
=
r
.
s
.
s
.
ScanValue
(
i
,
true
);
err
!=
nil
{
return
err
}
dest
[
i
],
_
=
r
.
s
.
s
.
ScanValue
(
i
,
true
)
/*if !driver.IsScanValue(dest[i]) {
panic("Invalid type returned by ScanValue")
}*/
...
...
meta.go
View file @
900f66f2
...
...
@@ -55,13 +55,10 @@ func (c *Conn) Tables(dbName string) ([]string, error) {
}
defer
s
.
finalize
()
var
tables
=
make
([]
string
,
0
,
20
)
err
=
s
.
Select
(
func
(
s
*
Stmt
)
(
err
error
)
{
if
name
,
_
,
err
:=
s
.
ScanText
(
0
);
err
!=
nil
{
return
err
}
else
{
tables
=
append
(
tables
,
name
)
}
return
err
=
s
.
Select
(
func
(
s
*
Stmt
)
error
{
name
,
_
:=
s
.
ScanText
(
0
)
tables
=
append
(
tables
,
name
)
return
nil
})
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -86,13 +83,10 @@ func (c *Conn) Views(dbName string) ([]string, error) {
}
defer
s
.
finalize
()
var
views
=
make
([]
string
,
0
,
20
)
err
=
s
.
Select
(
func
(
s
*
Stmt
)
(
err
error
)
{
if
name
,
_
,
err
:=
s
.
ScanText
(
0
);
err
!=
nil
{
return
err
}
else
{
views
=
append
(
views
,
name
)
}
return
err
=
s
.
Select
(
func
(
s
*
Stmt
)
error
{
name
,
_
:=
s
.
ScanText
(
0
)
views
=
append
(
views
,
name
)
return
nil
})
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -178,11 +172,11 @@ func (c *Conn) Columns(dbName, table string) ([]Column, error) {
// If the result column is an expression or subquery, then an empty string is returned.
// The left-most column is column 0.
// (See http://www.sqlite.org/c3ref/column_decltype.html)
func
(
s
*
Stmt
)
ColumnDeclaredType
(
index
int
)
(
string
,
error
)
{
func
(
s
*
Stmt
)
ColumnDeclaredType
(
index
int
)
string
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
""
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
return
C
.
GoString
(
C
.
sqlite3_column_decltype
(
s
.
stmt
,
C
.
int
(
index
)))
,
nil
return
C
.
GoString
(
C
.
sqlite3_column_decltype
(
s
.
stmt
,
C
.
int
(
index
)))
}
// Affinity enumerates SQLite column type affinity
...
...
@@ -201,13 +195,10 @@ const (
// If the result column is an expression or subquery, then None is returned.
// The left-most column is column 0.
// (See http://sqlite.org/datatype3.html)
func
(
s
*
Stmt
)
ColumnTypeAffinity
(
index
int
)
(
Affinity
,
error
)
{
func
(
s
*
Stmt
)
ColumnTypeAffinity
(
index
int
)
Affinity
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
None
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
return
s
.
columnTypeAffinity
(
index
),
nil
}
func
(
s
*
Stmt
)
columnTypeAffinity
(
index
int
)
Affinity
{
if
s
.
affinities
==
nil
{
count
:=
s
.
ColumnCount
()
s
.
affinities
=
make
([]
Affinity
,
count
)
...
...
@@ -216,7 +207,7 @@ func (s *Stmt) columnTypeAffinity(index int) Affinity {
return
affinity
}
}
declType
,
_
:=
s
.
ColumnDeclaredType
(
index
)
declType
:=
s
.
ColumnDeclaredType
(
index
)
affinity
:=
typeAffinity
(
declType
)
s
.
affinities
[
index
]
=
affinity
return
affinity
...
...
meta_extra.go
View file @
900f66f2
...
...
@@ -46,31 +46,31 @@ func (c *Conn) Column(dbName, tableName, columnName string) (*Column, error) {
// that is the origin of a particular result column in SELECT statement.
// The left-most column is column 0.
// (See http://www.sqlite.org/c3ref/column_database_name.html)
func
(
s
*
Stmt
)
ColumnDatabaseName
(
index
int
)
(
string
,
error
)
{
func
(
s
*
Stmt
)
ColumnDatabaseName
(
index
int
)
string
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
""
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
return
C
.
GoString
(
C
.
sqlite3_column_database_name
(
s
.
stmt
,
C
.
int
(
index
)))
,
nil
return
C
.
GoString
(
C
.
sqlite3_column_database_name
(
s
.
stmt
,
C
.
int
(
index
)))
}
// ColumnTableName returns the original un-aliased table name
// that is the origin of a particular result column in SELECT statement.
// The left-most column is column 0.
// (See http://www.sqlite.org/c3ref/column_database_name.html)
func
(
s
*
Stmt
)
ColumnTableName
(
index
int
)
(
string
,
error
)
{
func
(
s
*
Stmt
)
ColumnTableName
(
index
int
)
string
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
""
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
return
C
.
GoString
(
C
.
sqlite3_column_table_name
(
s
.
stmt
,
C
.
int
(
index
)))
,
nil
return
C
.
GoString
(
C
.
sqlite3_column_table_name
(
s
.
stmt
,
C
.
int
(
index
)))
}
// ColumnOriginName returns the original un-aliased table column name
// that is the origin of a particular result column in SELECT statement.
// The left-most column is column 0.
// (See http://www.sqlite.org/c3ref/column_database_name.html)
func
(
s
*
Stmt
)
ColumnOriginName
(
index
int
)
(
string
,
error
)
{
func
(
s
*
Stmt
)
ColumnOriginName
(
index
int
)
string
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
""
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
return
C
.
GoString
(
C
.
sqlite3_column_origin_name
(
s
.
stmt
,
C
.
int
(
index
)))
,
nil
return
C
.
GoString
(
C
.
sqlite3_column_origin_name
(
s
.
stmt
,
C
.
int
(
index
)))
}
meta_extra_test.go
View file @
900f66f2
...
...
@@ -40,20 +40,15 @@ func TestColumnMetadata(t *testing.T) {
check
(
err
)
defer
checkFinalize
(
s
,
t
)
databaseName
,
err
:=
s
.
ColumnDatabaseName
(
0
)
check
(
err
)
databaseName
:=
s
.
ColumnDatabaseName
(
0
)
assert
.
Equal
(
t
,
"main"
,
databaseName
,
"database name"
)
tableName
,
err
:=
s
.
ColumnTableName
(
0
)
check
(
err
)
tableName
:=
s
.
ColumnTableName
(
0
)
assert
.
Equal
(
t
,
"sqlite_master"
,
tableName
,
"table name"
)
originName
,
err
:=
s
.
ColumnOriginName
(
0
)
check
(
err
)
originName
:=
s
.
ColumnOriginName
(
0
)
assert
.
Equal
(
t
,
"name"
,
originName
,
"origin name"
)
declType
,
err
:=
s
.
ColumnDeclaredType
(
0
)
check
(
err
)
declType
:=
s
.
ColumnDeclaredType
(
0
)
assert
.
Equal
(
t
,
"text"
,
declType
,
"declared type"
)
affinity
,
err
:=
s
.
ColumnTypeAffinity
(
0
)
check
(
err
)
affinity
:=
s
.
ColumnTypeAffinity
(
0
)
assert
.
Equal
(
t
,
Textual
,
affinity
,
"affinity"
)
}
...
...
@@ -68,20 +63,15 @@ func TestColumnMetadataOnView(t *testing.T) {
check
(
err
)
defer
checkFinalize
(
s
,
t
)
databaseName
,
err
:=
s
.
ColumnDatabaseName
(
0
)
check
(
err
)
databaseName
:=
s
.
ColumnDatabaseName
(
0
)
assert
.
Equal
(
t
,
"main"
,
databaseName
,
"database name"
)
tableName
,
err
:=
s
.
ColumnTableName
(
0
)
check
(
err
)
tableName
:=
s
.
ColumnTableName
(
0
)
assert
.
Equal
(
t
,
"test"
,
tableName
,
"table name"
)
originName
,
err
:=
s
.
ColumnOriginName
(
0
)
check
(
err
)
originName
:=
s
.
ColumnOriginName
(
0
)
assert
.
Equal
(
t
,
"a_string"
,
originName
,
"origin name"
)
declType
,
err
:=
s
.
ColumnDeclaredType
(
0
)
check
(
err
)
declType
:=
s
.
ColumnDeclaredType
(
0
)
assert
.
Equal
(
t
,
"TEXT"
,
declType
,
"declared type"
)
affinity
,
err
:=
s
.
ColumnTypeAffinity
(
0
)
check
(
err
)
affinity
:=
s
.
ColumnTypeAffinity
(
0
)
assert
.
Equal
(
t
,
Textual
,
affinity
,
"affinity"
)
}
...
...
@@ -95,19 +85,14 @@ func TestColumnMetadataOnExpr(t *testing.T) {
check
(
err
)
defer
checkFinalize
(
s
,
t
)
databaseName
,
err
:=
s
.
ColumnDatabaseName
(
0
)
check
(
err
)
databaseName
:=
s
.
ColumnDatabaseName
(
0
)
assert
.
Equal
(
t
,
""
,
databaseName
,
"database name"
)
tableName
,
err
:=
s
.
ColumnTableName
(
0
)
check
(
err
)
tableName
:=
s
.
ColumnTableName
(
0
)
assert
.
Equal
(
t
,
""
,
tableName
,
"table name"
)
originName
,
err
:=
s
.
ColumnOriginName
(
0
)
check
(
err
)
originName
:=
s
.
ColumnOriginName
(
0
)
assert
.
Equal
(
t
,
""
,
originName
,
"origin name"
)
declType
,
err
:=
s
.
ColumnDeclaredType
(
0
)
check
(
err
)
declType
:=
s
.
ColumnDeclaredType
(
0
)
assert
.
Equal
(
t
,
""
,
declType
,
"declared type"
)
affinity
,
err
:=
s
.
ColumnTypeAffinity
(
0
)
check
(
err
)
affinity
:=
s
.
ColumnTypeAffinity
(
0
)
assert
.
Equal
(
t
,
None
,
affinity
,
"affinity"
)
}
meta_test.go
View file @
900f66f2
...
...
@@ -198,24 +198,12 @@ func TestColumnTypeAffinity(t *testing.T) {
checkNoError
(
t
,
err
,
"%s"
)
defer
checkFinalize
(
s
,
t
)
aff
,
err
:=
s
.
ColumnTypeAffinity
(
0
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
Integral
,
aff
,
"affinity"
)
aff
,
err
=
s
.
ColumnTypeAffinity
(
1
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
Real
,
aff
,
"affinity"
)
aff
,
err
=
s
.
ColumnTypeAffinity
(
2
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
Numerical
,
aff
,
"affinity"
)
aff
,
err
=
s
.
ColumnTypeAffinity
(
3
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
None
,
aff
,
"affinity"
)
aff
,
err
=
s
.
ColumnTypeAffinity
(
4
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
Textual
,
aff
,
"affinity"
)
aff
,
err
=
s
.
ColumnTypeAffinity
(
5
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
None
,
aff
,
"affinity"
)
assert
.
Equal
(
t
,
Integral
,
s
.
ColumnTypeAffinity
(
0
),
"affinity"
)
assert
.
Equal
(
t
,
Real
,
s
.
ColumnTypeAffinity
(
1
),
"affinity"
)
assert
.
Equal
(
t
,
Numerical
,
s
.
ColumnTypeAffinity
(
2
),
"affinity"
)
assert
.
Equal
(
t
,
None
,
s
.
ColumnTypeAffinity
(
3
),
"affinity"
)
assert
.
Equal
(
t
,
Textual
,
s
.
ColumnTypeAffinity
(
4
),
"affinity"
)
assert
.
Equal
(
t
,
None
,
s
.
ColumnTypeAffinity
(
5
),
"affinity"
)
}
func
TestExpressionTypeAffinity
(
t
*
testing
.
T
)
{
...
...
@@ -226,16 +214,8 @@ func TestExpressionTypeAffinity(t *testing.T) {
checkNoError
(
t
,
err
,
"%s"
)
defer
checkFinalize
(
s
,
t
)
aff
,
err
:=
s
.
ColumnTypeAffinity
(
0
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
None
,
aff
,
"affinity"
)
aff
,
err
=
s
.
ColumnTypeAffinity
(
1
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
None
,
aff
,
"affinity"
)
aff
,
err
=
s
.
ColumnTypeAffinity
(
2
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
None
,
aff
,
"affinity"
)
aff
,
err
=
s
.
ColumnTypeAffinity
(
3
)
checkNoError
(
t
,
err
,
"%s"
)
assert
.
Equal
(
t
,
None
,
aff
,
"affinity"
)
assert
.
Equal
(
t
,
None
,
s
.
ColumnTypeAffinity
(
0
),
"affinity"
)
assert
.
Equal
(
t
,
None
,
s
.
ColumnTypeAffinity
(
1
),
"affinity"
)
assert
.
Equal
(
t
,
None
,
s
.
ColumnTypeAffinity
(
2
),
"affinity"
)
assert
.
Equal
(
t
,
None
,
s
.
ColumnTypeAffinity
(
3
),
"affinity"
)
}
stmt.go
View file @
900f66f2
...
...
@@ -499,12 +499,12 @@ func (s *Stmt) DataCount() int {
// ColumnName returns the name of the Nth column of the result set returned by the SQL statement. (not cached)
// The leftmost column is number 0.
// (See http://sqlite.org/c3ref/column_name.html)
func
(
s
*
Stmt
)
ColumnName
(
index
int
)
(
string
,
error
)
{
func
(
s
*
Stmt
)
ColumnName
(
index
int
)
string
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
""
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
// If there is no AS clause then the name of the column is unspecified and may change from one release of SQLite to the next.
return
C
.
GoString
(
C
.
sqlite3_column_name
(
s
.
stmt
,
C
.
int
(
index
)))
,
nil
return
C
.
GoString
(
C
.
sqlite3_column_name
(
s
.
stmt
,
C
.
int
(
index
)))
}
// ColumnNames returns the name of the columns of the result set returned by the SQL statement. (not cached)
...
...
@@ -512,7 +512,7 @@ func (s *Stmt) ColumnNames() []string {
count
:=
s
.
ColumnCount
()
names
:=
make
([]
string
,
count
)
for
i
:=
0
;
i
<
count
;
i
++
{
names
[
i
]
,
_
=
s
.
ColumnName
(
i
)
names
[
i
]
=
s
.
ColumnName
(
i
)
}
return
names
}
...
...
@@ -547,14 +547,11 @@ var typeText = map[Type]string{
//
// After a type conversion, the value returned by sqlite3_column_type() is undefined.
// (See sqlite3_column_type: http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ColumnType
(
index
int
)
(
Type
,
error
)
{
func
(
s
*
Stmt
)
ColumnType
(
index
int
)
Type
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
Null
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
return
s
.
columnType
(
index
),
nil
// TODO request all columns type at once
}
func
(
s
*
Stmt
)
columnType
(
index
int
)
Type
{
return
Type
(
C
.
sqlite3_column_type
(
s
.
stmt
,
C
.
int
(
index
)))
return
Type
(
C
.
sqlite3_column_type
(
s
.
stmt
,
C
.
int
(
index
)))
// TODO request all columns type at once
}
// NamedScan scans result values from a query by name (name1, value1, ...).
...
...
@@ -634,8 +631,7 @@ func (s *Stmt) ColumnIndex(name string) (int, error) {
count
:=
s
.
ColumnCount
()
s
.
cols
=
make
(
map
[
string
]
int
,
count
)
for
i
:=
0
;
i
<
count
;
i
++
{
n
,
_
:=
s
.
ColumnName
(
i
)
s
.
cols
[
n
]
=
i
s
.
cols
[
s
.
ColumnName
(
i
)]
=
i
}
}
index
,
ok
:=
s
.
cols
[
name
]
...
...
@@ -677,20 +673,18 @@ func (s *Stmt) ScanByName(name string, value interface{}) (isNull bool, err erro
// (See http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ScanByIndex
(
index
int
,
value
interface
{})
(
isNull
bool
,
err
error
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
switch
value
:=
value
.
(
type
)
{
case
nil
:
case
*
string
:
*
value
,
isNull
,
err
=
s
.
ScanText
(
index
)
*
value
,
isNull
=
s
.
ScanText
(
index
)
case
**
string
:
var
st
string
if
st
,
isNull
,
err
=
s
.
ScanText
(
index
);
err
==
nil
{
if
isNull
{
*
value
=
nil
}
else
{
**
value
=
st
}
if
st
,
isNull
=
s
.
ScanText
(
index
);
isNull
{
*
value
=
nil
}
else
{
**
value
=
st
}
case
*
int
:
*
value
,
isNull
,
err
=
s
.
ScanInt
(
index
)
...
...
@@ -759,25 +753,22 @@ func (s *Stmt) ScanByIndex(index int, value interface{}) (isNull bool, err error
}
}
case
*
[]
byte
:
*
value
,
isNull
,
err
=
s
.
ScanBlob
(
index
)
*
value
,
isNull
=
s
.
ScanBlob
(
index
)
case
**
[]
byte
:
var
bs
[]
byte
if
bs
,
isNull
,
err
=
s
.
ScanBlob
(
index
);
err
==
nil
{
if
isNull
{
*
value
=
nil
}
else
{
**
value
=
bs
}
if
bs
,
isNull
=
s
.
ScanBlob
(
index
);
isNull
{
*
value
=
nil
}
else
{
**
value
=
bs
}
case
*
time
.
Time
:
// go fix doesn't like this type!
*
value
,
isNull
,
err
=
s
.
ScanTime
(
index
)
case
sql
.
Scanner
:
var
v
interface
{}
if
v
,
isNull
,
err
=
s
.
ScanValue
(
index
,
false
);
err
==
nil
{
err
=
value
.
Scan
(
v
)
}
v
,
isNull
=
s
.
ScanValue
(
index
,
false
)
err
=
value
.
Scan
(
v
)
case
*
interface
{}
:
*
value
,
isNull
,
err
=
s
.
ScanValue
(
index
,
false
)
*
value
,
isNull
=
s
.
ScanValue
(
index
,
false
)
default
:
return
s
.
ScanReflect
(
index
,
value
)
}
...
...
@@ -798,7 +789,7 @@ func (s *Stmt) ScanByIndex(index int, value interface{}) (isNull bool, err error
// Returns true when column is null.
func
(
s
*
Stmt
)
ScanReflect
(
index
int
,
v
interface
{})
(
isNull
bool
,
err
error
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
rv
:=
reflect
.
ValueOf
(
v
)
if
rv
.
Kind
()
!=
reflect
.
Ptr
||
rv
.
IsNil
()
{
...
...
@@ -808,9 +799,8 @@ func (s *Stmt) ScanReflect(index int, v interface{}) (isNull bool, err error) {
switch
dv
.
Kind
()
{
case
reflect
.
String
:
var
t
string
if
t
,
isNull
,
err
=
s
.
ScanText
(
index
);
err
==
nil
{
dv
.
SetString
(
t
)
}
t
,
isNull
=
s
.
ScanText
(
index
)
dv
.
SetString
(
t
)
case
reflect
.
Int
,
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
:
var
i
int64
if
i
,
isNull
,
err
=
s
.
ScanInt64
(
index
);
err
==
nil
{
...
...
@@ -854,64 +844,61 @@ func (s *Stmt) ScanReflect(index int, v interface{}) (isNull bool, err error) {
//
// Calls sqlite3_column_(blob|double|int|int64|text) depending on columns type.
// (See http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ScanValue
(
index
int
,
blob
bool
)
(
value
interface
{},
isNull
bool
,
err
error
)
{
func
(
s
*
Stmt
)
ScanValue
(
index
int
,
blob
bool
)
(
value
interface
{},
isNull
bool
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
nil
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
switch
s
.
c
olumnType
(
index
)
{
switch
s
.
C
olumnType
(
index
)
{
case
Null
:
return
nil
,
true
,
nil
return
nil
,
true
case
Text
:
// does not work as expected if column type affinity is TEXT but inserted value was a numeric
if
s
.
c
.
ScanNumericalAsTime
&&
s
.
c
.
DefaultTimeLayout
!=
""
&&
s
.
c
olumnTypeAffinity
(
index
)
==
Numerical
{
if
s
.
c
.
ScanNumericalAsTime
&&
s
.
c
.
DefaultTimeLayout
!=
""
&&
s
.
C
olumnTypeAffinity
(
index
)
==
Numerical
{
p
:=
C
.
sqlite3_column_text
(
s
.
stmt
,
C
.
int
(
index
))
txt
:=
C
.
GoString
((
*
C
.
char
)(
unsafe
.
Pointer
(
p
)))
value
,
err
:=
time
.
Parse
(
s
.
c
.
DefaultTimeLayout
,
txt
)
if
err
==
nil
{
return
value
,
false
,
nil
return
value
,
false
}
Log
(
-
1
,
err
.
Error
())
}
if
blob
{
p
:=
C
.
sqlite3_column_blob
(
s
.
stmt
,
C
.
int
(
index
))
n
:=
C
.
sqlite3_column_bytes
(
s
.
stmt
,
C
.
int
(
index
))
return
C
.
GoBytes
(
p
,
n
),
false
,
nil
return
C
.
GoBytes
(
p
,
n
),
false
}
p
:=
C
.
sqlite3_column_text
(
s
.
stmt
,
C
.
int
(
index
))
return
C
.
GoString
((
*
C
.
char
)(
unsafe
.
Pointer
(
p
))),
false
,
nil
return
C
.
GoString
((
*
C
.
char
)(
unsafe
.
Pointer
(
p
))),
false
case
Integer
:
value
:=
int64
(
C
.
sqlite3_column_int64
(
s
.
stmt
,
C
.
int
(
index
)))
if
s
.
c
.
ScanNumericalAsTime
&&
s
.
c
.
DefaultTimeLayout
==
""
&&
s
.
c
olumnTypeAffinity
(
index
)
==
Numerical
{
return
time
.
Unix
(
value
,
0
),
false
,
nil
if
s
.
c
.
ScanNumericalAsTime
&&
s
.
c
.
DefaultTimeLayout
==
""
&&
s
.
C
olumnTypeAffinity
(
index
)
==
Numerical
{
return
time
.
Unix
(
value
,
0
),
false
}
return
value
,
false
,
nil
return
value
,
false
case
Float
:
// does not work as expected if column type affinity is REAL but inserted value was an integer
return
float64
(
C
.
sqlite3_column_double
(
s
.
stmt
,
C
.
int
(
index
))),
false
,
nil
return
float64
(
C
.
sqlite3_column_double
(
s
.
stmt
,
C
.
int
(
index
))),
false
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))[:n]
return
C
.
GoBytes
(
p
,
n
),
false
,
nil
// The memory space used to hold strings and BLOBs is freed automatically.
return
C
.
GoBytes
(
p
,
n
),
false
// The memory space used to hold strings and BLOBs is freed automatically.
}
panic
(
"The column type is not one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL"
)
}
// ScanValues is like ScanValue on several columns.
func
(
s
*
Stmt
)
ScanValues
(
values
[]
interface
{})
(
err
error
)
{
func
(
s
*
Stmt
)
ScanValues
(
values
[]
interface
{})
{
for
i
:=
range
values
{
if
values
[
i
],
_
,
err
=
s
.
ScanValue
(
i
,
false
);
err
!=
nil
{
break
}
values
[
i
],
_
=
s
.
ScanValue
(
i
,
false
)
}
return
}
// ScanText scans result value from a query.
// The leftmost column/index is number 0.
// Returns true when column is null.
// (See sqlite3_column_text: http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ScanText
(
index
int
)
(
value
string
,
isNull
bool
,
err
error
)
{
func
(
s
*
Stmt
)
ScanText
(
index
int
)
(
value
string
,
isNull
bool
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
""
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
p
:=
C
.
sqlite3_column_text
(
s
.
stmt
,
C
.
int
(
index
))
if
p
==
nil
{
...
...
@@ -928,10 +915,7 @@ func (s *Stmt) ScanText(index int) (value string, isNull bool, err error) {
// (See sqlite3_column_int: http://sqlite.org/c3ref/column_blob.html)
// TODO Factorize with ScanByte, ScanBool
func
(
s
*
Stmt
)
ScanInt
(
index
int
)
(
value
int
,
isNull
bool
,
err
error
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
0
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
())
}
ctype
:=
s
.
columnType
(
index
)
ctype
:=
s
.
ColumnType
(
index
)
if
ctype
==
Null
{
isNull
=
true
}
else
{
...
...
@@ -953,10 +937,7 @@ func (s *Stmt) ScanInt(index int) (value int, isNull bool, err error) {
// (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
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
0
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
())
}
ctype
:=
s
.
columnType
(
index
)
ctype
:=
s
.
ColumnType
(
index
)
if
ctype
==
Null
{
isNull
=
true
}
else
{
...
...
@@ -973,10 +954,7 @@ func (s *Stmt) ScanInt32(index int) (value int32, isNull bool, err error) {
// Returns true when column is null.
// (See sqlite3_column_int64: http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ScanInt64
(
index
int
)
(
value
int64
,
isNull
bool
,
err
error
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
0
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
())
}
ctype
:=
s
.
columnType
(
index
)
ctype
:=
s
.
ColumnType
(
index
)
if
ctype
==
Null
{
isNull
=
true
}
else
{
...
...
@@ -993,10 +971,7 @@ func (s *Stmt) ScanInt64(index int) (value int64, isNull bool, err error) {
// Returns true when column is null.
// (See sqlite3_column_int: http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ScanByte
(
index
int
)
(
value
byte
,
isNull
bool
,
err
error
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
0
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
())
}
ctype
:=
s
.
columnType
(
index
)
ctype
:=
s
.
ColumnType
(
index
)
if
ctype
==
Null
{
isNull
=
true
}
else
{
...
...
@@ -1013,10 +988,7 @@ func (s *Stmt) ScanByte(index int) (value byte, isNull bool, err error) {
// Returns true when column is null.
// (See sqlite3_column_int: http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ScanBool
(
index
int
)
(
value
bool
,
isNull
bool
,
err
error
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
false
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
())
}
ctype
:=
s
.
columnType
(
index
)
ctype
:=
s
.
ColumnType
(
index
)
if
ctype
==
Null
{
isNull
=
true
}
else
{
...
...
@@ -1033,10 +1005,7 @@ func (s *Stmt) ScanBool(index int) (value bool, isNull bool, err error) {
// Returns true when column is null.
// (See sqlite3_column_double: http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ScanDouble
(
index
int
)
(
value
float64
,
isNull
bool
,
err
error
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
0
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
())
}
ctype
:=
s
.
columnType
(
index
)
ctype
:=
s
.
ColumnType
(
index
)
if
ctype
==
Null
{
isNull
=
true
}
else
{
...
...
@@ -1052,9 +1021,9 @@ func (s *Stmt) ScanDouble(index int) (value float64, isNull bool, err error) {
// The leftmost column/index is number 0.
// Returns true when column is null.
// (See sqlite3_column_blob: http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ScanBlob
(
index
int
)
(
value
[]
byte
,
isNull
bool
,
err
error
)
{
func
(
s
*
Stmt
)
ScanBlob
(
index
int
)
(
value
[]
byte
,
isNull
bool
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
nil
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
p
:=
C
.
sqlite3_column_blob
(
s
.
stmt
,
C
.
int
(
index
))
if
p
==
nil
{
...
...
@@ -1071,9 +1040,9 @@ func (s *Stmt) ScanBlob(index int) (value []byte, isNull bool, err error) {
// The leftmost column/index is number 0.
// Returns true when column is null.
// (See sqlite3_column_blob: http://sqlite.org/c3ref/column_blob.html)
func
(
s
*
Stmt
)
ScanRawBytes
(
index
int
)
(
value
[]
byte
,
isNull
bool
,
err
error
)
{
func
(
s
*
Stmt
)
ScanRawBytes
(
index
int
)
(
value
[]
byte
,
isNull
bool
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
return
nil
,
false
,
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
(
))
panic
(
fmt
.
Sprintf
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
()
))
}
p
:=
C
.
sqlite3_column_blob
(
s
.
stmt
,
C
.
int
(
index
))
if
p
==
nil
{
...
...
@@ -1092,11 +1061,7 @@ func (s *Stmt) ScanRawBytes(index int) (value []byte, isNull bool, err error) {
// Returns true when column is null.
// The column type affinity must be consistent with the format used (INTEGER or NUMERIC or NONE for unix time, REAL or NONE for julian day).
func
(
s
*
Stmt
)
ScanTime
(
index
int
)
(
value
time
.
Time
,
isNull
bool
,
err
error
)
{
if
index
<
0
||
index
>=
s
.
ColumnCount
()
{
err
=
s
.
specificError
(
"column index %d out of range [0,%d[."
,
index
,
s
.
ColumnCount
())
return
}
ctype
:=
s
.
columnType
(
index
)
ctype
:=
s
.
ColumnType
(
index
)
switch
ctype
{
case
Null
:
isNull
=
true
...
...
stmt_test.go
View file @
900f66f2
...
...
@@ -78,9 +78,7 @@ func TestInsertWithStatement(t *testing.T) {
defer
checkFinalize
(
rs
,
t
)
columnCount
=
rs
.
ColumnCount
()
assert
.
Equal
(
t
,
3
,
columnCount
,
"column count"
)
secondColumnName
,
err
:=
rs
.
ColumnName
(
1
)
checkNoError
(
t
,
err
,
"error accessing column name: %s"
)
assert
.
Equal
(
t
,
"int_num"
,
secondColumnName
,
"column name"
)
assert
.
Equal
(
t
,
"int_num"
,
rs
.
ColumnName
(
1
),
"column name"
)
if
checkStep
(
t
,
rs
)
{
var
fnum
float64
...
...
@@ -231,8 +229,7 @@ func TestScanNull(t *testing.T) {
assert
.
T
(
t
,
null
,
"expected null value"
)
assert
.
Equal
(
t
,
false
,
bo
,
"expected false"
)
rb
,
null
,
err
:=
s
.
ScanRawBytes
(
0
)
checkNoError
(
t
,
err
,
"scan error: %s"
)
rb
,
null
:=
s
.
ScanRawBytes
(
0
)
assert
.
T
(
t
,
null
,
"expected null value"
)
assert
.
Equal
(
t
,
0
,
len
(
rb
),
"expected empty"
)
}
...
...
@@ -256,8 +253,7 @@ func TestScanNotNull(t *testing.T) {
assert
.
T
(
t
,
!
null
,
"expected not null value"
)
assert
.
Equal
(
t
,
"1"
,
*
ps
)
rb
,
null
,
err
:=
s
.
ScanRawBytes
(
0
)
checkNoError
(
t
,
err
,
"scan error: %s"
)
rb
,
null
:=
s
.
ScanRawBytes
(
0
)
assert
.
T
(
t
,
!
null
,
"expected not null value"
)
assert
.
Equal
(
t
,
1
,
len
(
rb
),
"expected not empty"
)
...
...
@@ -512,8 +508,7 @@ func TestScanBytes(t *testing.T) {
checkNoError
(
t
,
err
,
"prepare error: %s"
)
defer
checkFinalize
(
s
,
t
)
assert
.
T
(
t
,
checkStep
(
t
,
s
))
blob
,
_
,
err
:=
s
.
ScanBlob
(
0
)
checkNoError
(
t
,
err
,
"scan error: %s"
)
blob
,
_
:=
s
.
ScanBlob
(
0
)
assert
.
Equal
(
t
,
"test"
,
string
(
blob
))
}
...
...
@@ -532,11 +527,9 @@ func TestBindEmptyZero(t *testing.T) {
err
=
s
.
Scan
(
&
ps
,
&
zt
)
checkNoError
(
t
,
err
,
"scan error: %s"
)
assert
.
T
(
t
,
ps
==
nil
&&
zt
.
IsZero
(),
"null pointers expected"
)
_
,
null
,
err
:=
s
.
ScanValue
(
0
,
false
)
checkNoError
(
t
,
err
,
"scan error: %s"
)
_
,
null
:=
s
.
ScanValue
(
0
,
false
)
assert
.
T
(
t
,
null
,
"null string expected"
)
_
,
null
,
err
=
s
.
ScanValue
(
1
,
false
)
checkNoError
(
t
,
err
,
"scan error: %s"
)
_
,
null
=
s
.
ScanValue
(
1
,
false
)
assert
.
T
(
t
,
null
,
"null time expected"
)
}
...
...
@@ -562,11 +555,9 @@ func TestBindEmptyZeroNotTransformedToNull(t *testing.T) {
err
=
s
.
Scan
(
&
st
,
&
zt
)
checkNoError
(
t
,
err
,
"scan error: %s"
)
assert
.
T
(
t
,
len
(
st
)
==
0
&&
zt
.
IsZero
(),
"null pointers expected"
)
_
,
null
,
err
:=
s
.
ScanValue
(
0
,
false
)
checkNoError
(
t
,
err
,
"scan error: %s"
)
_
,
null
:=
s
.
ScanValue
(
0
,
false
)
assert
.
T
(
t
,
!
null
,
"empty string expected"
)
_
,
null
,
err
=
s
.
ScanValue
(
1
,
false
)
checkNoError
(
t
,
err
,
"scan error: %s"
)
_
,
null
=
s
.
ScanValue
(
1
,
false
)
assert
.
T
(
t
,
!
null
,
"zero time expected"
)
}
...
...
@@ -582,12 +573,8 @@ func TestColumnType(t *testing.T) {
expectedAffinities
:=
[]
Affinity
{
Integral
,
Real
,
Integral
,
Textual
}
for
col
:=
0
;
col
<
s
.
ColumnCount
();
col
++
{
//println(col, s.ColumnName(col), s.ColumnOriginName(col), s.ColumnType(col), s.ColumnDeclaredType(col))
ct
,
err
:=
s
.
ColumnType
(
col
)
checkNoError
(
t
,
err
,
"column type error: %s"
)
assert
.
Equal
(
t
,
Null
,
ct
,
"column type"
)
cta
,
err
:=
s
.
ColumnTypeAffinity
(
col
)
checkNoError
(
t
,
err
,
"column type affinity error: %s"
)
assert
.
Equal
(
t
,
expectedAffinities
[
col
],
cta
,
"column type affinity"
)
assert
.
Equal
(
t
,
Null
,
s
.
ColumnType
(
col
),
"column type"
)
assert
.
Equal
(
t
,
expectedAffinities
[
col
],
s
.
ColumnTypeAffinity
(
col
),
"column type affinity"
)
}
}
...
...
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