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
27106877
Commit
27106877
authored
Jul 04, 2010
by
Orlando Vazquez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve awkward binding behaviour with Statement#bindArray.
parent
f89fa7e3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
287 additions
and
52 deletions
+287
-52
README.md
README.md
+3
-3
statement.cc
src/statement.cc
+274
-49
statement.h
src/statement.h
+10
-0
No files found.
README.md
View file @
27106877
...
@@ -29,13 +29,13 @@ additional steps.
...
@@ -29,13 +29,13 @@ additional steps.
// bindings list is optional
// bindings list is optional
var ponies = [];
var ponies = [];
db.query(sql, [colour], function (pony) {
db.query(sql, [colour], function (pony) {
if (!pony) {
if (!pony) {
// no more ponies
// no more ponies
if (!ponies.length)
if (!ponies.length)
sys.puts('There are no ponies with ' + colour + ' tails. :(');
sys.puts('There are no ponies with ' + colour + ' tails. :(');
else
else
sys.puts('The following ponies have ' + colour + ' tails: ' + ponies.join(', '));
sys.puts('The following ponies have ' + colour + ' tails: ' + ponies.join(', '));
}
}
sys.puts(sys.inspect(pony));
sys.puts(sys.inspect(pony));
...
@@ -88,7 +88,7 @@ from the API have been made to improve performance.
...
@@ -88,7 +88,7 @@ from the API have been made to improve performance.
});
});
});
});
});
});
DESCRIPTION
DESCRIPTION
-----------
-----------
...
...
src/statement.cc
View file @
27106877
...
@@ -33,8 +33,10 @@ void Statement::Init(v8::Handle<Object> target) {
...
@@ -33,8 +33,10 @@ void Statement::Init(v8::Handle<Object> target) {
constructor_template
->
SetClassName
(
String
::
NewSymbol
(
"Statement"
));
constructor_template
->
SetClassName
(
String
::
NewSymbol
(
"Statement"
));
NODE_SET_PROTOTYPE_METHOD
(
t
,
"bind"
,
Bind
);
NODE_SET_PROTOTYPE_METHOD
(
t
,
"bind"
,
Bind
);
NODE_SET_PROTOTYPE_METHOD
(
t
,
"bindArray"
,
BindArray
);
NODE_SET_PROTOTYPE_METHOD
(
t
,
"finalize"
,
Finalize
);
NODE_SET_PROTOTYPE_METHOD
(
t
,
"finalize"
,
Finalize
);
NODE_SET_PROTOTYPE_METHOD
(
t
,
"reset"
,
Reset
);
NODE_SET_PROTOTYPE_METHOD
(
t
,
"reset"
,
Reset
);
NODE_SET_PROTOTYPE_METHOD
(
t
,
"clearBindings"
,
ClearBindings
);
NODE_SET_PROTOTYPE_METHOD
(
t
,
"step"
,
Step
);
NODE_SET_PROTOTYPE_METHOD
(
t
,
"step"
,
Step
);
callback_sym
=
Persistent
<
String
>::
New
(
String
::
New
(
"callback"
));
callback_sym
=
Persistent
<
String
>::
New
(
String
::
New
(
"callback"
));
...
@@ -52,6 +54,38 @@ Handle<Value> Statement::New(const Arguments& args) {
...
@@ -52,6 +54,38 @@ Handle<Value> Statement::New(const Arguments& args) {
return
args
.
This
();
return
args
.
This
();
}
}
int
Statement
::
EIO_AfterBindArray
(
eio_req
*
req
)
{
ev_unref
(
EV_DEFAULT_UC
);
HandleScope
scope
;
struct
bind_request
*
bind_req
=
(
struct
bind_request
*
)(
req
->
data
);
Local
<
Value
>
argv
[
1
];
bool
err
=
false
;
if
(
req
->
result
)
{
err
=
true
;
argv
[
0
]
=
Exception
::
Error
(
String
::
New
(
"Error binding parameter"
));
}
TryCatch
try_catch
;
bind_req
->
cb
->
Call
(
Context
::
GetCurrent
()
->
Global
(),
err
?
1
:
0
,
argv
);
if
(
try_catch
.
HasCaught
())
{
FatalException
(
try_catch
);
}
bind_req
->
cb
.
Dispose
();
free
(
bind_req
->
pairs
->
key
);;
free
(
bind_req
->
pairs
->
value
);
free
(
bind_req
->
pairs
);
free
(
bind_req
);
return
0
;
return
0
;
}
int
Statement
::
EIO_AfterBind
(
eio_req
*
req
)
{
int
Statement
::
EIO_AfterBind
(
eio_req
*
req
)
{
ev_unref
(
EV_DEFAULT_UC
);
ev_unref
(
EV_DEFAULT_UC
);
...
@@ -75,26 +109,91 @@ int Statement::EIO_AfterBind(eio_req *req) {
...
@@ -75,26 +109,91 @@ int Statement::EIO_AfterBind(eio_req *req) {
bind_req
->
cb
.
Dispose
();
bind_req
->
cb
.
Dispose
();
free
(
bind_req
->
key
);
struct
bind_pair
*
pair
=
bind_req
->
pairs
;
free
(
bind_req
->
value
);
for
(
size_t
i
=
0
;
i
<
bind_req
->
len
;
i
++
,
pair
++
)
{
free
(
pair
->
key
);
free
(
pair
->
value
);
}
free
(
bind_req
->
pairs
);
free
(
bind_req
);
free
(
bind_req
);
return
0
;
return
0
;
}
}
int
Statement
::
EIO_BindArray
(
eio_req
*
req
)
{
struct
bind_request
*
bind_req
=
(
struct
bind_request
*
)(
req
->
data
);
Statement
*
sto
=
bind_req
->
sto
;
int
rc
(
0
);
struct
bind_pair
*
pair
=
bind_req
->
pairs
;
int
index
=
0
;
for
(
size_t
i
=
0
;
i
<
bind_req
->
len
;
i
++
,
pair
++
)
{
switch
(
pair
->
key_type
)
{
case
KEY_INT
:
index
=
*
(
int
*
)(
pair
->
key
);
break
;
case
KEY_STRING
:
index
=
sqlite3_bind_parameter_index
(
sto
->
stmt_
,
(
char
*
)(
pair
->
key
));
break
;
default
:
{
// this SHOULD be unreachable
}
}
if
(
!
index
)
{
req
->
result
=
SQLITE_MISMATCH
;
return
0
;
}
int
rc
=
0
;
switch
(
pair
->
value_type
)
{
case
VALUE_INT
:
rc
=
sqlite3_bind_int
(
sto
->
stmt_
,
index
,
*
(
int
*
)(
pair
->
value
));
break
;
case
VALUE_DOUBLE
:
rc
=
sqlite3_bind_double
(
sto
->
stmt_
,
index
,
*
(
double
*
)(
pair
->
value
));
break
;
case
VALUE_STRING
:
rc
=
sqlite3_bind_text
(
sto
->
stmt_
,
index
,
(
char
*
)(
pair
->
value
),
pair
->
value_size
,
SQLITE_TRANSIENT
);
break
;
case
VALUE_NULL
:
rc
=
sqlite3_bind_null
(
sto
->
stmt_
,
index
);
break
;
default
:
{
// should be unreachable
}
}
}
if
(
rc
)
{
req
->
result
=
rc
;
return
0
;
}
return
0
;
}
int
Statement
::
EIO_Bind
(
eio_req
*
req
)
{
int
Statement
::
EIO_Bind
(
eio_req
*
req
)
{
struct
bind_request
*
bind_req
=
(
struct
bind_request
*
)(
req
->
data
);
struct
bind_request
*
bind_req
=
(
struct
bind_request
*
)(
req
->
data
);
Statement
*
sto
=
bind_req
->
sto
;
Statement
*
sto
=
bind_req
->
sto
;
int
index
(
0
);
int
index
(
0
);
switch
(
bind_req
->
key_type
)
{
switch
(
bind_req
->
pairs
->
key_type
)
{
case
KEY_INT
:
case
KEY_INT
:
index
=
*
(
int
*
)(
bind_req
->
key
);
index
=
*
(
int
*
)(
bind_req
->
pairs
->
key
);
break
;
break
;
case
KEY_STRING
:
case
KEY_STRING
:
index
=
sqlite3_bind_parameter_index
(
sto
->
stmt_
,
index
=
sqlite3_bind_parameter_index
(
sto
->
stmt_
,
(
char
*
)(
bind_req
->
key
));
(
char
*
)(
bind_req
->
pairs
->
key
));
break
;
break
;
default
:
{
default
:
{
...
@@ -108,16 +207,16 @@ int Statement::EIO_Bind(eio_req *req) {
...
@@ -108,16 +207,16 @@ int Statement::EIO_Bind(eio_req *req) {
}
}
int
rc
=
0
;
int
rc
=
0
;
switch
(
bind_req
->
value_type
)
{
switch
(
bind_req
->
pairs
->
value_type
)
{
case
VALUE_INT
:
case
VALUE_INT
:
rc
=
sqlite3_bind_int
(
sto
->
stmt_
,
index
,
*
(
int
*
)(
bind_req
->
value
));
rc
=
sqlite3_bind_int
(
sto
->
stmt_
,
index
,
*
(
int
*
)(
bind_req
->
pairs
->
value
));
break
;
break
;
case
VALUE_DOUBLE
:
case
VALUE_DOUBLE
:
rc
=
sqlite3_bind_double
(
sto
->
stmt_
,
index
,
*
(
double
*
)(
bind_req
->
value
));
rc
=
sqlite3_bind_double
(
sto
->
stmt_
,
index
,
*
(
double
*
)(
bind_req
->
pairs
->
value
));
break
;
break
;
case
VALUE_STRING
:
case
VALUE_STRING
:
rc
=
sqlite3_bind_text
(
sto
->
stmt_
,
index
,
(
char
*
)(
bind_req
->
value
),
rc
=
sqlite3_bind_text
(
sto
->
stmt_
,
index
,
(
char
*
)(
bind_req
->
pairs
->
value
),
bind_req
->
value_size
,
SQLITE_TRANSIENT
);
bind_req
->
pairs
->
value_size
,
SQLITE_TRANSIENT
);
break
;
break
;
case
VALUE_NULL
:
case
VALUE_NULL
:
rc
=
sqlite3_bind_null
(
sto
->
stmt_
,
index
);
rc
=
sqlite3_bind_null
(
sto
->
stmt_
,
index
);
...
@@ -136,6 +235,98 @@ int Statement::EIO_Bind(eio_req *req) {
...
@@ -136,6 +235,98 @@ int Statement::EIO_Bind(eio_req *req) {
return
0
;
return
0
;
}
}
// db.prepare "SELECT $x, ?" -> statement
//
// Bind multiple placeholders by array
// statement.bind([ value0, value1 ], callback);
//
// Bind multiple placeholdders by name
// statement.bind({ $x: value }, callback);
//
// Bind single placeholder by name:
// statement.bind('$x', value, callback);
//
// Bind placeholder by index:
// statement.bind(1, value, callback);
Handle
<
Value
>
Statement
::
BindArray
(
const
Arguments
&
args
)
{
HandleScope
scope
;
Statement
*
sto
=
ObjectWrap
::
Unwrap
<
Statement
>
(
args
.
This
());
REQ_ARGS
(
2
);
REQ_FUN_ARG
(
1
,
cb
);
if
(
!
args
[
0
]
->
IsArray
())
return
ThrowException
(
Exception
::
TypeError
(
String
::
New
(
"First argument must be an Array."
)));
struct
bind_request
*
bind_req
=
(
struct
bind_request
*
)
calloc
(
1
,
sizeof
(
struct
bind_request
));
Local
<
Array
>
array
=
Local
<
Array
>::
Cast
(
args
[
0
]);
int
len
=
bind_req
->
len
=
array
->
Length
();
bind_req
->
pairs
=
(
struct
bind_pair
*
)
calloc
(
len
,
sizeof
(
struct
bind_pair
));
struct
bind_pair
*
pairs
=
bind_req
->
pairs
;
// pack the binds into the struct
for
(
int
i
=
0
;
i
<
len
;
i
++
,
pairs
++
)
{
Local
<
Value
>
val
=
array
->
Get
(
i
);
// setting key type
pairs
->
key_type
=
KEY_INT
;
int
*
index
=
(
int
*
)
malloc
(
sizeof
(
int
));
*
index
=
i
+
1
;
pairs
->
value_size
=
sizeof
(
int
);
// don't forget to `free` this
pairs
->
key
=
index
;
// setup value
if
(
val
->
IsInt32
())
{
pairs
->
value_type
=
VALUE_INT
;
int
*
value
=
(
int
*
)
malloc
(
sizeof
(
int
));
*
value
=
val
->
Int32Value
();
pairs
->
value
=
value
;
}
else
if
(
val
->
IsNumber
())
{
pairs
->
value_type
=
VALUE_DOUBLE
;
double
*
value
=
(
double
*
)
malloc
(
sizeof
(
double
));
*
value
=
val
->
NumberValue
();
pairs
->
value
=
value
;
}
else
if
(
val
->
IsString
())
{
pairs
->
value_type
=
VALUE_STRING
;
String
::
Utf8Value
text
(
val
);
char
*
value
=
(
char
*
)
calloc
(
text
.
length
()
+
1
,
sizeof
(
char
*
));
strcpy
(
value
,
*
text
);
pairs
->
value
=
value
;
pairs
->
value_size
=
text
.
length
()
+
1
;
}
else
if
(
val
->
IsNull
()
||
val
->
IsUndefined
())
{
pairs
->
value_type
=
VALUE_NULL
;
pairs
->
value
=
NULL
;
}
else
{
free
(
pairs
->
key
);
return
ThrowException
(
Exception
::
TypeError
(
String
::
New
(
"Unable to bind value of this type"
)));
}
}
bind_req
->
cb
=
Persistent
<
Function
>::
New
(
cb
);
bind_req
->
sto
=
sto
;
eio_custom
(
EIO_BindArray
,
EIO_PRI_DEFAULT
,
EIO_AfterBindArray
,
bind_req
);
ev_ref
(
EV_DEFAULT_UC
);
return
Undefined
();
}
Handle
<
Value
>
Statement
::
Bind
(
const
Arguments
&
args
)
{
Handle
<
Value
>
Statement
::
Bind
(
const
Arguments
&
args
)
{
HandleScope
scope
;
HandleScope
scope
;
Statement
*
sto
=
ObjectWrap
::
Unwrap
<
Statement
>
(
args
.
This
());
Statement
*
sto
=
ObjectWrap
::
Unwrap
<
Statement
>
(
args
.
This
());
...
@@ -143,61 +334,67 @@ Handle<Value> Statement::Bind(const Arguments& args) {
...
@@ -143,61 +334,67 @@ Handle<Value> Statement::Bind(const Arguments& args) {
REQ_ARGS
(
2
);
REQ_ARGS
(
2
);
REQ_FUN_ARG
(
2
,
cb
);
REQ_FUN_ARG
(
2
,
cb
);
if
(
!
args
[
0
]
->
IsString
()
&&
!
args
[
0
]
->
IsInt32
())
if
(
!
(
args
[
0
]
->
IsString
()
||
args
[
0
]
->
IsInt32
()
||
args
[
0
]
->
IsArray
()
||
args
[
0
]
->
IsObject
()))
return
ThrowException
(
Exception
::
TypeError
(
return
ThrowException
(
Exception
::
TypeError
(
String
::
New
(
"First argument must be a string
or integer
"
)));
String
::
New
(
"First argument must be a string
, number, array or object.
"
)));
struct
bind_request
*
bind_req
=
(
struct
bind_request
*
)
struct
bind_request
*
bind_req
=
(
struct
bind_request
*
)
calloc
(
1
,
sizeof
(
struct
bind_request
));
calloc
(
1
,
sizeof
(
struct
bind_request
));
bind_req
->
pairs
=
(
struct
bind_pair
*
)
calloc
(
1
,
sizeof
(
struct
bind_pair
));
// setup key
// setup key
if
(
args
[
0
]
->
IsString
())
{
if
(
args
[
0
]
->
IsString
())
{
String
::
Utf8Value
keyValue
(
args
[
0
]);
String
::
Utf8Value
keyValue
(
args
[
0
]);
bind_req
->
key_type
=
KEY_STRING
;
bind_req
->
pairs
->
key_type
=
KEY_STRING
;
char
*
key
=
(
char
*
)
calloc
(
1
,
keyValue
.
length
()
+
1
);
char
*
key
=
(
char
*
)
calloc
(
1
,
keyValue
.
length
()
+
1
);
bind_req
->
value_size
=
keyValue
.
length
()
+
1
;
bind_req
->
pairs
->
value_size
=
keyValue
.
length
()
+
1
;
strcpy
(
key
,
*
keyValue
);
strcpy
(
key
,
*
keyValue
);
bind_req
->
key
=
key
;
bind_req
->
pairs
->
key
=
key
;
}
}
else
if
(
args
[
0
]
->
IsInt32
())
{
else
if
(
args
[
0
]
->
IsInt32
())
{
bind_req
->
key_type
=
KEY_INT
;
bind_req
->
pairs
->
key_type
=
KEY_INT
;
int
*
index
=
(
int
*
)
malloc
(
sizeof
(
int
));
int
*
index
=
(
int
*
)
malloc
(
sizeof
(
int
));
*
index
=
args
[
0
]
->
Int32Value
();
*
index
=
args
[
0
]
->
Int32Value
();
bind_req
->
value_size
=
sizeof
(
int
);
bind_req
->
pairs
->
value_size
=
sizeof
(
int
);
// don't forget to `free` this
// don't forget to `free` this
bind_req
->
key
=
index
;
bind_req
->
pairs
->
key
=
index
;
}
}
// setup value
// setup value
if
(
args
[
1
]
->
IsInt32
())
{
if
(
args
[
1
]
->
IsInt32
())
{
bind_req
->
value_type
=
VALUE_INT
;
bind_req
->
pairs
->
value_type
=
VALUE_INT
;
int
*
value
=
(
int
*
)
malloc
(
sizeof
(
int
));
int
*
value
=
(
int
*
)
malloc
(
sizeof
(
int
));
*
value
=
args
[
1
]
->
Int32Value
();
*
value
=
args
[
1
]
->
Int32Value
();
bind_req
->
value
=
value
;
bind_req
->
pairs
->
value
=
value
;
}
}
else
if
(
args
[
1
]
->
IsNumber
())
{
else
if
(
args
[
1
]
->
IsNumber
())
{
bind_req
->
value_type
=
VALUE_DOUBLE
;
bind_req
->
pairs
->
value_type
=
VALUE_DOUBLE
;
double
*
value
=
(
double
*
)
malloc
(
sizeof
(
double
));
double
*
value
=
(
double
*
)
malloc
(
sizeof
(
double
));
*
value
=
args
[
1
]
->
NumberValue
();
*
value
=
args
[
1
]
->
NumberValue
();
bind_req
->
value
=
value
;
bind_req
->
pairs
->
value
=
value
;
}
}
else
if
(
args
[
1
]
->
IsString
())
{
else
if
(
args
[
1
]
->
IsString
())
{
bind_req
->
value_type
=
VALUE_STRING
;
bind_req
->
pairs
->
value_type
=
VALUE_STRING
;
String
::
Utf8Value
text
(
args
[
1
]);
String
::
Utf8Value
text
(
args
[
1
]);
char
*
value
=
(
char
*
)
calloc
(
text
.
length
()
+
1
,
sizeof
(
char
*
));
char
*
value
=
(
char
*
)
calloc
(
text
.
length
()
+
1
,
sizeof
(
char
*
));
strcpy
(
value
,
*
text
);
strcpy
(
value
,
*
text
);
bind_req
->
value
=
value
;
bind_req
->
pairs
->
value
=
value
;
bind_req
->
value_size
=
text
.
length
()
+
1
;
bind_req
->
pairs
->
value_size
=
text
.
length
()
+
1
;
}
}
else
if
(
args
[
1
]
->
IsNull
()
||
args
[
1
]
->
IsUndefined
())
{
else
if
(
args
[
1
]
->
IsNull
()
||
args
[
1
]
->
IsUndefined
())
{
bind_req
->
value_type
=
VALUE_NULL
;
bind_req
->
pairs
->
value_type
=
VALUE_NULL
;
bind_req
->
value
=
NULL
;
bind_req
->
pairs
->
value
=
NULL
;
}
}
else
{
else
{
free
(
bind_req
->
key
);
free
(
bind_req
->
pairs
->
key
);
return
ThrowException
(
Exception
::
TypeError
(
return
ThrowException
(
Exception
::
TypeError
(
String
::
New
(
"Unable to bind value of this type"
)));
String
::
New
(
"Unable to bind value of this type"
)));
}
}
...
@@ -263,9 +460,17 @@ Handle<Value> Statement::Finalize(const Arguments& args) {
...
@@ -263,9 +460,17 @@ Handle<Value> Statement::Finalize(const Arguments& args) {
return
Undefined
();
return
Undefined
();
}
}
Handle
<
Value
>
Statement
::
ClearBindings
(
const
Arguments
&
args
)
{
HandleScope
scope
;
Statement
*
sto
=
ObjectWrap
::
Unwrap
<
Statement
>
(
args
.
This
());
SCHECK
(
sqlite3_clear_bindings
(
sto
->
stmt_
));
return
Undefined
();
}
Handle
<
Value
>
Statement
::
Reset
(
const
Arguments
&
args
)
{
Handle
<
Value
>
Statement
::
Reset
(
const
Arguments
&
args
)
{
HandleScope
scope
;
HandleScope
scope
;
Statement
*
sto
=
ObjectWrap
::
Unwrap
<
Statement
>
(
args
.
This
());
Statement
*
sto
=
ObjectWrap
::
Unwrap
<
Statement
>
(
args
.
This
());
sto
->
FreeColumnData
();
SCHECK
(
sqlite3_reset
(
sto
->
stmt_
));
SCHECK
(
sqlite3_reset
(
sto
->
stmt_
));
return
Undefined
();
return
Undefined
();
}
}
...
@@ -295,29 +500,34 @@ int Statement::EIO_AfterStep(eio_req *req) {
...
@@ -295,29 +500,34 @@ int Statement::EIO_AfterStep(eio_req *req) {
for
(
int
i
=
0
;
i
<
sto
->
column_count_
;
i
++
)
{
for
(
int
i
=
0
;
i
<
sto
->
column_count_
;
i
++
)
{
assert
(
sto
->
column_data_
);
assert
(
sto
->
column_data_
);
assert
(((
void
**
)
sto
->
column_data_
)[
i
]);
if
(((
int
*
)
sto
->
column_types_
)[
i
]
!=
SQLITE_NULL
)
assert
(((
void
**
)
sto
->
column_data_
)[
i
]);
assert
(
sto
->
column_names_
[
i
]);
assert
(
sto
->
column_names_
[
i
]);
assert
(
sto
->
column_types_
[
i
]);
assert
(
sto
->
column_types_
[
i
]);
switch
(
sto
->
column_types_
[
i
])
{
switch
(
sto
->
column_types_
[
i
])
{
// XXX why does using String::New make v8 croak here?
case
SQLITE_INTEGER
:
case
SQLITE_INTEGER
:
row
->
Set
(
String
::
NewSymbol
((
char
*
)
sto
->
column_names_
[
i
]),
row
->
Set
(
String
::
NewSymbol
((
char
*
)
sto
->
column_names_
[
i
]),
Int32
::
New
(
*
(
int
*
)
(
sto
->
column_data_
[
i
])));
Int32
::
New
(
*
(
int
*
)
(
sto
->
column_data_
[
i
])));
break
;
break
;
case
SQLITE_FLOAT
:
case
SQLITE_FLOAT
:
row
->
Set
(
String
::
New
(
sto
->
column_names_
[
i
]),
row
->
Set
(
String
::
New
Symbol
(
sto
->
column_names_
[
i
]),
Number
::
New
(
*
(
double
*
)
(
sto
->
column_data_
[
i
])));
Number
::
New
(
*
(
double
*
)
(
sto
->
column_data_
[
i
])));
break
;
break
;
case
SQLITE_TEXT
:
case
SQLITE_TEXT
:
assert
(
strlen
((
char
*
)
sto
->
column_data_
[
i
]));
assert
(
strlen
((
char
*
)
sto
->
column_data_
[
i
]));
row
->
Set
(
String
::
New
(
sto
->
column_names_
[
i
]),
row
->
Set
(
String
::
New
Symbol
(
sto
->
column_names_
[
i
]),
String
::
New
((
char
*
)
(
sto
->
column_data_
[
i
])));
String
::
New
((
char
*
)
(
sto
->
column_data_
[
i
])));
// don't free this pointer, it's owned by sqlite3
// don't free this pointer, it's owned by sqlite3
break
;
break
;
case
SQLITE_NULL
:
row
->
Set
(
String
::
New
(
sto
->
column_names_
[
i
]),
Local
<
Value
>::
New
(
Null
()));
break
;
// no default
// no default
}
}
}
}
...
@@ -355,8 +565,12 @@ void Statement::FreeColumnData(void) {
...
@@ -355,8 +565,12 @@ void Statement::FreeColumnData(void) {
}
}
column_data_
[
i
]
=
NULL
;
column_data_
[
i
]
=
NULL
;
}
}
free
(
column_names_
);
free
(
column_types_
);
free
(
column_data_
);
free
(
column_data_
);
column_count_
=
0
;
column_types_
=
NULL
;
column_names_
=
NULL
;
column_data_
=
NULL
;
column_data_
=
NULL
;
}
}
...
@@ -397,25 +611,31 @@ int Statement::EIO_Step(eio_req *req) {
...
@@ -397,25 +611,31 @@ int Statement::EIO_Step(eio_req *req) {
sto
->
column_data_
=
(
void
**
)
calloc
(
sto
->
column_count_
,
sto
->
column_data_
=
(
void
**
)
calloc
(
sto
->
column_count_
,
sizeof
(
void
*
));
sizeof
(
void
*
));
}
}
}
for
(
int
i
=
0
;
i
<
sto
->
column_count_
;
i
++
)
{
for
(
int
i
=
0
;
i
<
sto
->
column_count_
;
i
++
)
{
sto
->
column_types_
[
i
]
=
sqlite3_column_type
(
stmt
,
i
);
sto
->
column_types_
[
i
]
=
sqlite3_column_type
(
stmt
,
i
);
sto
->
column_names_
[
i
]
=
(
char
*
)
sqlite3_column_name
(
stmt
,
i
);
switch
(
sto
->
column_types_
[
i
])
{
// Don't free this!
case
SQLITE_INTEGER
:
sto
->
column_names_
[
i
]
=
(
char
*
)
sqlite3_column_name
(
stmt
,
i
);
sto
->
column_data_
[
i
]
=
(
int
*
)
malloc
(
sizeof
(
int
));
break
;
case
SQLITE_FLOAT
:
switch
(
sto
->
column_types_
[
i
])
{
sto
->
column_data_
[
i
]
=
(
double
*
)
malloc
(
sizeof
(
double
));
case
SQLITE_INTEGER
:
break
;
sto
->
column_data_
[
i
]
=
(
int
*
)
malloc
(
sizeof
(
int
));
break
;
// no need to allocate memory for strings
case
SQLITE_FLOAT
:
sto
->
column_data_
[
i
]
=
(
double
*
)
malloc
(
sizeof
(
double
));
break
;
default
:
{
case
SQLITE_NULL
:
// unsupported type
sto
->
column_data_
[
i
]
=
NULL
;
}
break
;
// no need to allocate memory for strings
default
:
{
// unsupported type
}
}
}
}
}
}
...
@@ -426,7 +646,7 @@ int Statement::EIO_Step(eio_req *req) {
...
@@ -426,7 +646,7 @@ int Statement::EIO_Step(eio_req *req) {
int
type
=
sto
->
column_types_
[
i
];
int
type
=
sto
->
column_types_
[
i
];
switch
(
type
)
{
switch
(
type
)
{
case
SQLITE_INTEGER
:
case
SQLITE_INTEGER
:
*
(
int
*
)(
sto
->
column_data_
[
i
])
=
sqlite3_column_int
(
stmt
,
i
);
*
(
int
*
)(
sto
->
column_data_
[
i
])
=
sqlite3_column_int
(
stmt
,
i
);
assert
(
sto
->
column_data_
[
i
]);
assert
(
sto
->
column_data_
[
i
]);
break
;
break
;
...
@@ -445,11 +665,16 @@ int Statement::EIO_Step(eio_req *req) {
...
@@ -445,11 +665,16 @@ int Statement::EIO_Step(eio_req *req) {
}
}
break
;
break
;
case
SQLITE_NULL
:
sto
->
column_data_
[
i
]
=
NULL
;
break
;
default
:
{
default
:
{
assert
(
0
&&
"unsupported type"
);
assert
(
0
&&
"unsupported type"
);
}
}
}
}
assert
(
sto
->
column_data_
[
i
]);
if
(
sto
->
column_types_
[
i
]
!=
SQLITE_NULL
)
assert
(
sto
->
column_data_
[
i
]);
assert
(
sto
->
column_names_
[
i
]);
assert
(
sto
->
column_names_
[
i
]);
assert
(
sto
->
column_types_
[
i
]);
assert
(
sto
->
column_types_
[
i
]);
}
}
...
...
src/statement.h
View file @
27106877
...
@@ -53,12 +53,17 @@ class Statement : public EventEmitter {
...
@@ -53,12 +53,17 @@ class Statement : public EventEmitter {
static
int
EIO_AfterBind
(
eio_req
*
req
);
static
int
EIO_AfterBind
(
eio_req
*
req
);
static
int
EIO_Bind
(
eio_req
*
req
);
static
int
EIO_Bind
(
eio_req
*
req
);
static
Handle
<
Value
>
Bind
(
const
Arguments
&
args
);
static
Handle
<
Value
>
Bind
(
const
Arguments
&
args
);
static
int
EIO_AfterBindArray
(
eio_req
*
req
);
static
int
EIO_BindArray
(
eio_req
*
req
);
static
Handle
<
Value
>
BindArray
(
const
Arguments
&
args
);
static
int
EIO_AfterFinalize
(
eio_req
*
req
);
static
int
EIO_AfterFinalize
(
eio_req
*
req
);
static
int
EIO_Finalize
(
eio_req
*
req
);
static
int
EIO_Finalize
(
eio_req
*
req
);
static
Handle
<
Value
>
Finalize
(
const
Arguments
&
args
);
static
Handle
<
Value
>
Finalize
(
const
Arguments
&
args
);
static
Handle
<
Value
>
Reset
(
const
Arguments
&
args
);
static
Handle
<
Value
>
Reset
(
const
Arguments
&
args
);
static
Handle
<
Value
>
ClearBindings
(
const
Arguments
&
args
);
static
int
EIO_AfterStep
(
eio_req
*
req
);
static
int
EIO_AfterStep
(
eio_req
*
req
);
static
int
EIO_Step
(
eio_req
*
req
);
static
int
EIO_Step
(
eio_req
*
req
);
...
@@ -100,6 +105,11 @@ struct bind_request {
...
@@ -100,6 +105,11 @@ struct bind_request {
Persistent
<
Function
>
cb
;
Persistent
<
Function
>
cb
;
Statement
*
sto
;
Statement
*
sto
;
struct
bind_pair
*
pairs
;
size_t
len
;
};
struct
bind_pair
{
enum
BindKeyType
key_type
;
enum
BindKeyType
key_type
;
enum
BindValueType
value_type
;
enum
BindValueType
value_type
;
...
...
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