IndexedDB result of deleting a record should be true or false
https://bugs.webkit.org/show_bug.cgi?id=60197

Patch by Joshua Bell <jsbell@chromium.org> on 2011-11-03
Reviewed by David Levin.

Source/WebCore:

IDBObjectStore.delete() was incorrectly firing an error if there
was no record to remove. Match the spec, and return true/false
as success values instead. Bring JSC binding implementation of
SerializedScriptValue more in line with V8 version for methods
called from IDB code.

Test: storage/indexeddb/mozilla/delete-result.html

* bindings/js/SerializedScriptValue.cpp:
(WebCore::SerializedScriptValue::createFromWire):
(WebCore::SerializedScriptValue::undefinedValue):
(WebCore::SerializedScriptValue::booleanValue):
* bindings/js/SerializedScriptValue.h:
* bindings/v8/SerializedScriptValue.cpp:
(WebCore::SerializedScriptValue::nullValue):
(WebCore::SerializedScriptValue::undefinedValue):
(WebCore::SerializedScriptValue::booleanValue):
* bindings/v8/SerializedScriptValue.h:
* storage/IDBObjectStoreBackendImpl.cpp:
(WebCore::IDBObjectStoreBackendImpl::deleteInternal):

LayoutTests:

Add tests for IDBObjectStore.delete() - should succeed if
record exists or not, and return true/false as success value.

* storage/indexeddb/mozilla/delete-result-expected.txt: Added.
* storage/indexeddb/mozilla/delete-result.html: Added.
* storage/indexeddb/objectstore-basics-expected.txt:
* storage/indexeddb/objectstore-basics.html:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@99229 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/bindings/js/SerializedScriptValue.cpp b/Source/WebCore/bindings/js/SerializedScriptValue.cpp
index 19aefc2..b675ca3 100644
--- a/Source/WebCore/bindings/js/SerializedScriptValue.cpp
+++ b/Source/WebCore/bindings/js/SerializedScriptValue.cpp
@@ -126,6 +126,8 @@
  *    | IntTag <value:int32_t>
  *    | ZeroTag
  *    | OneTag
+ *    | FalseTag
+ *    | TrueTag
  *    | DoubleTag <value:double>
  *    | DateTag <value:double>
  *    | String
@@ -272,6 +274,18 @@
         return writeLittleEndian(out, s.impl()->characters(), s.length());
     }
 
+    static void serializeUndefined(Vector<uint8_t>& out)
+    {
+        writeLittleEndian(out, CurrentVersion);
+        writeLittleEndian<uint8_t>(out, UndefinedTag);
+    }
+
+    static void serializeBoolean(bool value, Vector<uint8_t>& out)
+    {
+        writeLittleEndian(out, CurrentVersion);
+        writeLittleEndian<uint8_t>(out, value ? TrueTag : FalseTag);
+    }
+
 private:
     CloneSerializer(ExecState* exec, MessagePortArray* messagePorts, Vector<uint8_t>& out)
         : CloneBase(exec)
@@ -1466,6 +1480,20 @@
     return emptyValue.get();
 }
 
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::undefinedValue()
+{
+    Vector<uint8_t> buffer;
+    CloneSerializer::serializeUndefined(buffer);
+    return adoptRef(new SerializedScriptValue(buffer));
+}
+
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::booleanValue(bool value)
+{
+    Vector<uint8_t> buffer;
+    CloneSerializer::serializeBoolean(value, buffer);
+    return adoptRef(new SerializedScriptValue(buffer));
+}
+
 void SerializedScriptValue::maybeThrowExceptionIfSerializationFailed(ExecState* exec, SerializationReturnCode code)
 {
     if (code == SuccessfullyCompleted)
diff --git a/Source/WebCore/bindings/js/SerializedScriptValue.h b/Source/WebCore/bindings/js/SerializedScriptValue.h
index 5072fa6..caed647 100644
--- a/Source/WebCore/bindings/js/SerializedScriptValue.h
+++ b/Source/WebCore/bindings/js/SerializedScriptValue.h
@@ -68,6 +68,8 @@
 
     static PassRefPtr<SerializedScriptValue> create();
     static SerializedScriptValue* nullValue();
+    static PassRefPtr<SerializedScriptValue> undefinedValue();
+    static PassRefPtr<SerializedScriptValue> booleanValue(bool value);
 
     String toString();
     
diff --git a/Source/WebCore/bindings/v8/SerializedScriptValue.cpp b/Source/WebCore/bindings/v8/SerializedScriptValue.cpp
index 42a3708..9bae908 100644
--- a/Source/WebCore/bindings/v8/SerializedScriptValue.cpp
+++ b/Source/WebCore/bindings/v8/SerializedScriptValue.cpp
@@ -1931,6 +1931,8 @@
 
 SerializedScriptValue* SerializedScriptValue::nullValue()
 {
+    // FIXME: This is not thread-safe. Move caching to callers.
+    // https://bugs.webkit.org/show_bug.cgi?id=70833
     DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, nullValue, (0));
     if (!nullValue) {
         Writer writer;
@@ -1941,16 +1943,23 @@
     return nullValue.get();
 }
 
-SerializedScriptValue* SerializedScriptValue::undefinedValue()
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::undefinedValue()
 {
-    DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, undefinedValue, (0));
-    if (!undefinedValue) {
-        Writer writer;
-        writer.writeUndefined();
-        String wireData = StringImpl::adopt(writer.data());
-        undefinedValue = adoptRef(new SerializedScriptValue(wireData));
-    }
-    return undefinedValue.get();
+    Writer writer;
+    writer.writeUndefined();
+    String wireData = StringImpl::adopt(writer.data());
+    return adoptRef(new SerializedScriptValue(wireData));
+}
+
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::booleanValue(bool value)
+{
+    Writer writer;
+    if (value)
+        writer.writeTrue();
+    else
+        writer.writeFalse();
+    String wireData = StringImpl::adopt(writer.data());
+    return adoptRef(new SerializedScriptValue(wireData));
 }
 
 PassRefPtr<SerializedScriptValue> SerializedScriptValue::release()
diff --git a/Source/WebCore/bindings/v8/SerializedScriptValue.h b/Source/WebCore/bindings/v8/SerializedScriptValue.h
index a559cf9..c65bb2d 100644
--- a/Source/WebCore/bindings/v8/SerializedScriptValue.h
+++ b/Source/WebCore/bindings/v8/SerializedScriptValue.h
@@ -60,7 +60,8 @@
     static PassRefPtr<SerializedScriptValue> create();
 
     static SerializedScriptValue* nullValue();
-    static SerializedScriptValue* undefinedValue();
+    static PassRefPtr<SerializedScriptValue> undefinedValue();
+    static PassRefPtr<SerializedScriptValue> booleanValue(bool value);
 
     PassRefPtr<SerializedScriptValue> release();