Bug 490867 - Variant fixes: coerce null to empty string, GetIsNull should check correct type, variant base type should be void, r=sdwilsh
authorDrew Willcoxon <adw@mozilla.com>
Wed, 24 Jun 2009 15:04:49 -0700
changeset 29605 074a69d4dcce3376362ed539031d3993aad37f48
parent 29604 c25385c417b95e203fae87438315bd98f20d267c
child 29606 2533ef04e498ead87f6ab33b6c26454579a3781f
push idunknown
push userunknown
push dateunknown
reviewerssdwilsh
bugs490867
milestone1.9.2a1pre
Bug 490867 - Variant fixes: coerce null to empty string, GetIsNull should check correct type, variant base type should be void, r=sdwilsh Adds a NullVariant derived class of Variant_base.
storage/src/Variant.h
storage/src/Variant_inl.h
storage/src/mozStorageRow.cpp
storage/test/unit/test_statement_executeAsync.js
--- a/storage/src/Variant.h
+++ b/storage/src/Variant.h
@@ -17,16 +17,17 @@
  *
  * The Initial Developer of the Original Code is
  * Mozilla Corporation
  * Portions created by the Initial Developer are Copyright (C) 2008
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *   Drew Willcoxon <adw@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -294,16 +295,47 @@ struct variant_blob_traits<PRUint8[]>
 
     // Set type and size
     *_type = nsIDataType::VTYPE_UINT8;
     *_size = aData.Length();
     return NS_OK;
   }
 };
 
+/**
+ * NULL type
+ */
+
+class NullVariant : public Variant_base
+{
+public:
+  NS_IMETHOD GetDataType(PRUint16 *_type)
+  {
+    NS_ENSURE_ARG_POINTER(_type);
+    *_type = nsIDataType::VTYPE_EMPTY;
+    return NS_OK;
+  }
+
+  NS_IMETHOD GetAsAUTF8String(nsACString &_str)
+  {
+    // Return a void string.
+    _str.Truncate(0);
+    _str.SetIsVoid(PR_TRUE);
+    return NS_OK;
+  }
+
+  NS_IMETHOD GetAsAString(nsAString &_str)
+  {
+    // Return a void string.
+    _str.Truncate(0);
+    _str.SetIsVoid(PR_TRUE);
+    return NS_OK;
+  }
+};
+
 ////////////////////////////////////////////////////////////////////////////////
 //// Template Implementation
 
 template <typename DataType>
 class Variant : public Variant_base
 {
 public:
   Variant(typename variant_storage_traits<DataType>::ConstructorType aData)
@@ -356,16 +388,15 @@ private:
 ////////////////////////////////////////////////////////////////////////////////
 //// Handy typedefs!  Use these for the right mapping.
 
 typedef Variant<PRInt64> IntegerVariant;
 typedef Variant<double> FloatVariant;
 typedef Variant<nsString> TextVariant;
 typedef Variant<nsCString> UTF8TextVariant;
 typedef Variant<PRUint8[]> BlobVariant;
-typedef Variant_base NullVariant;
 
 } // namespace storage
 } // namespace mozilla
 
 #include "Variant_inl.h"
 
 #endif // mozilla_storage_Variant_h__
--- a/storage/src/Variant_inl.h
+++ b/storage/src/Variant_inl.h
@@ -60,17 +60,18 @@ inline NS_IMPL_THREADSAFE_QUERY_INTERFAC
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsIVariant
 
 inline
 NS_IMETHODIMP
 Variant_base::GetDataType(PRUint16 *_type)
 {
-  *_type = nsIDataType::VTYPE_EMPTY;
+  NS_ENSURE_ARG_POINTER(_type);
+  *_type = nsIDataType::VTYPE_VOID;
   return NS_OK;
 }
 
 inline
 NS_IMETHODIMP
 Variant_base::GetAsInt32(PRInt32 *)
 {
   return NS_ERROR_CANNOT_CONVERT_DATA;
--- a/storage/src/mozStorageRow.cpp
+++ b/storage/src/mozStorageRow.cpp
@@ -230,20 +230,21 @@ Row::GetBlob(PRUint32 aIndex,
                                             reinterpret_cast<void **>(_blob));
 }
 
 NS_IMETHODIMP
 Row::GetIsNull(PRUint32 aIndex,
                PRBool *_isNull)
 {
   ENSURE_INDEX_VALUE(aIndex, mNumCols);
+  NS_ENSURE_ARG_POINTER(_isNull);
 
   PRUint16 type;
   (void)mData.ObjectAt(aIndex)->GetDataType(&type);
-  *_isNull = type == nsIDataType::VTYPE_VOID;
+  *_isNull = type == nsIDataType::VTYPE_EMPTY;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Row::GetSharedUTF8String(PRUint32,
                          PRUint32 *,
                          char const **)
 {
--- a/storage/test/unit/test_statement_executeAsync.js
+++ b/storage/test/unit/test_statement_executeAsync.js
@@ -162,31 +162,35 @@ function test_get_data()
       do_check_false(this.resultObtained);
       this.resultObtained = true;
 
       // Check that we have a result
       var tuple = aResultSet.getNextRow();
       do_check_neq(null, tuple);
 
       // Check that it's what we expect
+      do_check_false(tuple.getIsNull(0));
       do_check_eq(tuple.getResultByName("string"), tuple.getResultByIndex(0));
       do_check_eq(TEXT, tuple.getResultByName("string"));
       do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_TEXT,
                   tuple.getTypeOfIndex(0));
 
+      do_check_false(tuple.getIsNull(1));
       do_check_eq(tuple.getResultByName("number"), tuple.getResultByIndex(1));
       do_check_eq(REAL, tuple.getResultByName("number"));
       do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_FLOAT,
                   tuple.getTypeOfIndex(1));
 
+      do_check_true(tuple.getIsNull(2));
       do_check_eq(tuple.getResultByName("nuller"), tuple.getResultByIndex(2));
       do_check_eq(null, tuple.getResultByName("nuller"));
       do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_NULL,
                   tuple.getTypeOfIndex(2));
 
+      do_check_false(tuple.getIsNull(3));
       var blobByName = tuple.getResultByName("blober");
       do_check_eq(BLOB.length, blobByName.length);
       var blobByIndex = tuple.getResultByIndex(3);
       do_check_eq(BLOB.length, blobByIndex.length);
       for (var i = 0; i < BLOB.length; i++) {
         do_check_eq(BLOB[i], blobByName[i]);
         do_check_eq(BLOB[i], blobByIndex[i]);
       }
@@ -194,16 +198,17 @@ function test_get_data()
       var blob = { value: null };
       tuple.getBlob(3, count, blob);
       do_check_eq(BLOB.length, count.value);
       for (var i = 0; i < BLOB.length; i++)
         do_check_eq(BLOB[i], blob.value[i]);
       do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_BLOB,
                   tuple.getTypeOfIndex(3));
 
+      do_check_false(tuple.getIsNull(4));
       do_check_eq(tuple.getResultByName("id"), tuple.getResultByIndex(4));
       do_check_eq(INTEGER, tuple.getResultByName("id"));
       do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_INTEGER,
                   tuple.getTypeOfIndex(4));
 
       // check that we have no more results
       tuple = aResultSet.getNextRow();
       do_check_eq(null, tuple);