Index: gears/database2/statement.h =================================================================== --- gears/database2/statement.h (revision 1639) +++ gears/database2/statement.h (working copy) @@ -26,6 +26,8 @@ #ifndef GEARS_DATABASE2_STATEMENT_H__ #define GEARS_DATABASE2_STATEMENT_H__ +#include + #include "gears/base/common/common.h" #include "gears/base/common/js_types.h" #include "gears/third_party/scoped_ptr/scoped_ptr.h" @@ -33,42 +35,98 @@ // forward declarations class Database2; class Database2Transaction; +class Database2Values; -// represents Database2Statement +// represents statement, for both synchronous and asynchronous operations class Database2Statement { public: - Database2Statement() {} - bool HasCallback() const { - assert(callback_.get()); - return !JsTokenIsNullOrUndefined(callback_->token()); + return callback_.get() != NULL; } bool HasErrorCallback() const { - assert(error_callback_.get()); - return !JsTokenIsNullOrUndefined(error_callback_->token()); + return error_callback_.get() != NULL; } void InvokeCallback(Database2Transaction *tx); void InvokeErrorCallback(Database2Transaction *tx, JsObject *error); + // create a statement instance + // must passs NULL for arguments or callbacks if they are not specified static bool Create(const std::string16 &sql_statement, - const JsArray &sql_arguments, + JsArray *sql_arguments, JsRootedCallback *callback, JsRootedCallback *error_callback, Database2Statement **instance); std::string16 sql() const { return sql_statement_; } - JsParamToSend *arguments() const { return sql_arguments_; } - int num_arguments() const { return num_arguments_; } + Database2Values *arguments() const { return arguments_.get(); } private: + Database2Statement() {} + // if true, the statement has invalid arguments + bool bogus_; std::string16 sql_statement_; - int num_arguments_; - JsParamToSend *sql_arguments_; + scoped_ptr arguments_; scoped_ptr callback_; scoped_ptr error_callback_; DISALLOW_EVIL_CONSTRUCTORS(Database2Statement); }; +// Used for marshaling statement arguments to the database thread and results to +// the main thread. A union-based structure is used to store value-type pairs. +class Database2Values { + public: + Database2Values() {} + ~Database2Values() { + // remove all rows + for(unsigned int i = 0; i < rows_.size(); i++) { + delete[] rows_[i]; + } + } + + static bool CreateFromJsArray(const JsArray *js_array, + Database2Values **instance); + + // methods for reading values + int length() const { return length_; } + void Reset() { current_row_ = 0; } + bool Next(); + JsParamType GetType(int index) const; + bool GetElementAsInt(int index, int *value); + bool GetElementAsDouble(int index, double *value); + bool GetElementAsString(int index, std::string16 *value); + + private: + void StartNewRow(); + + // used to store value-type pairs + struct Variant { + Variant() : type(JSPARAM_NULL) {} + ~Variant() { + if (type == JSPARAM_STRING16) { delete string_value; } + } + + JsParamType type; + union { + int int_value; + double double_value; + std::string16 *string_value; + }; + }; + + inline Variant ¤t(int index) const { + assert(index >= 0 && index < length_); + assert(current_row_ < length_); + return rows_[current_row_][index]; + } + + friend class vector; + std::vector rows_; + int length_; + int current_row_; + + DISALLOW_EVIL_CONSTRUCTORS(Database2Values); +}; + #endif // GEARS_DATABASE2_STATEMENT_H__