Bug 1552547 part 2. Stop using [array] in mozIStorageBindingParams. r=mak
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 20 May 2019 16:30:12 +0000
changeset 474561 5f2932daeff2c6370358feceb7d55f60952a47a1
parent 474560 63d2eaf71d022b0fdaca6f12ca8ec4219d46f4c7
child 474562 67e2703726dad4f41430ba2962695d8fb9cdb31d
push id36042
push userdvarga@mozilla.com
push dateTue, 21 May 2019 04:19:40 +0000
treeherdermozilla-central@ca560ff55451 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs1552547
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1552547 part 2. Stop using [array] in mozIStorageBindingParams. r=mak Differential Revision: https://phabricator.services.mozilla.com/D31659
storage/StorageBaseStatementInternal.h
storage/mozIStorageBindingParams.idl
storage/mozStorageBindingParams.cpp
storage/test/unit/test_connection_executeAsync.js
storage/test/unit/test_statement_executeAsync.js
--- a/storage/StorageBaseStatementInternal.h
+++ b/storage/StorageBaseStatementInternal.h
@@ -265,16 +265,20 @@ NS_DEFINE_STATIC_IID_ACCESSOR(StorageBas
                 (uint32_t aWhere, int64_t aValue), (aWhere, aValue))           \
   BIND_GEN_IMPL(_class, _optionalGuard, Null, (const nsACString& aWhere),      \
                 (uint32_t aWhere), (aWhere))                                   \
   BIND_GEN_IMPL(                                                               \
       _class, _optionalGuard, Blob,                                            \
       (const nsACString& aWhere, const uint8_t* aValue, uint32_t aValueSize),  \
       (uint32_t aWhere, const uint8_t* aValue, uint32_t aValueSize),           \
       (aWhere, aValue, aValueSize))                                            \
