Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(35)

Unified Diff: gears/database2/statement.cc

Issue 717: Database2Values, argument conversion implemented (Closed) SVN Base: http://google-gears.googlecode.com/svn/contrib/dimitri.glazkov/database2/
Patch Set: ready for another look. Created 3 months, 2 weeks ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side by-side-diff with in-line comments
Download patch
Index: gears/database2/statement.cc
===================================================================
--- gears/database2/statement.cc (revision 1639)
+++ gears/database2/statement.cc (working copy)
@@ -43,20 +43,147 @@
JsObject *error) {
}
-bool Database2Statement::Create(const std::string16 &sql_statement,
- const JsArray &sql_arguments,
- JsRootedCallback *callback,
- JsRootedCallback *error_callback,
+bool Database2Statement::Create(const std::string16 &sql_statement,
+ JsArray *sql_arguments,
+ JsRootedCallback *callback,
+ JsRootedCallback *error_callback,
Database2Statement **instance) {
- Database2Statement *statement = new Database2Statement();
+ scoped_ptr<Database2Statement> statement(new Database2Statement());
+
+ // NULL should be passed if no arguments are specified
+ assert(!sql_arguments || !JsTokenIsNullOrUndefined(sql_arguments->token()));
+ // NULL should be passed if a callback is not specified
+ assert(!callback || !JsTokenIsNullOrUndefined(callback->token()));
+ assert(!error_callback || !JsTokenIsNullOrUndefined(error_callback->token()));
+
statement->sql_statement_.assign(sql_statement);
statement->callback_.reset(callback);
statement->error_callback_.reset(error_callback);
- // TODO(dimitri.glazkov): convert sql_arguments to JsParamToSend[]. Accepted
- // types are: double, int32, int64, string. All other types, are considered
- // invalid
- *instance = statement;
- // TODO(dimitri.glazkov): decide whether ever return false (so that creator
- // could throw an exception, for instance) or mark statement as bogus
+
+ Database2Values *arguments;
+ if (!Database2Values::CreateFromJsArray(sql_arguments, &arguments)) {
+ return false;
+ }
+
+ statement->arguments_.reset(arguments);
+
+ *instance = statement.release();
return true;
}
+
+// static
+bool Database2Values::CreateFromJsArray(const JsArray *sql_arguments,
+ Database2Values **instance) {
+ scoped_ptr<Database2Values> result;
+ result.reset(new Database2Values());
+
+ // since the arguments are optional, they could be passed as NULL
+ if (sql_arguments == NULL) {
+ result->arguments_.reset(NULL);
+ result->length_ = 0;
+ *instance = result.release();
+ return true;
+ }
+
+ int len;
+ if (!sql_arguments->GetLength(&len)) {
+ // unable to query JsArray, someting's gone horribly wrong
+ // returning with failure will trigger an internal error
+ assert(false);
+ return false;
+ }
+
+ result->length_ = len;
+
+ result->arguments_.reset(new JsParamToSend[len]);
+ for(int i = 0; i < len; i++) {
+ if (!SetJsParamToSend(sql_arguments, i, result->arguments_.get())) {
+ // one invalid argument make the whole statement bogus
+ // no need to process any more parameters
+ // set length to only include last processed parameter
+ result->length_ = i;
+ return false;
+ }
+ }
+
+ *instance = result.release();
+ return true;
+}
+
+// static
+bool Database2Values::SetJsParamToSend(const JsArray *js_array,
+ int index,
+ JsParamToSend *arguments) {
+ assert(index >= 0 && arguments);
+ JsParamToSend *param = &arguments[index];
+ param->type = js_array->GetElementType(index);
+ switch(param->type) {
+ case JSPARAM_INT: {
+ scoped_ptr<int> value;
+ value.reset(new int);
+ if (js_array->GetElementAsInt(index, value.get())) {
+ param->value_ptr = value.release();
+ return true;
+ }
+ return false;
+ }
+ case JSPARAM_DOUBLE: {
+ scoped_ptr<double> value;
+ value.reset(new double);
+ if (js_array->GetElementAsDouble(index, value.get())) {
+ param->value_ptr = value.release();
+ return true;
+ }
+ return false;
+ }
+ case JSPARAM_STRING16: {
+ scoped_ptr<std::string16> value;
+ value.reset(new std::string16());
+ if (js_array->GetElementAsString(index, value.get())) {
+ param->value_ptr = value.release();
+ return true;
+ }
+ return false;
+ }
+ case JSPARAM_NULL: {
+ param->value_ptr = NULL;
+ return true;
+ }
+ }
+ // all other types are considered invalid
+ return false;
+}
+
+JsParamType Database2Values::GetType(int index) const {
+ assert(index >= 0 && index < length_);
+ return arguments_[index].type;
+}
+
+int Database2Values::GetAsInt(int index) const {
+ assert(index >= 0 && index < length_);
+ JsParamToSend param = arguments_[index];
+ assert(param.type == JSPARAM_INT);
+ return *static_cast<int*>(const_cast<void*>(param.value_ptr));
+}
+
+double Database2Values::GetAsDouble(int index) const {
+ assert(index >= 0 && index < length_);
+ JsParamToSend param = arguments_[index];
+ assert(param.type == JSPARAM_DOUBLE);
+ return *static_cast<int*>(const_cast<void*>(param.value_ptr));
+}
+
+std::string16 &Database2Values::GetAsString(int index) const {
+ assert(index >= 0 && index < length_);
+ JsParamToSend param = arguments_[index];
+ assert(param.type == JSPARAM_STRING16);
+ return *static_cast<std::string16*>(const_cast<void*>(param.value_ptr));
+}
+
+Database2Values::~Database2Values() {
+ // dispose of the data, pointed to the value_ptrs
+ for(int i = 0; i < length_; i++) {
+ JsParamToSend param = arguments_[i];
+ if (param.value_ptr) delete param.value_ptr;
+ }
+}

Powered by Google App Engine
This is Rietveld r292