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
eaf72f23
Commit
eaf72f23
authored
Feb 17, 2011
by
Konstantin Käfer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
saving work
parent
c09549d0
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
90 additions
and
458 deletions
+90
-458
sqlite3.js
lib/sqlite3.js
+10
-262
database.cc
src/database.cc
+0
-0
database.h
src/database.h
+46
-62
macros.h
src/macros.h
+9
-20
statement.cc
src/statement.cc
+0
-0
statement.h
src/statement.h
+25
-114
No files found.
lib/sqlite3.js
View file @
eaf72f23
...
...
@@ -16,273 +16,22 @@
var
sqlite3
=
module
.
exports
=
exports
=
require
(
'./sqlite3_bindings'
);
var
sys
=
require
(
"sys"
);
function
noop
(
err
)
{
if
(
err
)
throw
err
;
};
var
Database
=
sqlite3
.
Database
;
// var realClose = Database.prototype.close;
// sqlite3.Database.prototype.close = function(callback) {
// if (this.status === sqlite3.STATUS_IDLE) {
// return realClose.call(this, callback);
// } else {
// this.once('idle', function() {
// realClose.call(this, callback);
// });
// }
// function noop(err) {
// if (err) throw err;
// };
// var realClose = sqlite3.Database.prototype.close;
// sqlite3.Database.prototype.close = function() {
// var db = this;
// process.nextTick(function() {
// if (!db.idle) {
// db.on('idle', function fn() {
// realClose.call(db);
// db.removeListener('idle', fn);
// });
// } else {
// realClose.call(db);
// }
// });
// return this;
// };
/*
sqlite3.Database.prototype.query = function(sql, bindings, rowCallback) {
var self = this;
if (typeof(bindings) == "function") {
rowCallback = bindings;
bindings = undefined;
}
this.prepare(sql, function(error, statement) {
function next() {
_doStep(self, statement, rowCallback);
}
if (error) {
return rowCallback (error);
}
if (statement) {
if (Array.isArray(bindings)) {
statement.bindArray(bindings, next);
}
else if (typeof(bindings) === 'object') {
statement.bindObject(bindings, next);
}
else {
next();
}
}
else {
rowCallback();
}
});
}
function _doStep(db, statement, rowCallback) {
statement.step(function (error, row) {
if (error) {
return rowCallback(error);
}
if (!row) {
rowCallback();
statement.finalize(function(){});
return;
}
rowCallback(undefined, row);
_doStep(db, statement, rowCallback);
});
}
// Execute a single SQL query with the given optional parameters. Calls
// `callback` with all rows or an error on query completion.
sqlite3.Database.prototype.execute = function (sql /* , bindings, callback ) {
var self = this;
var bindings, callback;
var n = arguments.length;
var
Database
=
sqlite3
.
Database
;
var
Statement
=
sqlite3
.
Statement
;
switch (n) {
case 3:
callback = arguments[2];
bindings = arguments[1];
break;
case 2:
callback = arguments[1];
break;
default: throw new Error("Invalid number of arguments ("+n+")");
}
self.prepare(sql, function (error, statement) {
function next (error) {
if (error) return callback(new Error("Error binding: " + error.toString()));
fetchAll(statement);
}
// Database#prepare(sql, [bind1, bind2, ...], [callback])
Database
.
prototype
.
prepare
=
function
(
sql
)
{
var
callback
,
params
=
Array
.
prototype
.
slice
.
call
(
arguments
,
1
);
if (
error
) {
return callback(error
);
if
(
params
.
length
&&
typeof
params
[
params
.
length
-
1
]
===
'function'
)
{
callback
=
params
.
pop
(
);
}
if (bindings) {
if (Array.isArray(bindings)) {
statement.bindArray(bindings, next);
}
else if (typeof(bindings) === 'object') {
statement.bindObject(bindings, next);
}
}
else {
next();
}
function fetchAll(statement) {
statement.fetchAll(function (error, rows) {
if (error) {
return callback(error);
}
statement.finalize(function () {
callback(undefined, rows);
});
});
}
});
}
// Execute SQL statements separated by semi-colons.
// SQL must contain no placeholders. Results are discarded.
sqlite3.Database.prototype.executeScript = function (script, callback) {
var self = this;
(function stepOverSQL(sql) {
self.prepare(sql, function(error, statement) {
if (error) {
return callback(error);
}
statement.step(function (error, row) {
var tail;
if (error) {
callback(error);
return;
}
if (!row) {
statement.finalize(function(){});
tail = statement.tail;
if (typeof tail == "string") {
tail = tail.trim();
}
if (tail) {
stepOverSQL(tail);
}
else {
callback();
}
}
});
});
})(script);
}
sqlite3.Database.prototype.insertMany = function (table, columns, rows, callback) {
var columnsFragment = columns.join(",");
var placeholdersFragment = [];
var i = columns.length;
if (!rows.length) {
callback();
return;
}
while (i--) {
placeholdersFragment.push('?');
}
placeholdersFragment = placeholdersFragment.join(", ");
var sql = [ 'INSERT INTO'
, table
, '('
, columnsFragment
, ')'
, 'VALUES'
, '('
, placeholdersFragment
, ')'
]
.join(" ");
var i = rows.length;
var statement;
function doStep(i) {
statement.bindArray(rows[i], function () {
statement.step(function (error, row) {
if (error) return callback(error);
statement.reset();
if (i) {
doStep(--i);
}
else {
statement.finalize(function () {
callback();
});
}
});
});
}
this.prepare(sql, function (error, stmt) {
if (error) return callback(error);
statement = stmt;
doStep(--i);
});
}
sqlite3.fromErrorCode = function(code) {
switch (code) {
case 0: return "SQLITE_OK";
case 1: return "SQLITE_ERROR";
case 2: return "SQLITE_INTERNAL";
case 3: return "SQLITE_PERM";
case 4: return "SQLITE_ABORT";
case 5: return "SQLITE_BUSY";
case 6: return "SQLITE_LOCKED";
case 7: return "SQLITE_NOMEM";
case 8: return "SQLITE_READONLY";
case 9: return "SQLITE_INTERRUPT";
case 10: return "SQLITE_IOERR";
case 11: return "SQLITE_CORRUPT";
case 12: return "SQLITE_NOTFOUND";
case 13: return "SQLITE_FULL";
case 14: return "SQLITE_CANTOPEN";
case 15: return "SQLITE_PROTOCOL";
case 16: return "SQLITE_EMPTY";
case 17: return "SQLITE_SCHEMA";
case 18: return "SQLITE_TOOBIG";
case 19: return "SQLITE_CONSTRAINT";
case 20: return "SQLITE_MISMATCH";
case 21: return "SQLITE_MISUSE";
case 22: return "SQLITE_NOLFS";
case 23: return "SQLITE_AUTH";
case 24: return "SQLITE_FORMAT";
case 25: return "SQLITE_RANGE";
case 26: return "SQLITE_NOTADB";
}
return
new
Statement
(
this
,
sql
,
params
,
callback
);
};
sqlite3.sanitizeError = function(err, data) {
err.message = exports.fromErrorCode(err.errno) + ', ' + err.message +
' in query "' + err.query +
'" with values ' + JSON.stringify(data, false, 4);
return err;
};
*/
\ No newline at end of file
src/database.cc
View file @
eaf72f23
This diff is collapsed.
Click to expand it.
src/database.h
View file @
eaf72f23
...
...
@@ -19,8 +19,6 @@
#include <node.h>
#include <node_events.h>
#include "deferred_call.h"
#include <string>
#include <queue>
...
...
@@ -29,34 +27,52 @@
using
namespace
v8
;
using
namespace
node
;
class
Database
;
static
struct
Baton
{
Database
*
db
;
Persistent
<
Function
>
callback
;
int
status
;
std
::
string
message
;
~
Baton
()
{
callback
.
Dispose
();
}
};
static
struct
OpenBaton
:
Baton
{
std
::
string
filename
;
int
mode
;
};
class
Database
:
public
EventEmitter
{
public
:
public
:
static
Persistent
<
FunctionTemplate
>
constructor_template
;
static
void
Init
(
v8
::
Handle
<
Object
>
target
);
static
enum
Status
{
IsClosed
=
1
<<
0
,
IsOpening
=
1
<<
1
,
IsOpen
=
1
<<
2
,
IsClosing
=
1
<<
3
,
DoesntMatter
=
IsClosed
|
IsOpening
|
IsOpen
|
IsClosing
};
static
inline
bool
HasInstance
(
Handle
<
Value
>
val
)
{
if
(
!
val
->
IsObject
())
return
false
;
Local
<
Object
>
obj
=
val
->
ToObject
();
return
constructor_template
->
HasInstance
(
obj
);
}
typedef
Deferred
::
Call
<
Status
>
Call
;
typedef
void
(
*
EIO_Callback
)(
Baton
*
baton
)
;
struct
Baton
{
Baton
(
Database
*
db_
,
Persistent
<
Function
>
callback_
)
:
db
(
db_
),
callback
(
callback_
)
{};
Database
*
db
;
Persistent
<
Function
>
callback
;
struct
Call
{
Call
(
EIO_Callback
callback_
,
Baton
*
baton_
,
bool
exclusive_
=
false
)
:
callback
(
callback_
),
exclusive
(
exclusive_
),
baton
(
baton_
)
{};
EIO_Callback
callback
;
bool
exclusive
;
Baton
*
baton
;
};
friend
class
Statement
;
protected
:
protected
:
Database
()
:
EventEmitter
(),
handle
(
NULL
),
pending
(
0
),
status
(
IsClosed
)
{
open
(
false
),
locked
(
false
),
pending
(
0
)
{
}
...
...
@@ -65,64 +81,32 @@ class Database : public EventEmitter {
}
static
Handle
<
Value
>
New
(
const
Arguments
&
args
);
static
void
ProcessQueue
(
Database
*
db
);
static
Handle
<
Value
>
OpenSync
(
const
Arguments
&
args
);
static
Handle
<
Value
>
Open
(
const
Arguments
&
args
);
static
bool
Open
(
Database
*
db
);
static
void
EIO_BeginOpen
(
Baton
*
baton
);
static
int
EIO_Open
(
eio_req
*
req
);
static
int
EIO_AfterOpen
(
eio_req
*
req
);
static
Handle
<
Value
>
CloseSync
(
const
Arguments
&
args
);
static
void
Schedule
(
Database
*
db
,
EIO_Callback
callback
,
Baton
*
baton
,
bool
exclusive
);
static
void
Process
(
Database
*
db
);
static
Handle
<
Value
>
Close
(
const
Arguments
&
args
);
static
bool
Close
(
Database
*
db
);
static
void
EIO_BeginClose
(
Baton
*
baton
);
static
int
EIO_Close
(
eio_req
*
req
);
static
int
EIO_AfterClose
(
eio_req
*
req
);
static
int
EIO_AfterPrepareAndStep
(
eio_req
*
req
);
static
int
EIO_PrepareAndStep
(
eio_req
*
req
);
static
Handle
<
Value
>
PrepareAndStep
(
const
Arguments
&
args
);
static
int
EIO_AfterPrepare
(
eio_req
*
req
);
static
int
EIO_Prepare
(
eio_req
*
req
);
static
Handle
<
Value
>
Prepare
(
const
Arguments
&
args
);
void
Wrap
(
Handle
<
Object
>
handle
);
static
void
Destruct
(
Persistent
<
Value
>
value
,
void
*
data
);
static
int
EIO_Destruct
(
eio_req
*
req
);
static
int
EIO_AfterDestruct
(
eio_req
*
req
);
protected
:
protected
:
sqlite3
*
handle
;
std
::
string
filename
;
int
open_mode
;
std
::
string
error_message
;
int
error_status
;
bool
open
;
bool
locked
;
unsigned
int
pending
;
int
pending
;
Status
status
;
std
::
queue
<
Call
*>
queue
;
private
:
};
enum
ExecMode
{
EXEC_EMPTY
=
0
,
EXEC_LAST_INSERT_ID
=
1
,
EXEC_AFFECTED_ROWS
=
2
};
struct
prepare_request
{
Persistent
<
Function
>
cb
;
Database
*
db
;
sqlite3_stmt
*
stmt
;
int
mode
;
sqlite3_int64
lastInsertId
;
int
affectedRows
;
const
char
*
tail
;
char
sql
[
1
];
};
#endif
src/macros.h
View file @
eaf72f23
...
...
@@ -121,7 +121,7 @@ const char* sqlite_code_string(int code);
String::NewSymbol(sqlite_code_string(errno)), \
String::NewSymbol(": ") \
), \
String::New(msg)
\
(msg)
\
) \
); \
Local<Object> name ##_obj = name->ToObject(); \
...
...
@@ -129,30 +129,19 @@ const char* sqlite_code_string(int code);
name ##_obj->Set(NODE_PSYMBOL("code"), \
String::NewSymbol(sqlite_code_string(errno)));
#define EVENT_ONCE(event, callback) \
Local<Value> argv[2] = { \
String::NewSymbol(event), \
args.This()->Get(String::NewSymbol(callback)) \
}; \
v8::Local<v8::Value> fn_val = args.This()->Get(String::NewSymbol("once")); \
Local<Function> fn = Local<Function>::Cast(fn_val); \
fn->Call(args.This(), 2, argv);
#define SET_STRING(sym, str) \
Set(String::NewSymbol(#sym), String::New(str), ReadOnly)
#define SET_INTEGER(sym, i) \
Set(String::NewSymbol(#sym), Integer::New(i), ReadOnly)
#define EMIT_EVENT(obj, argc, argv) \
TRY_CATCH_CALL((obj), \
Local<Function>::Cast((obj)->Get(String::NewSymbol("emit"))), \
argc, argv \
);
#define TRY_CATCH_CALL(context, callback, argc, argv) \
{ \
TryCatch try_catch; \
{ TryCatch try_catch; \
(callback)->Call((context), (argc), (argv)); \
if (try_catch.HasCaught()) { \
FatalException(try_catch); \
} \
}
} }
#endif
src/statement.cc
View file @
eaf72f23
This diff is collapsed.
Click to expand it.
src/statement.h
View file @
eaf72f23
// Copyright (c) 2010, Orlando Vazquez <ovazquez@gmail.com>
//
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
...
...
@@ -18,139 +18,50 @@
#include <v8.h>
#include <node.h>
#include <node_events.h>
#include <sqlite3.h>
#include <stdlib.h>
#include <node_buffer.h>
extern
"C"
{
#include <mpool.h>
};
#include "database.h"
#include <string>
#include <queue>
#include <sqlite3.h>
using
namespace
v8
;
using
namespace
node
;
struct
cell_node
{
void
*
value
;
int
type
;
struct
cell_node
*
next
;
int
size
;
};
class
Statement
;
st
ruct
row_node
{
struct
cell_node
*
cells
;
struct
row_node
*
next
;
st
atic
struct
PrepareBaton
:
Baton
{
Statement
*
stmt
;
std
::
string
sql
;
};
// represent strings with this struct
struct
string_t
{
size_t
bytes
;
char
data
[];
};
class
Statement
:
public
EventEmitter
{
public
:
public
:
static
Persistent
<
FunctionTemplate
>
constructor_template
;
static
void
Init
(
v8
::
Handle
<
Object
>
target
);
static
void
Init
(
Handle
<
Object
>
target
);
static
Handle
<
Value
>
New
(
const
Arguments
&
args
);
protected
:
Statement
(
sqlite3_stmt
*
stmt
,
int
first_rc
=
-
1
,
int
mode
=
0
)
:
EventEmitter
(),
first_rc_
(
first_rc
),
mode_
(
mode
),
stmt_
(
stmt
)
{
column_count_
=
-
1
;
column_names_
=
NULL
;
Statement
(
Database
*
db_
)
:
EventEmitter
()
{
db
=
db_
;
db
->
Ref
();
}
~
Statement
()
{
if
(
stmt_
)
sqlite3_finalize
(
stmt_
);
if
(
column_names_
)
FreeColumnData
();
db
->
Unref
();
}
static
Handle
<
Value
>
Bind
(
const
Arguments
&
args
);
static
Handle
<
Value
>
BindObject
(
const
Arguments
&
args
);
static
Handle
<
Value
>
BindArray
(
const
Arguments
&
args
);
static
int
EIO_BindArray
(
eio_req
*
req
);
static
int
EIO_AfterBindArray
(
eio_req
*
req
);
static
int
EIO_AfterFinalize
(
eio_req
*
req
);
static
int
EIO_Finalize
(
eio_req
*
req
);
static
Handle
<
Value
>
Finalize
(
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_Step
(
eio_req
*
req
);
static
Handle
<
Value
>
Step
(
const
Arguments
&
args
);
static
int
EIO_AfterFetchAll
(
eio_req
*
req
);
static
int
EIO_FetchAll
(
eio_req
*
req
);
static
Handle
<
Value
>
FetchAll
(
const
Arguments
&
args
);
void
InitializeColumns
(
void
);
void
FreeColumnData
(
void
);
bool
HasCallback
();
void
SetCallback
(
Local
<
Function
>
cb
);
protected
:
static
void
EIO_BeginPrepare
(
Baton
*
baton
);
static
int
EIO_Prepare
(
eio_req
*
req
);
static
int
EIO_AfterPrepare
(
eio_req
*
req
);
Local
<
Function
>
GetCallback
();
private
:
int
column_count_
;
char
**
column_names_
;
int
error_
;
Local
<
String
>
error_msg_
;
int
first_rc_
;
int
mode_
;
sqlite3_stmt
*
stmt_
;
// for statment.step
cell_node
*
cells
;
};
// indicates the key type (integer index or name string)
enum
BindKeyType
{
KEY_INT
,
KEY_STRING
};
// indicate the parameter type
enum
BindValueType
{
VALUE_INT
,
VALUE_DOUBLE
,
VALUE_BLOB
,
VALUE_STRING
,
VALUE_NULL
};
struct
bind_request
{
Persistent
<
Function
>
cb
;
Statement
*
sto
;
struct
bind_pair
*
pairs
;
size_t
len
;
};
struct
bind_pair
{
enum
BindKeyType
key_type
;
enum
BindValueType
value_type
;
void
*
key
;
// char * | int *
void
*
value
;
// char * | int * | double * | 0
size_t
value_size
;
};
private
:
Database
*
db
;
struct
fetchall_request
{
Persistent
<
Function
>
cb
;
Statement
*
sto
;
mpool_t
*
pool
;
char
*
error
;
struct
row_node
*
rows
;
sqlite3_stmt
*
handle
;
};
#endif
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