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
1be09629
Commit
1be09629
authored
Nov 21, 2010
by
Patrick Crosby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial version
parent
5bbb81e0
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
405 additions
and
0 deletions
+405
-0
.gitignore
.gitignore
+13
-0
Makefile
Makefile
+18
-0
fsqlite.go
fsqlite.go
+374
-0
No files found.
.gitignore
0 → 100644
View file @
1be09629
*.6
*.8
*.swp
*~
_obj
*.o
*.out
*.cgo*
_test
cgo_*
_cgo_*
Makefile
0 → 100644
View file @
1be09629
# 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.
include
$(GOROOT)/src/Make.inc
TARG
=
fsqlite
CGOFILES
=
\
fsqlite.go
ifeq
($(GOOS),darwin)
CGO_LDFLAGS
=
/usr/lib/libsqlite3.0.dylib
else
CGO_LDFLAGS
=
-lsqlite3
endif
include
$(GOROOT)/src/Make.pkg
fsqlite.go
0 → 100644
View file @
1be09629
// 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
fsqlite
/*
#include <sqlite3.h>
#include <stdlib.h>
// These wrappers are necessary because SQLITE_TRANSIENT
// is a pointer constant, and cgo doesn't translate them correctly.
// The definition in sqlite3.h is:
//
// typedef void (*sqlite3_destructor_type)(void*);
// #define SQLITE_STATIC ((sqlite3_destructor_type)0)
// #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
static int my_bind_text(sqlite3_stmt *stmt, int n, char *p, int np) {
return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT);
}
static int my_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT);
}
*/
import
"C"
import
(
"fmt"
"os"
"reflect"
"strconv"
"unsafe"
"time"
)
type
Errno
int
func
(
e
Errno
)
String
()
string
{
s
:=
errText
[
e
]
if
s
==
""
{
return
fmt
.
Sprintf
(
"errno %d"
,
e
)
}
return
s
}
var
(
ErrError
os
.
Error
=
Errno
(
1
)
// /* SQL error or missing database */
ErrInternal
os
.
Error
=
Errno
(
2
)
// /* Internal logic error in SQLite */
ErrPerm
os
.
Error
=
Errno
(
3
)
// /* Access permission denied */
ErrAbort
os
.
Error
=
Errno
(
4
)
// /* Callback routine requested an abort */
ErrBusy
os
.
Error
=
Errno
(
5
)
// /* The database file is locked */
ErrLocked
os
.
Error
=
Errno
(
6
)
// /* A table in the database is locked */
ErrNoMem
os
.
Error
=
Errno
(
7
)
// /* A malloc() failed */
ErrReadOnly
os
.
Error
=
Errno
(
8
)
// /* Attempt to write a readonly database */
ErrInterrupt
os
.
Error
=
Errno
(
9
)
// /* Operation terminated by sqlite3_interrupt()*/
ErrIOErr
os
.
Error
=
Errno
(
10
)
// /* Some kind of disk I/O error occurred */
ErrCorrupt
os
.
Error
=
Errno
(
11
)
// /* The database disk image is malformed */
ErrFull
os
.
Error
=
Errno
(
13
)
// /* Insertion failed because database is full */
ErrCantOpen
os
.
Error
=
Errno
(
14
)
// /* Unable to open the database file */
ErrEmpty
os
.
Error
=
Errno
(
16
)
// /* Database is empty */
ErrSchema
os
.
Error
=
Errno
(
17
)
// /* The database schema changed */
ErrTooBig
os
.
Error
=
Errno
(
18
)
// /* String or BLOB exceeds size limit */
ErrConstraint
os
.
Error
=
Errno
(
19
)
// /* Abort due to constraint violation */
ErrMismatch
os
.
Error
=
Errno
(
20
)
// /* Data type mismatch */
ErrMisuse
os
.
Error
=
Errno
(
21
)
// /* Library used incorrectly */
ErrNolfs
os
.
Error
=
Errno
(
22
)
// /* Uses OS features not supported on host */
ErrAuth
os
.
Error
=
Errno
(
23
)
// /* Authorization denied */
ErrFormat
os
.
Error
=
Errno
(
24
)
// /* Auxiliary database format error */
ErrRange
os
.
Error
=
Errno
(
25
)
// /* 2nd parameter to sqlite3_bind out of range */
ErrNotDB
os
.
Error
=
Errno
(
26
)
// /* File opened that is not a database file */
Row
=
Errno
(
100
)
// /* sqlite3_step() has another row ready */
Done
=
Errno
(
101
)
// /* sqlite3_step() has finished executing */
)
var
errText
=
map
[
Errno
]
string
{
1
:
"SQL error or missing database"
,
2
:
"Internal logic error in SQLite"
,
3
:
"Access permission denied"
,
4
:
"Callback routine requested an abort"
,
5
:
"The database file is locked"
,
6
:
"A table in the database is locked"
,
7
:
"A malloc() failed"
,
8
:
"Attempt to write a readonly database"
,
9
:
"Operation terminated by sqlite3_interrupt()*/"
,
10
:
"Some kind of disk I/O error occurred"
,
11
:
"The database disk image is malformed"
,
12
:
"NOT USED. Table or record not found"
,
13
:
"Insertion failed because database is full"
,
14
:
"Unable to open the database file"
,
15
:
"NOT USED. Database lock protocol error"
,
16
:
"Database is empty"
,
17
:
"The database schema changed"
,
18
:
"String or BLOB exceeds size limit"
,
19
:
"Abort due to constraint violation"
,
20
:
"Data type mismatch"
,
21
:
"Library used incorrectly"
,
22
:
"Uses OS features not supported on host"
,
23
:
"Authorization denied"
,
24
:
"Auxiliary database format error"
,
25
:
"2nd parameter to sqlite3_bind out of range"
,
26
:
"File opened that is not a database file"
,
100
:
"sqlite3_step() has another row ready"
,
101
:
"sqlite3_step() has finished executing"
,
}
func
(
c
*
Conn
)
error
(
rv
C
.
int
)
os
.
Error
{
if
c
==
nil
||
c
.
db
==
nil
{
return
os
.
NewError
(
"nil sqlite database"
)
}
if
rv
==
21
{
// misuse
return
Errno
(
rv
)
}
return
os
.
NewError
(
Errno
(
rv
)
.
String
()
+
": "
+
C
.
GoString
(
C
.
sqlite3_errmsg
(
c
.
db
)))
}
type
Conn
struct
{
db
*
C
.
sqlite3
}
func
Version
()
string
{
p
:=
C
.
sqlite3_libversion
()
return
C
.
GoString
(
p
)
}
func
Open
(
filename
string
)
(
*
Conn
,
os
.
Error
)
{
if
C
.
sqlite3_threadsafe
()
==
0
{
return
nil
,
os
.
NewError
(
"sqlite library was not compiled for thread-safe operation"
)
}
var
db
*
C
.
sqlite3
name
:=
C
.
CString
(
filename
)
defer
C
.
free
(
unsafe
.
Pointer
(
name
))
rv
:=
C
.
sqlite3_open_v2
(
name
,
&
db
,
C
.
SQLITE_OPEN_FULLMUTEX
|
C
.
SQLITE_OPEN_READWRITE
|
C
.
SQLITE_OPEN_CREATE
,
nil
)
if
rv
!=
0
{
return
nil
,
Errno
(
rv
)
}
if
db
==
nil
{
return
nil
,
os
.
NewError
(
"sqlite succeeded without returning a database"
)
}
return
&
Conn
{
db
},
nil
}
func
(
c
*
Conn
)
Exec
(
cmd
string
,
args
...
interface
{})
os
.
Error
{
s
,
err
:=
c
.
Prepare
(
cmd
)
if
err
!=
nil
{
return
err
}
defer
s
.
Finalize
()
err
=
s
.
Exec
(
args
...
)
if
err
!=
nil
{
return
err
}
rv
:=
C
.
sqlite3_step
(
s
.
stmt
)
if
Errno
(
rv
)
!=
Done
{
return
c
.
error
(
rv
)
}
return
nil
}
type
Stmt
struct
{
c
*
Conn
stmt
*
C
.
sqlite3_stmt
err
os
.
Error
t0
int64
sql
string
args
string
}
func
(
c
*
Conn
)
Prepare
(
cmd
string
)
(
*
Stmt
,
os
.
Error
)
{
if
c
==
nil
||
c
.
db
==
nil
{
return
nil
,
os
.
NewError
(
"nil sqlite database"
)
}
cmdstr
:=
C
.
CString
(
cmd
)
defer
C
.
free
(
unsafe
.
Pointer
(
cmdstr
))
var
stmt
*
C
.
sqlite3_stmt
var
tail
*
C
.
char
rv
:=
C
.
sqlite3_prepare_v2
(
c
.
db
,
cmdstr
,
C
.
int
(
len
(
cmd
)
+
1
),
&
stmt
,
&
tail
)
if
rv
!=
0
{
return
nil
,
c
.
error
(
rv
)
}
return
&
Stmt
{
c
:
c
,
stmt
:
stmt
,
sql
:
cmd
,
t0
:
time
.
Nanoseconds
()},
nil
}
func
(
s
*
Stmt
)
Exec
(
args
...
interface
{})
os
.
Error
{
s
.
args
=
fmt
.
Sprintf
(
" %v"
,
[]
interface
{}(
args
))
rv
:=
C
.
sqlite3_reset
(
s
.
stmt
)
if
rv
!=
0
{
return
s
.
c
.
error
(
rv
)
}
n
:=
int
(
C
.
sqlite3_bind_parameter_count
(
s
.
stmt
))
if
n
!=
len
(
args
)
{
return
os
.
NewError
(
fmt
.
Sprintf
(
"incorrect argument count for Stmt.Exec: have %d want %d"
,
len
(
args
),
n
))
}
for
i
,
v
:=
range
args
{
var
str
string
switch
v
:=
v
.
(
type
)
{
case
[]
byte
:
var
p
*
byte
if
len
(
v
)
>
0
{
p
=
&
v
[
0
]
}
if
rv
:=
C
.
my_bind_blob
(
s
.
stmt
,
C
.
int
(
i
+
1
),
unsafe
.
Pointer
(
p
),
C
.
int
(
len
(
v
)));
rv
!=
0
{
return
s
.
c
.
error
(
rv
)
}
continue
case
bool
:
if
v
{
str
=
"1"
}
else
{
str
=
"0"
}
default
:
str
=
fmt
.
Sprint
(
v
)
}
cstr
:=
C
.
CString
(
str
)
rv
:=
C
.
my_bind_text
(
s
.
stmt
,
C
.
int
(
i
+
1
),
cstr
,
C
.
int
(
len
(
str
)))
C
.
free
(
unsafe
.
Pointer
(
cstr
))
if
rv
!=
0
{
return
s
.
c
.
error
(
rv
)
}
}
return
nil
}
func
(
s
*
Stmt
)
Error
()
os
.
Error
{
return
s
.
err
}
func
(
s
*
Stmt
)
Next
()
bool
{
rv
:=
C
.
sqlite3_step
(
s
.
stmt
)
err
:=
Errno
(
rv
)
if
err
==
Row
{
return
true
}
if
err
!=
Done
{
s
.
err
=
s
.
c
.
error
(
rv
)
}
return
false
}
func
(
s
*
Stmt
)
Scan
(
args
...
interface
{})
os
.
Error
{
n
:=
int
(
C
.
sqlite3_column_count
(
s
.
stmt
))
if
n
!=
len
(
args
)
{
return
os
.
NewError
(
fmt
.
Sprintf
(
"incorrect argument count for Stmt.Scan: have %d want %d"
,
len
(
args
),
n
))
}
for
i
,
v
:=
range
args
{
n
:=
C
.
sqlite3_column_bytes
(
s
.
stmt
,
C
.
int
(
i
))
p
:=
C
.
sqlite3_column_blob
(
s
.
stmt
,
C
.
int
(
i
))
if
p
==
nil
&&
n
>
0
{
return
os
.
NewError
(
"got nil blob"
)
}
var
data
[]
byte
if
n
>
0
{
data
=
(
*
[
1
<<
30
]
byte
)(
unsafe
.
Pointer
(
p
))[
0
:
n
]
}
switch
v
:=
v
.
(
type
)
{
case
*
[]
byte
:
*
v
=
data
case
*
string
:
*
v
=
string
(
data
)
case
*
bool
:
*
v
=
string
(
data
)
==
"1"
case
*
int
:
x
,
err
:=
strconv
.
Atoi
(
string
(
data
))
if
err
!=
nil
{
return
os
.
NewError
(
"arg "
+
strconv
.
Itoa
(
i
)
+
" as int: "
+
err
.
String
())
}
*
v
=
x
case
*
int64
:
x
,
err
:=
strconv
.
Atoi64
(
string
(
data
))
if
err
!=
nil
{
return
os
.
NewError
(
"arg "
+
strconv
.
Itoa
(
i
)
+
" as int64: "
+
err
.
String
())
}
*
v
=
x
case
*
float64
:
x
,
err
:=
strconv
.
Atof64
(
string
(
data
))
if
err
!=
nil
{
return
os
.
NewError
(
"arg "
+
strconv
.
Itoa
(
i
)
+
" as float64: "
+
err
.
String
())
}
*
v
=
x
default
:
return
os
.
NewError
(
"unsupported type in Scan: "
+
reflect
.
Typeof
(
v
)
.
String
())
}
}
return
nil
}
func
(
s
*
Stmt
)
Scan2
(
args
...
interface
{})
os
.
Error
{
n
:=
int
(
C
.
sqlite3_column_count
(
s
.
stmt
))
if
n
!=
len
(
args
)
{
return
os
.
NewError
(
fmt
.
Sprintf
(
"incorrect argument count for Stmt.Scan: have %d want %d"
,
len
(
args
),
n
))
}
for
i
,
v
:=
range
args
{
/*
n := C.sqlite3_column_bytes(s.stmt, C.int(i))
p := C.sqlite3_column_blob(s.stmt, C.int(i))
if p == nil && n > 0 {
return os.NewError("got nil blob")
}
var data []byte
if n > 0 {
data = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]
}
*/
switch
v
:=
v
.
(
type
)
{
/*
case *[]byte:
*v = data
case *string:
*v = string(data)
case *bool:
*v = string(data) == "1"
case *int:
x, err := strconv.Atoi(string(data))
if err != nil {
return os.NewError("arg " + strconv.Itoa(i) + " as int: " + err.String())
}
*v = x
*/
case
*
int64
:
x
:=
C
.
sqlite3_column_int64
(
s
.
stmt
,
C
.
int
(
i
))
*
v
=
int64
(
x
)
case
*
float64
:
x
:=
C
.
sqlite3_column_double
(
s
.
stmt
,
C
.
int
(
i
))
*
v
=
float64
(
x
)
default
:
return
os
.
NewError
(
"unsupported type in Scan: "
+
reflect
.
Typeof
(
v
)
.
String
())
}
}
return
nil
}
func
(
s
*
Stmt
)
SQL
()
string
{
return
s
.
sql
+
s
.
args
}
func
(
s
*
Stmt
)
Nanoseconds
()
int64
{
return
time
.
Nanoseconds
()
-
s
.
t0
}
func
(
s
*
Stmt
)
Finalize
()
os
.
Error
{
rv
:=
C
.
sqlite3_finalize
(
s
.
stmt
)
if
rv
!=
0
{
return
s
.
c
.
error
(
rv
)
}
return
nil
}
func
(
c
*
Conn
)
Close
()
os
.
Error
{
if
c
==
nil
||
c
.
db
==
nil
{
return
os
.
NewError
(
"nil sqlite database"
)
}
rv
:=
C
.
sqlite3_close
(
c
.
db
)
if
rv
!=
0
{
return
c
.
error
(
rv
)
}
c
.
db
=
nil
return
nil
}
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