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
7453f923
Commit
7453f923
authored
Jan 01, 2012
by
gwenn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce OneValue helper.
parent
72cf0e47
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
42 additions
and
30 deletions
+42
-30
README
README
+14
-2
function_test.go
function_test.go
+4
-14
sqlite.go
sqlite.go
+22
-12
sqlite_test.go
sqlite_test.go
+2
-2
No files found.
README
View file @
7453f923
Yet another SQLite binding based on:
- original [Russ Cox's](http://code.google.com/p/gosqlite/) implementation,
- the [Patrick Crosby's](https://github.com/patrickxb/fgosqlite/) fork.
This binding implements the "exp/sql/driver" interface but leaves dangling statements (see drivert_test).
Open supports flags.
Conn#Exec handles multiple statements (separated by semicolons) properly.
...
...
@@ -8,9 +9,10 @@ Conn#Prepare can optionnaly #Bind as well.
Conn#Close ensures that all dangling statements are finalized.
Stmt#Exec is renamed in Stmt#Bind and a new Stmt#Exec method is introduced to #Bind and #Step.
Stmt#Bind uses native sqlite3_bind_x methods and failed if unsupported type.
Stmt#NamedBind can be used to bind by name.
Stmt#Next returns a (bool, os.Error) couple like Reader#Read.
Stmt#Scan uses native sqlite3_column_x methods.
Stmt#NamedScan is added. It's compliant with [go-dbi](https://github.com/thomaslee/go-dbi/)
API but I think its signature should be improved/modified
.
Stmt#NamedScan is added. It's compliant with [go-dbi](https://github.com/thomaslee/go-dbi/).
Stmt#ScanByIndex/ScanByName are added to test NULL value.
Currently, the weak point of the binding is the *Scan methods:
...
...
@@ -26,6 +28,10 @@ Using the native sqlite3_column_x implies:
Maybe we should let the caller do the conversion.
Misc:
Conn#Exists
Conn#OneValue
Conn#OpenVfs
Conn#EnableFkey/IsFKeyEnabled
Conn#Changes/TotalChanges
Conn#LastInsertRowid
...
...
@@ -33,8 +39,9 @@ Conn#Interrupt
Conn#Begin/BeginTransaction(type)/Commit/Rollback
Conn#GetAutocommit
Conn#EnableLoadExtension/LoadExtension
Conn#IntegrityCheck
Stmt#ExecUpdate
Stmt#Exec
Insert/Exec
Update
Stmt#BindParameterCount/BindParameterIndex/BindParameterName
Stmt#ClearBindings
Stmt#ColumnCount/ColumnNames/ColumnIndex(name)/ColumnName(index)/ColumnType(index)
...
...
@@ -64,3 +71,8 @@ Conn#ProgressHandler
Conn#SetAuthorizer
Conn#Trace
Stmt#Status
Hook:
Conn#CommitHook
Conn#RollbackHook
Conn#UpdateHook
function_test.go
View file @
7453f923
...
...
@@ -24,22 +24,12 @@ func TestScalarFunction(t *testing.T) {
if
err
=
db
.
CreateScalarFunction
(
"half"
,
1
,
nil
,
half
,
nil
);
err
!=
nil
{
t
.
Fatalf
(
"couldn't create function: %s"
,
err
)
}
s
,
err
:=
db
.
Prepar
e
(
"select half(6)"
)
d
,
err
:=
db
.
OneValu
e
(
"select half(6)"
)
if
err
!=
nil
{
t
.
Fatalf
(
"couldn't prepare statement: %s"
,
err
)
}
if
b
:=
Must
(
s
.
Next
());
!
b
{
t
.
Fatalf
(
"No result"
)
}
d
,
_
,
err
:=
s
.
ScanDouble
(
0
)
if
err
!=
nil
{
t
.
Fatalf
(
"couldn't scan result: %s"
,
err
)
}
if
d
!=
3
{
t
.
Errorf
(
"Expected %f but got %f"
,
3
,
d
)
t
.
Fatalf
(
"couldn't retrieve result: %s"
,
err
)
}
if
err
=
s
.
Finalize
();
err
!=
nil
{
t
.
Fatalf
(
"couldn't finalize statement: %s"
,
err
)
if
d
!=
3.0
{
t
.
Errorf
(
"Expected %f but got %f"
,
3.0
,
d
)
}
if
err
=
db
.
CreateScalarFunction
(
"half"
,
1
,
nil
,
nil
,
nil
);
err
!=
nil
{
t
.
Errorf
(
"couldn't destroy function: %s"
,
err
)
...
...
sqlite.go
View file @
7453f923
...
...
@@ -37,6 +37,7 @@ import "C"
import
(
"errors"
"fmt"
"io"
"reflect"
"unsafe"
)
...
...
@@ -373,6 +374,23 @@ func (c *Conn) Exists(query string, args ...interface{}) (bool, error) {
return
s
.
Next
()
}
// Use it with SELECT that returns only one row with only one column.
// Returns io.EOF when there is no row.
func
(
c
*
Conn
)
OneValue
(
query
string
,
args
...
interface
{})
(
interface
{},
error
)
{
s
,
err
:=
c
.
Prepare
(
query
,
args
...
)
if
err
!=
nil
{
return
nil
,
err
}
defer
s
.
Finalize
()
b
,
err
:=
s
.
Next
()
if
err
!=
nil
{
return
nil
,
err
}
else
if
!
b
{
return
nil
,
io
.
EOF
}
return
s
.
ScanValue
(
0
),
nil
}
// Count the number of rows modified
// Calls http://sqlite.org/c3ref/changes.html
func
(
c
*
Conn
)
Changes
()
int
{
...
...
@@ -872,6 +890,7 @@ func (s *Stmt) ScanByName(name string, value interface{}) (bool, error) {
// The leftmost column/index is number 0.
//
// Destination type is specified by the caller.
// The value must be of one of the following types:
// *string
// *int, *int64, *byte,
...
...
@@ -912,7 +931,8 @@ func (s *Stmt) ScanByIndex(index int, value interface{}) (bool, error) {
}
// The leftmost column/index is number 0.
//
//
// Destination type is decided by SQLite.
// The returned value will be of one of the following types:
// nil
// string
...
...
@@ -1193,20 +1213,10 @@ func (c *Conn) IntegrityCheck(max int, quick bool) error {
}
else
{
pragma
=
"integrity"
}
s
,
err
:=
c
.
Prepar
e
(
fmt
.
Sprintf
(
"PRAGMA %s_check(%d)"
,
pragma
,
max
))
msg
,
err
:=
c
.
OneValu
e
(
fmt
.
Sprintf
(
"PRAGMA %s_check(%d)"
,
pragma
,
max
))
if
err
!=
nil
{
return
err
}
defer
s
.
Finalize
()
if
ok
,
err
:=
s
.
Next
();
err
!=
nil
{
return
err
}
else
if
!
ok
{
return
c
.
specificError
(
"Integrity check failed (no result)"
)
}
msg
,
null
:=
s
.
ScanText
(
0
)
if
null
{
return
c
.
specificError
(
"Integrity check failed (null result)"
)
}
if
msg
!=
"ok"
{
return
c
.
specificError
(
"Integrity check failed (%s)"
,
msg
)
}
...
...
sqlite_test.go
View file @
7453f923
...
...
@@ -166,7 +166,7 @@ func TestInsertWithStatement(t *testing.T) {
defer
s
.
Finalize
()
if
s
.
ReadOnly
()
{
t
.
Errorf
(
"update statement
is not
readonly"
)
t
.
Errorf
(
"update statement
should not be
readonly"
)
}
paramCount
:=
s
.
BindParameterCount
()
...
...
@@ -200,7 +200,7 @@ func TestInsertWithStatement(t *testing.T) {
cs
,
_
:=
db
.
Prepare
(
"SELECT COUNT(*) FROM test"
)
defer
cs
.
Finalize
()
if
!
cs
.
ReadOnly
()
{
t
.
Errorf
(
"
update statement is not
readonly"
)
t
.
Errorf
(
"
select statement should be
readonly"
)
}
if
!
Must
(
cs
.
Next
())
{
t
.
Fatal
(
"no result for count"
)
...
...
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