+  BIND_GEN_IMPL(_class, _optionalGuard, BlobArray,                             \
+                (const nsACString& aWhere, const nsTArray<uint8_t>& aValue),   \
+                (uint32_t aWhere, const nsTArray<uint8_t>& aValue),            \
+                (aWhere, aValue))                                              \
   BIND_GEN_IMPL(_class, _optionalGuard, StringAsBlob,                          \
                 (const nsACString& aWhere, const nsAString& aValue),           \
                 (uint32_t aWhere, const nsAString& aValue), (aWhere, aValue))  \
   BIND_GEN_IMPL(_class, _optionalGuard, UTF8StringAsBlob,                      \
                 (const nsACString& aWhere, const nsACString& aValue),          \
                 (uint32_t aWhere, const nsACString& aValue), (aWhere, aValue)) \
   BIND_GEN_IMPL(                                                               \
       _class, _optionalGuard, AdoptedBlob,                                     \
--- a/storage/mozIStorageBindingParams.idl
+++ b/storage/mozIStorageBindingParams.idl
@@ -3,17 +3,19 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIVariant;
 
-[scriptable, uuid(2d09f42f-966e-4663-b4b3-b0c8676bf2bf)]
+[ptr] native octetPtr(uint8_t);
+
+[scriptable, builtinclass, uuid(2d09f42f-966e-4663-b4b3-b0c8676bf2bf)]
 interface mozIStorageBindingParams : nsISupports {
   /**
    * Binds aValue to the parameter with the name aName.
    *
    * @param aName
    *        The name of the parameter to bind aValue to.
    * @param aValue
    *        The value to bind.
@@ -26,30 +28,37 @@ interface mozIStorageBindingParams : nsI
                                     in AString aValue);
    [noscript] void bindDoubleByName(in AUTF8String aName,
                                     in double aValue);
    [noscript] void bindInt32ByName(in AUTF8String aName,
                                    in long aValue);
    [noscript] void bindInt64ByName(in AUTF8String aName,
                                    in long long aValue);
    [noscript] void bindNullByName(in AUTF8String aName);
-   void bindBlobByName(in AUTF8String aName,
-                       [array, const, size_is(aValueSize)] in octet aValue,
-                       in unsigned long aValueSize);
+
+   // The noscript version of bindBlobByName can be used with any (const
+   // uint8_t*, length) pair.  The scriptable version is meant for use with
+   // nsTArray<uint8_t>, which is what xpconnect has to work with.
+   [noscript, binaryname(BindBlobByName)]
+   void bindBlobByNameNoscript(in AUTF8String aName,
+                               [const] in octetPtr aValue,
+                               in unsigned long aValueSize);
+   [binaryname(BindBlobArrayByName)]
+   void bindBlobByName(in AUTF8String aName, in Array<octet> aValue);
 
    // Convenience routines for storing strings as blobs.
    void bindStringAsBlobByName(in AUTF8String aName, in AString aValue);
    void bindUTF8StringAsBlobByName(in AUTF8String aName, in AUTF8String aValue);
 
    // The function adopts the storage for the provided blob.  After calling
    // this function, mozStorage will ensure that free is called on the
    // underlying pointer.
    [noscript]
    void bindAdoptedBlobByName(in AUTF8String aName,
-                              [array, size_is(aValueSize)] in octet aValue,
+                              in octetPtr aValue,
                               in unsigned long aValueSize);
 
    /**
     * Binds aValue to the parameter with the index aIndex.
     *
     * @param aIndex
     *        The zero-based index of the parameter to bind aValue to.
     * @param aValue
@@ -63,24 +72,32 @@ interface mozIStorageBindingParams : nsI
                                      in AString aValue);
    [noscript] void bindDoubleByIndex(in unsigned long aIndex,
                                      in double aValue);
    [noscript] void bindInt32ByIndex(in unsigned long aIndex,
                                     in long aValue);
    [noscript] void bindInt64ByIndex(in unsigned long aIndex,
                                     in long long aValue);
    [noscript] void bindNullByIndex(in unsigned long aIndex);
+
+   // The noscript version of bindBlobByIndex can be used with any (const
+   // uint8_t*, length) pair.  The scriptable version is meant for use with
+   // nsTArray<uint8_t>, which is what xpconnect has to work with.
+   [noscript, binaryname(BindBlobByIndex)]
+   void bindBlobByIndexNoscript(in unsigned long aIndex,
+                                [const] in octetPtr aValue,
+                                in unsigned long aValueSize);
+   [binaryname(BindBlobArrayByIndex)]
    void bindBlobByIndex(in unsigned long aIndex,
-                        [array, const, size_is(aValueSize)] in octet aValue,
-                        in unsigned long aValueSize);
+                        in Array<octet> aValue);
 
    // Convenience routines for storing strings as blobs.
    void bindStringAsBlobByIndex(in unsigned long aIndex, in AString aValue);
    void bindUTF8StringAsBlobByIndex(in unsigned long aIndex, in AUTF8String aValue);
 
    // The function adopts the storage for the provided blob.  After calling
    // this function, mozStorage will ensure that free is called on the
    // underlying pointer.
    [noscript]
    void bindAdoptedBlobByIndex(in unsigned long aIndex,
-                               [array, size_is(aValueSize)] in octet aValue,
+                               in octetPtr aValue,
                                in unsigned long aValueSize);
 };
--- a/storage/mozStorageBindingParams.cpp
+++ b/storage/mozStorageBindingParams.cpp
@@ -273,16 +273,22 @@ BindingParams::BindBlobByName(const nsAC
                                    int(aValueSize));
   nsCOMPtr<nsIVariant> value(new BlobVariant(data));
   NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
 
   return BindByName(aName, value);
 }
 
 NS_IMETHODIMP
+BindingParams::BindBlobArrayByName(const nsACString& aName,
+                                   const nsTArray<uint8_t>& aValue) {
+  return BindBlobByName(aName, aValue.Elements(), aValue.Length());
+}
+
+NS_IMETHODIMP
 BindingParams::BindStringAsBlobByName(const nsACString& aName,
                                       const nsAString& aValue) {
   return DoBindStringAsBlobByName(this, aName, aValue);
 }
 
 NS_IMETHODIMP
 BindingParams::BindUTF8StringAsBlobByName(const nsACString& aName,
                                           const nsACString& aValue) {
@@ -393,16 +399,22 @@ BindingParams::BindBlobByIndex(uint32_t 
                                    int(aValueSize));
   nsCOMPtr<nsIVariant> value(new BlobVariant(data));
   NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
 
   return BindByIndex(aIndex, value);
 }
 
 NS_IMETHODIMP
+BindingParams::BindBlobArrayByIndex(uint32_t aIndex,
+                                    const nsTArray<uint8_t>& aValue) {
+  return BindBlobByIndex(aIndex, aValue.Elements(), aValue.Length());
+}
+
+NS_IMETHODIMP
 BindingParams::BindStringAsBlobByIndex(uint32_t aIndex,
                                        const nsAString& aValue) {
   return DoBindStringAsBlobByIndex(this, aIndex, aValue);
 }
 
 NS_IMETHODIMP
 BindingParams::BindUTF8StringAsBlobByIndex(uint32_t aIndex,
                                            const nsACString& aValue) {
--- a/storage/test/unit/test_connection_executeAsync.js
+++ b/storage/test/unit/test_connection_executeAsync.js
@@ -113,17 +113,17 @@ add_task(async function test_last_multip
 
     let params = stmts[i].newBindingParamsArray();
     for (let j = 0; j < AMOUNT_TO_ADD; j++) {
       let bp = params.newBindingParams();
       bp.bindByName("int", INTEGER);
       bp.bindByName("text", TEXT);
       bp.bindByName("real", REAL);
       bp.bindByName("null", null);
-      bp.bindBlobByName("blob", BLOB, BLOB.length);
+      bp.bindBlobByName("blob", BLOB);
       params.addParams(bp);
     }
     stmts[i].bindParameters(params);
   }
 
   // Get our current number of rows in the table.
   let currentRows = 0;
   let countStmt = getOpenedDatabase().createStatement(
--- a/storage/test/unit/test_statement_executeAsync.js
+++ b/storage/test/unit/test_statement_executeAsync.js
@@ -474,17 +474,17 @@ function test_bind_direct_binding_params
     "INSERT INTO test (id, string, number, nuller, blober) " +
     "VALUES (:int, :text, :real, :null, :blob)"
   );
   let insertId = nextUniqueId++;
   stmt.bindByName("int", insertId);
   stmt.bindByName("text", TEXT);
   stmt.bindByName("real", REAL);
   stmt.bindByName("null", null);
-  stmt.bindBlobByName("blob", BLOB, BLOB.length);
+  stmt.bindBlobByName("blob", BLOB);
   execAsync(stmt);
   stmt.finalize();
   verifyQuery("SELECT string, number, nuller, blober FROM test WHERE id = ?",
               insertId,
               [TEXT, REAL, null, BLOB]);
   run_next_test();
 }
 
@@ -558,17 +558,17 @@ function test_bind_multiple_rows_by_name
   );
   var array = stmt.newBindingParamsArray();
   for (let i = 0; i < AMOUNT_TO_ADD; i++) {
     let bp = array.newBindingParams();
     bp.bindByName("int", INTEGER);
     bp.bindByName("text", TEXT);
     bp.bindByName("real", REAL);
     bp.bindByName("null", null);
-    bp.bindBlobByName("blob", BLOB, BLOB.length);
+    bp.bindBlobByName("blob", BLOB);
     array.addParams(bp);
     Assert.equal(array.length, i + 1);
   }
   stmt.bindParameters(array);
 
   let rowCount = getTableRowCount("test");
   execAsync(stmt);
   Assert.equal(rowCount + AMOUNT_TO_ADD, getTableRowCount("test"));
@@ -634,17 +634,17 @@ function test_bind_no_such_name_sync_imm
   let array = stmt.newBindingParamsArray();
   let bp = array.newBindingParams();
 
   // Check variant binding.
   expectError(Cr.NS_ERROR_INVALID_ARG,
               () => bp.bindByName("doesnotexist", INTEGER));
   // Check blob binding.
   expectError(Cr.NS_ERROR_INVALID_ARG,
-              () => bp.bindBlobByName("doesnotexist", BLOB, BLOB.length));
+              () => bp.bindBlobByName("doesnotexist", BLOB));
 
   stmt.finalize();
   run_next_test();
 }
 test_bind_no_such_name_sync_immediate.syncOnly = true;
 
 function test_bind_no_such_name_async_deferred() {
   let stmt = makeTestStatement(