OSDN Git Service

Add functionality to V8 bindings for SQLTransaction to allow array-like objects to...
authorBen Murdoch <benm@google.com>
Wed, 26 Aug 2009 11:42:59 +0000 (12:42 +0100)
committerBen Murdoch <benm@google.com>
Wed, 2 Sep 2009 11:32:47 +0000 (12:32 +0100)
WebCore/bindings/js/JSSQLTransactionCustom.cpp
WebCore/bindings/v8/V8Binding.cpp
WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp

index 30d59aa..dbe8e3c 100644 (file)
@@ -44,6 +44,11 @@ namespace WebCore {
     
 JSValue JSSQLTransaction::executeSql(ExecState* exec, const ArgList& args)
 {
+    if (args.isEmpty()) {
+        setDOMException(exec, SYNTAX_ERR);
+        return jsUndefined();
+    }
+
     String sqlStatement = args.at(0).toString(exec);
     if (exec->hadException())
         return jsUndefined();
index c5d580a..0da910b 100644 (file)
@@ -39,6 +39,7 @@
 #include "StringBuffer.h"
 #include "StringHash.h"
 #include "Threading.h"
+#include "V8Proxy.h"
 
 #include <v8.h>
 
@@ -191,10 +192,11 @@ String v8ValueToWebCoreString(v8::Handle<v8::Value> object)
 
     v8::TryCatch block;
     v8::Handle<v8::String> v8String = object->ToString();
-    // Check for empty handles to handle the case where an exception
-    // is thrown as part of invoking toString on the objectect.
-    if (v8String.IsEmpty())
+    // Handle the case where an exception is thrown as part of invoking toString on the object.
+    if (block.HasCaught()) {
+        throwError(block.Exception());
         return StringImpl::empty();
+    }
     return v8StringToWebCoreString(v8String, DoNotExternalize, PlainStringType);
 }
 
index 8fa5bde..dc801bd 100644 (file)
@@ -49,34 +49,49 @@ CALLBACK_FUNC_DECL(SQLTransactionExecuteSql)
 {
     INC_STATS("DOM.SQLTransaction.executeSql()");
 
-    if (args.Length() == 0) {
-        V8Proxy::throwError(V8Proxy::SyntaxError, "SQL statement is required.");
-        return v8::Undefined();
-    }
+    if (args.Length() == 0)
+        return throwError("SQL statement is required.", V8Proxy::SyntaxError);
 
     String statement = toWebCoreString(args[0]);
 
     Vector<SQLValue> sqlValues;
 
-    if (args.Length() > 1) {
-        // FIXME: Make this work for v8::Arrayish objects, as well
-        if (!args[1]->IsArray()) {
-            V8Proxy::throwError(V8Proxy::TypeError, "Statement arguments must be an v8::Array.");
-            return v8::Undefined();
-        }
-
-        v8::Local<v8::Array> arguments = v8::Local<v8::Array>::Cast(args[1]);
-        uint32_t length = arguments->Length();
-
-        for (unsigned int i = 0; i < length; ++i) {
-            v8::Local<v8::Value> value = arguments->Get(v8::Integer::New(i));
-            if (value.IsEmpty() || value->IsNull())
-                sqlValues.append(SQLValue());
-            else if (value->IsNumber())
-                sqlValues.append(SQLValue(value->NumberValue()));
+    if (args.Length() > 1 && !isUndefinedOrNull(args[1])) {
+        if (args[1]->IsObject()) {
+            uint32_t sqlArgsLength = 0;
+            v8::Local<v8::Object> sqlArgsObject = args[1]->ToObject();
+            v8::Local<v8::Value> lengthGetter;
+            {
+                v8::TryCatch block;
+                lengthGetter = sqlArgsObject->Get(v8::String::New("length"));
+                if (block.HasCaught())
+                    return throwError(block.Exception());
+            }
+
+            if (isUndefinedOrNull(lengthGetter))
+                sqlArgsLength = sqlArgsObject->GetPropertyNames()->Length();
             else
-                sqlValues.append(SQLValue(toWebCoreString(value)));
-        }
+                sqlArgsLength = lengthGetter->Uint32Value();
+
+            for (unsigned int i = 0; i < sqlArgsLength; ++i) {
+                v8::Local<v8::Integer> key = v8::Integer::New(i);
+                v8::Local<v8::Value> value;
+                {
+                    v8::TryCatch block;
+                    value = sqlArgsObject->Get(key);
+                    if (block.HasCaught())
+                        return throwError(block.Exception());
+                }
+
+                if (value.IsEmpty() || value->IsNull())
+                    sqlValues.append(SQLValue());
+                else if (value->IsNumber())
+                    sqlValues.append(SQLValue(value->NumberValue()));
+                else
+                    sqlValues.append(SQLValue(toWebCoreString(value)));
+            }
+        } else
+            return throwError("sqlArgs should be array or object!", V8Proxy::TypeError);
     }
 
     SQLTransaction* transaction = V8DOMWrapper::convertToNativeObject<SQLTransaction>(V8ClassIndex::SQLTRANSACTION, args.Holder());
@@ -84,22 +99,18 @@ CALLBACK_FUNC_DECL(SQLTransactionExecuteSql)
     Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
 
     RefPtr<SQLStatementCallback> callback;
-    if (args.Length() > 2) {
-        if (!args[2]->IsObject()) {
-            V8Proxy::throwError(V8Proxy::TypeError, "Statement callback must be of valid type.");
-            return v8::Undefined();
-        }
+    if (args.Length() > 2 && !isUndefinedOrNull(args[2])) {
+        if (!args[2]->IsObject())
+            return throwError("Statement callback must be of valid type.", V8Proxy::TypeError);
 
         if (frame)
             callback = V8CustomSQLStatementCallback::create(args[2], frame);
     }
 
     RefPtr<SQLStatementErrorCallback> errorCallback;
-    if (args.Length() > 3) {
-        if (!args[2]->IsObject()) {
-            V8Proxy::throwError(V8Proxy::TypeError, "Statement error callback must be of valid type.");
-            return v8::Undefined();
-        }
+    if (args.Length() > 3 && !isUndefinedOrNull(args[3])) {
+        if (!args[3]->IsObject())
+            return throwError("Statement error callback must be of valid type.", V8Proxy::TypeError);
 
         if (frame)
             errorCallback = V8CustomSQLStatementErrorCallback::create(args[3], frame);