Commit 01a5a040 by Konstantin Käfer

integrate the Parameter object into Fields

parent f0f0c835
...@@ -162,34 +162,35 @@ int Statement::EIO_AfterPrepare(eio_req *req) { ...@@ -162,34 +162,35 @@ int Statement::EIO_AfterPrepare(eio_req *req) {
return 0; return 0;
} }
inline Data::Field* Statement::BindParameter(const Handle<Value> source) { template <class T> Data::Field*
Statement::BindParameter(const Handle<Value> source, T pos) {
if (source->IsString() || source->IsRegExp()) { if (source->IsString() || source->IsRegExp()) {
String::Utf8Value val(source->ToString()); String::Utf8Value val(source->ToString());
return new Data::Text(val.length(), *val); return new Data::Text(pos, val.length(), *val);
} }
else if (source->IsInt32()) { else if (source->IsInt32()) {
return new Data::Integer(source->Int32Value()); return new Data::Integer(pos, source->Int32Value());
} }
else if (source->IsNumber()) { else if (source->IsNumber()) {
return new Data::Float(source->NumberValue()); return new Data::Float(pos, source->NumberValue());
} }
else if (source->IsBoolean()) { else if (source->IsBoolean()) {
return new Data::Integer(source->BooleanValue() ? 1 : 0); return new Data::Integer(pos, source->BooleanValue() ? 1 : 0);
} }
else if (source->IsNull()) { else if (source->IsNull()) {
return new Data::Null(); return new Data::Null(pos);
} }
else if (Buffer::HasInstance(source)) { else if (Buffer::HasInstance(source)) {
#if NODE_VERSION_AT_LEAST(0,3,0) #if NODE_VERSION_AT_LEAST(0,3,0)
Local<Object> buffer = source->ToObject(); Local<Object> buffer = source->ToObject();
return new Data::Blob(Buffer::Length(buffer), Buffer::Data(buffer)); return new Data::Blob(pos, Buffer::Length(buffer), Buffer::Data(buffer));
#else #else
Buffer* buffer = ObjectWrap::Unwrap<Buffer>(source->ToObject()); Buffer* buffer = ObjectWrap::Unwrap<Buffer>(source->ToObject());
return new Data::Blob(buffer->length(), buffer->data()); return new Data::Blob(pos, buffer->length(), buffer->data());
#endif #endif
} }
else if (source->IsDate()) { else if (source->IsDate()) {
return new Data::Float(source->NumberValue()); return new Data::Float(pos, source->NumberValue());
} }
else if (source->IsUndefined()) { else if (source->IsUndefined()) {
return NULL; return NULL;
...@@ -215,16 +216,14 @@ template <class T> T* Statement::Bind(const Arguments& args, int start) { ...@@ -215,16 +216,14 @@ template <class T> T* Statement::Bind(const Arguments& args, int start) {
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( baton->parameters.push_back(BindParameter(array->Get(i), pos));
new Data::Parameter(pos, BindParameter(array->Get(i))));
} }
} }
else if (!args[start]->IsObject() || args[start]->IsRegExp() || args[start]->IsDate()) { else if (!args[start]->IsObject() || args[start]->IsRegExp() || args[start]->IsDate()) {
// 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++) {
baton->parameters.push_back( baton->parameters.push_back(BindParameter(args[i], pos));
new Data::Parameter(pos, BindParameter(args[i])));
} }
} }
else if (args[start]->IsObject()) { else if (args[start]->IsObject()) {
...@@ -235,16 +234,12 @@ template <class T> T* Statement::Bind(const Arguments& args, int start) { ...@@ -235,16 +234,12 @@ template <class T> T* Statement::Bind(const Arguments& args, int start) {
Local<Value> name = array->Get(i); Local<Value> name = array->Get(i);
if (name->IsInt32()) { if (name->IsInt32()) {
baton->parameters.push_back(new Data::Parameter( baton->parameters.push_back(
name->Int32Value(), BindParameter(object->Get(name), name->Int32Value()));
BindParameter(object->Get(name))
));
} }
else { else {
baton->parameters.push_back(new Data::Parameter( baton->parameters.push_back(BindParameter(object->Get(name),
*String::Utf8Value(Local<String>::Cast(name)), *String::Utf8Value(Local<String>::Cast(name))));
BindParameter(object->Get(name))
));
} }
} }
} }
...@@ -268,35 +263,35 @@ bool Statement::Bind(const Data::Parameters parameters) { ...@@ -268,35 +263,35 @@ bool Statement::Bind(const Data::Parameters parameters) {
Data::Parameters::const_iterator end = parameters.end(); Data::Parameters::const_iterator end = parameters.end();
for (; it < end; it++) { for (; it < end; it++) {
Data::Parameter* param = *it; Data::Field* field = *it;
if (field != NULL) {
int pos; int pos;
if (param->position > 0) { if (field->index > 0) {
pos = param->position; pos = field->index;
} }
else { else {
pos = sqlite3_bind_parameter_index(handle, param->name.c_str()); pos = sqlite3_bind_parameter_index(handle, field->name.c_str());
} }
if (param->field != NULL) { switch (field->type) {
switch (param->field->type) {
case SQLITE_INTEGER: { case SQLITE_INTEGER: {
status = sqlite3_bind_int(handle, pos, status = sqlite3_bind_int(handle, pos,
((Data::Integer*)param->field)->value); ((Data::Integer*)field)->value);
} break; } break;
case SQLITE_FLOAT: { case SQLITE_FLOAT: {
status = sqlite3_bind_double(handle, pos, status = sqlite3_bind_double(handle, pos,
((Data::Float*)param->field)->value); ((Data::Float*)field)->value);
} break; } break;
case SQLITE_TEXT: { case SQLITE_TEXT: {
status = sqlite3_bind_text(handle, pos, status = sqlite3_bind_text(handle, pos,
((Data::Text*)param->field)->value.c_str(), ((Data::Text*)field)->value.c_str(),
((Data::Text*)param->field)->value.size(), SQLITE_TRANSIENT); ((Data::Text*)field)->value.size(), SQLITE_TRANSIENT);
} break; } break;
case SQLITE_BLOB: { case SQLITE_BLOB: {
status = sqlite3_bind_blob(handle, pos, status = sqlite3_bind_blob(handle, pos,
((Data::Blob*)param->field)->value, ((Data::Blob*)field)->value,
((Data::Blob*)param->field)->length, SQLITE_TRANSIENT); ((Data::Blob*)field)->length, SQLITE_TRANSIENT);
} break; } break;
case SQLITE_NULL: { case SQLITE_NULL: {
status = sqlite3_bind_null(handle, pos); status = sqlite3_bind_null(handle, pos);
...@@ -769,23 +764,23 @@ void Statement::GetRow(Data::Row* row, sqlite3_stmt* stmt) { ...@@ -769,23 +764,23 @@ void Statement::GetRow(Data::Row* row, sqlite3_stmt* stmt) {
int type = sqlite3_column_type(stmt, i); int type = sqlite3_column_type(stmt, i);
switch (type) { switch (type) {
case SQLITE_INTEGER: { case SQLITE_INTEGER: {
row->push_back(new Data::Integer(sqlite3_column_int(stmt, i))); row->push_back(new Data::Integer(i, sqlite3_column_int(stmt, i)));
} break; } break;
case SQLITE_FLOAT: { case SQLITE_FLOAT: {
row->push_back(new Data::Float(sqlite3_column_double(stmt, i))); row->push_back(new Data::Float(i, sqlite3_column_double(stmt, i)));
} break; } break;
case SQLITE_TEXT: { case SQLITE_TEXT: {
const char* text = (const char*)sqlite3_column_text(stmt, i); const char* text = (const char*)sqlite3_column_text(stmt, i);
int length = sqlite3_column_bytes(stmt, i); int length = sqlite3_column_bytes(stmt, i);
row->push_back(new Data::Text(length, text)); row->push_back(new Data::Text(i, length, text));
} break; } break;
case SQLITE_BLOB: { case SQLITE_BLOB: {
const void* blob = sqlite3_column_blob(stmt, i); const void* blob = sqlite3_column_blob(stmt, i);
int length = sqlite3_column_bytes(stmt, i); int length = sqlite3_column_bytes(stmt, i);
row->push_back(new Data::Blob(length, blob)); row->push_back(new Data::Blob(i, length, blob));
} break; } break;
case SQLITE_NULL: { case SQLITE_NULL: {
row->push_back(new Data::Null()); row->push_back(new Data::Null(i));
} break; } break;
default: default:
assert(false); assert(false);
......
...@@ -21,27 +21,37 @@ namespace node_sqlite3 { ...@@ -21,27 +21,37 @@ namespace node_sqlite3 {
namespace Data { namespace Data {
struct Field { struct Field {
inline Field(unsigned short _type = SQLITE_NULL) : type(_type) {} inline Field(unsigned short _index, unsigned short _type = SQLITE_NULL) :
type(_type), index(_index) {}
inline Field(const char* _name, unsigned short _type = SQLITE_NULL) :
type(_type), index(0), name(_name) {}
unsigned short type; unsigned short type;
unsigned short index;
std::string name;
}; };
struct Integer : Field { struct Integer : Field {
inline Integer(int val) : Field(SQLITE_INTEGER), value(val) {} template <class T> inline Integer(T _name, int val) :
Field(_name, SQLITE_INTEGER), value(val) {}
int value; int value;
}; };
struct Float : Field { struct Float : Field {
inline Float(double val) : Field(SQLITE_FLOAT), value(val) {} template <class T> inline Float(T _name, double val) :
Field(_name, SQLITE_FLOAT), value(val) {}
double value; double value;
}; };
struct Text : Field { struct Text : Field {
inline Text(size_t len, const char* val) : Field(SQLITE_TEXT), value(val, len) {} template <class T> inline Text(T _name, size_t len, const char* val) :
Field(_name, SQLITE_TEXT), value(val, len) {}
std::string value; std::string value;
}; };
struct Blob : Field { struct Blob : Field {
inline Blob(size_t len, const void* val) : Field(SQLITE_BLOB), length(len) { template <class T> inline Blob(T _name, size_t len, const void* val) :
Field(_name, SQLITE_BLOB), length(len) {
value = (char*)malloc(len); value = (char*)malloc(len);
memcpy(value, val, len); memcpy(value, val, len);
} }
...@@ -55,23 +65,7 @@ namespace Data { ...@@ -55,23 +65,7 @@ namespace Data {
typedef Field Null; typedef Field Null;
typedef std::vector<Field*> Row; typedef std::vector<Field*> Row;
typedef std::vector<Row*> Rows; typedef std::vector<Row*> Rows;
typedef Row Parameters;
struct Parameter {
unsigned short position;
std::string name;
Field* field;
inline Parameter(unsigned short pos_, Field* field_) : position(pos_), field(field_) {}
inline Parameter(const char* name_, Field* field_) : position(0), name(name_), field(field_) {}
inline ~Parameter() {
if (field) {
delete field;
}
}
};
typedef std::vector<Parameter*> Parameters;
} }
...@@ -197,7 +191,7 @@ protected: ...@@ -197,7 +191,7 @@ protected:
static void Finalize(Baton* baton); static void Finalize(Baton* baton);
void Finalize(); void Finalize();
Data::Field* BindParameter(const Handle<Value> source); template <class T> inline Data::Field* BindParameter(const Handle<Value> source, T pos);
template <class T> T* Bind(const Arguments& args, int start = 0); template <class T> T* Bind(const Arguments& args, int start = 0);
bool Bind(const Data::Parameters parameters); bool Bind(const Data::Parameters parameters);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment