Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
node-sqlite3
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
俞永鹏
node-sqlite3
Commits
3b410607
Commit
3b410607
authored
Sep 26, 2011
by
Konstantin Käfer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first stab at 0.5.x compatibility
parent
9f039e82
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
205 additions
and
198 deletions
+205
-198
sqlite3.js
lib/sqlite3.js
+7
-1
database.cc
src/database.cc
+7
-18
database.h
src/database.h
+9
-10
macros.h
src/macros.h
+1
-1
sqlite3.cc
src/sqlite3.cc
+12
-2
statement.cc
src/statement.cc
+40
-42
statement.h
src/statement.h
+19
-23
each.test.js
test/each.test.js
+21
-21
wscript
wscript
+89
-80
No files found.
lib/sqlite3.js
View file @
3b410607
var
sqlite3
=
module
.
exports
=
exports
=
require
(
'./sqlite3_bindings'
);
var
sqlite3
=
module
.
exports
=
exports
=
require
(
'./sqlite3_bindings
.node
'
);
var
path
=
require
(
'path'
);
var
util
=
require
(
'util'
);
var
EventEmitter
=
require
(
'events'
).
EventEmitter
;
var
Database
=
sqlite3
.
Database
;
...
...
@@ -148,6 +149,11 @@ Database.prototype.removeAllListeners = function(type) {
return
val
;
};
Database
.
prototype
.
emit
=
EventEmitter
.
prototype
.
emit
;
Database
.
prototype
.
once
=
EventEmitter
.
prototype
.
once
;
// util.inherits(Database, EventEmitter);
// util.inherits(Statement, EventEmitter);
// Save the stack trace over EIO callbacks.
sqlite3
.
verbose
=
function
()
{
...
...
src/database.cc
View file @
3b410607
#include <string.h>
#include <v8.h>
#include <node.h>
#include <node_events.h>
#include <node/v8.h>
#include <node/node.h>
#include "macros.h"
#include "database.h"
...
...
@@ -17,7 +16,6 @@ void Database::Init(Handle<Object> target) {
Local
<
FunctionTemplate
>
t
=
FunctionTemplate
::
New
(
New
);
constructor_template
=
Persistent
<
FunctionTemplate
>::
New
(
t
);
constructor_template
->
Inherit
(
EventEmitter
::
constructor_template
);
constructor_template
->
InstanceTemplate
()
->
SetInternalFieldCount
(
1
);
constructor_template
->
SetClassName
(
String
::
NewSymbol
(
"Database"
));
...
...
@@ -141,7 +139,7 @@ void Database::EIO_BeginOpen(Baton* baton) {
eio_custom
(
EIO_Open
,
EIO_PRI_DEFAULT
,
EIO_AfterOpen
,
baton
);
}
int
Database
::
EIO_Open
(
eio_req
*
req
)
{
void
Database
::
EIO_Open
(
eio_req
*
req
)
{
OpenBaton
*
baton
=
static_cast
<
OpenBaton
*>
(
req
->
data
);
Database
*
db
=
baton
->
db
;
...
...
@@ -161,8 +159,6 @@ int Database::EIO_Open(eio_req *req) {
// Set default database handle values.
sqlite3_busy_timeout
(
db
->
handle
,
1000
);
}
return
0
;
}
int
Database
::
EIO_AfterOpen
(
eio_req
*
req
)
{
...
...
@@ -225,7 +221,7 @@ void Database::EIO_BeginClose(Baton* baton) {
eio_custom
(
EIO_Close
,
EIO_PRI_DEFAULT
,
EIO_AfterClose
,
baton
);
}
int
Database
::
EIO_Close
(
eio_req
*
req
)
{
void
Database
::
EIO_Close
(
eio_req
*
req
)
{
Baton
*
baton
=
static_cast
<
Baton
*>
(
req
->
data
);
Database
*
db
=
baton
->
db
;
...
...
@@ -237,7 +233,6 @@ int Database::EIO_Close(eio_req *req) {
else
{
db
->
handle
=
NULL
;
}
return
0
;
}
int
Database
::
EIO_AfterClose
(
eio_req
*
req
)
{
...
...
@@ -504,7 +499,7 @@ void Database::EIO_BeginExec(Baton* baton) {
eio_custom
(
EIO_Exec
,
EIO_PRI_DEFAULT
,
EIO_AfterExec
,
baton
);
}
int
Database
::
EIO_Exec
(
eio_req
*
req
)
{
void
Database
::
EIO_Exec
(
eio_req
*
req
)
{
ExecBaton
*
baton
=
static_cast
<
ExecBaton
*>
(
req
->
data
);
char
*
message
=
NULL
;
...
...
@@ -520,8 +515,6 @@ int Database::EIO_Exec(eio_req *req) {
baton
->
message
=
std
::
string
(
message
);
sqlite3_free
(
message
);
}
return
0
;
}
int
Database
::
EIO_AfterExec
(
eio_req
*
req
)
{
...
...
@@ -574,7 +567,7 @@ void Database::EIO_BeginLoadExtension(Baton* baton) {
eio_custom
(
EIO_LoadExtension
,
EIO_PRI_DEFAULT
,
EIO_AfterLoadExtension
,
baton
);
}
int
Database
::
EIO_LoadExtension
(
eio_req
*
req
)
{
void
Database
::
EIO_LoadExtension
(
eio_req
*
req
)
{
LoadExtensionBaton
*
baton
=
static_cast
<
LoadExtensionBaton
*>
(
req
->
data
);
sqlite3_enable_load_extension
(
baton
->
db
->
handle
,
1
);
...
...
@@ -593,8 +586,6 @@ int Database::EIO_LoadExtension(eio_req *req) {
baton
->
message
=
std
::
string
(
message
);
sqlite3_free
(
message
);
}
return
0
;
}
int
Database
::
EIO_AfterLoadExtension
(
eio_req
*
req
)
{
...
...
@@ -673,13 +664,11 @@ void Database::Destruct(Persistent<Value> value, void *data) {
}
}
int
Database
::
EIO_Destruct
(
eio_req
*
req
)
{
void
Database
::
EIO_Destruct
(
eio_req
*
req
)
{
Database
*
db
=
static_cast
<
Database
*>
(
req
->
data
);
sqlite3_close
(
db
->
handle
);
db
->
handle
=
NULL
;
return
0
;
}
int
Database
::
EIO_AfterDestruct
(
eio_req
*
req
)
{
...
...
src/database.h
View file @
3b410607
#ifndef NODE_SQLITE3_SRC_DATABASE_H
#define NODE_SQLITE3_SRC_DATABASE_H
#include <v8.h>
#include <node.h>
#include <node_events.h>
#include <node/v8.h>
#include <node/node.h>
#include <string>
#include <queue>
...
...
@@ -19,7 +18,7 @@ namespace node_sqlite3 {
class
Database
;
class
Database
:
public
EventEmitter
{
class
Database
:
public
ObjectWrap
{
public
:
static
Persistent
<
FunctionTemplate
>
constructor_template
;
static
void
Init
(
Handle
<
Object
>
target
);
...
...
@@ -100,7 +99,7 @@ public:
friend
class
Statement
;
protected
:
Database
()
:
EventEmitter
(),
Database
()
:
ObjectWrap
(),
handle
(
NULL
),
open
(
false
),
locked
(
false
),
...
...
@@ -121,7 +120,7 @@ protected:
static
Handle
<
Value
>
New
(
const
Arguments
&
args
);
static
void
EIO_BeginOpen
(
Baton
*
baton
);
static
int
EIO_Open
(
eio_req
*
req
);
static
void
EIO_Open
(
eio_req
*
req
);
static
int
EIO_AfterOpen
(
eio_req
*
req
);
static
Handle
<
Value
>
OpenGetter
(
Local
<
String
>
str
,
const
AccessorInfo
&
accessor
);
...
...
@@ -131,17 +130,17 @@ protected:
static
Handle
<
Value
>
Exec
(
const
Arguments
&
args
);
static
void
EIO_BeginExec
(
Baton
*
baton
);
static
int
EIO_Exec
(
eio_req
*
req
);
static
void
EIO_Exec
(
eio_req
*
req
);
static
int
EIO_AfterExec
(
eio_req
*
req
);
static
Handle
<
Value
>
Close
(
const
Arguments
&
args
);
static
void
EIO_BeginClose
(
Baton
*
baton
);
static
int
EIO_Close
(
eio_req
*
req
);
static
void
EIO_Close
(
eio_req
*
req
);
static
int
EIO_AfterClose
(
eio_req
*
req
);
static
Handle
<
Value
>
LoadExtension
(
const
Arguments
&
args
);
static
void
EIO_BeginLoadExtension
(
Baton
*
baton
);
static
int
EIO_LoadExtension
(
eio_req
*
req
);
static
void
EIO_LoadExtension
(
eio_req
*
req
);
static
int
EIO_AfterLoadExtension
(
eio_req
*
req
);
static
Handle
<
Value
>
Serialize
(
const
Arguments
&
args
);
...
...
@@ -168,7 +167,7 @@ protected:
inline
void
MakeWeak
();
virtual
void
Unref
();
static
void
Destruct
(
Persistent
<
Value
>
value
,
void
*
data
);
static
int
EIO_Destruct
(
eio_req
*
req
);
static
void
EIO_Destruct
(
eio_req
*
req
);
static
int
EIO_AfterDestruct
(
eio_req
*
req
);
protected
:
...
...
src/macros.h
View file @
3b410607
...
...
@@ -124,7 +124,7 @@ const char* sqlite_authorizer_string(int type);
#define EIO_DEFINITION(name) \
static Handle<Value> name(const Arguments& args); \
static void EIO_Begin##name(Baton* baton); \
static
int EIO_##name(eio_req *req);
\
static
void EIO_##name(eio_req *req);
\
static int EIO_After##name(eio_req *req);
#define STATEMENT_BEGIN(type) \
...
...
src/sqlite3.cc
View file @
3b410607
#include <v8.h>
#include <node.h>
#include <node_
events
.h>
#include <node_
buffer
.h>
#include <stdint.h>
#include <sstream>
#include <cstring>
#include <string>
#include <sqlite3.h>
#include "macros.h"
...
...
@@ -10,7 +14,9 @@
using
namespace
node_sqlite3
;
extern
"C"
void
init
(
v8
::
Handle
<
Object
>
target
)
{
namespace
{
void
RegisterModule
(
v8
::
Handle
<
Object
>
target
)
{
Database
::
Init
(
target
);
Statement
::
Init
(
target
);
...
...
@@ -52,6 +58,8 @@ extern "C" void init (v8::Handle<Object> target) {
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_NOTADB
,
NOTADB
);
}
}
const
char
*
sqlite_code_string
(
int
code
)
{
switch
(
code
)
{
case
SQLITE_OK
:
return
"SQLITE_OK"
;
...
...
@@ -95,3 +103,5 @@ const char* sqlite_authorizer_string(int type) {
default
:
return
""
;
}
}
NODE_MODULE
(
sqlite3_bindings
,
RegisterModule
);
src/statement.cc
View file @
3b410607
#include <string.h>
#include <v8.h>
#include <node.h>
#include <node_events.h>
#include <node_buffer.h>
#include <node_version.h>
#include <node/v8.h>
#include <node/node.h>
#include <node/node_buffer.h>
#include <node/node_version.h>
#include "macros.h"
#include "database.h"
...
...
@@ -19,7 +18,6 @@ void Statement::Init(Handle<Object> target) {
Local
<
FunctionTemplate
>
t
=
FunctionTemplate
::
New
(
New
);
constructor_template
=
Persistent
<
FunctionTemplate
>::
New
(
t
);
constructor_template
->
Inherit
(
EventEmitter
::
constructor_template
);
constructor_template
->
InstanceTemplate
()
->
SetInternalFieldCount
(
1
);
constructor_template
->
SetClassName
(
String
::
NewSymbol
(
"Statement"
));
...
...
@@ -124,7 +122,7 @@ void Statement::EIO_BeginPrepare(Database::Baton* baton) {
eio_custom
(
EIO_Prepare
,
EIO_PRI_DEFAULT
,
EIO_AfterPrepare
,
baton
);
}
int
Statement
::
EIO_Prepare
(
eio_req
*
req
)
{
void
Statement
::
EIO_Prepare
(
eio_req
*
req
)
{
STATEMENT_INIT
(
PrepareBaton
);
// In case preparing fails, we use a mutex to make sure we get the associated
...
...
@@ -146,8 +144,6 @@ int Statement::EIO_Prepare(eio_req *req) {
}
sqlite3_mutex_leave
(
mtx
);
return
0
;
}
int
Statement
::
EIO_AfterPrepare
(
eio_req
*
req
)
{
...
...
@@ -334,15 +330,13 @@ void Statement::EIO_BeginBind(Baton* baton) {
STATEMENT_BEGIN
(
Bind
);
}
int
Statement
::
EIO_Bind
(
eio_req
*
req
)
{
void
Statement
::
EIO_Bind
(
eio_req
*
req
)
{
STATEMENT_INIT
(
Baton
);
sqlite3_mutex
*
mtx
=
sqlite3_db_mutex
(
stmt
->
db
->
handle
);
sqlite3_mutex_enter
(
mtx
);
stmt
->
Bind
(
baton
->
parameters
);
sqlite3_mutex_leave
(
mtx
);
return
0
;
}
int
Statement
::
EIO_AfterBind
(
eio_req
*
req
)
{
...
...
@@ -384,7 +378,7 @@ void Statement::EIO_BeginGet(Baton* baton) {
STATEMENT_BEGIN
(
Get
);
}
int
Statement
::
EIO_Get
(
eio_req
*
req
)
{
void
Statement
::
EIO_Get
(
eio_req
*
req
)
{
STATEMENT_INIT
(
RowBaton
);
if
(
stmt
->
status
!=
SQLITE_DONE
||
baton
->
parameters
.
size
())
{
...
...
@@ -406,8 +400,6 @@ int Statement::EIO_Get(eio_req *req) {
GetRow
(
&
baton
->
row
,
stmt
->
handle
);
}
}
return
0
;
}
int
Statement
::
EIO_AfterGet
(
eio_req
*
req
)
{
...
...
@@ -454,7 +446,7 @@ void Statement::EIO_BeginRun(Baton* baton) {
STATEMENT_BEGIN
(
Run
);
}
int
Statement
::
EIO_Run
(
eio_req
*
req
)
{
void
Statement
::
EIO_Run
(
eio_req
*
req
)
{
STATEMENT_INIT
(
RunBaton
);
sqlite3_mutex
*
mtx
=
sqlite3_db_mutex
(
stmt
->
db
->
handle
);
...
...
@@ -478,8 +470,6 @@ int Statement::EIO_Run(eio_req *req) {
}
sqlite3_mutex_leave
(
mtx
);
return
0
;
}
int
Statement
::
EIO_AfterRun
(
eio_req
*
req
)
{
...
...
@@ -522,7 +512,7 @@ void Statement::EIO_BeginAll(Baton* baton) {
STATEMENT_BEGIN
(
All
);
}
int
Statement
::
EIO_All
(
eio_req
*
req
)
{
void
Statement
::
EIO_All
(
eio_req
*
req
)
{
STATEMENT_INIT
(
RowsBaton
);
sqlite3_mutex
*
mtx
=
sqlite3_db_mutex
(
stmt
->
db
->
handle
);
...
...
@@ -546,8 +536,6 @@ int Statement::EIO_All(eio_req *req) {
}
sqlite3_mutex_leave
(
mtx
);
return
0
;
}
int
Statement
::
EIO_AfterAll
(
eio_req
*
req
)
{
...
...
@@ -605,6 +593,7 @@ Handle<Value> Statement::Each(const Arguments& args) {
}
else
{
baton
->
completed
=
Persistent
<
Function
>::
New
(
completed
);
baton
->
async
=
new
Async
(
stmt
,
baton
,
AsyncEach
);
stmt
->
Schedule
(
EIO_BeginEach
,
baton
);
return
args
.
This
();
}
...
...
@@ -614,10 +603,11 @@ void Statement::EIO_BeginEach(Baton* baton) {
STATEMENT_BEGIN
(
Each
);
}
int
Statement
::
EIO_Each
(
eio_req
*
req
)
{
void
Statement
::
EIO_Each
(
eio_req
*
req
)
{
STATEMENT_INIT
(
EachBaton
);
Async
*
async
=
new
Async
(
stmt
,
baton
->
callback
,
baton
->
completed
,
AsyncEach
);
Async
*
async
=
baton
->
async
;
fprintf
(
stderr
,
"async:%p
\n
"
,
async
);
sqlite3_mutex
*
mtx
=
sqlite3_db_mutex
(
stmt
->
db
->
handle
);
...
...
@@ -630,6 +620,7 @@ int Statement::EIO_Each(eio_req *req) {
if
(
stmt
->
Bind
(
baton
->
parameters
))
{
while
(
true
)
{
fprintf
(
stderr
,
"before mutex
\n
"
);
sqlite3_mutex_enter
(
mtx
);
stmt
->
status
=
sqlite3_step
(
stmt
->
handle
);
if
(
stmt
->
status
==
SQLITE_ROW
)
{
...
...
@@ -637,32 +628,39 @@ int Statement::EIO_Each(eio_req *req) {
Row
*
row
=
new
Row
();
GetRow
(
row
,
stmt
->
handle
);
pthread_mutex_lock
(
&
async
->
mutex
);
//
pthread_mutex_lock(&async->mutex);
async
->
data
.
push_back
(
row
);
retrieved
++
;
pthread_mutex_unlock
(
&
async
->
mutex
);
ev_async_send
(
EV_DEFAULT_
&
async
->
watcher
);
// pthread_mutex_unlock(&async->mutex);
fprintf
(
stderr
,
"retrieved:%d
\n
"
,
retrieved
);
// uv_async_send(&async->watcher);
}
else
{
if
(
stmt
->
status
!=
SQLITE_DONE
)
{
stmt
->
message
=
std
::
string
(
sqlite3_errmsg
(
stmt
->
db
->
handle
));
}
sqlite3_mutex_leave
(
mtx
);
fprintf
(
stderr
,
"done
\n
"
);
break
;
}
}
}
fprintf
(
stderr
,
"retrieved:%d
\n
"
,
retrieved
);
async
->
completed
=
true
;
ev_async_send
(
EV_DEFAULT_
&
async
->
watcher
);
// uv_async_send(&async->watcher);
}
return
0
;
void
Statement
::
CloseCallback
(
uv_handle_t
*
handle
)
{
assert
(
handle
!=
NULL
);
fprintf
(
stderr
,
"close callback
\n
"
);
}
void
Statement
::
AsyncEach
(
EV_P_
ev_async
*
w
,
int
revent
s
)
{
void
Statement
::
AsyncEach
(
uv_async_t
*
handle
,
int
statu
s
)
{
HandleScope
scope
;
Async
*
async
=
static_cast
<
Async
*>
(
w
->
data
);
Async
*
async
=
static_cast
<
Async
*>
(
handle
->
data
);
EachBaton
*
baton
=
async
->
baton
;
while
(
true
)
{
// Get the contents out of the data cache for us to process in the JS callback.
...
...
@@ -675,32 +673,34 @@ void Statement::AsyncEach(EV_P_ ev_async *w, int revents) {
break
;
}
if
(
!
async
->
callback
.
IsEmpty
()
&&
async
->
callback
->
IsFunction
())
{
if
(
!
baton
->
callback
.
IsEmpty
()
&&
baton
->
callback
->
IsFunction
())
{
Local
<
Value
>
argv
[
2
];
argv
[
0
]
=
Local
<
Value
>::
New
(
Null
());
Rows
::
const_iterator
it
=
rows
.
begin
();
Rows
::
const_iterator
end
=
rows
.
end
();
for
(
int
i
=
0
;
it
<
end
;
it
++
,
i
++
)
{
argv
[
1
]
=
RowToJS
(
*
it
);
//
argv[1] = RowToJS(*it);
async
->
retrieved
++
;
TRY_CATCH_CALL
(
async
->
stmt
->
handle_
,
async
->
callback
,
2
,
argv
);
delete
*
it
;
// TRY_CATCH_CALL(async->stmt->handle_, baton
->callback, 2, argv);
//
delete *it;
}
}
}
if
(
async
->
completed
)
{
if
(
!
async
->
completed_callback
.
IsEmpty
()
&&
async
->
completed_callback
->
IsFunction
())
{
fprintf
(
stderr
,
"completed
\n
"
);
if
(
!
baton
->
completed
.
IsEmpty
()
&&
baton
->
completed
->
IsFunction
())
{
Local
<
Value
>
argv
[]
=
{
Local
<
Value
>::
New
(
Null
()),
Integer
::
New
(
async
->
retrieved
)
};
TRY_CATCH_CALL
(
async
->
stmt
->
handle_
,
async
->
completed_callback
,
2
,
argv
);
TRY_CATCH_CALL
(
async
->
stmt
->
handle_
,
baton
->
completed
,
2
,
argv
);
}
// uv_close((uv_handle_t*)handle, CloseCallback);
delete
async
;
w
->
data
=
NULL
;
handle
->
data
=
NULL
;
}
}
...
...
@@ -732,13 +732,11 @@ void Statement::EIO_BeginReset(Baton* baton) {
STATEMENT_BEGIN
(
Reset
);
}
int
Statement
::
EIO_Reset
(
eio_req
*
req
)
{
void
Statement
::
EIO_Reset
(
eio_req
*
req
)
{
STATEMENT_INIT
(
Baton
);
sqlite3_reset
(
stmt
->
handle
);
stmt
->
status
=
SQLITE_OK
;
return
0
;
}
int
Statement
::
EIO_AfterReset
(
eio_req
*
req
)
{
...
...
src/statement.h
View file @
3b410607
#ifndef NODE_SQLITE3_SRC_STATEMENT_H
#define NODE_SQLITE3_SRC_STATEMENT_H
#include <v8.h>
#include <node.h>
#include <node_events.h>
#include <node/v8.h>
#include <node/node.h>
#include "database.h"
...
...
@@ -72,7 +71,7 @@ typedef Row Parameters;
class
Statement
:
public
EventEmitter
{
class
Statement
:
public
ObjectWrap
{
public
:
static
Persistent
<
FunctionTemplate
>
constructor_template
;
...
...
@@ -119,10 +118,13 @@ public:
Rows
rows
;
};
struct
Async
;
struct
EachBaton
:
Baton
{
EachBaton
(
Statement
*
stmt_
,
Handle
<
Function
>
cb_
)
:
Baton
(
stmt_
,
cb_
)
{}
Persistent
<
Function
>
completed
;
Async
*
async
;
};
struct
PrepareBaton
:
Database
::
Baton
{
...
...
@@ -150,40 +152,33 @@ public:
Baton
*
baton
;
};
typedef
void
(
*
Async_Callback
)(
EV_P_
ev_async
*
w
,
int
revents
);
struct
Async
{
ev_async
watcher
;
uv_async_t
watcher
;
Statement
*
stmt
;
EachBaton
*
baton
;
Rows
data
;
pthread_mutex_t
mutex
;
Persistent
<
Function
>
callback
;
bool
completed
;
int
retrieved
;
Persistent
<
Function
>
completed_callback
;
Async
(
Statement
*
st
,
Handle
<
Function
>
cb
,
Handle
<
Function
>
completed_cb
,
Async_Callback
async_cb
)
:
stmt
(
st
),
completed
(
false
),
retrieved
(
0
)
{
Async
(
Statement
*
st
,
EachBaton
*
eb
,
uv_async_cb
async_cb
)
:
stmt
(
st
),
baton
(
eb
),
completed
(
false
),
retrieved
(
0
)
{
watcher
.
data
=
this
;
ev_async_init
(
&
watcher
,
async_cb
);
ev_async_start
(
EV_DEFAULT_UC_
&
watcher
);
callback
=
Persistent
<
Function
>::
New
(
cb
);
completed_callback
=
Persistent
<
Function
>::
New
(
completed_cb
);
stmt
->
Ref
();
pthread_mutex_init
(
&
mutex
,
NULL
);
fprintf
(
stderr
,
"initialized mutex
\n
"
);
stmt
->
Ref
();
fprintf
(
stderr
,
"referenced stmt
\n
"
);
uv_async_init
(
uv_default_loop
(),
&
watcher
,
async_cb
);
fprintf
(
stderr
,
"started async
\n
"
);
}
~
Async
()
{
callback
.
Dispose
();
completed_callback
.
Dispose
();
stmt
->
Unref
();
pthread_mutex_destroy
(
&
mutex
);
ev_async_stop
(
EV_DEFAULT_UC_
&
watcher
);
}
};
Statement
(
Database
*
db_
)
:
EventEmitter
(),
Statement
(
Database
*
db_
)
:
ObjectWrap
(),
db
(
db_
),
handle
(
NULL
),
status
(
SQLITE_OK
),
...
...
@@ -199,7 +194,7 @@ public:
protected
:
static
void
EIO_BeginPrepare
(
Database
::
Baton
*
baton
);
static
int
EIO_Prepare
(
eio_req
*
req
);
static
void
EIO_Prepare
(
eio_req
*
req
);
static
int
EIO_AfterPrepare
(
eio_req
*
req
);
EIO_DEFINITION
(
Bind
);
...
...
@@ -209,7 +204,8 @@ protected:
EIO_DEFINITION
(
Each
);
EIO_DEFINITION
(
Reset
);
static
void
AsyncEach
(
EV_P_
ev_async
*
w
,
int
revents
);
static
void
AsyncEach
(
uv_async_t
*
handle
,
int
status
);
static
void
CloseCallback
(
uv_handle_t
*
handle
);
static
Handle
<
Value
>
Finalize
(
const
Arguments
&
args
);
static
void
Finalize
(
Baton
*
baton
);
...
...
test/each.test.js
View file @
3b410607
...
...
@@ -19,24 +19,24 @@ exports['test Statement#each'] = function(beforeExit) {
assert
.
equal
(
retrieved
,
total
,
"Only retrieved "
+
retrieved
+
" out of "
+
total
+
" rows."
);
});
};
exports
[
'test Statement#each with complete callback'
]
=
function
(
beforeExit
)
{
var
db
=
new
sqlite3
.
Database
(
'test/support/big.db'
,
sqlite3
.
OPEN_READONLY
);
var
total
=
10000
;
var
retrieved
=
0
;
var
completed
=
false
;
db
.
each
(
'SELECT id, txt FROM foo LIMIT 0, ?'
,
total
,
function
(
err
,
row
)
{
if
(
err
)
throw
err
;
retrieved
++
;
},
function
(
err
,
num
)
{
assert
.
equal
(
retrieved
,
num
);
completed
=
true
;
});
beforeExit
(
function
()
{
assert
.
ok
(
completed
);
assert
.
equal
(
retrieved
,
total
,
"Only retrieved "
+
retrieved
+
" out of "
+
total
+
" rows."
);
});
};
//
//
exports['test Statement#each with complete callback'] = function(beforeExit) {
//
var db = new sqlite3.Database('test/support/big.db', sqlite3.OPEN_READONLY);
//
//
var total = 10000;
//
var retrieved = 0;
//
var completed = false;
//
//
db.each('SELECT id, txt FROM foo LIMIT 0, ?', total, function(err, row) {
//
if (err) throw err;
//
retrieved++;
//
}, function(err, num) {
//
assert.equal(retrieved, num);
//
completed = true;
//
});
//
//
beforeExit(function() {
//
assert.ok(completed);
//
assert.equal(retrieved, total, "Only retrieved " + retrieved + " out of " + total + " rows.");
//
});
//
};
wscript
View file @
3b410607
#!/usr/bin/env python
import
os
import
sys
import Options
from Configure import ConfigurationError
from
os.path
import
exists
from
os
import
unlink
from
shutil
import
copy2
as
copy
,
rmtree
# node-wafadmin
import
Options
import
Utils
from
Configure
import
ConfigurationError
TARGET
=
'sqlite3_bindings'
TARGET_FILE
=
'
%
s.node'
%
TARGET
built = 'build/
default
/%s' % TARGET_FILE
built
=
'build/
Release
/
%
s'
%
TARGET_FILE
dest
=
'lib/
%
s'
%
TARGET_FILE
BUNDLED_SQLITE3_VERSION
=
'3070701'
...
...
@@ -20,95 +21,103 @@ BUNDLED_SQLITE3 = 'sqlite-autoconf-%s' % BUNDLED_SQLITE3_VERSION
BUNDLED_SQLITE3_TAR
=
'sqlite-autoconf-
%
s.tar.gz'
%
BUNDLED_SQLITE3_VERSION
SQLITE3_TARGET
=
'deps/
%
s'
%
BUNDLED_SQLITE3
def set_options(opt):
opt.tool_options("compiler_cxx")
opt.add_option( '--internal-sqlite'
, action='store_true'
, default=True
, help='Build dynamically against external install of libsqlite3 (default False - build uses internal copy)'
, dest='internal_sqlite'
)
def
set_options
(
ctx
):
ctx
.
tool_options
(
"compiler_cxx"
)
ctx
.
add_option
(
'--internal-sqlite'
,
action
=
'store_true'
,
default
=
True
,
help
=
'Build dynamically against external install of libsqlite3 (default False - build uses internal copy)'
,
dest
=
'internal_sqlite'
)
def configure(conf):
conf.check_tool("compiler_cxx")
c
onf.check_tool("node_addon"
)
def
configure
(
ctx
):
c
tx
.
check_tool
(
'compiler_cxx'
)
ctx
.
check_tool
(
'node_addon'
)
if
not
Options
.
options
.
internal_sqlite
:
try
:
ctx
.
check_cfg
(
package
=
"sqlite3"
,
args
=
'--libs --cflags'
,
uselib_store
=
"SQLITE3"
,
mandatory
=
True
)
except
ConfigurationError
:
ctx
.
check
(
lib
=
"sqlite3"
,
libpath
=
[
'/usr/local/lib'
,
'/opt/local/lib'
],
uselib_store
=
"SQLITE3"
,
mandatory
=
True
)
try:
conf.check_cfg(package="sqlite3", args='--libs --cflags',
uselib_store="SQLITE3", mandatory=True)
except ConfigurationError:
conf.check(lib="sqlite3", libpath=['/usr/local/lib', '/opt/local/lib'],
uselib_store="SQLITE3", mandatory=True)
Utils
.
pprint
(
'YELLOW'
,
'Note: pass --internal-sqlite to compile and link against bundled sqlite (version
%
s)'
%
BUNDLED_SQLITE3_VERSION
)
Utils.pprint('YELLOW','Note: pass --internal-sqlite to compile and link against bundled sqlite (version %s)' % BUNDLED_SQLITE3_VERSION)
else
:
configure_interal_sqlite3(conf)
linkflags = []
if os.environ.has_key('LINKFLAGS'):
linkflags.extend(os.environ['LINKFLAGS'].split(' '))
if Options.options.internal_sqlite and Options.platform == 'darwin':
linkflags.append('-Wl,-search_paths_first')
conf.env.append_value("LINKFLAGS", linkflags)
def configure_interal_sqlite3(conf):
Utils.pprint('GREEN','Using internal sqlite3!')
os.chdir('deps')
if not os.path.exists(BUNDLED_SQLITE3):
os.system('tar xvf %s' % BUNDLED_SQLITE3_TAR)
os.chdir(BUNDLED_SQLITE3)
cxxflags = ''
if os.environ.has_key('CFLAGS'):
cxxflags += os.environ['CFLAGS']
cxxflags += ' '
if os.environ.has_key('CXXFLAGS'):
cxxflags += os.environ['CXXFLAGS']
# LINKFLAGS appear to be picked up automatically...
if not os.path.exists('config.status'):
os.system("CFLAGS='%s -DSQLITE_ENABLE_RTREE=1 -fPIC -O3 -DNDEBUG' ./configure --disable-dependency-tracking --enable-static --disable-shared" % cxxflags)
os.chdir('../../')
conf.env.append_value("CPPPATH_SQLITE3", ['../deps/%s' % BUNDLED_SQLITE3])
conf.env.append_value("LINKFLAGS", ['-L../deps/%s/.libs' % BUNDLED_SQLITE3, '-lsqlite3'])
configure_interal_sqlite3
(
ctx
)
def
configure_interal_sqlite3
(
ctx
):
os
.
chdir
(
'deps'
)
if
not
os
.
path
.
exists
(
BUNDLED_SQLITE3
):
os
.
system
(
'tar xvf
%
s'
%
BUNDLED_SQLITE3_TAR
)
os
.
chdir
(
BUNDLED_SQLITE3
)
cxxflags
=
''
if
os
.
environ
.
has_key
(
'CFLAGS'
):
cxxflags
+=
os
.
environ
[
'CFLAGS'
]
cxxflags
+=
' '
if
os
.
environ
.
has_key
(
'CXXFLAGS'
):
cxxflags
+=
os
.
environ
[
'CXXFLAGS'
]
# LINKFLAGS appear to be picked up automatically...
if
not
os
.
path
.
exists
(
'config.status'
):
Utils
.
pprint
(
'GREEN'
,
'Configuring internal SQLite...'
)
os
.
system
(
"CFLAGS='
%
s -DSQLITE_ENABLE_RTREE=1 -fPIC -O3 -DNDEBUG' ./configure --disable-dependency-tracking --enable-static --disable-shared"
%
cxxflags
)
os
.
chdir
(
'../../'
)
ctx
.
env
.
append_value
(
"CPPPATH_SQLITE3"
,
[
'../deps/
%
s'
%
BUNDLED_SQLITE3
])
ctx
.
env
.
append_value
(
"LINKFLAGS"
,
[
'-L../deps/
%
s/.libs'
%
BUNDLED_SQLITE3
,
'-lsqlite3'
])
sys
.
stderr
.
write
(
'Configured internal SQLite : '
)
Utils
.
pprint
(
'GREEN'
,
'ok'
)
def
build_internal_sqlite3
():
if not Options.commands['clean'] and Options.options.internal_sqlite:
if not os.path.exists(SQLITE3_TARGET):
Utils.pprint('RED','Please re-run ./configure or node-waf configure')
sys.exit()
os.chdir(SQLITE3_TARGET)
os.system('make')
os.chdir('../../')
if
not
Options
.
commands
[
'clean'
]
and
Options
.
options
.
internal_sqlite
:
if
not
os
.
path
.
exists
(
SQLITE3_TARGET
):
Utils
.
pprint
(
'RED'
,
'Please re-run ./configure or node-waf configure'
)
sys
.
exit
()
os
.
chdir
(
SQLITE3_TARGET
)
if
not
os
.
path
.
exists
(
'libsqlite3.la'
):
Utils
.
pprint
(
'GREEN'
,
'Building internal SQLite...'
)
os
.
system
(
'make libsqlite3.la'
)
else
:
Utils
.
pprint
(
'GREEN'
,
'Internal SQLite already built.'
)
os
.
chdir
(
'../../'
)
def
clean_internal_sqlite3
():
if os.path.exists(SQLITE3_TARGET):
rmtree(SQLITE3_TARGET)
if
os
.
path
.
exists
(
SQLITE3_TARGET
):
rmtree
(
SQLITE3_TARGET
)
def build(bld):
obj = bld.new_task_gen("cxx", "shlib", "node_addon")
def
build
(
ctx
):
build_internal_sqlite3
()
obj.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE",
"-DSQLITE_ENABLE_RTREE=1", "-pthread", "-Wall"]
# uncomment the next line to remove '-undefined dynamic_lookup'
t
=
ctx
.
new_task_gen
(
'cxx'
,
'shlib'
,
'node_addon'
)
t
.
cxxflags
=
[
"-g"
,
"-D_FILE_OFFSET_BITS=64"
,
"-D_LARGEFILE_SOURCE"
,
"-DSQLITE_ENABLE_RTREE=1"
,
"-pthread"
,
"-Wall"
]
# uncomment the next line to remove '-undefined -dynamic_lookup'
# in order to review linker errors (v8, libev/eio references can be ignored)
#obj.env['LINKFLAGS_MACBUNDLE'] = ['-bundle']
obj.target = TARGET
obj.source = "src/sqlite3.cc src/database.cc src/statement.cc"
obj.uselib = "SQLITE3"
# t.env['LINKFLAGS_MACBUNDLE'] = ['-bundle']
t
.
target
=
TARGET
t
.
source
=
"src/database.cc src/statement.cc src/sqlite3.cc"
# t.uselib = "SQLITE3"
def
clean
(
ctx
):
if
exists
(
"build"
):
rmtree
(
"build"
)
if
exists
(
dest
):
unlink
(
dest
)
clean_internal_sqlite3
()
def
shutdown
():
if Options.commands['clean']:
if exists(TARGET_FILE):
unlink(TARGET_FILE)
clean_internal_sqlite3()
else:
if exists(built):
copy(built, dest)
if
not
Options
.
commands
[
'clean'
]
and
exists
(
built
):
copy
(
built
,
dest
)
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