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
dd3ef522
Commit
dd3ef522
authored
Jul 08, 2019
by
Jim Schlight
Committed by
Mohamed Akram
Apr 11, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix compilation
parent
fc09ced9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
505 additions
and
432 deletions
+505
-432
backup.cc
src/backup.cc
+80
-76
backup.h
src/backup.h
+15
-15
database.cc
src/database.cc
+109
-97
database.h
src/database.h
+25
-22
macros.h
src/macros.h
+48
-45
node_sqlite3.cc
src/node_sqlite3.cc
+44
-40
statement.cc
src/statement.cc
+167
-121
statement.h
src/statement.h
+15
-14
database_fail.test.js
test/database_fail.test.js
+2
-2
No files found.
src/backup.cc
View file @
dd3ef522
...
@@ -16,25 +16,22 @@ Napi::FunctionReference Backup::constructor;
...
@@ -16,25 +16,22 @@ Napi::FunctionReference Backup::constructor;
Napi
::
Object
Backup
::
Init
(
Napi
::
Env
env
,
Napi
::
Object
exports
)
{
Napi
::
Object
Backup
::
Init
(
Napi
::
Env
env
,
Napi
::
Object
exports
)
{
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
Napi
::
FunctionReference
t
=
Napi
::
Function
::
New
(
env
,
New
);
Napi
::
Function
t
=
DefineClass
(
env
,
"Backup"
,
{
InstanceMethod
(
"step"
,
&
Backup
::
Step
),
InstanceMethod
(
"finish"
,
&
Backup
::
Finish
),
t
->
SetClassName
(
Napi
::
String
::
New
(
env
,
"Backup"
));
InstanceAccessor
(
"idle"
,
&
Backup
::
IdleGetter
,
nullptr
),
InstanceAccessor
(
"completed"
,
&
Backup
::
CompletedGetter
,
nullptr
),
InstanceMethod
(
"step"
,
&
Step
),
InstanceAccessor
(
"failed"
,
&
Backup
::
FailedGetter
,
nullptr
),
InstanceMethod
(
"finish"
,
&
Finish
),
InstanceAccessor
(
"remaining"
,
&
Backup
::
RemainingGetter
,
nullptr
),
InstanceAccessor
(
"pageCount"
,
&
Backup
::
PageCountGetter
,
nullptr
),
NODE_SET_GETTER
(
t
,
"idle"
,
IdleGetter
);
InstanceAccessor
(
"retryErrors"
,
&
Backup
::
RetryErrorGetter
,
&
Backup
::
RetryErrorSetter
),
NODE_SET_GETTER
(
t
,
"completed"
,
CompletedGetter
);
});
NODE_SET_GETTER
(
t
,
"failed"
,
FailedGetter
);
NODE_SET_GETTER
(
t
,
"remaining"
,
RemainingGetter
);
constructor
=
Napi
::
Persistent
(
t
);
NODE_SET_GETTER
(
t
,
"pageCount"
,
PageCountGetter
);
constructor
.
SuppressDestruct
();
NODE_SET_SETTER
(
t
,
"retryErrors"
,
RetryErrorGetter
,
RetryErrorSetter
);
exports
.
Set
(
"Backup"
,
t
);
return
exports
;
constructor
.
Reset
(
t
);
(
target
).
Set
(
Napi
::
String
::
New
(
env
,
"Backup"
),
Napi
::
GetFunction
(
t
));
}
}
void
Backup
::
Process
()
{
void
Backup
::
Process
()
{
...
@@ -65,32 +62,34 @@ void Backup::Schedule(Work_Callback callback, Baton* baton) {
...
@@ -65,32 +62,34 @@ void Backup::Schedule(Work_Callback callback, Baton* baton) {
}
}
template
<
class
T
>
void
Backup
::
Error
(
T
*
baton
)
{
template
<
class
T
>
void
Backup
::
Error
(
T
*
baton
)
{
Napi
::
Env
env
=
baton
->
backup
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
Backup
*
backup
=
baton
->
backup
;
Backup
*
backup
=
baton
->
backup
;
// Fail hard on logic errors.
// Fail hard on logic errors.
assert
(
backup
->
status
!=
0
);
assert
(
backup
->
status
!=
0
);
EXCEPTION
(
backup
->
message
,
backup
->
status
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
backup
->
message
)
,
backup
->
status
,
exception
);
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
IsEmpty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
IsEmpty
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
exception
};
Napi
::
Value
argv
[]
=
{
exception
};
TRY_CATCH_CALL
(
backup
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
backup
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
else
{
else
{
Napi
::
Value
argv
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
Napi
::
Value
argv
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
EMIT_EVENT
(
backup
->
handl
e
(),
2
,
argv
);
EMIT_EVENT
(
backup
->
Valu
e
(),
2
,
argv
);
}
}
}
}
void
Backup
::
CleanQueue
()
{
void
Backup
::
CleanQueue
()
{
Napi
::
Env
env
=
this
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
if
(
inited
&&
!
queue
.
empty
())
{
if
(
inited
&&
!
queue
.
empty
())
{
// This backup has already been initialized and is now finished.
// This backup has already been initialized and is now finished.
// Fire error for all remaining items in the queue.
// Fire error for all remaining items in the queue.
EXCEPTION
(
"Backup is already finished"
,
SQLITE_MISUSE
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
"Backup is already finished"
)
,
SQLITE_MISUSE
,
exception
);
Napi
::
Value
argv
[]
=
{
exception
};
Napi
::
Value
argv
[]
=
{
exception
};
bool
called
=
false
;
bool
called
=
false
;
...
@@ -99,11 +98,11 @@ void Backup::CleanQueue() {
...
@@ -99,11 +98,11 @@ void Backup::CleanQueue() {
Call
*
call
=
queue
.
front
();
Call
*
call
=
queue
.
front
();
queue
.
pop
();
queue
.
pop
();
Napi
::
Function
cb
=
Napi
::
New
(
env
,
call
->
baton
->
callback
);
Napi
::
Function
cb
=
call
->
baton
->
callback
.
Value
(
);
if
(
inited
&&
!
cb
.
IsEmpty
()
&&
if
(
inited
&&
!
cb
.
IsEmpty
()
&&
cb
->
IsFunction
())
{
cb
.
IsFunction
())
{
TRY_CATCH_CALL
(
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
Valu
e
(),
cb
,
1
,
argv
);
called
=
true
;
called
=
true
;
}
}
...
@@ -117,7 +116,7 @@ void Backup::CleanQueue() {
...
@@ -117,7 +116,7 @@ void Backup::CleanQueue() {
// Backup object.
// Backup object.
if
(
!
called
)
{
if
(
!
called
)
{
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
EMIT_EVENT
(
handl
e
(),
2
,
info
);
EMIT_EVENT
(
Valu
e
(),
2
,
info
);
}
}
}
}
else
while
(
!
queue
.
empty
())
{
else
while
(
!
queue
.
empty
())
{
...
@@ -133,61 +132,59 @@ void Backup::CleanQueue() {
...
@@ -133,61 +132,59 @@ void Backup::CleanQueue() {
}
}
}
}
Napi
::
Value
Backup
::
New
(
const
Napi
::
CallbackInfo
&
info
)
{
Backup
::
Backup
(
const
Napi
::
CallbackInfo
&
info
)
:
Napi
::
ObjectWrap
<
Backup
>
(
info
)
{
Napi
::
Env
env
=
info
.
Env
();
if
(
!
info
.
IsConstructCall
())
{
if
(
!
info
.
IsConstructCall
())
{
Napi
::
TypeError
::
New
(
env
,
"Use the new operator to create new Backup objects"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"Use the new operator to create new Backup objects"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
int
length
=
info
.
Length
();
int
length
=
info
.
Length
();
if
(
length
<=
0
||
!
Database
::
HasInstance
(
info
[
0
]))
{
if
(
length
<=
0
||
!
Database
::
HasInstance
(
info
[
0
]))
{
Napi
::
TypeError
::
New
(
env
,
"Database object expected"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"Database object expected"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
else
if
(
length
<=
1
||
!
info
[
1
].
IsString
())
{
else
if
(
length
<=
1
||
!
info
[
1
].
IsString
())
{
Napi
::
TypeError
::
New
(
env
,
"Filename expected"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"Filename expected"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
else
if
(
length
<=
2
||
!
info
[
2
].
IsString
())
{
else
if
(
length
<=
2
||
!
info
[
2
].
IsString
())
{
Napi
::
TypeError
::
New
(
env
,
"Source database name expected"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"Source database name expected"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
else
if
(
length
<=
3
||
!
info
[
3
].
IsString
())
{
else
if
(
length
<=
3
||
!
info
[
3
].
IsString
())
{
Napi
::
TypeError
::
New
(
env
,
"Destination database name expected"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"Destination database name expected"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
else
if
(
length
<=
4
||
!
info
[
4
].
IsBoolean
())
{
else
if
(
length
<=
4
||
!
info
[
4
].
IsBoolean
())
{
Napi
::
TypeError
::
New
(
env
,
"Direction flag expected"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"Direction flag expected"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
else
if
(
length
>
5
&&
!
info
[
5
].
IsUndefined
()
&&
!
info
[
5
].
IsFunction
())
{
else
if
(
length
>
5
&&
!
info
[
5
].
IsUndefined
()
&&
!
info
[
5
].
IsFunction
())
{
Napi
::
TypeError
::
New
(
env
,
"Callback expected"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"Callback expected"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
Database
*
db
=
info
[
0
].
As
<
Napi
::
Object
>
().
Unwrap
<
Database
>
(
);
Database
*
db
=
Napi
::
ObjectWrap
<
Database
>::
Unwrap
(
info
[
0
].
As
<
Napi
::
Object
>
()
);
Napi
::
String
filename
=
info
[
1
].
As
<
Napi
::
String
>
();
Napi
::
String
filename
=
info
[
1
].
As
<
Napi
::
String
>
();
Napi
::
String
sourceName
=
info
[
2
].
As
<
Napi
::
String
>
();
Napi
::
String
sourceName
=
info
[
2
].
As
<
Napi
::
String
>
();
Napi
::
String
destName
=
info
[
3
].
As
<
Napi
::
String
>
();
Napi
::
String
destName
=
info
[
3
].
As
<
Napi
::
String
>
();
Napi
::
Boolean
filenameIsDest
=
info
[
4
].
As
<
Napi
::
Boolean
>
();
Napi
::
Boolean
filenameIsDest
=
info
[
4
].
As
<
Napi
::
Boolean
>
();
info
.
This
().
DefineProperty
(
Napi
::
String
::
New
(
env
,
"filename"
),
filename
,
ReadOnly
);
info
.
This
().
As
<
Napi
::
Object
>
().
DefineProperty
(
Napi
::
PropertyDescriptor
::
Value
(
"filename"
,
filename
)
);
info
.
This
().
DefineProperty
(
Napi
::
String
::
New
(
env
,
"sourceName"
),
sourceName
,
ReadOnly
);
info
.
This
().
As
<
Napi
::
Object
>
().
DefineProperty
(
Napi
::
PropertyDescriptor
::
Value
(
"sourceName"
,
sourceName
)
);
info
.
This
().
DefineProperty
(
Napi
::
String
::
New
(
env
,
"destName"
),
destName
,
ReadOnly
);
info
.
This
().
As
<
Napi
::
Object
>
().
DefineProperty
(
Napi
::
PropertyDescriptor
::
Value
(
"destName"
,
destName
)
);
info
.
This
().
DefineProperty
(
Napi
::
String
::
New
(
env
,
"filenameIsDest"
),
filenameIsDest
,
ReadOnly
);
info
.
This
().
As
<
Napi
::
Object
>
().
DefineProperty
(
Napi
::
PropertyDescriptor
::
Value
(
"filenameIsDest"
,
filenameIsDest
)
);
Backup
*
backup
=
new
Backup
(
db
);
init
(
db
);
backup
->
Wrap
(
info
.
This
());
InitializeBaton
*
baton
=
new
InitializeBaton
(
db
,
info
[
5
].
As
<
Napi
::
Function
>
(),
backup
);
InitializeBaton
*
baton
=
new
InitializeBaton
(
db
,
info
[
5
].
As
<
Napi
::
Function
>
(),
this
);
baton
->
filename
=
std
::
string
(
filename
->
As
<
Napi
::
String
>
().
Utf8Value
().
c_str
()
);
baton
->
filename
=
filename
.
Utf8Value
(
);
baton
->
sourceName
=
s
td
::
string
(
sourceName
->
As
<
Napi
::
String
>
().
Utf8Value
().
c_str
()
);
baton
->
sourceName
=
s
ourceName
.
Utf8Value
(
);
baton
->
destName
=
std
::
string
(
destName
->
As
<
Napi
::
String
>
().
Utf8Value
().
c_str
()
);
baton
->
destName
=
destName
.
Utf8Value
(
);
baton
->
filenameIsDest
=
filenameIsDest
.
As
<
Napi
::
Boolean
>
().
Value
();
baton
->
filenameIsDest
=
filenameIsDest
.
Value
();
db
->
Schedule
(
Work_BeginInitialize
,
baton
);
db
->
Schedule
(
Work_BeginInitialize
,
baton
);
return
info
.
This
();
}
}
void
Backup
::
Work_BeginInitialize
(
Database
::
Baton
*
baton
)
{
void
Backup
::
Work_BeginInitialize
(
Database
::
Baton
*
baton
)
{
...
@@ -228,20 +225,21 @@ void Backup::Work_Initialize(uv_work_t* req) {
...
@@ -228,20 +225,21 @@ void Backup::Work_Initialize(uv_work_t* req) {
}
}
void
Backup
::
Work_AfterInitialize
(
uv_work_t
*
req
)
{
void
Backup
::
Work_AfterInitialize
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
BACKUP_INIT
(
InitializeBaton
);
BACKUP_INIT
(
InitializeBaton
);
Napi
::
Env
env
=
backup
->
Env
();
Napi
::
HandleScope
scope
(
env
);
if
(
backup
->
status
!=
SQLITE_OK
)
{
if
(
backup
->
status
!=
SQLITE_OK
)
{
Error
(
baton
);
Error
(
baton
);
backup
->
FinishAll
();
backup
->
FinishAll
();
}
}
else
{
else
{
backup
->
inited
=
true
;
backup
->
inited
=
true
;
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
IsEmpty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
IsEmpty
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
TRY_CATCH_CALL
(
backup
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
backup
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
}
}
BACKUP_END
();
BACKUP_END
();
...
@@ -249,6 +247,7 @@ void Backup::Work_AfterInitialize(uv_work_t* req) {
...
@@ -249,6 +247,7 @@ void Backup::Work_AfterInitialize(uv_work_t* req) {
Napi
::
Value
Backup
::
Step
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Backup
::
Step
(
const
Napi
::
CallbackInfo
&
info
)
{
Backup
*
backup
=
this
;
Backup
*
backup
=
this
;
Napi
::
Env
env
=
backup
->
Env
();
REQUIRE_ARGUMENT_INTEGER
(
0
,
pages
);
REQUIRE_ARGUMENT_INTEGER
(
0
,
pages
);
OPTIONAL_ARGUMENT_FUNCTION
(
1
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
1
,
callback
);
...
@@ -288,10 +287,11 @@ void Backup::Work_Step(uv_work_t* req) {
...
@@ -288,10 +287,11 @@ void Backup::Work_Step(uv_work_t* req) {
}
}
void
Backup
::
Work_AfterStep
(
uv_work_t
*
req
)
{
void
Backup
::
Work_AfterStep
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
BACKUP_INIT
(
StepBaton
);
BACKUP_INIT
(
StepBaton
);
Napi
::
Env
env
=
backup
->
Env
();
Napi
::
HandleScope
scope
(
env
);
if
(
backup
->
status
==
SQLITE_DONE
)
{
if
(
backup
->
status
==
SQLITE_DONE
)
{
backup
->
completed
=
true
;
backup
->
completed
=
true
;
}
else
if
(
!
backup
->
_handle
)
{
}
else
if
(
!
backup
->
_handle
)
{
...
@@ -303,10 +303,10 @@ void Backup::Work_AfterStep(uv_work_t* req) {
...
@@ -303,10 +303,10 @@ void Backup::Work_AfterStep(uv_work_t* req) {
}
}
else
{
else
{
// Fire callbacks.
// Fire callbacks.
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
IsEmpty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
IsEmpty
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
env
.
Null
(),
Napi
::
New
(
env
,
backup
->
status
==
SQLITE_DONE
)
};
Napi
::
Value
argv
[]
=
{
env
.
Null
(),
Napi
::
Boolean
::
New
(
env
,
backup
->
status
==
SQLITE_DONE
)
};
TRY_CATCH_CALL
(
backup
->
handl
e
(),
cb
,
2
,
argv
);
TRY_CATCH_CALL
(
backup
->
Valu
e
(),
cb
,
2
,
argv
);
}
}
}
}
...
@@ -315,6 +315,7 @@ void Backup::Work_AfterStep(uv_work_t* req) {
...
@@ -315,6 +315,7 @@ void Backup::Work_AfterStep(uv_work_t* req) {
Napi
::
Value
Backup
::
Finish
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Backup
::
Finish
(
const
Napi
::
CallbackInfo
&
info
)
{
Backup
*
backup
=
this
;
Backup
*
backup
=
this
;
Napi
::
Env
env
=
backup
->
Env
();
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
...
@@ -333,15 +334,17 @@ void Backup::Work_Finish(uv_work_t* req) {
...
@@ -333,15 +334,17 @@ void Backup::Work_Finish(uv_work_t* req) {
}
}
void
Backup
::
Work_AfterFinish
(
uv_work_t
*
req
)
{
void
Backup
::
Work_AfterFinish
(
uv_work_t
*
req
)
{
BACKUP_INIT
(
Baton
);
Napi
::
Env
env
=
backup
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
BACKUP_INIT
(
Baton
);
backup
->
FinishAll
();
backup
->
FinishAll
();
// Fire callback in case there was one.
// Fire callback in case there was one.
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
IsEmpty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
IsEmpty
()
&&
cb
.
IsFunction
())
{
TRY_CATCH_CALL
(
backup
->
handl
e
(),
cb
,
0
,
NULL
);
TRY_CATCH_CALL
(
backup
->
Valu
e
(),
cb
,
0
,
NULL
);
}
}
BACKUP_END
();
BACKUP_END
();
...
@@ -373,39 +376,40 @@ void Backup::FinishSqlite() {
...
@@ -373,39 +376,40 @@ void Backup::FinishSqlite() {
Napi
::
Value
Backup
::
IdleGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Backup
::
IdleGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Backup
*
backup
=
this
;
Backup
*
backup
=
this
;
bool
idle
=
backup
->
inited
&&
!
backup
->
locked
&&
backup
->
queue
.
empty
();
bool
idle
=
backup
->
inited
&&
!
backup
->
locked
&&
backup
->
queue
.
empty
();
return
idle
;
return
Napi
::
Boolean
::
New
(
this
->
Env
(),
idle
)
;
}
}
Napi
::
Value
Backup
::
CompletedGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Backup
::
CompletedGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Backup
*
backup
=
this
;
Backup
*
backup
=
this
;
return
backup
->
completed
;
return
Napi
::
Boolean
::
New
(
this
->
Env
(),
backup
->
completed
)
;
}
}
Napi
::
Value
Backup
::
FailedGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Backup
::
FailedGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Backup
*
backup
=
this
;
Backup
*
backup
=
this
;
return
backup
->
failed
;
return
Napi
::
Boolean
::
New
(
this
->
Env
(),
backup
->
failed
)
;
}
}
Napi
::
Value
Backup
::
RemainingGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Backup
::
RemainingGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Backup
*
backup
=
this
;
Backup
*
backup
=
this
;
return
backup
->
remaining
;
return
Napi
::
Number
::
New
(
this
->
Env
(),
backup
->
remaining
)
;
}
}
Napi
::
Value
Backup
::
PageCountGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Backup
::
PageCountGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Backup
*
backup
=
this
;
Backup
*
backup
=
this
;
return
backup
->
pageCount
;
return
Napi
::
Number
::
New
(
this
->
Env
(),
backup
->
pageCount
)
;
}
}
Napi
::
Value
Backup
::
RetryErrorGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Backup
::
RetryErrorGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Backup
*
backup
=
this
;
Backup
*
backup
=
this
;
return
Napi
::
New
(
env
,
backup
->
retryErrors
);
return
backup
->
retryErrors
.
Value
(
);
}
}
void
Backup
::
RetryErrorSetter
(
const
Napi
::
CallbackInfo
&
info
,
const
Napi
::
Value
&
value
)
{
void
Backup
::
RetryErrorSetter
(
const
Napi
::
CallbackInfo
&
info
,
const
Napi
::
Value
&
value
)
{
Backup
*
backup
=
this
;
Backup
*
backup
=
this
;
if
(
!
value
->
IsArray
())
{
Napi
::
Env
env
=
backup
->
Env
();
if
(
!
value
.
IsArray
())
{
Napi
::
Error
::
New
(
env
,
"retryErrors must be an array"
).
ThrowAsJavaScriptException
();
Napi
::
Error
::
New
(
env
,
"retryErrors must be an array"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
Napi
::
Array
array
=
value
.
As
<
Napi
::
Array
>
();
Napi
::
Array
array
=
value
.
As
<
Napi
::
Array
>
();
backup
->
retryErrors
.
Reset
(
array
);
backup
->
retryErrors
.
Reset
(
array
);
...
@@ -413,8 +417,8 @@ void Backup::RetryErrorSetter(const Napi::CallbackInfo& info, const Napi::Value&
...
@@ -413,8 +417,8 @@ void Backup::RetryErrorSetter(const Napi::CallbackInfo& info, const Napi::Value&
void
Backup
::
GetRetryErrors
(
std
::
set
<
int
>&
retryErrorsSet
)
{
void
Backup
::
GetRetryErrors
(
std
::
set
<
int
>&
retryErrorsSet
)
{
retryErrorsSet
.
clear
();
retryErrorsSet
.
clear
();
Napi
::
Array
array
=
Napi
::
New
(
env
,
retryErrors
);
Napi
::
Array
array
=
retryErrors
.
Value
(
);
int
length
=
array
->
Length
();
int
length
=
array
.
Length
();
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
Napi
::
Value
code
=
(
array
).
Get
(
i
);
Napi
::
Value
code
=
(
array
).
Get
(
i
);
if
(
code
.
IsNumber
())
{
if
(
code
.
IsNumber
())
{
...
...
src/backup.h
View file @
dd3ef522
...
@@ -12,7 +12,6 @@
...
@@ -12,7 +12,6 @@
#include <uv.h>
#include <uv.h>
using
namespace
Napi
;
using
namespace
Napi
;
using
namespace
Napi
;
namespace
node_sqlite3
{
namespace
node_sqlite3
{
...
@@ -98,7 +97,6 @@ public:
...
@@ -98,7 +97,6 @@ public:
static
Napi
::
FunctionReference
constructor
;
static
Napi
::
FunctionReference
constructor
;
static
Napi
::
Object
Init
(
Napi
::
Env
env
,
Napi
::
Object
exports
);
static
Napi
::
Object
Init
(
Napi
::
Env
env
,
Napi
::
Object
exports
);
static
Napi
::
Value
New
(
const
Napi
::
CallbackInfo
&
info
);
struct
Baton
{
struct
Baton
{
uv_work_t
request
;
uv_work_t
request
;
...
@@ -150,21 +148,23 @@ public:
...
@@ -150,21 +148,23 @@ public:
Baton
*
baton
;
Baton
*
baton
;
};
};
Backup
(
Database
*
db_
)
:
Napi
::
ObjectWrap
<
Backup
>
(),
void
init
(
Database
*
db_
)
{
db
(
db_
),
db
=
db_
;
_handle
(
NULL
),
_handle
=
NULL
;
_otherDb
(
NULL
),
_otherDb
=
NULL
;
_destDb
(
NULL
),
_destDb
=
NULL
;
inited
(
false
),
inited
=
false
;
locked
(
true
),
locked
=
true
;
completed
(
false
),
completed
=
false
;
failed
(
false
),
failed
=
false
;
remaining
(
-
1
),
remaining
=
-
1
;
pageCount
(
-
1
),
pageCount
=
-
1
;
finished
(
false
)
{
finished
=
false
;
db
->
Ref
();
db
->
Ref
();
}
}
Backup
(
const
Napi
::
CallbackInfo
&
info
);
~
Backup
()
{
~
Backup
()
{
if
(
!
finished
)
{
if
(
!
finished
)
{
FinishAll
();
FinishAll
();
...
@@ -216,7 +216,7 @@ protected:
...
@@ -216,7 +216,7 @@ protected:
bool
finished
;
bool
finished
;
std
::
queue
<
Call
*>
queue
;
std
::
queue
<
Call
*>
queue
;
Napi
::
Persistent
<
Array
>
retryErrors
;
Napi
::
Reference
<
Array
>
retryErrors
;
};
};
}
}
...
...
src/database.cc
View file @
dd3ef522
...
@@ -11,42 +11,40 @@ Napi::FunctionReference Database::constructor;
...
@@ -11,42 +11,40 @@ Napi::FunctionReference Database::constructor;
Napi
::
Object
Database
::
Init
(
Napi
::
Env
env
,
Napi
::
Object
exports
)
{
Napi
::
Object
Database
::
Init
(
Napi
::
Env
env
,
Napi
::
Object
exports
)
{
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
Napi
::
FunctionReference
t
=
Napi
::
Function
::
New
(
env
,
New
);
Napi
::
Function
t
=
DefineClass
(
env
,
"Database"
,
{
InstanceMethod
(
"close"
,
&
Database
::
Close
),
InstanceMethod
(
"exec"
,
&
Database
::
Exec
),
InstanceMethod
(
"wait"
,
&
Database
::
Wait
),
InstanceMethod
(
"loadExtension"
,
&
Database
::
LoadExtension
),
InstanceMethod
(
"serialize"
,
&
Database
::
Serialize
),
InstanceMethod
(
"parallelize"
,
&
Database
::
Parallelize
),
InstanceMethod
(
"configure"
,
&
Database
::
Configure
),
InstanceMethod
(
"interrupt"
,
&
Database
::
Interrupt
),
InstanceAccessor
(
"open"
,
&
Database
::
OpenGetter
,
nullptr
)
});
constructor
=
Napi
::
Persistent
(
t
);
constructor
.
SuppressDestruct
();
t
->
SetClassName
(
Napi
::
String
::
New
(
env
,
"Database"
));
exports
.
Set
(
"Database"
,
t
);
return
exports
;
InstanceMethod
(
"close"
,
&
Close
),
InstanceMethod
(
"exec"
,
&
Exec
),
InstanceMethod
(
"wait"
,
&
Wait
),
InstanceMethod
(
"loadExtension"
,
&
LoadExtension
),
InstanceMethod
(
"serialize"
,
&
Serialize
),
InstanceMethod
(
"parallelize"
,
&
Parallelize
),
InstanceMethod
(
"configure"
,
&
Configure
),
InstanceMethod
(
"interrupt"
,
&
Interrupt
),
NODE_SET_GETTER
(
t
,
"open"
,
OpenGetter
);
constructor
.
Reset
(
t
);
(
target
).
Set
(
Napi
::
String
::
New
(
env
,
"Database"
),
Napi
::
GetFunction
(
t
));
}
}
void
Database
::
Process
()
{
void
Database
::
Process
()
{
Napi
::
Env
env
=
this
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
if
(
!
open
&&
locked
&&
!
queue
.
empty
())
{
if
(
!
open
&&
locked
&&
!
queue
.
empty
())
{
EXCEPTION
(
"Database handle is closed"
,
SQLITE_MISUSE
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
"Database handle is closed"
)
,
SQLITE_MISUSE
,
exception
);
Napi
::
Value
argv
[]
=
{
exception
};
Napi
::
Value
argv
[]
=
{
exception
};
bool
called
=
false
;
bool
called
=
false
;
// Call all callbacks with the error object.
// Call all callbacks with the error object.
while
(
!
queue
.
empty
())
{
while
(
!
queue
.
empty
())
{
Call
*
call
=
queue
.
front
();
Call
*
call
=
queue
.
front
();
Napi
::
Function
cb
=
Napi
::
New
(
env
,
call
->
baton
->
callback
);
Napi
::
Function
cb
=
call
->
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
TRY_CATCH_CALL
(
this
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
this
->
Valu
e
(),
cb
,
1
,
argv
);
called
=
true
;
called
=
true
;
}
}
queue
.
pop
();
queue
.
pop
();
...
@@ -60,7 +58,7 @@ void Database::Process() {
...
@@ -60,7 +58,7 @@ void Database::Process() {
// Database object.
// Database object.
if
(
!
called
)
{
if
(
!
called
)
{
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
EMIT_EVENT
(
handl
e
(),
2
,
info
);
EMIT_EVENT
(
Valu
e
(),
2
,
info
);
}
}
return
;
return
;
}
}
...
@@ -82,18 +80,19 @@ void Database::Process() {
...
@@ -82,18 +80,19 @@ void Database::Process() {
}
}
void
Database
::
Schedule
(
Work_Callback
callback
,
Baton
*
baton
,
bool
exclusive
)
{
void
Database
::
Schedule
(
Work_Callback
callback
,
Baton
*
baton
,
bool
exclusive
)
{
Napi
::
Env
env
=
this
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
if
(
!
open
&&
locked
)
{
if
(
!
open
&&
locked
)
{
EXCEPTION
(
"Database is closed"
,
SQLITE_MISUSE
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
"Database is closed"
)
,
SQLITE_MISUSE
,
exception
);
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
exception
};
Napi
::
Value
argv
[]
=
{
exception
};
TRY_CATCH_CALL
(
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
Valu
e
(),
cb
,
1
,
argv
);
}
}
else
{
else
{
Napi
::
Value
argv
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
Napi
::
Value
argv
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
EMIT_EVENT
(
handl
e
(),
2
,
argv
);
EMIT_EVENT
(
Valu
e
(),
2
,
argv
);
}
}
return
;
return
;
}
}
...
@@ -107,19 +106,18 @@ void Database::Schedule(Work_Callback callback, Baton* baton, bool exclusive) {
...
@@ -107,19 +106,18 @@ void Database::Schedule(Work_Callback callback, Baton* baton, bool exclusive) {
}
}
}
}
Napi
::
Value
Database
::
New
(
const
Napi
::
CallbackInfo
&
info
)
{
Database
::
Database
(
const
Napi
::
CallbackInfo
&
info
)
:
Napi
::
ObjectWrap
<
Database
>
(
info
)
{
if
(
!
info
.
IsConstructCall
())
{
init
();
Napi
::
TypeError
::
New
(
env
,
"Use the new operator to create new Database objects"
).
ThrowAsJavaScriptException
();
Napi
::
Env
env
=
info
.
Env
();
return
env
.
Null
();
}
REQUIRE_ARGUMENT_STRING
(
0
,
filename
);
REQUIRE_ARGUMENT_STRING
(
0
,
filename
);
int
pos
=
1
;
unsigned
int
pos
=
1
;
int
mode
;
int
mode
;
if
(
info
.
Length
()
>=
pos
&&
info
[
pos
].
IsNumber
())
{
if
(
info
.
Length
()
>=
pos
&&
info
[
pos
].
IsNumber
()
&&
OtherIsInt
(
info
[
pos
].
As
<
Napi
::
Number
>
())
)
{
mode
=
info
[
pos
++
].
As
<
Napi
::
Number
>
().
Int32Value
();
mode
=
info
[
pos
++
].
As
<
Napi
::
Number
>
().
Int32Value
();
}
else
{
}
else
{
mode
=
SQLITE_OPEN_READWRITE
|
SQLITE_OPEN_CREATE
|
SQLITE_OPEN_FULLMUTEX
;
mode
=
SQLITE_OPEN_READWRITE
|
SQLITE_OPEN_CREATE
|
SQLITE_OPEN_FULLMUTEX
;
}
}
...
@@ -128,17 +126,12 @@ Napi::Value Database::New(const Napi::CallbackInfo& info) {
...
@@ -128,17 +126,12 @@ Napi::Value Database::New(const Napi::CallbackInfo& info) {
callback
=
info
[
pos
++
].
As
<
Napi
::
Function
>
();
callback
=
info
[
pos
++
].
As
<
Napi
::
Function
>
();
}
}
Database
*
db
=
new
Database
();
info
.
This
().
As
<
Napi
::
Object
>
().
DefineProperty
(
Napi
::
PropertyDescriptor
::
Value
(
"filename"
,
info
[
0
].
As
<
Napi
::
String
>
(),
napi_default
));
db
->
Wrap
(
info
.
This
());
info
.
This
().
As
<
Napi
::
Object
>
().
DefineProperty
(
Napi
::
PropertyDescriptor
::
Value
(
"mode"
,
Napi
::
Number
::
New
(
env
,
mode
),
napi_default
));
info
.
This
().
DefineProperty
(
Napi
::
String
::
New
(
env
,
"filename"
),
info
[
0
].
As
<
Napi
::
String
>
(),
ReadOnly
);
info
.
This
().
DefineProperty
(
Napi
::
String
::
New
(
env
,
"mode"
),
Napi
::
New
(
env
,
mode
),
ReadOnly
);
// Start opening the database.
// Start opening the database.
OpenBaton
*
baton
=
new
OpenBaton
(
db
,
callback
,
*
filename
,
mode
);
OpenBaton
*
baton
=
new
OpenBaton
(
this
,
callback
,
filename
.
c_str
()
,
mode
);
Work_BeginOpen
(
baton
);
Work_BeginOpen
(
baton
);
return
info
.
This
();
}
}
void
Database
::
Work_BeginOpen
(
Baton
*
baton
)
{
void
Database
::
Work_BeginOpen
(
Baton
*
baton
)
{
...
@@ -170,14 +163,15 @@ void Database::Work_Open(uv_work_t* req) {
...
@@ -170,14 +163,15 @@ void Database::Work_Open(uv_work_t* req) {
}
}
void
Database
::
Work_AfterOpen
(
uv_work_t
*
req
)
{
void
Database
::
Work_AfterOpen
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
OpenBaton
*
baton
=
static_cast
<
OpenBaton
*>
(
req
->
data
);
OpenBaton
*
baton
=
static_cast
<
OpenBaton
*>
(
req
->
data
);
Database
*
db
=
baton
->
db
;
Database
*
db
=
baton
->
db
;
Napi
::
Env
env
=
db
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
Value
argv
[
1
];
Napi
::
Value
argv
[
1
];
if
(
baton
->
status
!=
SQLITE_OK
)
{
if
(
baton
->
status
!=
SQLITE_OK
)
{
EXCEPTION
(
baton
->
message
,
baton
->
status
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
baton
->
message
.
c_str
())
,
baton
->
status
,
exception
);
argv
[
0
]
=
exception
;
argv
[
0
]
=
exception
;
}
}
else
{
else
{
...
@@ -185,19 +179,19 @@ void Database::Work_AfterOpen(uv_work_t* req) {
...
@@ -185,19 +179,19 @@ void Database::Work_AfterOpen(uv_work_t* req) {
argv
[
0
]
=
env
.
Null
();
argv
[
0
]
=
env
.
Null
();
}
}
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
TRY_CATCH_CALL
(
db
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
db
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
else
if
(
!
db
->
open
)
{
else
if
(
!
db
->
open
)
{
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
argv
[
0
]
};
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
argv
[
0
]
};
EMIT_EVENT
(
db
->
handl
e
(),
2
,
info
);
EMIT_EVENT
(
db
->
Valu
e
(),
2
,
info
);
}
}
if
(
db
->
open
)
{
if
(
db
->
open
)
{
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"open"
)
};
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"open"
)
};
EMIT_EVENT
(
db
->
handl
e
(),
1
,
info
);
EMIT_EVENT
(
db
->
Valu
e
(),
1
,
info
);
db
->
Process
();
db
->
Process
();
}
}
...
@@ -205,11 +199,13 @@ void Database::Work_AfterOpen(uv_work_t* req) {
...
@@ -205,11 +199,13 @@ void Database::Work_AfterOpen(uv_work_t* req) {
}
}
Napi
::
Value
Database
::
OpenGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Database
::
OpenGetter
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
this
->
Env
();
Database
*
db
=
this
;
Database
*
db
=
this
;
return
db
->
open
;
return
Napi
::
Boolean
::
New
(
env
,
db
->
open
)
;
}
}
Napi
::
Value
Database
::
Close
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Database
::
Close
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
info
.
Env
();
Database
*
db
=
this
;
Database
*
db
=
this
;
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
...
@@ -248,16 +244,17 @@ void Database::Work_Close(uv_work_t* req) {
...
@@ -248,16 +244,17 @@ void Database::Work_Close(uv_work_t* req) {
}
}
void
Database
::
Work_AfterClose
(
uv_work_t
*
req
)
{
void
Database
::
Work_AfterClose
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
Baton
*
baton
=
static_cast
<
Baton
*>
(
req
->
data
);
Baton
*
baton
=
static_cast
<
Baton
*>
(
req
->
data
);
Database
*
db
=
baton
->
db
;
Database
*
db
=
baton
->
db
;
Napi
::
Env
env
=
db
->
Env
();
Napi
::
HandleScope
scope
(
env
);
db
->
closing
=
false
;
db
->
closing
=
false
;
Napi
::
Value
argv
[
1
];
Napi
::
Value
argv
[
1
];
if
(
baton
->
status
!=
SQLITE_OK
)
{
if
(
baton
->
status
!=
SQLITE_OK
)
{
EXCEPTION
(
baton
->
message
,
baton
->
status
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
baton
->
message
.
c_str
())
,
baton
->
status
,
exception
);
argv
[
0
]
=
exception
;
argv
[
0
]
=
exception
;
}
}
else
{
else
{
...
@@ -267,20 +264,20 @@ void Database::Work_AfterClose(uv_work_t* req) {
...
@@ -267,20 +264,20 @@ void Database::Work_AfterClose(uv_work_t* req) {
argv
[
0
]
=
env
.
Null
();
argv
[
0
]
=
env
.
Null
();
}
}
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
// Fire callbacks.
// Fire callbacks.
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
TRY_CATCH_CALL
(
db
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
db
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
else
if
(
db
->
open
)
{
else
if
(
db
->
open
)
{
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
argv
[
0
]
};
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
argv
[
0
]
};
EMIT_EVENT
(
db
->
handl
e
(),
2
,
info
);
EMIT_EVENT
(
db
->
Valu
e
(),
2
,
info
);
}
}
if
(
!
db
->
open
)
{
if
(
!
db
->
open
)
{
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"close"
),
argv
[
0
]
};
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"close"
),
argv
[
0
]
};
EMIT_EVENT
(
db
->
handl
e
(),
1
,
info
);
EMIT_EVENT
(
db
->
Valu
e
(),
1
,
info
);
db
->
Process
();
db
->
Process
();
}
}
...
@@ -288,13 +285,14 @@ void Database::Work_AfterClose(uv_work_t* req) {
...
@@ -288,13 +285,14 @@ void Database::Work_AfterClose(uv_work_t* req) {
}
}
Napi
::
Value
Database
::
Serialize
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Database
::
Serialize
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
this
->
Env
();
Database
*
db
=
this
;
Database
*
db
=
this
;
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
bool
before
=
db
->
serialize
;
bool
before
=
db
->
serialize
;
db
->
serialize
=
true
;
db
->
serialize
=
true
;
if
(
!
callback
.
IsEmpty
()
&&
callback
->
IsFunction
())
{
if
(
!
callback
.
IsEmpty
()
&&
callback
.
IsFunction
())
{
TRY_CATCH_CALL
(
info
.
This
(),
callback
,
0
,
NULL
);
TRY_CATCH_CALL
(
info
.
This
(),
callback
,
0
,
NULL
);
db
->
serialize
=
before
;
db
->
serialize
=
before
;
}
}
...
@@ -305,13 +303,14 @@ Napi::Value Database::Serialize(const Napi::CallbackInfo& info) {
...
@@ -305,13 +303,14 @@ Napi::Value Database::Serialize(const Napi::CallbackInfo& info) {
}
}
Napi
::
Value
Database
::
Parallelize
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Database
::
Parallelize
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
this
->
Env
();
Database
*
db
=
this
;
Database
*
db
=
this
;
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
bool
before
=
db
->
serialize
;
bool
before
=
db
->
serialize
;
db
->
serialize
=
false
;
db
->
serialize
=
false
;
if
(
!
callback
.
IsEmpty
()
&&
callback
->
IsFunction
())
{
if
(
!
callback
.
IsEmpty
()
&&
callback
.
IsFunction
())
{
TRY_CATCH_CALL
(
info
.
This
(),
callback
,
0
,
NULL
);
TRY_CATCH_CALL
(
info
.
This
(),
callback
,
0
,
NULL
);
db
->
serialize
=
before
;
db
->
serialize
=
before
;
}
}
...
@@ -322,6 +321,7 @@ Napi::Value Database::Parallelize(const Napi::CallbackInfo& info) {
...
@@ -322,6 +321,7 @@ Napi::Value Database::Parallelize(const Napi::CallbackInfo& info) {
}
}
Napi
::
Value
Database
::
Configure
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Database
::
Configure
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
this
->
Env
();
Database
*
db
=
this
;
Database
*
db
=
this
;
REQUIRE_ARGUMENTS
(
2
);
REQUIRE_ARGUMENTS
(
2
);
...
@@ -347,13 +347,14 @@ Napi::Value Database::Configure(const Napi::CallbackInfo& info) {
...
@@ -347,13 +347,14 @@ Napi::Value Database::Configure(const Napi::CallbackInfo& info) {
db
->
Schedule
(
SetBusyTimeout
,
baton
);
db
->
Schedule
(
SetBusyTimeout
,
baton
);
}
}
else
{
else
{
return
Napi
::
ThrowError
(
Exception
::
Error
(
String
::
Concat
(
Napi
::
TypeError
::
New
(
env
,
(
String
Concat
(
#if V8_MAJOR_VERSION > 6
#if V8_MAJOR_VERSION > 6
info
.
GetIsolate
(),
info
.
GetIsolate
(),
#endif
#endif
info
[
0
].
To
<
Napi
::
String
>
(),
info
[
0
].
As
<
Napi
::
String
>
(),
Napi
::
String
::
New
(
env
,
" is not a valid configuration option"
)
Napi
::
String
::
New
(
env
,
" is not a valid configuration option"
)
)));
)).
Utf8Value
().
c_str
()).
ThrowAsJavaScriptException
();
return
env
.
Null
();
}
}
db
->
Process
();
db
->
Process
();
...
@@ -362,6 +363,7 @@ Napi::Value Database::Configure(const Napi::CallbackInfo& info) {
...
@@ -362,6 +363,7 @@ Napi::Value Database::Configure(const Napi::CallbackInfo& info) {
}
}
Napi
::
Value
Database
::
Interrupt
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Database
::
Interrupt
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
this
->
Env
();
Database
*
db
=
this
;
Database
*
db
=
this
;
if
(
!
db
->
open
)
{
if
(
!
db
->
open
)
{
...
@@ -416,13 +418,14 @@ void Database::TraceCallback(void* db, const char* sql) {
...
@@ -416,13 +418,14 @@ void Database::TraceCallback(void* db, const char* sql) {
void
Database
::
TraceCallback
(
Database
*
db
,
std
::
string
*
sql
)
{
void
Database
::
TraceCallback
(
Database
*
db
,
std
::
string
*
sql
)
{
// Note: This function is called in the main V8 thread.
// Note: This function is called in the main V8 thread.
Napi
::
Env
env
=
db
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
Napi
::
Value
argv
[]
=
{
Napi
::
Value
argv
[]
=
{
Napi
::
String
::
New
(
env
,
"trace"
),
Napi
::
String
::
New
(
env
,
"trace"
),
Napi
::
New
(
env
,
sql
->
c_str
())
Napi
::
String
::
New
(
env
,
sql
->
c_str
())
};
};
EMIT_EVENT
(
db
->
handl
e
(),
2
,
argv
);
EMIT_EVENT
(
db
->
Valu
e
(),
2
,
argv
);
delete
sql
;
delete
sql
;
}
}
...
@@ -456,14 +459,15 @@ void Database::ProfileCallback(void* db, const char* sql, sqlite3_uint64 nsecs)
...
@@ -456,14 +459,15 @@ void Database::ProfileCallback(void* db, const char* sql, sqlite3_uint64 nsecs)
}
}
void
Database
::
ProfileCallback
(
Database
*
db
,
ProfileInfo
*
info
)
{
void
Database
::
ProfileCallback
(
Database
*
db
,
ProfileInfo
*
info
)
{
Napi
::
Env
env
=
db
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
Napi
::
Value
argv
[]
=
{
Napi
::
Value
argv
[]
=
{
Napi
::
String
::
New
(
env
,
"profile"
),
Napi
::
String
::
New
(
env
,
"profile"
),
Napi
::
New
(
env
,
info
->
sql
.
c_str
()),
Napi
::
String
::
New
(
env
,
info
->
sql
.
c_str
()),
Napi
::
Number
::
New
(
env
,
(
double
)
info
->
nsecs
/
1000000.0
)
Napi
::
Number
::
New
(
env
,
(
double
)
info
->
nsecs
/
1000000.0
)
};
};
EMIT_EVENT
(
db
->
handl
e
(),
3
,
argv
);
EMIT_EVENT
(
db
->
Valu
e
(),
3
,
argv
);
delete
info
;
delete
info
;
}
}
...
@@ -500,25 +504,27 @@ void Database::UpdateCallback(void* db, int type, const char* database,
...
@@ -500,25 +504,27 @@ void Database::UpdateCallback(void* db, int type, const char* database,
}
}
void
Database
::
UpdateCallback
(
Database
*
db
,
UpdateInfo
*
info
)
{
void
Database
::
UpdateCallback
(
Database
*
db
,
UpdateInfo
*
info
)
{
Napi
::
Env
env
=
db
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
Napi
::
Value
argv
[]
=
{
Napi
::
Value
argv
[]
=
{
Napi
::
New
(
env
,
sqlite_authorizer_string
(
info
->
type
)),
Napi
::
String
::
New
(
env
,
sqlite_authorizer_string
(
info
->
type
)),
Napi
::
New
(
env
,
info
->
database
.
c_str
()),
Napi
::
String
::
New
(
env
,
info
->
database
.
c_str
()),
Napi
::
New
(
env
,
info
->
table
.
c_str
()),
Napi
::
String
::
New
(
env
,
info
->
table
.
c_str
()),
Napi
::
Number
::
New
(
env
,
info
->
rowid
),
Napi
::
Number
::
New
(
env
,
info
->
rowid
),
};
};
EMIT_EVENT
(
db
->
handl
e
(),
4
,
argv
);
EMIT_EVENT
(
db
->
Valu
e
(),
4
,
argv
);
delete
info
;
delete
info
;
}
}
Napi
::
Value
Database
::
Exec
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Database
::
Exec
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
this
->
Env
();
Database
*
db
=
this
;
Database
*
db
=
this
;
REQUIRE_ARGUMENT_STRING
(
0
,
sql
);
REQUIRE_ARGUMENT_STRING
(
0
,
sql
);
OPTIONAL_ARGUMENT_FUNCTION
(
1
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
1
,
callback
);
Baton
*
baton
=
new
ExecBaton
(
db
,
callback
,
*
sql
);
Baton
*
baton
=
new
ExecBaton
(
db
,
callback
,
sql
.
c_str
()
);
db
->
Schedule
(
Work_BeginExec
,
baton
,
true
);
db
->
Schedule
(
Work_BeginExec
,
baton
,
true
);
return
info
.
This
();
return
info
.
This
();
...
@@ -553,28 +559,29 @@ void Database::Work_Exec(uv_work_t* req) {
...
@@ -553,28 +559,29 @@ void Database::Work_Exec(uv_work_t* req) {
}
}
void
Database
::
Work_AfterExec
(
uv_work_t
*
req
)
{
void
Database
::
Work_AfterExec
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
ExecBaton
*
baton
=
static_cast
<
ExecBaton
*>
(
req
->
data
);
ExecBaton
*
baton
=
static_cast
<
ExecBaton
*>
(
req
->
data
);
Database
*
db
=
baton
->
db
;
Database
*
db
=
baton
->
db
;
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Env
env
=
db
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
();
if
(
baton
->
status
!=
SQLITE_OK
)
{
if
(
baton
->
status
!=
SQLITE_OK
)
{
EXCEPTION
(
baton
->
message
,
baton
->
status
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
baton
->
message
.
c_str
())
,
baton
->
status
,
exception
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
exception
};
Napi
::
Value
argv
[]
=
{
exception
};
TRY_CATCH_CALL
(
db
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
db
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
else
{
else
{
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
EMIT_EVENT
(
db
->
handl
e
(),
2
,
info
);
EMIT_EVENT
(
db
->
Valu
e
(),
2
,
info
);
}
}
}
}
else
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
else
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
TRY_CATCH_CALL
(
db
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
db
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
db
->
Process
();
db
->
Process
();
...
@@ -583,6 +590,7 @@ void Database::Work_AfterExec(uv_work_t* req) {
...
@@ -583,6 +590,7 @@ void Database::Work_AfterExec(uv_work_t* req) {
}
}
Napi
::
Value
Database
::
Wait
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Database
::
Wait
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
info
.
Env
();
Database
*
db
=
this
;
Database
*
db
=
this
;
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
...
@@ -594,6 +602,7 @@ Napi::Value Database::Wait(const Napi::CallbackInfo& info) {
...
@@ -594,6 +602,7 @@ Napi::Value Database::Wait(const Napi::CallbackInfo& info) {
}
}
void
Database
::
Work_Wait
(
Baton
*
baton
)
{
void
Database
::
Work_Wait
(
Baton
*
baton
)
{
Napi
::
Env
env
=
baton
->
db
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
assert
(
baton
->
db
->
locked
);
assert
(
baton
->
db
->
locked
);
...
@@ -601,10 +610,10 @@ void Database::Work_Wait(Baton* baton) {
...
@@ -601,10 +610,10 @@ void Database::Work_Wait(Baton* baton) {
assert
(
baton
->
db
->
_handle
);
assert
(
baton
->
db
->
_handle
);
assert
(
baton
->
db
->
pending
==
0
);
assert
(
baton
->
db
->
pending
==
0
);
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
TRY_CATCH_CALL
(
baton
->
db
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
baton
->
db
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
baton
->
db
->
Process
();
baton
->
db
->
Process
();
...
@@ -613,12 +622,13 @@ void Database::Work_Wait(Baton* baton) {
...
@@ -613,12 +622,13 @@ void Database::Work_Wait(Baton* baton) {
}
}
Napi
::
Value
Database
::
LoadExtension
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Database
::
LoadExtension
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
this
->
Env
();
Database
*
db
=
this
;
Database
*
db
=
this
;
REQUIRE_ARGUMENT_STRING
(
0
,
filename
);
REQUIRE_ARGUMENT_STRING
(
0
,
filename
);
OPTIONAL_ARGUMENT_FUNCTION
(
1
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
1
,
callback
);
Baton
*
baton
=
new
LoadExtensionBaton
(
db
,
callback
,
*
filename
);
Baton
*
baton
=
new
LoadExtensionBaton
(
db
,
callback
,
filename
.
c_str
()
);
db
->
Schedule
(
Work_BeginLoadExtension
,
baton
,
true
);
db
->
Schedule
(
Work_BeginLoadExtension
,
baton
,
true
);
return
info
.
This
();
return
info
.
This
();
...
@@ -656,27 +666,29 @@ void Database::Work_LoadExtension(uv_work_t* req) {
...
@@ -656,27 +666,29 @@ void Database::Work_LoadExtension(uv_work_t* req) {
}
}
void
Database
::
Work_AfterLoadExtension
(
uv_work_t
*
req
)
{
void
Database
::
Work_AfterLoadExtension
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
LoadExtensionBaton
*
baton
=
static_cast
<
LoadExtensionBaton
*>
(
req
->
data
);
LoadExtensionBaton
*
baton
=
static_cast
<
LoadExtensionBaton
*>
(
req
->
data
);
Database
*
db
=
baton
->
db
;
Database
*
db
=
baton
->
db
;
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Env
env
=
db
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
();
if
(
baton
->
status
!=
SQLITE_OK
)
{
if
(
baton
->
status
!=
SQLITE_OK
)
{
EXCEPTION
(
baton
->
message
,
baton
->
status
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
baton
->
message
.
c_str
())
,
baton
->
status
,
exception
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
exception
};
Napi
::
Value
argv
[]
=
{
exception
};
TRY_CATCH_CALL
(
db
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
db
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
else
{
else
{
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
EMIT_EVENT
(
db
->
handl
e
(),
2
,
info
);
EMIT_EVENT
(
db
->
Valu
e
(),
2
,
info
);
}
}
}
}
else
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
else
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
TRY_CATCH_CALL
(
db
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
db
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
db
->
Process
();
db
->
Process
();
...
...
src/database.h
View file @
dd3ef522
...
@@ -29,7 +29,7 @@ public:
...
@@ -29,7 +29,7 @@ public:
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
if
(
!
val
.
IsObject
())
return
false
;
if
(
!
val
.
IsObject
())
return
false
;
Napi
::
Object
obj
=
val
.
As
<
Napi
::
Object
>
();
Napi
::
Object
obj
=
val
.
As
<
Napi
::
Object
>
();
return
Napi
::
New
(
env
,
constructor
)
->
HasInstance
(
obj
);
return
obj
.
InstanceOf
(
constructor
.
Value
()
);
}
}
struct
Baton
{
struct
Baton
{
...
@@ -43,7 +43,9 @@ public:
...
@@ -43,7 +43,9 @@ public:
db
(
db_
),
status
(
SQLITE_OK
)
{
db
(
db_
),
status
(
SQLITE_OK
)
{
db
->
Ref
();
db
->
Ref
();
request
.
data
=
this
;
request
.
data
=
this
;
callback
.
Reset
(
cb_
);
if
(
!
cb_
.
IsUndefined
()
&&
cb_
.
IsFunction
())
{
callback
.
Reset
(
cb_
,
1
);
}
}
}
virtual
~
Baton
()
{
virtual
~
Baton
()
{
db
->
Unref
();
db
->
Unref
();
...
@@ -102,19 +104,20 @@ public:
...
@@ -102,19 +104,20 @@ public:
friend
class
Statement
;
friend
class
Statement
;
friend
class
Backup
;
friend
class
Backup
;
protected
:
void
init
()
{
Database
()
:
Napi
::
ObjectWrap
<
Database
>
(),
_handle
=
NULL
;
_handle
(
NULL
),
open
=
false
;
open
(
false
),
closing
=
false
;
closing
(
false
),
locked
=
false
;
locked
(
false
),
pending
=
0
;
pending
(
0
),
serialize
=
false
;
serialize
(
false
),
debug_trace
=
NULL
;
debug_trace
(
NULL
),
debug_profile
=
NULL
;
debug_profile
(
NULL
),
update_event
=
NULL
;
update_event
(
NULL
)
{
}
}
Database
(
const
Napi
::
CallbackInfo
&
info
);
~
Database
()
{
~
Database
()
{
RemoveCallbacks
();
RemoveCallbacks
();
sqlite3_close
(
_handle
);
sqlite3_close
(
_handle
);
...
@@ -122,7 +125,7 @@ protected:
...
@@ -122,7 +125,7 @@ protected:
open
=
false
;
open
=
false
;
}
}
static
Napi
::
Value
New
(
const
Napi
::
CallbackInfo
&
info
);
protected
:
static
void
Work_BeginOpen
(
Baton
*
baton
);
static
void
Work_BeginOpen
(
Baton
*
baton
);
static
void
Work_Open
(
uv_work_t
*
req
);
static
void
Work_Open
(
uv_work_t
*
req
);
static
void
Work_AfterOpen
(
uv_work_t
*
req
);
static
void
Work_AfterOpen
(
uv_work_t
*
req
);
...
@@ -132,30 +135,30 @@ protected:
...
@@ -132,30 +135,30 @@ protected:
void
Schedule
(
Work_Callback
callback
,
Baton
*
baton
,
bool
exclusive
=
false
);
void
Schedule
(
Work_Callback
callback
,
Baton
*
baton
,
bool
exclusive
=
false
);
void
Process
();
void
Process
();
static
Napi
::
Value
Exec
(
const
Napi
::
CallbackInfo
&
info
);
Napi
::
Value
Exec
(
const
Napi
::
CallbackInfo
&
info
);
static
void
Work_BeginExec
(
Baton
*
baton
);
static
void
Work_BeginExec
(
Baton
*
baton
);
static
void
Work_Exec
(
uv_work_t
*
req
);
static
void
Work_Exec
(
uv_work_t
*
req
);
static
void
Work_AfterExec
(
uv_work_t
*
req
);
static
void
Work_AfterExec
(
uv_work_t
*
req
);
static
Napi
::
Value
Wait
(
const
Napi
::
CallbackInfo
&
info
);
Napi
::
Value
Wait
(
const
Napi
::
CallbackInfo
&
info
);
static
void
Work_Wait
(
Baton
*
baton
);
static
void
Work_Wait
(
Baton
*
baton
);
static
Napi
::
Value
Close
(
const
Napi
::
CallbackInfo
&
info
);
Napi
::
Value
Close
(
const
Napi
::
CallbackInfo
&
info
);
static
void
Work_BeginClose
(
Baton
*
baton
);
static
void
Work_BeginClose
(
Baton
*
baton
);
static
void
Work_Close
(
uv_work_t
*
req
);
static
void
Work_Close
(
uv_work_t
*
req
);
static
void
Work_AfterClose
(
uv_work_t
*
req
);
static
void
Work_AfterClose
(
uv_work_t
*
req
);
static
Napi
::
Value
LoadExtension
(
const
Napi
::
CallbackInfo
&
info
);
Napi
::
Value
LoadExtension
(
const
Napi
::
CallbackInfo
&
info
);
static
void
Work_BeginLoadExtension
(
Baton
*
baton
);
static
void
Work_BeginLoadExtension
(
Baton
*
baton
);
static
void
Work_LoadExtension
(
uv_work_t
*
req
);
static
void
Work_LoadExtension
(
uv_work_t
*
req
);
static
void
Work_AfterLoadExtension
(
uv_work_t
*
req
);
static
void
Work_AfterLoadExtension
(
uv_work_t
*
req
);
static
Napi
::
Value
Serialize
(
const
Napi
::
CallbackInfo
&
info
);
Napi
::
Value
Serialize
(
const
Napi
::
CallbackInfo
&
info
);
static
Napi
::
Value
Parallelize
(
const
Napi
::
CallbackInfo
&
info
);
Napi
::
Value
Parallelize
(
const
Napi
::
CallbackInfo
&
info
);
static
Napi
::
Value
Configure
(
const
Napi
::
CallbackInfo
&
info
);
Napi
::
Value
Configure
(
const
Napi
::
CallbackInfo
&
info
);
static
Napi
::
Value
Interrupt
(
const
Napi
::
CallbackInfo
&
info
);
Napi
::
Value
Interrupt
(
const
Napi
::
CallbackInfo
&
info
);
static
void
SetBusyTimeout
(
Baton
*
baton
);
static
void
SetBusyTimeout
(
Baton
*
baton
);
...
...
src/macros.h
View file @
dd3ef522
...
@@ -3,19 +3,35 @@
...
@@ -3,19 +3,35 @@
const
char
*
sqlite_code_string
(
int
code
);
const
char
*
sqlite_code_string
(
int
code
);
const
char
*
sqlite_authorizer_string
(
int
type
);
const
char
*
sqlite_authorizer_string
(
int
type
);
#include <vector>
// TODO: better way to work around StringConcat?
#include <napi.h>
inline
Napi
::
String
StringConcat
(
Napi
::
Value
str1
,
Napi
::
Value
str2
)
{
return
Napi
::
String
::
New
(
str1
.
Env
(),
str1
.
As
<
Napi
::
String
>
().
Utf8Value
()
+
str2
.
As
<
Napi
::
String
>
().
Utf8Value
()
);
}
// A Napi substitute IsInt32()
inline
bool
OtherIsInt
(
Napi
::
Number
source
)
{
double
orig_val
=
source
.
DoubleValue
();
double
int_val
=
(
double
)
source
.
Int32Value
();
if
(
orig_val
==
int_val
)
{
return
true
;
}
else
{
return
false
;
}
}
#define REQUIRE_ARGUMENTS(n) \
#define REQUIRE_ARGUMENTS(n) \
if (info.Length() < (n)) { \
if (info.Length() < (n)) { \
Napi::TypeError::New(env, "Expected " #n "arguments").ThrowAsJavaScriptException(); \
Napi::TypeError::New(env, "Expected " #n "arguments").ThrowAsJavaScriptException(); \
return env.Null(); \
}
}
#define REQUIRE_ARGUMENT_EXTERNAL(i, var) \
#define REQUIRE_ARGUMENT_EXTERNAL(i, var) \
if (info.Length() <= (i) || !info[i].IsExternal()) { \
if (info.Length() <= (i) || !info[i].IsExternal()) { \
Napi::TypeError::New(env, "Argument " #i " invalid").ThrowAsJavaScriptException(); \
Napi::TypeError::New(env, "Argument " #i " invalid").ThrowAsJavaScriptException(); \
return env.Null(); \
} \
} \
Napi::External var = info[i].As<Napi::External>();
Napi::External var = info[i].As<Napi::External>();
...
@@ -23,7 +39,6 @@ const char* sqlite_authorizer_string(int type);
...
@@ -23,7 +39,6 @@ const char* sqlite_authorizer_string(int type);
#define REQUIRE_ARGUMENT_FUNCTION(i, var) \
#define REQUIRE_ARGUMENT_FUNCTION(i, var) \
if (info.Length() <= (i) || !info[i].IsFunction()) { \
if (info.Length() <= (i) || !info[i].IsFunction()) { \
Napi::TypeError::New(env, "Argument " #i " must be a function").ThrowAsJavaScriptException(); \
Napi::TypeError::New(env, "Argument " #i " must be a function").ThrowAsJavaScriptException(); \
return env.Null(); \
} \
} \
Napi::Function var = info[i].As<Napi::Function>();
Napi::Function var = info[i].As<Napi::Function>();
...
@@ -31,7 +46,6 @@ const char* sqlite_authorizer_string(int type);
...
@@ -31,7 +46,6 @@ const char* sqlite_authorizer_string(int type);
#define REQUIRE_ARGUMENT_STRING(i, var) \
#define REQUIRE_ARGUMENT_STRING(i, var) \
if (info.Length() <= (i) || !info[i].IsString()) { \
if (info.Length() <= (i) || !info[i].IsString()) { \
Napi::TypeError::New(env, "Argument " #i " must be a string").ThrowAsJavaScriptException(); \
Napi::TypeError::New(env, "Argument " #i " must be a string").ThrowAsJavaScriptException(); \
return env.Null(); \
} \
} \
std::string var = info[i].As<Napi::String>();
std::string var = info[i].As<Napi::String>();
...
@@ -47,7 +61,6 @@ const char* sqlite_authorizer_string(int type);
...
@@ -47,7 +61,6 @@ const char* sqlite_authorizer_string(int type);
if (info.Length() > i && !info[i].IsUndefined()) { \
if (info.Length() > i && !info[i].IsUndefined()) { \
if (!info[i].IsFunction()) { \
if (!info[i].IsFunction()) { \
Napi::TypeError::New(env, "Argument " #i " must be a function").ThrowAsJavaScriptException(); \
Napi::TypeError::New(env, "Argument " #i " must be a function").ThrowAsJavaScriptException(); \
return env.Null(); \
} \
} \
var = info[i].As<Napi::Function>(); \
var = info[i].As<Napi::Function>(); \
}
}
...
@@ -59,67 +72,57 @@ const char* sqlite_authorizer_string(int type);
...
@@ -59,67 +72,57 @@ const char* sqlite_authorizer_string(int type);
var = (default); \
var = (default); \
} \
} \
else if (info[i].IsNumber()) { \
else if (info[i].IsNumber()) { \
if (OtherIsInt(info[i].As<Number>())) { \
var = info[i].As<Napi::Number>().Int32Value(); \
var = info[i].As<Napi::Number>().Int32Value(); \
} \
} \
} \
else { \
else { \
Napi::TypeError::New(env, "Argument " #i " must be an integer").ThrowAsJavaScriptException(); \
Napi::TypeError::New(env, "Argument " #i " must be an integer").ThrowAsJavaScriptException(); \
return env.Null(); \
}
}
#define DEFINE_CONSTANT_INTEGER(target, constant, name) \
#define DEFINE_CONSTANT_INTEGER(target, constant, name) \
target->DefineProperty( \
Napi::PropertyDescriptor::Value(#name, Napi::Number::New(env, constant), \
Napi::New(env, #name), \
static_cast<napi_property_attributes>(napi_enumerable | napi_configurable)),
Napi::Number::New(env, constant), \
static_cast<napi_property_attributes>(napi_enumerable | napi_configurable) \
);
#define DEFINE_CONSTANT_STRING(target, constant, name) \
#define DEFINE_CONSTANT_STRING(target, constant, name) \
target->DefineProperty( \
Napi::PropertyDescriptor::Value(#name, Napi::String::New(env, constant), \
Napi::New(env, #name), \
static_cast<napi_property_attributes>(napi_enumerable | napi_configurable)),
Napi::New(env, constant), \
static_cast<napi_property_attributes>(napi_enumerable | napi_configurable) \
);
#define NODE_SET_GETTER(target, name, function) \
Napi::SetAccessor((target)->InstanceTemplate(), \
Napi::New(env, name), (function));
#define NODE_SET_SETTER(target, name, getter, setter) \
Napi::SetAccessor((target)->InstanceTemplate(), \
Napi::New(env, name), getter, setter);
#define GET_STRING(source, name, property) \
std::string name = (source).Get(\
Napi::New(env, prop.As<Napi::String>()));
#define GET_INTEGER(source, name, prop) \
int name = Napi::To<int>((source).Get(\
Napi::New(env, property)));
#define EXCEPTION(msg, errno, name) \
#define EXCEPTION(msg, errno, name) \
Napi::Value name = Exception::Error(Napi::New(env, \
Napi::Value name = Napi::Error::New(env, \
std::string(sqlite_code_string(errno)) + \
StringConcat( \
std::string(": ") + std::string(msg) \
StringConcat( \
)); \
Napi::String::New(env, sqlite_code_string(errno)), \
Napi::String::New(env, ": ") \
), \
(msg) \
).Utf8Value() \
).Value(); \
Napi::Object name ##_obj = name.As<Napi::Object>(); \
Napi::Object name ##_obj = name.As<Napi::Object>(); \
(name ##_obj).Set(Napi::String::New(env, "errno"), Napi::New(env, errno));\
(name ##_obj).Set( Napi::String::New(env, "errno"), Napi::Number::New(env, errno)); \
(name ##_obj).Set(Napi::String::New(env, "code"), \
(name ##_obj).Set( Napi::String::New(env, "code"), \
Napi::New(env, sqlite_code_string(errno)));
Napi::String::New(env, sqlite_code_string(errno)));
#define EMIT_EVENT(obj, argc, argv) \
#define EMIT_EVENT(obj, argc, argv) \
TRY_CATCH_CALL((obj), \
TRY_CATCH_CALL((obj), \
(obj).Get(\
(obj).Get("emit").As<Napi::Function>(),\
Napi::String::New(env, "emit")).As<Napi::Function>(),\
argc, argv \
argc, argv \
);
);
// The Mac OS compiler complains when argv is NULL unless we
// first assign it to a locally defined variable.
#define TRY_CATCH_CALL(context, callback, argc, argv) \
#define TRY_CATCH_CALL(context, callback, argc, argv) \
(callback).MakeCallback((context), (argc), (argv))
Napi::Value* passed_argv = argv;\
std::vector<napi_value> args;\
if ((argc != 0) && (passed_argv != NULL)) {\
args.assign(passed_argv, passed_argv + argc);\
}\
(callback).MakeCallback(Napi::Value(context), args);
#define WORK_DEFINITION(name) \
#define WORK_DEFINITION(name) \
static Napi::Value name(const Napi::CallbackInfo& info);
\
Napi::Value name(const Napi::CallbackInfo& info);
\
static void Work_Begin##name(Baton* baton); \
static void Work_Begin##name(Baton* baton); \
static void Work_##name(uv_work_t* req); \
static void Work_##name(uv_work_t* req); \
static void Work_After##name(uv_work_t* req);
static void Work_After##name(uv_work_t* req);
...
...
src/node_sqlite3.cc
View file @
dd3ef522
...
@@ -16,50 +16,54 @@ namespace {
...
@@ -16,50 +16,54 @@ namespace {
Napi
::
Object
RegisterModule
(
Napi
::
Env
env
,
Napi
::
Object
exports
)
{
Napi
::
Object
RegisterModule
(
Napi
::
Env
env
,
Napi
::
Object
exports
)
{
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
Database
::
Init
(
env
,
target
,
module
);
Database
::
Init
(
env
,
exports
);
Statement
::
Init
(
env
,
target
,
module
);
Statement
::
Init
(
env
,
exports
);
Backup
::
Init
(
env
,
target
,
module
);
Backup
::
Init
(
env
,
exports
);
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_OPEN_READONLY
,
OPEN_READONLY
);
exports
.
DefineProperties
({
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_OPEN_READWRITE
,
OPEN_READWRITE
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_OPEN_READONLY
,
OPEN_READONLY
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_OPEN_CREATE
,
OPEN_CREATE
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_OPEN_READWRITE
,
OPEN_READWRITE
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_OPEN_FULLMUTEX
,
OPEN_FULLMUTEX
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_OPEN_CREATE
,
OPEN_CREATE
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_OPEN_URI
,
OPEN_URI
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_OPEN_FULLMUTEX
,
OPEN_FULLMUTEX
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_OPEN_SHAREDCACHE
,
OPEN_SHAREDCACHE
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_OPEN_URI
,
OPEN_URI
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_OPEN_PRIVATECACHE
,
OPEN_PRIVATECACHE
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_OPEN_SHAREDCACHE
,
OPEN_SHAREDCACHE
)
DEFINE_CONSTANT_STRING
(
target
,
SQLITE_VERSION
,
VERSION
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_OPEN_PRIVATECACHE
,
OPEN_PRIVATECACHE
)
DEFINE_CONSTANT_STRING
(
exports
,
SQLITE_VERSION
,
VERSION
)
#ifdef SQLITE_SOURCE_ID
#ifdef SQLITE_SOURCE_ID
DEFINE_CONSTANT_STRING
(
target
,
SQLITE_SOURCE_ID
,
SOURCE_ID
);
DEFINE_CONSTANT_STRING
(
exports
,
SQLITE_SOURCE_ID
,
SOURCE_ID
)
#endif
#endif
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_VERSION_NUMBER
,
VERSION_NUMBER
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_VERSION_NUMBER
,
VERSION_NUMBER
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_OK
,
OK
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_OK
,
OK
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_ERROR
,
ERROR
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_ERROR
,
ERROR
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_INTERNAL
,
INTERNAL
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_INTERNAL
,
INTERNAL
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_PERM
,
PERM
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_PERM
,
PERM
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_ABORT
,
ABORT
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_ABORT
,
ABORT
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_BUSY
,
BUSY
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_BUSY
,
BUSY
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_LOCKED
,
LOCKED
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_LOCKED
,
LOCKED
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_NOMEM
,
NOMEM
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_NOMEM
,
NOMEM
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_READONLY
,
READONLY
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_READONLY
,
READONLY
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_INTERRUPT
,
INTERRUPT
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_INTERRUPT
,
INTERRUPT
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_IOERR
,
IOERR
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_IOERR
,
IOERR
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_CORRUPT
,
CORRUPT
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_CORRUPT
,
CORRUPT
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_NOTFOUND
,
NOTFOUND
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_NOTFOUND
,
NOTFOUND
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_FULL
,
FULL
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_FULL
,
FULL
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_CANTOPEN
,
CANTOPEN
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_CANTOPEN
,
CANTOPEN
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_PROTOCOL
,
PROTOCOL
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_PROTOCOL
,
PROTOCOL
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_EMPTY
,
EMPTY
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_EMPTY
,
EMPTY
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_SCHEMA
,
SCHEMA
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_SCHEMA
,
SCHEMA
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_TOOBIG
,
TOOBIG
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_TOOBIG
,
TOOBIG
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_CONSTRAINT
,
CONSTRAINT
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_CONSTRAINT
,
CONSTRAINT
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_MISMATCH
,
MISMATCH
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_MISMATCH
,
MISMATCH
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_MISUSE
,
MISUSE
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_MISUSE
,
MISUSE
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_NOLFS
,
NOLFS
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_NOLFS
,
NOLFS
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_AUTH
,
AUTH
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_AUTH
,
AUTH
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_FORMAT
,
FORMAT
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_FORMAT
,
FORMAT
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_RANGE
,
RANGE
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_RANGE
,
RANGE
)
DEFINE_CONSTANT_INTEGER
(
target
,
SQLITE_NOTADB
,
NOTADB
);
DEFINE_CONSTANT_INTEGER
(
exports
,
SQLITE_NOTADB
,
NOTADB
)
});
return
exports
;
}
}
}
}
...
...
src/statement.cc
View file @
dd3ef522
...
@@ -11,26 +11,49 @@
...
@@ -11,26 +11,49 @@
using
namespace
node_sqlite3
;
using
namespace
node_sqlite3
;
Napi
::
FunctionReference
Statement
::
constructor
;
Napi
::
FunctionReference
Statement
::
constructor
;
static
Napi
::
FunctionReference
date
;
static
Napi
::
FunctionReference
regexp
;
Napi
::
Object
Statement
::
Init
(
Napi
::
Env
env
,
Napi
::
Object
exports
)
{
Napi
::
Object
Statement
::
Init
(
Napi
::
Env
env
,
Napi
::
Object
exports
)
{
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
Napi
::
FunctionReference
t
=
Napi
::
Function
::
New
(
env
,
New
);
Napi
::
Function
t
=
DefineClass
(
env
,
"Statement"
,
{
InstanceMethod
(
"bind"
,
&
Statement
::
Bind
),
InstanceMethod
(
"get"
,
&
Statement
::
Get
),
InstanceMethod
(
"run"
,
&
Statement
::
Run
),
InstanceMethod
(
"all"
,
&
Statement
::
All
),
InstanceMethod
(
"each"
,
&
Statement
::
Each
),
InstanceMethod
(
"reset"
,
&
Statement
::
Reset
),
InstanceMethod
(
"finalize"
,
&
Statement
::
Finalize_
),
});
constructor
=
Napi
::
Persistent
(
t
);
constructor
.
SuppressDestruct
();
t
->
SetClassName
(
Napi
::
String
::
New
(
env
,
"Statement"
));
exports
.
Set
(
"Statement"
,
t
);
return
exports
;
}
// A Napi InstanceOf for Javascript Objects "Date" and "RegExp"
bool
OtherInstanceOf
(
Napi
::
Object
source
,
char
*
object_type
)
{
if
(
date
.
IsEmpty
())
{
Napi
::
Function
date_func
=
source
.
Env
().
Global
().
Get
(
"Date"
).
As
<
Function
>
();
Napi
::
Function
regexp_func
=
source
.
Env
().
Global
().
Get
(
"RegExp"
).
As
<
Function
>
();
date
=
Napi
::
Persistent
(
date_func
);
date
.
SuppressDestruct
();
regexp
=
Napi
::
Persistent
(
regexp_func
);
regexp
.
SuppressDestruct
();
}
InstanceMethod
(
"bind"
,
&
Bind
),
if
(
object_type
==
"Date"
)
{
InstanceMethod
(
"get"
,
&
Get
),
return
source
.
InstanceOf
(
date
.
Value
());
InstanceMethod
(
"run"
,
&
Run
),
}
else
if
(
object_type
==
"RegExp"
)
{
InstanceMethod
(
"all"
,
&
All
),
return
source
.
InstanceOf
(
regexp
.
Value
());
InstanceMethod
(
"each"
,
&
Each
),
}
InstanceMethod
(
"reset"
,
&
Reset
),
InstanceMethod
(
"finalize"
,
&
Finalize
),
constructor
.
Reset
(
t
);
return
false
;
(
target
).
Set
(
Napi
::
String
::
New
(
env
,
"Statement"
),
Napi
::
GetFunction
(
t
));
}
}
void
Statement
::
Process
()
{
void
Statement
::
Process
()
{
...
@@ -61,60 +84,56 @@ void Statement::Schedule(Work_Callback callback, Baton* baton) {
...
@@ -61,60 +84,56 @@ void Statement::Schedule(Work_Callback callback, Baton* baton) {
}
}
template
<
class
T
>
void
Statement
::
Error
(
T
*
baton
)
{
template
<
class
T
>
void
Statement
::
Error
(
T
*
baton
)
{
Statement
*
stmt
=
baton
->
stmt
;
Napi
::
Env
env
=
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
Statement
*
stmt
=
baton
->
stmt
;
// Fail hard on logic errors.
// Fail hard on logic errors.
assert
(
stmt
->
status
!=
0
);
assert
(
stmt
->
status
!=
0
);
EXCEPTION
(
stmt
->
message
,
stmt
->
status
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
stmt
->
message
.
c_str
())
,
stmt
->
status
,
exception
);
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
exception
};
Napi
::
Value
argv
[]
=
{
exception
};
TRY_CATCH_CALL
(
stmt
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
stmt
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
else
{
else
{
Napi
::
Value
argv
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
Napi
::
Value
argv
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
EMIT_EVENT
(
stmt
->
handl
e
(),
2
,
argv
);
EMIT_EVENT
(
stmt
->
Valu
e
(),
2
,
argv
);
}
}
}
}
// { Database db, String sql, Array params, Function callback }
// { Database db, String sql, Array params, Function callback }
Napi
::
Value
Statement
::
New
(
const
Napi
::
CallbackInfo
&
info
)
{
Statement
::
Statement
(
const
Napi
::
CallbackInfo
&
info
)
:
Napi
::
ObjectWrap
<
Statement
>
(
info
)
{
if
(
!
info
.
IsConstructCall
())
{
Napi
::
Env
env
=
info
.
Env
();
Napi
::
TypeError
::
New
(
env
,
"Use the new operator to create new Statement objects"
).
ThrowAsJavaScriptException
();
return
env
.
Null
();
}
int
length
=
info
.
Length
();
int
length
=
info
.
Length
();
if
(
length
<=
0
||
!
Database
::
HasInstance
(
info
[
0
]))
{
if
(
length
<=
0
||
!
Database
::
HasInstance
(
info
[
0
]))
{
Napi
::
TypeError
::
New
(
env
,
"Database object expected"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"Database object expected"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
else
if
(
length
<=
1
||
!
info
[
1
].
IsString
())
{
else
if
(
length
<=
1
||
!
info
[
1
].
IsString
())
{
Napi
::
TypeError
::
New
(
env
,
"SQL query expected"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"SQL query expected"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
else
if
(
length
>
2
&&
!
info
[
2
].
IsUndefined
()
&&
!
info
[
2
].
IsFunction
())
{
else
if
(
length
>
2
&&
!
info
[
2
].
IsUndefined
()
&&
!
info
[
2
].
IsFunction
())
{
Napi
::
TypeError
::
New
(
env
,
"Callback expected"
).
ThrowAsJavaScriptException
();
Napi
::
TypeError
::
New
(
env
,
"Callback expected"
).
ThrowAsJavaScriptException
();
return
env
.
Null
()
;
return
;
}
}
Database
*
db
=
info
[
0
].
As
<
Napi
::
Object
>
().
Unwrap
<
Database
>
(
);
Database
*
db
=
Napi
::
ObjectWrap
<
Database
>::
Unwrap
(
info
[
0
].
As
<
Napi
::
Object
>
()
);
Napi
::
String
sql
=
info
[
1
].
As
<
Napi
::
String
>
();
Napi
::
String
sql
=
info
[
1
].
As
<
Napi
::
String
>
();
info
.
This
().
DefineProperty
(
Napi
::
String
::
New
(
env
,
"sql"
),
sql
,
ReadOnly
);
info
.
This
().
As
<
Napi
::
Object
>
().
DefineProperty
(
Napi
::
PropertyDescriptor
::
Value
(
"sql"
,
sql
,
napi_default
)
);
Statement
*
stmt
=
new
Statemen
t
(
db
);
ini
t
(
db
);
stmt
->
Wrap
(
info
.
This
())
;
Statement
*
stmt
=
this
;
PrepareBaton
*
baton
=
new
PrepareBaton
(
db
,
info
[
2
].
As
<
Napi
::
Function
>
(),
stmt
);
PrepareBaton
*
baton
=
new
PrepareBaton
(
db
,
info
[
2
].
As
<
Napi
::
Function
>
(),
stmt
);
baton
->
sql
=
std
::
string
(
sql
->
As
<
Napi
::
String
>
().
Utf8Value
().
c_str
());
baton
->
sql
=
std
::
string
(
sql
.
As
<
Napi
::
String
>
().
Utf8Value
().
c_str
());
db
->
Schedule
(
Work_BeginPrepare
,
baton
);
db
->
Schedule
(
Work_BeginPrepare
,
baton
);
return
info
.
This
();
}
}
void
Statement
::
Work_BeginPrepare
(
Database
::
Baton
*
baton
)
{
void
Statement
::
Work_BeginPrepare
(
Database
::
Baton
*
baton
)
{
...
@@ -150,20 +169,21 @@ void Statement::Work_Prepare(uv_work_t* req) {
...
@@ -150,20 +169,21 @@ void Statement::Work_Prepare(uv_work_t* req) {
}
}
void
Statement
::
Work_AfterPrepare
(
uv_work_t
*
req
)
{
void
Statement
::
Work_AfterPrepare
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
STATEMENT_INIT
(
PrepareBaton
);
STATEMENT_INIT
(
PrepareBaton
);
Napi
::
Env
env
=
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
if
(
stmt
->
status
!=
SQLITE_OK
)
{
if
(
stmt
->
status
!=
SQLITE_OK
)
{
Error
(
baton
);
Error
(
baton
);
stmt
->
Finalize
();
stmt
->
Finalize
_
();
}
}
else
{
else
{
stmt
->
prepared
=
true
;
stmt
->
prepared
=
true
;
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
if
(
!
baton
->
callback
.
IsEmpty
()
&&
baton
->
callback
.
Value
().
IsFunction
())
{
if
(
!
cb
.
IsEmpty
()
&&
cb
->
IsFunction
())
{
Napi
::
Function
cb
=
baton
->
callback
.
Value
();
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
TRY_CATCH_CALL
(
stmt
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
stmt
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
}
}
...
@@ -172,28 +192,37 @@ void Statement::Work_AfterPrepare(uv_work_t* req) {
...
@@ -172,28 +192,37 @@ void Statement::Work_AfterPrepare(uv_work_t* req) {
template
<
class
T
>
Values
::
Field
*
template
<
class
T
>
Values
::
Field
*
Statement
::
BindParameter
(
const
Napi
::
Value
source
,
T
pos
)
{
Statement
::
BindParameter
(
const
Napi
::
Value
source
,
T
pos
)
{
if
(
source
.
IsString
()
||
source
->
IsRegExp
()
)
{
if
(
source
.
IsString
())
{
std
::
string
val
=
source
.
As
<
Napi
::
String
>
();
std
::
string
val
=
source
.
As
<
Napi
::
String
>
()
.
Utf8Value
()
;
return
new
Values
::
Text
(
pos
,
val
.
Length
(),
*
val
);
return
new
Values
::
Text
(
pos
,
val
.
length
(),
val
.
c_str
()
);
}
}
else
if
(
source
.
IsNumber
())
{
else
if
(
OtherInstanceOf
(
source
.
As
<
Object
>
(),
"RegExp"
))
{
return
new
Values
::
Integer
(
pos
,
source
.
As
<
Napi
::
Number
>
().
Int32Value
());
std
::
string
val
=
source
.
ToString
().
Utf8Value
();
return
new
Values
::
Text
(
pos
,
val
.
length
(),
val
.
c_str
());
}
}
else
if
(
source
.
IsNumber
())
{
else
if
(
source
.
IsNumber
())
{
if
(
OtherIsInt
(
source
.
As
<
Napi
::
Number
>
()))
{
return
new
Values
::
Integer
(
pos
,
source
.
As
<
Napi
::
Number
>
().
Int32Value
());
}
else
{
return
new
Values
::
Float
(
pos
,
source
.
As
<
Napi
::
Number
>
().
DoubleValue
());
return
new
Values
::
Float
(
pos
,
source
.
As
<
Napi
::
Number
>
().
DoubleValue
());
}
}
else
if
(
source
->
IsBoolean
())
{
}
else
if
(
source
.
IsBoolean
())
{
return
new
Values
::
Integer
(
pos
,
source
.
As
<
Napi
::
Boolean
>
().
Value
()
?
1
:
0
);
return
new
Values
::
Integer
(
pos
,
source
.
As
<
Napi
::
Boolean
>
().
Value
()
?
1
:
0
);
}
}
else
if
(
source
->
IsNull
())
{
else
if
(
source
.
IsNull
())
{
return
new
Values
::
Null
(
pos
);
return
new
Values
::
Null
(
pos
);
}
}
else
if
(
source
.
IsBuffer
())
{
else
if
(
source
.
IsBuffer
())
{
Napi
::
Object
buffer
=
source
.
To
<
Napi
::
Object
>
();
Napi
::
Buffer
<
char
>
buffer
=
source
.
As
<
Napi
::
Buffer
<
char
>
>
();
return
new
Values
::
Blob
(
pos
,
Buffer
::
Length
(
buffer
),
Buffer
::
Data
(
buffer
));
return
new
Values
::
Blob
(
pos
,
buffer
.
Length
(),
buffer
.
Data
(
));
}
}
else
if
(
source
->
IsDate
())
{
else
if
(
OtherInstanceOf
(
source
.
As
<
Object
>
(),
"Date"
))
{
return
new
Values
::
Float
(
pos
,
source
.
As
<
Napi
::
Number
>
().
DoubleValue
());
return
new
Values
::
Float
(
pos
,
source
.
ToNumber
().
DoubleValue
());
}
else
if
(
source
.
IsObject
())
{
std
::
string
val
=
source
.
ToString
().
Utf8Value
();
return
new
Values
::
Text
(
pos
,
val
.
length
(),
val
.
c_str
());
}
}
else
{
else
{
return
NULL
;
return
NULL
;
...
@@ -201,11 +230,12 @@ template <class T> Values::Field*
...
@@ -201,11 +230,12 @@ template <class T> Values::Field*
}
}
template
<
class
T
>
T
*
Statement
::
Bind
(
const
Napi
::
CallbackInfo
&
info
,
int
start
,
int
last
)
{
template
<
class
T
>
T
*
Statement
::
Bind
(
const
Napi
::
CallbackInfo
&
info
,
int
start
,
int
last
)
{
Napi
::
Env
env
=
info
.
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
if
(
last
<
0
)
last
=
info
.
Length
();
if
(
last
<
0
)
last
=
info
.
Length
();
Napi
::
Function
callback
;
Napi
::
Function
callback
;
if
(
last
>
start
&&
info
[
last
-
1
]
->
IsFunction
())
{
if
(
last
>
start
&&
info
[
last
-
1
]
.
IsFunction
())
{
callback
=
info
[
last
-
1
].
As
<
Napi
::
Function
>
();
callback
=
info
[
last
-
1
].
As
<
Napi
::
Function
>
();
last
--
;
last
--
;
}
}
...
@@ -215,13 +245,13 @@ template <class T> T* Statement::Bind(const Napi::CallbackInfo& info, int start,
...
@@ -215,13 +245,13 @@ template <class T> T* Statement::Bind(const Napi::CallbackInfo& info, int start,
if
(
start
<
last
)
{
if
(
start
<
last
)
{
if
(
info
[
start
].
IsArray
())
{
if
(
info
[
start
].
IsArray
())
{
Napi
::
Array
array
=
info
[
start
].
As
<
Napi
::
Array
>
();
Napi
::
Array
array
=
info
[
start
].
As
<
Napi
::
Array
>
();
int
length
=
array
->
Length
();
int
length
=
array
.
Length
();
// Note: bind parameters start with 1.
// Note: bind parameters start with 1.
for
(
int
i
=
0
,
pos
=
1
;
i
<
length
;
i
++
,
pos
++
)
{
for
(
int
i
=
0
,
pos
=
1
;
i
<
length
;
i
++
,
pos
++
)
{
baton
->
parameters
.
push_back
(
BindParameter
((
array
).
Get
(
i
),
pos
));
baton
->
parameters
.
push_back
(
BindParameter
((
array
).
Get
(
i
),
pos
));
}
}
}
}
else
if
(
!
info
[
start
].
IsObject
()
||
info
[
start
].
IsRegExp
()
||
info
[
start
].
IsDate
(
)
||
info
[
start
].
IsBuffer
())
{
else
if
(
!
info
[
start
].
IsObject
()
||
OtherInstanceOf
(
info
[
start
].
As
<
Object
>
(),
"RegExp"
)
||
OtherInstanceOf
(
info
[
start
].
As
<
Object
>
(),
"Date"
)
||
info
[
start
].
IsBuffer
())
{
// Parameters directly in array.
// Parameters directly in array.
// Note: bind parameters start with 1.
// Note: bind parameters start with 1.
for
(
int
i
=
start
,
pos
=
1
;
i
<
last
;
i
++
,
pos
++
)
{
for
(
int
i
=
start
,
pos
=
1
;
i
<
last
;
i
++
,
pos
++
)
{
...
@@ -230,8 +260,8 @@ template <class T> T* Statement::Bind(const Napi::CallbackInfo& info, int start,
...
@@ -230,8 +260,8 @@ template <class T> T* Statement::Bind(const Napi::CallbackInfo& info, int start,
}
}
else
if
(
info
[
start
].
IsObject
())
{
else
if
(
info
[
start
].
IsObject
())
{
Napi
::
Object
object
=
info
[
start
].
As
<
Napi
::
Object
>
();
Napi
::
Object
object
=
info
[
start
].
As
<
Napi
::
Object
>
();
Napi
::
Array
array
=
Napi
::
GetPropertyNames
(
object
);
Napi
::
Array
array
=
object
.
GetPropertyNames
(
);
int
length
=
array
->
Length
();
int
length
=
array
.
Length
();
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
Napi
::
Value
name
=
(
array
).
Get
(
i
);
Napi
::
Value
name
=
(
array
).
Get
(
i
);
...
@@ -241,7 +271,7 @@ template <class T> T* Statement::Bind(const Napi::CallbackInfo& info, int start,
...
@@ -241,7 +271,7 @@ template <class T> T* Statement::Bind(const Napi::CallbackInfo& info, int start,
}
}
else
{
else
{
baton
->
parameters
.
push_back
(
BindParameter
((
object
).
Get
(
name
),
baton
->
parameters
.
push_back
(
BindParameter
((
object
).
Get
(
name
),
name
->
As
<
Napi
::
String
>
().
Utf8Value
().
c_str
()));
name
.
As
<
Napi
::
String
>
().
Utf8Value
().
c_str
()));
}
}
}
}
}
}
...
@@ -268,7 +298,7 @@ bool Statement::Bind(const Parameters & parameters) {
...
@@ -268,7 +298,7 @@ bool Statement::Bind(const Parameters & parameters) {
Values
::
Field
*
field
=
*
it
;
Values
::
Field
*
field
=
*
it
;
if
(
field
!=
NULL
)
{
if
(
field
!=
NULL
)
{
int
pos
;
unsigned
int
pos
;
if
(
field
->
index
>
0
)
{
if
(
field
->
index
>
0
)
{
pos
=
field
->
index
;
pos
=
field
->
index
;
}
}
...
@@ -311,6 +341,7 @@ bool Statement::Bind(const Parameters & parameters) {
...
@@ -311,6 +341,7 @@ bool Statement::Bind(const Parameters & parameters) {
}
}
Napi
::
Value
Statement
::
Bind
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Statement
::
Bind
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
info
.
Env
();
Statement
*
stmt
=
this
;
Statement
*
stmt
=
this
;
Baton
*
baton
=
stmt
->
Bind
<
Baton
>
(
info
);
Baton
*
baton
=
stmt
->
Bind
<
Baton
>
(
info
);
...
@@ -338,19 +369,20 @@ void Statement::Work_Bind(uv_work_t* req) {
...
@@ -338,19 +369,20 @@ void Statement::Work_Bind(uv_work_t* req) {
}
}
void
Statement
::
Work_AfterBind
(
uv_work_t
*
req
)
{
void
Statement
::
Work_AfterBind
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
STATEMENT_INIT
(
Baton
);
STATEMENT_INIT
(
Baton
);
Napi
::
Env
env
=
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
if
(
stmt
->
status
!=
SQLITE_OK
)
{
if
(
stmt
->
status
!=
SQLITE_OK
)
{
Error
(
baton
);
Error
(
baton
);
}
}
else
{
else
{
// Fire callbacks.
// Fire callbacks.
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
TRY_CATCH_CALL
(
stmt
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
stmt
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
}
}
...
@@ -360,6 +392,7 @@ void Statement::Work_AfterBind(uv_work_t* req) {
...
@@ -360,6 +392,7 @@ void Statement::Work_AfterBind(uv_work_t* req) {
Napi
::
Value
Statement
::
Get
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Statement
::
Get
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
info
.
Env
();
Statement
*
stmt
=
this
;
Statement
*
stmt
=
this
;
Baton
*
baton
=
stmt
->
Bind
<
RowBaton
>
(
info
);
Baton
*
baton
=
stmt
->
Bind
<
RowBaton
>
(
info
);
...
@@ -402,25 +435,26 @@ void Statement::Work_Get(uv_work_t* req) {
...
@@ -402,25 +435,26 @@ void Statement::Work_Get(uv_work_t* req) {
}
}
void
Statement
::
Work_AfterGet
(
uv_work_t
*
req
)
{
void
Statement
::
Work_AfterGet
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
STATEMENT_INIT
(
RowBaton
);
STATEMENT_INIT
(
RowBaton
);
Napi
::
Env
env
=
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
if
(
stmt
->
status
!=
SQLITE_ROW
&&
stmt
->
status
!=
SQLITE_DONE
)
{
if
(
stmt
->
status
!=
SQLITE_ROW
&&
stmt
->
status
!=
SQLITE_DONE
)
{
Error
(
baton
);
Error
(
baton
);
}
}
else
{
else
{
// Fire callbacks.
// Fire callbacks.
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
if
(
stmt
->
status
==
SQLITE_ROW
)
{
if
(
stmt
->
status
==
SQLITE_ROW
)
{
// Create the result array from the data we acquired.
// Create the result array from the data we acquired.
Napi
::
Value
argv
[]
=
{
env
.
Null
(),
RowToJS
(
&
baton
->
row
)
};
Napi
::
Value
argv
[]
=
{
env
.
Null
(),
RowToJS
(
env
,
&
baton
->
row
)
};
TRY_CATCH_CALL
(
stmt
->
handl
e
(),
cb
,
2
,
argv
);
TRY_CATCH_CALL
(
stmt
->
Valu
e
(),
cb
,
2
,
argv
);
}
}
else
{
else
{
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
TRY_CATCH_CALL
(
stmt
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
stmt
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
}
}
}
}
...
@@ -429,6 +463,7 @@ void Statement::Work_AfterGet(uv_work_t* req) {
...
@@ -429,6 +463,7 @@ void Statement::Work_AfterGet(uv_work_t* req) {
}
}
Napi
::
Value
Statement
::
Run
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Statement
::
Run
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
info
.
Env
();
Statement
*
stmt
=
this
;
Statement
*
stmt
=
this
;
Baton
*
baton
=
stmt
->
Bind
<
RunBaton
>
(
info
);
Baton
*
baton
=
stmt
->
Bind
<
RunBaton
>
(
info
);
...
@@ -473,22 +508,23 @@ void Statement::Work_Run(uv_work_t* req) {
...
@@ -473,22 +508,23 @@ void Statement::Work_Run(uv_work_t* req) {
}
}
void
Statement
::
Work_AfterRun
(
uv_work_t
*
req
)
{
void
Statement
::
Work_AfterRun
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
STATEMENT_INIT
(
RunBaton
);
STATEMENT_INIT
(
RunBaton
);
Napi
::
Env
env
=
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
if
(
stmt
->
status
!=
SQLITE_ROW
&&
stmt
->
status
!=
SQLITE_DONE
)
{
if
(
stmt
->
status
!=
SQLITE_ROW
&&
stmt
->
status
!=
SQLITE_DONE
)
{
Error
(
baton
);
Error
(
baton
);
}
}
else
{
else
{
// Fire callbacks.
// Fire callbacks.
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
(
stmt
->
handl
e
()).
Set
(
Napi
::
String
::
New
(
env
,
"lastID"
),
Napi
::
Number
::
New
(
env
,
baton
->
inserted_id
));
(
stmt
->
Valu
e
()).
Set
(
Napi
::
String
::
New
(
env
,
"lastID"
),
Napi
::
Number
::
New
(
env
,
baton
->
inserted_id
));
(
stmt
->
handle
()).
Set
(
Napi
::
String
::
New
(
env
,
"changes"
),
Napi
::
New
(
env
,
baton
->
changes
));
(
stmt
->
Value
()).
Set
(
Napi
::
String
::
New
(
env
,
"changes"
),
Napi
::
Number
::
New
(
env
,
baton
->
changes
));
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
TRY_CATCH_CALL
(
stmt
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
stmt
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
}
}
...
@@ -496,6 +532,7 @@ void Statement::Work_AfterRun(uv_work_t* req) {
...
@@ -496,6 +532,7 @@ void Statement::Work_AfterRun(uv_work_t* req) {
}
}
Napi
::
Value
Statement
::
All
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Statement
::
All
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
info
.
Env
();
Statement
*
stmt
=
this
;
Statement
*
stmt
=
this
;
Baton
*
baton
=
stmt
->
Bind
<
RowsBaton
>
(
info
);
Baton
*
baton
=
stmt
->
Bind
<
RowsBaton
>
(
info
);
...
@@ -540,29 +577,30 @@ void Statement::Work_All(uv_work_t* req) {
...
@@ -540,29 +577,30 @@ void Statement::Work_All(uv_work_t* req) {
}
}
void
Statement
::
Work_AfterAll
(
uv_work_t
*
req
)
{
void
Statement
::
Work_AfterAll
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
STATEMENT_INIT
(
RowsBaton
);
STATEMENT_INIT
(
RowsBaton
);
Napi
::
Env
env
=
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
if
(
stmt
->
status
!=
SQLITE_DONE
)
{
if
(
stmt
->
status
!=
SQLITE_DONE
)
{
Error
(
baton
);
Error
(
baton
);
}
}
else
{
else
{
// Fire callbacks.
// Fire callbacks.
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
if
(
baton
->
rows
.
size
())
{
if
(
baton
->
rows
.
size
())
{
// Create the result array from the data we acquired.
// Create the result array from the data we acquired.
Napi
::
Array
result
(
Napi
::
Array
::
New
(
env
,
baton
->
rows
.
size
()));
Napi
::
Array
result
(
Napi
::
Array
::
New
(
env
,
baton
->
rows
.
size
()));
Rows
::
const_iterator
it
=
baton
->
rows
.
begin
();
Rows
::
const_iterator
it
=
baton
->
rows
.
begin
();
Rows
::
const_iterator
end
=
baton
->
rows
.
end
();
Rows
::
const_iterator
end
=
baton
->
rows
.
end
();
for
(
int
i
=
0
;
it
<
end
;
++
it
,
i
++
)
{
for
(
int
i
=
0
;
it
<
end
;
++
it
,
i
++
)
{
(
result
).
Set
(
i
,
RowToJS
(
*
it
));
(
result
).
Set
(
i
,
RowToJS
(
env
,
*
it
));
delete
*
it
;
delete
*
it
;
}
}
Napi
::
Value
argv
[]
=
{
env
.
Null
(),
result
};
Napi
::
Value
argv
[]
=
{
env
.
Null
(),
result
};
TRY_CATCH_CALL
(
stmt
->
handl
e
(),
cb
,
2
,
argv
);
TRY_CATCH_CALL
(
stmt
->
Valu
e
(),
cb
,
2
,
argv
);
}
}
else
{
else
{
// There were no result rows.
// There were no result rows.
...
@@ -570,7 +608,7 @@ void Statement::Work_AfterAll(uv_work_t* req) {
...
@@ -570,7 +608,7 @@ void Statement::Work_AfterAll(uv_work_t* req) {
env
.
Null
(),
env
.
Null
(),
Napi
::
Array
::
New
(
env
,
0
)
Napi
::
Array
::
New
(
env
,
0
)
};
};
TRY_CATCH_CALL
(
stmt
->
handl
e
(),
cb
,
2
,
argv
);
TRY_CATCH_CALL
(
stmt
->
Valu
e
(),
cb
,
2
,
argv
);
}
}
}
}
}
}
...
@@ -579,12 +617,13 @@ void Statement::Work_AfterAll(uv_work_t* req) {
...
@@ -579,12 +617,13 @@ void Statement::Work_AfterAll(uv_work_t* req) {
}
}
Napi
::
Value
Statement
::
Each
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Statement
::
Each
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
info
.
Env
();
Statement
*
stmt
=
this
;
Statement
*
stmt
=
this
;
int
last
=
info
.
Length
();
int
last
=
info
.
Length
();
Napi
::
Function
completed
;
Napi
::
Function
completed
;
if
(
last
>=
2
&&
info
[
last
-
1
]
->
IsFunction
()
&&
info
[
last
-
2
]
->
IsFunction
())
{
if
(
last
>=
2
&&
info
[
last
-
1
]
.
IsFunction
()
&&
info
[
last
-
2
].
IsFunction
())
{
completed
=
info
[
--
last
].
As
<
Napi
::
Function
>
();
completed
=
info
[
--
last
].
As
<
Napi
::
Function
>
();
}
}
...
@@ -605,8 +644,8 @@ void Statement::Work_BeginEach(Baton* baton) {
...
@@ -605,8 +644,8 @@ void Statement::Work_BeginEach(Baton* baton) {
// the event loop. This prevents dangling events.
// the event loop. This prevents dangling events.
EachBaton
*
each_baton
=
static_cast
<
EachBaton
*>
(
baton
);
EachBaton
*
each_baton
=
static_cast
<
EachBaton
*>
(
baton
);
each_baton
->
async
=
new
Async
(
each_baton
->
stmt
,
reinterpret_cast
<
uv_async_cb
>
(
AsyncEach
));
each_baton
->
async
=
new
Async
(
each_baton
->
stmt
,
reinterpret_cast
<
uv_async_cb
>
(
AsyncEach
));
each_baton
->
async
->
item_cb
.
Reset
(
each_baton
->
callback
);
each_baton
->
async
->
item_cb
.
Reset
(
each_baton
->
callback
.
Value
(),
1
);
each_baton
->
async
->
completed_cb
.
Reset
(
each_baton
->
completed
);
each_baton
->
async
->
completed_cb
.
Reset
(
each_baton
->
completed
.
Value
(),
1
);
STATEMENT_BEGIN
(
Each
);
STATEMENT_BEGIN
(
Each
);
}
}
...
@@ -662,10 +701,11 @@ void Statement::CloseCallback(uv_handle_t* handle) {
...
@@ -662,10 +701,11 @@ void Statement::CloseCallback(uv_handle_t* handle) {
}
}
void
Statement
::
AsyncEach
(
uv_async_t
*
handle
,
int
status
)
{
void
Statement
::
AsyncEach
(
uv_async_t
*
handle
,
int
status
)
{
Napi
::
HandleScope
scope
(
env
);
Async
*
async
=
static_cast
<
Async
*>
(
handle
->
data
);
Async
*
async
=
static_cast
<
Async
*>
(
handle
->
data
);
Napi
::
Env
env
=
async
->
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
while
(
true
)
{
while
(
true
)
{
// Get the contents out of the data cache for us to process in the JS callback.
// Get the contents out of the data cache for us to process in the JS callback.
Rows
rows
;
Rows
rows
;
...
@@ -677,41 +717,42 @@ void Statement::AsyncEach(uv_async_t* handle, int status) {
...
@@ -677,41 +717,42 @@ void Statement::AsyncEach(uv_async_t* handle, int status) {
break
;
break
;
}
}
Napi
::
Function
cb
=
Napi
::
New
(
env
,
async
->
item_cb
);
Napi
::
Function
cb
=
async
->
item_cb
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[
2
];
Napi
::
Value
argv
[
2
];
argv
[
0
]
=
env
.
Null
();
argv
[
0
]
=
env
.
Null
();
Rows
::
const_iterator
it
=
rows
.
begin
();
Rows
::
const_iterator
it
=
rows
.
begin
();
Rows
::
const_iterator
end
=
rows
.
end
();
Rows
::
const_iterator
end
=
rows
.
end
();
for
(
int
i
=
0
;
it
<
end
;
++
it
,
i
++
)
{
for
(
int
i
=
0
;
it
<
end
;
++
it
,
i
++
)
{
argv
[
1
]
=
RowToJS
(
*
it
);
argv
[
1
]
=
RowToJS
(
env
,
*
it
);
async
->
retrieved
++
;
async
->
retrieved
++
;
TRY_CATCH_CALL
(
async
->
stmt
->
handl
e
(),
cb
,
2
,
argv
);
TRY_CATCH_CALL
(
async
->
stmt
->
Valu
e
(),
cb
,
2
,
argv
);
delete
*
it
;
delete
*
it
;
}
}
}
}
}
}
Napi
::
Function
cb
=
Napi
::
New
(
env
,
async
->
completed_cb
);
Napi
::
Function
cb
=
async
->
completed_cb
.
Value
(
);
if
(
async
->
completed
)
{
if
(
async
->
completed
)
{
if
(
!
cb
.
IsEmpty
()
&&
if
(
!
cb
.
IsEmpty
()
&&
cb
->
IsFunction
())
{
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
Napi
::
Value
argv
[]
=
{
env
.
Null
(),
env
.
Null
(),
Napi
::
New
(
env
,
async
->
retrieved
)
Napi
::
N
umber
::
N
ew
(
env
,
async
->
retrieved
)
};
};
TRY_CATCH_CALL
(
async
->
stmt
->
handl
e
(),
cb
,
2
,
argv
);
TRY_CATCH_CALL
(
async
->
stmt
->
Valu
e
(),
cb
,
2
,
argv
);
}
}
uv_close
(
reinterpret_cast
<
uv_handle_t
*>
(
handle
),
CloseCallback
);
uv_close
(
reinterpret_cast
<
uv_handle_t
*>
(
handle
),
CloseCallback
);
}
}
}
}
void
Statement
::
Work_AfterEach
(
uv_work_t
*
req
)
{
void
Statement
::
Work_AfterEach
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
STATEMENT_INIT
(
EachBaton
);
STATEMENT_INIT
(
EachBaton
);
Napi
::
Env
env
=
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
if
(
stmt
->
status
!=
SQLITE_DONE
)
{
if
(
stmt
->
status
!=
SQLITE_DONE
)
{
Error
(
baton
);
Error
(
baton
);
}
}
...
@@ -720,6 +761,7 @@ void Statement::Work_AfterEach(uv_work_t* req) {
...
@@ -720,6 +761,7 @@ void Statement::Work_AfterEach(uv_work_t* req) {
}
}
Napi
::
Value
Statement
::
Reset
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Statement
::
Reset
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
info
.
Env
();
Statement
*
stmt
=
this
;
Statement
*
stmt
=
this
;
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
...
@@ -742,21 +784,22 @@ void Statement::Work_Reset(uv_work_t* req) {
...
@@ -742,21 +784,22 @@ void Statement::Work_Reset(uv_work_t* req) {
}
}
void
Statement
::
Work_AfterReset
(
uv_work_t
*
req
)
{
void
Statement
::
Work_AfterReset
(
uv_work_t
*
req
)
{
Napi
::
HandleScope
scope
(
env
);
STATEMENT_INIT
(
Baton
);
STATEMENT_INIT
(
Baton
);
Napi
::
Env
env
=
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
// Fire callbacks.
// Fire callbacks.
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
Napi
::
Value
argv
[]
=
{
env
.
Null
()
};
TRY_CATCH_CALL
(
stmt
->
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
stmt
->
Valu
e
(),
cb
,
1
,
argv
);
}
}
STATEMENT_END
();
STATEMENT_END
();
}
}
Napi
::
Object
Statement
::
RowToJS
(
Row
*
row
)
{
Napi
::
Value
Statement
::
RowToJS
(
Napi
::
Env
env
,
Row
*
row
)
{
Napi
::
EscapableHandleScope
scope
(
env
);
Napi
::
EscapableHandleScope
scope
(
env
);
Napi
::
Object
result
=
Napi
::
Object
::
New
(
env
);
Napi
::
Object
result
=
Napi
::
Object
::
New
(
env
);
...
@@ -779,14 +822,14 @@ Napi::Object Statement::RowToJS(Row* row) {
...
@@ -779,14 +822,14 @@ Napi::Object Statement::RowToJS(Row* row) {
value
=
Napi
::
String
::
New
(
env
,
((
Values
::
Text
*
)
field
)
->
value
.
c_str
(),
((
Values
::
Text
*
)
field
)
->
value
.
size
());
value
=
Napi
::
String
::
New
(
env
,
((
Values
::
Text
*
)
field
)
->
value
.
c_str
(),
((
Values
::
Text
*
)
field
)
->
value
.
size
());
}
break
;
}
break
;
case
SQLITE_BLOB
:
{
case
SQLITE_BLOB
:
{
value
=
Napi
::
Buffer
::
Copy
(
env
,
((
Values
::
Blob
*
)
field
)
->
value
,
((
Values
::
Blob
*
)
field
)
->
length
);
value
=
Napi
::
Buffer
<
char
>
::
Copy
(
env
,
((
Values
::
Blob
*
)
field
)
->
value
,
((
Values
::
Blob
*
)
field
)
->
length
);
}
break
;
}
break
;
case
SQLITE_NULL
:
{
case
SQLITE_NULL
:
{
value
=
env
.
Null
();
value
=
env
.
Null
();
}
break
;
}
break
;
}
}
(
result
).
Set
(
Napi
::
New
(
env
,
field
->
name
.
c_str
()),
value
);
(
result
).
Set
(
Napi
::
String
::
New
(
env
,
field
->
name
.
c_str
()),
value
);
DELETE_FIELD
(
field
);
DELETE_FIELD
(
field
);
}
}
...
@@ -826,31 +869,33 @@ void Statement::GetRow(Row* row, sqlite3_stmt* stmt) {
...
@@ -826,31 +869,33 @@ void Statement::GetRow(Row* row, sqlite3_stmt* stmt) {
}
}
}
}
Napi
::
Value
Statement
::
Finalize
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Value
Statement
::
Finalize_
(
const
Napi
::
CallbackInfo
&
info
)
{
Napi
::
Env
env
=
info
.
Env
();
Statement
*
stmt
=
this
;
Statement
*
stmt
=
this
;
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
OPTIONAL_ARGUMENT_FUNCTION
(
0
,
callback
);
Baton
*
baton
=
new
Baton
(
stmt
,
callback
);
Baton
*
baton
=
new
Baton
(
stmt
,
callback
);
stmt
->
Schedule
(
Finalize
,
baton
);
stmt
->
Schedule
(
Finalize
_
,
baton
);
return
stmt
->
db
->
handl
e
();
return
stmt
->
db
->
Valu
e
();
}
}
void
Statement
::
Finalize
(
Baton
*
baton
)
{
void
Statement
::
Finalize_
(
Baton
*
baton
)
{
Napi
::
Env
env
=
baton
->
stmt
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
baton
->
stmt
->
Finalize
();
baton
->
stmt
->
Finalize
_
();
// Fire callback in case there was one.
// Fire callback in case there was one.
Napi
::
Function
cb
=
Napi
::
New
(
env
,
baton
->
callback
);
Napi
::
Function
cb
=
baton
->
callback
.
Value
(
);
if
(
!
cb
.
Is
Empty
()
&&
cb
->
IsFunction
())
{
if
(
!
cb
.
Is
Undefined
()
&&
cb
.
IsFunction
())
{
TRY_CATCH_CALL
(
baton
->
stmt
->
handl
e
(),
cb
,
0
,
NULL
);
TRY_CATCH_CALL
(
baton
->
stmt
->
Valu
e
(),
cb
,
0
,
NULL
);
}
}
delete
baton
;
delete
baton
;
}
}
void
Statement
::
Finalize
()
{
void
Statement
::
Finalize
_
()
{
assert
(
!
finalized
);
assert
(
!
finalized
);
finalized
=
true
;
finalized
=
true
;
CleanQueue
();
CleanQueue
();
...
@@ -862,12 +907,13 @@ void Statement::Finalize() {
...
@@ -862,12 +907,13 @@ void Statement::Finalize() {
}
}
void
Statement
::
CleanQueue
()
{
void
Statement
::
CleanQueue
()
{
Napi
::
Env
env
=
this
->
Env
();
Napi
::
HandleScope
scope
(
env
);
Napi
::
HandleScope
scope
(
env
);
if
(
prepared
&&
!
queue
.
empty
())
{
if
(
prepared
&&
!
queue
.
empty
())
{
// This statement has already been prepared and is now finalized.
// This statement has already been prepared and is now finalized.
// Fire error for all remaining items in the queue.
// Fire error for all remaining items in the queue.
EXCEPTION
(
"Statement is already finalized"
,
SQLITE_MISUSE
,
exception
);
EXCEPTION
(
Napi
::
String
::
New
(
env
,
"Statement is already finalized"
)
,
SQLITE_MISUSE
,
exception
);
Napi
::
Value
argv
[]
=
{
exception
};
Napi
::
Value
argv
[]
=
{
exception
};
bool
called
=
false
;
bool
called
=
false
;
...
@@ -876,11 +922,11 @@ void Statement::CleanQueue() {
...
@@ -876,11 +922,11 @@ void Statement::CleanQueue() {
Call
*
call
=
queue
.
front
();
Call
*
call
=
queue
.
front
();
queue
.
pop
();
queue
.
pop
();
Napi
::
Function
cb
=
Napi
::
New
(
env
,
call
->
baton
->
callback
);
Napi
::
Function
cb
=
call
->
baton
->
callback
.
Value
(
);
if
(
prepared
&&
!
cb
.
IsEmpty
()
&&
if
(
prepared
&&
!
cb
.
IsEmpty
()
&&
cb
->
IsFunction
())
{
cb
.
IsFunction
())
{
TRY_CATCH_CALL
(
handl
e
(),
cb
,
1
,
argv
);
TRY_CATCH_CALL
(
Valu
e
(),
cb
,
1
,
argv
);
called
=
true
;
called
=
true
;
}
}
...
@@ -894,7 +940,7 @@ void Statement::CleanQueue() {
...
@@ -894,7 +940,7 @@ void Statement::CleanQueue() {
// Statement object.
// Statement object.
if
(
!
called
)
{
if
(
!
called
)
{
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
Napi
::
Value
info
[]
=
{
Napi
::
String
::
New
(
env
,
"error"
),
exception
};
EMIT_EVENT
(
handl
e
(),
2
,
info
);
EMIT_EVENT
(
Valu
e
(),
2
,
info
);
}
}
}
}
else
while
(
!
queue
.
empty
())
{
else
while
(
!
queue
.
empty
())
{
...
...
src/statement.h
View file @
dd3ef522
...
@@ -16,7 +16,6 @@
...
@@ -16,7 +16,6 @@
#include <uv.h>
#include <uv.h>
using
namespace
Napi
;
using
namespace
Napi
;
using
namespace
Napi
;
namespace
node_sqlite3
{
namespace
node_sqlite3
{
...
@@ -144,7 +143,7 @@ public:
...
@@ -144,7 +143,7 @@ public:
if
(
!
db
->
IsOpen
()
&&
db
->
IsLocked
())
{
if
(
!
db
->
IsOpen
()
&&
db
->
IsLocked
())
{
// The database handle was closed before the statement could be
// The database handle was closed before the statement could be
// prepared.
// prepared.
stmt
->
Finalize
();
stmt
->
Finalize
_
();
}
}
}
}
};
};
...
@@ -186,18 +185,20 @@ public:
...
@@ -186,18 +185,20 @@ public:
}
}
};
};
Statement
(
Database
*
db_
)
:
Napi
::
ObjectWrap
<
Statement
>
(),
void
init
(
Database
*
db_
)
{
db
(
db_
),
db
=
db_
;
_handle
(
NULL
),
_handle
=
NULL
;
status
(
SQLITE_OK
),
status
=
SQLITE_OK
;
prepared
(
false
),
prepared
=
false
;
locked
(
true
),
locked
=
true
;
finalized
(
false
)
{
finalized
=
false
;
db
->
Ref
();
db
->
Ref
();
}
}
Statement
(
const
Napi
::
CallbackInfo
&
info
);
~
Statement
()
{
~
Statement
()
{
if
(
!
finalized
)
Finalize
();
if
(
!
finalized
)
Finalize
_
();
}
}
WORK_DEFINITION
(
Bind
);
WORK_DEFINITION
(
Bind
);
...
@@ -207,7 +208,7 @@ public:
...
@@ -207,7 +208,7 @@ public:
WORK_DEFINITION
(
Each
);
WORK_DEFINITION
(
Each
);
WORK_DEFINITION
(
Reset
);
WORK_DEFINITION
(
Reset
);
static
Napi
::
Value
Finalize
(
const
Napi
::
CallbackInfo
&
info
);
Napi
::
Value
Finalize_
(
const
Napi
::
CallbackInfo
&
info
);
protected
:
protected
:
static
void
Work_BeginPrepare
(
Database
::
Baton
*
baton
);
static
void
Work_BeginPrepare
(
Database
::
Baton
*
baton
);
...
@@ -217,15 +218,15 @@ protected:
...
@@ -217,15 +218,15 @@ protected:
static
void
AsyncEach
(
uv_async_t
*
handle
,
int
status
);
static
void
AsyncEach
(
uv_async_t
*
handle
,
int
status
);
static
void
CloseCallback
(
uv_handle_t
*
handle
);
static
void
CloseCallback
(
uv_handle_t
*
handle
);
static
void
Finalize
(
Baton
*
baton
);
static
void
Finalize
_
(
Baton
*
baton
);
void
Finalize
();
void
Finalize
_
();
template
<
class
T
>
inline
Values
::
Field
*
BindParameter
(
const
Napi
::
Value
source
,
T
pos
);
template
<
class
T
>
inline
Values
::
Field
*
BindParameter
(
const
Napi
::
Value
source
,
T
pos
);
template
<
class
T
>
T
*
Bind
(
const
Napi
::
CallbackInfo
&
info
,
int
start
=
0
,
int
end
=
-
1
);
template
<
class
T
>
T
*
Bind
(
const
Napi
::
CallbackInfo
&
info
,
int
start
=
0
,
int
end
=
-
1
);
bool
Bind
(
const
Parameters
&
parameters
);
bool
Bind
(
const
Parameters
&
parameters
);
static
void
GetRow
(
Row
*
row
,
sqlite3_stmt
*
stmt
);
static
void
GetRow
(
Row
*
row
,
sqlite3_stmt
*
stmt
);
static
Napi
::
Object
RowToJS
(
Row
*
row
);
static
Napi
::
Value
RowToJS
(
Napi
::
Env
env
,
Row
*
row
);
void
Schedule
(
Work_Callback
callback
,
Baton
*
baton
);
void
Schedule
(
Work_Callback
callback
,
Baton
*
baton
);
void
Process
();
void
Process
();
void
CleanQueue
();
void
CleanQueue
();
...
...
test/database_fail.test.js
View file @
dd3ef522
...
@@ -10,11 +10,11 @@ describe('error handling', function() {
...
@@ -10,11 +10,11 @@ describe('error handling', function() {
it
(
'throw when calling Database() without new'
,
function
()
{
it
(
'throw when calling Database() without new'
,
function
()
{
assert
.
throws
(
function
()
{
assert
.
throws
(
function
()
{
sqlite3
.
Database
(
':memory:'
);
sqlite3
.
Database
(
':memory:'
);
},
(
/
Use the new operator to create new Database objects
/
));
},
(
/
Class constructors cannot be invoked without 'new'
/
));
assert
.
throws
(
function
()
{
assert
.
throws
(
function
()
{
sqlite3
.
Statement
();
sqlite3
.
Statement
();
},
(
/
Use the new operator to create new Statement objects
/
));
},
(
/
Class constructors cannot be invoked without 'new'
/
));
});
});
it
(
'should error when calling Database#get on a missing table'
,
function
(
done
)
{
it
(
'should error when calling Database#get on a missing table'
,
function
(
done
)
{
...
...
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