Skip to content

Commit

Permalink
fixed bugs with mulitbinder
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua Wise committed Sep 1, 2016
1 parent 41eacfd commit d819cea
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 46 deletions.
4 changes: 2 additions & 2 deletions src/binder/bind-object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ unsigned int Binder::BindObject(v8::Local<v8::Object> obj) {

// Get the parameter index of the current named parameter.
Nan::Utf8String utf8(key);
int index = GetNamedParameterIndex(*utf8, utf8.length());
unsigned int index = GetNamedParameterIndex(*utf8, utf8.length());
if (!index) {
error = "The named parameter \"%s\" does not exist.";
error_extra = new char[utf8.length() + 1];
Expand All @@ -52,7 +52,7 @@ unsigned int Binder::BindObject(v8::Local<v8::Object> obj) {
}

// Bind value.
BindValue(maybeValue.ToLocalChecked(), (unsigned int)index);
BindValue(maybeValue.ToLocalChecked(), index);
if (error) {
return i - symbol_count;
}
Expand Down
2 changes: 1 addition & 1 deletion src/binder/bind.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void Binder::Bind(Nan::NAN_METHOD_ARGS_TYPE info, int len) {
}
bound_object = true;

count += BindObject(v8::Local<v8::Object>::Cast(arg));
count += BindObject(obj);
if (error) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/binder/binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Binder {
unsigned int BindArrayLike(v8::Local<v8::Object>, unsigned int);
virtual unsigned int BindObject(v8::Local<v8::Object>); // This should only be invoked once

int GetNamedParameterIndex(const char*, int);
unsigned int GetNamedParameterIndex(const char*, int);
double GetArrayLikeLength(v8::Local<v8::Object>);
static bool IsPlainObject(v8::Local<v8::Object>);

Expand Down
2 changes: 1 addition & 1 deletion src/binder/get-array-like-length.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ double Binder::GetArrayLikeLength(v8::Local<v8::Object> obj) {

if (length->IsNumber()) {
double value = v8::Local<v8::Number>::Cast(length)->Value();
return IS_POSITIVE_INTEGER(value) ? value : -1;
return (IS_POSITIVE_INTEGER(value) && value <= (double)0xffffffff) ? value : -1;
}
return -1;
}
11 changes: 4 additions & 7 deletions src/binder/get-named-parameter-index.cc
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
// Given the name of a named parameter, returns the index of the parameter.
// If the named parameter does not exist, 0 is returned.

int Binder::GetNamedParameterIndex(const char* string, int length) {
unsigned int Binder::GetNamedParameterIndex(const char* string, int length) {
int index;
char temp[length + 2];
strlcpy(temp + 1, string, length + 1);

temp[0] = '@';
index = sqlite3_bind_parameter_index(handle, temp);
if (index) {
return index;
return (unsigned int)index;
}

temp[0] = ':';
index = sqlite3_bind_parameter_index(handle, temp);
if (index) {
return index;
return (unsigned int)index;
}

temp[0] = '$';
index = sqlite3_bind_parameter_index(handle, temp);
if (index) {
return index;
}

return index;
return (unsigned int)index;
}
69 changes: 49 additions & 20 deletions src/multi-binder/bind-object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
// is considered to be named.
// If an error occurs, error is set to an appropriately descriptive string.
// Regardless of whether an error occurs, the return value is the number of
// parameters that were bound.
// parameters that were bound. Unlike the normal Binder, this will bind
// parameters to all handles, not just the current one.

unsigned int MultiBinder::BindObject(v8::Local<v8::Object> obj) {
// Get array of properties.
Expand All @@ -15,7 +16,10 @@ unsigned int MultiBinder::BindObject(v8::Local<v8::Object> obj) {

// Get property count.
unsigned int len = keys->Length();
unsigned int symbol_count = 0;
unsigned int bound_count = 0;

// Save current handle.
sqlite3_stmt* current_handle = handle;

// Loop through each property.
for (unsigned int i=0; i<len; ++i) {
Expand All @@ -24,39 +28,64 @@ unsigned int MultiBinder::BindObject(v8::Local<v8::Object> obj) {
Nan::MaybeLocal<v8::Value> maybeKey = Nan::Get(keys, i);
if (maybeKey.IsEmpty()) {
error = "An error was thrown while trying to get the property names of the given object.";
return i - symbol_count;
return bound_count;
}
v8::Local<v8::Value> key = maybeKey.ToLocalChecked();

// If this property is a symbol, ignore it.
if (key->IsSymbol()) {
++symbol_count;
continue;
}

// Get the parameter index of the current named parameter.
Nan::Utf8String utf8(key);
int index = GetNamedParameterIndex(*utf8, utf8.length());
if (!index) {
error = "The named parameter \"%s\" does not exist.";
error_extra = new char[utf8.length() + 1];
strlcpy(error_extra, *utf8, utf8.length() + 1);
return i - symbol_count;
}

// Get the current property value.
Nan::MaybeLocal<v8::Value> maybeValue = Nan::Get(obj, key);
if (maybeValue.IsEmpty()) {
error = "An error was thrown while trying to get property values of the given object.";
return i - symbol_count;
return bound_count;
}
v8::Local<v8::Value> value = maybeValue.ToLocalChecked();

// Dissect the property name.
Nan::Utf8String utf8(key);
const char* utf8_value = *utf8;
int utf8_length = utf8.length();


bool someoneHadNamedParameter = false;


// Loop through each handle.
for (unsigned int h=0; h<handle_count; ++h) {
handle = handles[h];

// Get the parameter index of the current named parameter.
unsigned int index = GetNamedParameterIndex(utf8_value, utf8_length);
if (index) {

// Bind value.
BindValue(value, index);
if (error) {
return bound_count;
}
++bound_count;

if (!someoneHadNamedParameter) {
someoneHadNamedParameter = true;
}
}

}

// Bind value.
BindValue(maybeValue.ToLocalChecked(), (unsigned int)index);
if (error) {
return i - symbol_count;

// If no handles had this named parameter, provide an error.
if (!someoneHadNamedParameter) {
error = "The named parameter \"%s\" does not exist.";
error_extra = new char[utf8_length + 1];
strlcpy(error_extra, utf8_value, utf8_length + 1);
return bound_count;
}
}

return len - symbol_count;
handle = current_handle;
return bound_count;
}
24 changes: 11 additions & 13 deletions src/multi-binder/bind.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// If an error occurs, error is set to an appropriately descriptive string.

void MultiBinder::Bind(Nan::NAN_METHOD_ARGS_TYPE info, int len) {
// bool bound_object = false;
bool bound_object = false;
unsigned int count = 0;

for (int i=0; i<len; ++i) {
Expand Down Expand Up @@ -41,19 +41,17 @@ void MultiBinder::Bind(Nan::NAN_METHOD_ARGS_TYPE info, int len) {

// Plain objects
if (IsPlainObject(obj)) {
error = "Named parameters are not yet supported in transactions.";
return;
// if (bound_object) {
// error = "You cannot specify named parameters in two different objects.";
// return;
// }
// bound_object = true;
if (bound_object) {
error = "You cannot specify named parameters in two different objects.";
return;
}
bound_object = true;

// count += BindObject(v8::Local<v8::Object>::Cast(arg));
// if (error) {
// return;
// }
// continue;
count += BindObject(obj);
if (error) {
return;
}
continue;
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/multi-binder/next-anon-index.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Binder, this also loops through all handles.

unsigned int MultiBinder::NextAnonIndex() {
startloop:
while (sqlite3_bind_parameter_name(handle, ++anon_index) != NULL) {}
if (anon_index > param_count && handle_index + 1 < handle_count) {
do {
Expand All @@ -11,6 +12,9 @@ unsigned int MultiBinder::NextAnonIndex() {
} while (param_count == 0 && handle_index + 1 < handle_count);
anon_index = 1;
param_count_sum += param_count;
if (sqlite3_bind_parameter_name(handle, anon_index) != NULL) {
goto startloop;
}
}
return anon_index;
}
2 changes: 1 addition & 1 deletion src/objects/statement/cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ NAN_METHOD(Statement::Cache) {
if (!IS_POSITIVE_INTEGER(numberValue)) {
return Nan::ThrowRangeError("Argument 0 must be a positive, finite integer.");
}
if (numberValue > 0x7ffffffe) {
if (numberValue > (double)0x7ffffffe) {
return Nan::ThrowRangeError("The specified cache size is too large.");
}
if (numberValue < 1) {
Expand Down

0 comments on commit d819cea

Please sign in to comment.