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
67fc1ed7
Commit
67fc1ed7
authored
Jul 17, 2011
by
gwenn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Customize to my needs.
parent
8e81aa1b
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
423 additions
and
365 deletions
+423
-365
.gitignore
.gitignore
+4
-12
Makefile
Makefile
+2
-8
README
README
+9
-7
sqlite.go
sqlite.go
+289
-214
sqlite_test.go
sqlite_test.go
+119
-124
No files found.
.gitignore
View file @
67fc1ed7
*.6
*.8
*.swp
*~
*.[568ao]
[568a].out
_testmain.go
_obj
*.o
*.out
*.cgo*
_test
cgo_*
_cgo_*
_testmain.go
*.swp
Makefile
View file @
67fc1ed7
...
...
@@ -4,15 +4,9 @@
include
$(GOROOT)/src/Make.inc
TARG
=
f
sqlite
TARG
=
github.com/gwenn/
sqlite
CGOFILES
=
\
fsqlite.go
ifeq
($(GOOS),darwin)
CGO_LDFLAGS
=
/usr/lib/libsqlite3.0.dylib
else
CGO_LDFLAGS
=
-lsqlite3
endif
sqlite.go
include
$(GOROOT)/src/Make.pkg
README
View file @
67fc1ed7
This is based on Russ Cox's original gosqlite package:
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.
http://code.google.com/p/gosqlite/
I added Scan2 and Exec2 which use sqlite api calls to get/bind values instead of the
original which basically converted everything to strings
.
S
can2 and Exec2 are significantly faster. See the benchmarks in fgosqlite_test.go
.
Conn#Exec handles multiple statements (separated by semicolons) properly.
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#Next returns a (bool, os.Error) couple like Reader#Read. But its use in for loop becomes inelegant..
.
Stmt#Scan uses native sqlite3_column_x methods.
S
tmt#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
.
sqlite.go
View file @
67fc1ed7
This diff is collapsed.
Click to expand it.
sqlite_test.go
View file @
67fc1ed7
package
f
sqlite
package
sqlite
import
(
"testing"
"fmt
"
"os
"
)
func
TestOpen
(
t
*
testing
.
T
)
{
db
,
err
:=
Open
(
"
/tmp/test.db
"
)
func
open
(
t
*
testing
.
T
)
*
Conn
{
db
,
err
:=
Open
(
""
)
if
err
!=
nil
{
t
.
Error
f
(
"couldn't open database file: %s"
,
err
)
t
.
Fatal
f
(
"couldn't open database file: %s"
,
err
)
}
if
db
==
nil
{
t
.
Error
(
"opened database is nil"
)
t
.
Fatal
(
"opened database is nil"
)
}
db
.
Close
()
return
db
}
func
TestCreateTable
(
t
*
testing
.
T
)
{
db
,
err
:=
Open
(
"/tmp/test.db"
)
db
.
Exec
(
"DROP TABLE test"
)
err
=
db
.
Exec
(
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, float_num REAL, int_num INTEGER, a_string TEXT)
"
)
func
createTable
(
db
*
Conn
,
t
*
testing
.
T
)
{
err
:=
db
.
Exec
(
"DROP TABLE IF EXISTS test;"
+
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+
" float_num REAL, int_num INTEGER, a_string TEXT); -- bim
"
)
if
err
!=
nil
{
t
.
Error
f
(
"error creating table: %s"
,
err
)
t
.
Fatal
f
(
"error creating table: %s"
,
err
)
}
}
type
OutRow
struct
{
Key
int64
FloatNum
float64
IntNum
int64
AString
string
func
TestOpen
(
t
*
testing
.
T
)
{
db
:=
open
(
t
)
db
.
Close
()
}
func
TestCreateTable
(
t
*
testing
.
T
)
{
db
:=
open
(
t
)
defer
db
.
Close
()
createTable
(
db
,
t
)
}
func
TestInsert
(
t
*
testing
.
T
)
{
db
,
_
:=
Open
(
"/tmp/test.db"
)
d
b
.
Exec
(
"DROP TABLE test"
)
db
.
Exec
(
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, float_num REAL, int_num INTEGER, a_string TEXT)"
)
db
:=
open
(
t
)
d
efer
db
.
Close
(
)
createTable
(
db
,
t
)
for
i
:=
0
;
i
<
1000
;
i
++
{
ierr
:=
db
.
Exec
(
"INSERT INTO test (float_num, int_num, a_string) VALUES (?, ?, ?)"
,
float64
(
i
)
*
float64
(
3.14
),
i
,
"hello"
)
if
ierr
!=
nil
{
t
.
Errorf
(
"insert error: %s"
,
ierr
)
t
.
Fatalf
(
"insert error: %s"
,
ierr
)
}
c
:=
db
.
Changes
()
if
c
!=
1
{
t
.
Errorf
(
"insert error: %d <> 1"
,
c
)
}
}
cs
,
_
:=
db
.
Prepare
(
"SELECT COUNT(*) FROM test"
)
cs
.
Exec
()
if
!
cs
.
Next
()
{
t
.
Error
(
"no result for count"
)
defer
cs
.
Finalize
()
if
ok
,
err
:=
cs
.
Next
();
!
ok
{
if
err
!=
nil
{
t
.
Fatalf
(
"error preparing count: %s"
,
err
)
}
t
.
Fatal
(
"no result for count"
)
}
var
i
int
err
:=
cs
.
Scan
(
&
i
)
if
err
!=
nil
{
t
.
Error
f
(
"error scanning count: %s"
,
err
)
t
.
Fatal
f
(
"error scanning count: %s"
,
err
)
}
if
i
!=
1000
{
t
.
Errorf
(
"count should be 1000, but it is %d"
,
i
)
...
...
@@ -59,169 +70,153 @@ func TestInsert(t *testing.T) {
}
func
TestInsertWithStatement
(
t
*
testing
.
T
)
{
db
,
_
:=
Open
(
"/tmp/test_is.db"
)
d
b
.
Exec
(
"DROP TABLE test"
)
db
.
Exec
(
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, float_num REAL, int_num INTEGER, a_string TEXT)"
)
db
:=
open
(
t
)
d
efer
db
.
Close
(
)
createTable
(
db
,
t
)
s
,
serr
:=
db
.
Prepare
(
"INSERT INTO test (float_num, int_num, a_string) VALUES (?, ?, ?)"
)
if
serr
!=
nil
{
t
.
Error
f
(
"prepare error: %s"
,
serr
)
t
.
Fatal
f
(
"prepare error: %s"
,
serr
)
}
if
s
==
nil
{
t
.
Error
(
"statement is nil"
)
t
.
Fatal
(
"statement is nil"
)
}
defer
s
.
Finalize
()
for
i
:=
0
;
i
<
1000
;
i
++
{
ierr
:=
s
.
Exec
(
float64
(
i
)
*
float64
(
3.14
),
i
,
"hello"
)
if
ierr
!=
nil
{
t
.
Error
f
(
"insert error: %s"
,
ierr
)
t
.
Fatal
f
(
"insert error: %s"
,
ierr
)
}
s
.
Next
()
}
s
.
Finalize
()
cs
,
_
:=
db
.
Prepare
(
"SELECT COUNT(*) FROM test"
)
cs
.
Exec
()
if
!
cs
.
Next
()
{
t
.
Error
(
"no result for count"
)
}
var
i
int
err
:=
cs
.
Scan
(
&
i
)
if
err
!=
nil
{
t
.
Errorf
(
"error scanning count: %s"
,
err
)
}
if
i
!=
1000
{
t
.
Errorf
(
"count should be 1000, but it is %d"
,
i
)
}
}
func
TestInsertWithStatement2
(
t
*
testing
.
T
)
{
db
,
_
:=
Open
(
"/tmp/test_is2.db"
)
db
.
Exec
(
"DROP TABLE test"
)
db
.
Exec
(
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, float_num REAL, int_num INTEGER, a_string TEXT)"
)
s
,
serr
:=
db
.
Prepare
(
"INSERT INTO test (float_num, int_num, a_string) VALUES (?, ?, ?)"
)
if
serr
!=
nil
{
t
.
Errorf
(
"prepare error: %s"
,
serr
)
}
if
s
==
nil
{
t
.
Error
(
"statement is nil"
)
}
for
i
:=
0
;
i
<
1000
;
i
++
{
ierr
:=
s
.
Exec2
(
float64
(
i
)
*
float64
(
3.14
),
i
,
"hello"
)
if
ierr
!=
nil
{
t
.
Errorf
(
"insert error: %s"
,
ierr
)
c
:=
db
.
Changes
()
if
c
!=
1
{
t
.
Errorf
(
"insert error: %d <> 1"
,
c
)
}
s
.
Next
()
}
s
.
Finalize
()
cs
,
_
:=
db
.
Prepare
(
"SELECT COUNT(*) FROM test"
)
cs
.
Exec
()
if
!
cs
.
Next
()
{
t
.
Error
(
"no result for count"
)
defer
cs
.
Finalize
()
if
ok
,
_
:=
cs
.
Next
();
!
ok
{
t
.
Fatal
(
"no result for count"
)
}
var
i
int
err
:=
cs
.
Scan
(
&
i
)
if
err
!=
nil
{
t
.
Error
f
(
"error scanning count: %s"
,
err
)
t
.
Fatal
f
(
"error scanning count: %s"
,
err
)
}
if
i
!=
1000
{
t
.
Errorf
(
"count should be 1000, but it is %d"
,
i
)
}
rs
,
_
:=
db
.
Prepare
(
"SELECT float_num, int_num, a_string FROM test ORDER BY int_num LIMIT 10
"
)
rs
,
_
:=
db
.
Prepare
(
"SELECT float_num, int_num, a_string FROM test ORDER BY int_num LIMIT 2
"
)
var
fnum
float64
var
inum
int64
var
sstr
string
for
rs
.
Next
()
{
rs
.
Scan
(
&
fnum
,
&
inum
,
&
sstr
)
fmt
.
Printf
(
"fnum = %f, inum = %d, sstre = %s
\n
"
,
fnum
,
inum
,
sstr
)
}
if
ok
,
_
:=
rs
.
Next
();
ok
{
rs
.
Scan
(
&
fnum
,
&
inum
,
&
sstr
)
if
fnum
!=
0
{
t
.
Errorf
(
"Expected 0 <> %f
\n
"
,
fnum
)
}
if
inum
!=
0
{
t
.
Errorf
(
"Expected 0 <> %d
\n
"
,
inum
)
}
if
sstr
!=
"hello"
{
t
.
Errorf
(
"Expected 'hello' <> %s
\n
"
,
sstr
)
}
}
if
ok
,
_
:=
rs
.
Next
();
ok
{
var
fnum
float64
var
inum
int64
var
sstr
string
rs
.
NamedScan
(
"a_string"
,
&
sstr
,
"float_num"
,
&
fnum
,
"int_num"
,
&
inum
)
if
fnum
!=
3.14
{
t
.
Errorf
(
"Expected 3.14 <> %f
\n
"
,
fnum
)
}
if
inum
!=
1
{
t
.
Errorf
(
"Expected 1 <> %d
\n
"
,
inum
)
}
if
sstr
!=
"hello"
{
t
.
Errorf
(
"Expected 'hello' <> %s
\n
"
,
sstr
)
}
}
}
func
BenchmarkScan
(
b
*
testing
.
B
)
{
b
.
StopTimer
()
db
,
_
:=
Open
(
"/tmp/test_bs.db"
)
db
.
Exec
(
"DROP TABLE test"
)
db
,
_
:=
Open
(
""
)
defer
db
.
Close
()
db
.
Exec
(
"DROP TABLE IF EXISTS test"
)
db
.
Exec
(
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, float_num REAL, int_num INTEGER, a_string TEXT)"
)
s
,
_
:=
db
.
Prepare
(
"INSERT INTO test (float_num, int_num, a_string) VALUES (?, ?, ?)"
)
for
i
:=
0
;
i
<
1000
;
i
++
{
s
.
Exec
(
float64
(
i
)
*
float64
(
3.14
),
i
,
"hello"
)
s
.
Next
()
}
s
.
Finalize
()
b
.
StartTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
cs
,
_
:=
db
.
Prepare
(
"SELECT float_num, int_num, a_string FROM test"
)
cs
,
_
:=
db
.
Prepare
(
"SELECT float_num, int_num, a_string FROM test"
)
cs
.
Exec
()
var
fnum
float64
var
inum
int64
var
sstr
string
var
fnum
float64
var
inum
int64
var
sstr
string
for
cs
.
Next
()
{
var
ok
bool
var
err
os
.
Error
for
ok
,
err
=
cs
.
Next
();
ok
;
ok
,
err
=
cs
.
Next
()
{
cs
.
Scan
(
&
fnum
,
&
inum
,
&
sstr
)
}
if
err
!=
nil
{
panic
(
err
)
}
cs
.
Finalize
()
}
}
func
Benchmark
Scan2
(
b
*
testing
.
B
)
{
func
Benchmark
NamedScan
(
b
*
testing
.
B
)
{
b
.
StopTimer
()
db
,
_
:=
Open
(
"/tmp/test_bs2.db"
)
db
.
Exec
(
"DROP TABLE test"
)
db
,
_
:=
Open
(
""
)
defer
db
.
Close
()
db
.
Exec
(
"DROP TABLE IF EXISTS test"
)
db
.
Exec
(
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, float_num REAL, int_num INTEGER, a_string TEXT)"
)
s
,
_
:=
db
.
Prepare
(
"INSERT INTO test (float_num, int_num, a_string) VALUES (?, ?, ?)"
)
for
i
:=
0
;
i
<
1000
;
i
++
{
s
.
Exec
(
float64
(
i
)
*
float64
(
3.14
),
i
,
"hello"
)
s
.
Next
()
}
s
.
Finalize
()
b
.
StartTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
cs
,
_
:=
db
.
Prepare
(
"SELECT float_num, int_num, a_string FROM test"
)
cs
.
Exec
()
cs
,
_
:=
db
.
Prepare
(
"SELECT float_num, int_num, a_string FROM test"
)
var
fnum
float64
var
inum
int64
var
sstr
string
var
fnum
float64
var
inum
int64
var
sstr
string
for
cs
.
Next
()
{
cs
.
Scan2
(
&
fnum
,
&
inum
,
&
sstr
)
var
ok
bool
var
err
os
.
Error
for
ok
,
err
=
cs
.
Next
();
ok
;
ok
,
err
=
cs
.
Next
()
{
cs
.
NamedScan
(
"float_num"
,
&
fnum
,
"int_num"
,
&
inum
,
"a_string"
,
&
sstr
)
}
if
err
!=
nil
{
panic
(
err
)
}
cs
.
Finalize
()
}
}
func
BenchmarkInsert
(
b
*
testing
.
B
)
{
db
,
_
:=
Open
(
"/tmp/test_bi.db"
)
db
.
Exec
(
"DROP TABLE test"
)
db
.
Exec
(
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, float_num REAL, int_num INTEGER, a_string TEXT)"
)
s
,
_
:=
db
.
Prepare
(
"INSERT INTO test (float_num, int_num, a_string) VALUES (?, ?, ?)"
)
// for x := 0; x < b.N; x++ {
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
s
.
Exec
(
float64
(
i
)
*
float64
(
3.14
),
i
,
"hello"
)
s
.
Next
()
}
// }
s
.
Finalize
()
}
func
BenchmarkInsert2
(
b
*
testing
.
B
)
{
db
,
_
:=
Open
(
"/tmp/test_bi2.db"
)
db
.
Exec
(
"DROP TABLE test"
)
db
.
Exec
(
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, float_num REAL, int_num INTEGER, a_string TEXT)"
)
s
,
_
:=
db
.
Prepare
(
"INSERT INTO test (float_num, int_num, a_string) VALUES (?, ?, ?)"
)
db
,
_
:=
Open
(
""
)
defer
db
.
Close
()
db
.
Exec
(
"DROP TABLE IF EXISTS test"
)
db
.
Exec
(
"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT,"
+
" float_num REAL, int_num INTEGER, a_string TEXT)"
)
s
,
_
:=
db
.
Prepare
(
"INSERT INTO test (float_num, int_num, a_string)"
+
" VALUES (?, ?, ?)"
)
defer
s
.
Finalize
()
// for x := 0; x < b.N; x++ {
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
s
.
Exec2
(
float64
(
i
)
*
float64
(
3.14
),
i
,
"hello"
)
s
.
Next
()
}
// }
s
.
Finalize
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
s
.
Exec
(
float64
(
i
)
*
float64
(
3.14
),
i
,
"hello"
)
}
}
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