Bug 388059 - Add a getColumnIndex method to mozIStorageStatement. r=sspitzer
authorsdwilsh@shawnwilsher.com
Thu, 19 Jul 2007 09:30:17 -0700
changeset 3679 8462f281a3305a2e8512f1ab359015953a759571
parent 3678 85de01fd06bb3be77d86180d91a05de39accb430
child 3680 1db2bb33676fed3b2c6772b5b2368e2a291e2ba4
push idunknown
push userunknown
push dateunknown
reviewerssspitzer
bugs388059
milestone1.9a7pre
Bug 388059 - Add a getColumnIndex method to mozIStorageStatement. r=sspitzer
storage/public/mozIStorageStatement.idl
storage/src/mozStorageStatement.cpp
storage/src/mozStorageStatement.h
storage/test/unit/test_storage_statement.js
--- a/storage/public/mozIStorageStatement.idl
+++ b/storage/public/mozIStorageStatement.idl
@@ -40,17 +40,17 @@
 #include "mozIStorageValueArray.idl"
 
 interface mozIStorageConnection;
 interface mozIStorageDataSet;
 interface nsISimpleEnumerator;
 
 [ptr] native sqlite3stmtptr(struct sqlite3_stmt);
 
-[scriptable, uuid(76b1b70e-5740-488d-b910-3f0f02ab2fd1)]
+[scriptable, uuid(98379cef-b1da-4731-8556-402f0e55eb9f)]
 interface mozIStorageStatement : mozIStorageValueArray {
   /**
    * Initialize this query with the given SQL statement.
    *
    */
   void initialize(in mozIStorageConnection aDBConnection,
                   in AUTF8String aSQLStatement);
 
@@ -87,16 +87,24 @@ interface mozIStorageStatement : mozISto
   readonly attribute unsigned long columnCount;
 
   /**
    * Name of nth column
    */
   AUTF8String getColumnName(in unsigned long aColumnIndex);
 
   /**
+   * Obtains the index of the column with the specified name.
+   *
+   * @param aName The name of the column.
+   * @return The index of the column with the specified name.
+   */
+  unsigned long getColumnIndex(in AUTF8String aName);
+
+  /**
    * Reset parameters/statement execution
    */
   void reset();
 
   /**
    * Bind the given value to the parameter at aParamIndex.
    */
   void bindUTF8StringParameter(in unsigned long aParamIndex,
--- a/storage/src/mozStorageStatement.cpp
+++ b/storage/src/mozStorageStatement.cpp
@@ -136,20 +136,19 @@ mozStorageStatement::Initialize(mozIStor
     }
 
     mDBConnection = aDBConnection;
     mStatementString.Assign (aSQLStatement);
     mParamCount = sqlite3_bind_parameter_count (mDBStatement);
     mResultColumnCount = sqlite3_column_count (mDBStatement);
     mColumnNames.Clear();
 
-    for (unsigned int i = 0; i < mResultColumnCount; i++) {
-        const void *name = sqlite3_column_name16 (mDBStatement, i);
-        mColumnNames.AppendString(
-            nsDependentString(static_cast<const PRUnichar*>(name)));
+    for (PRUint32 i = 0; i < mResultColumnCount; i++) {
+        const char *name = sqlite3_column_name(mDBStatement, i);
+        mColumnNames.AppendCString(nsDependentCString(name));
     }
 
     // doing a sqlite3_prepare sets up the execution engine
     // for that statement; doing a create_function after that
     // results in badness, because there's a selected statement.
     // use this hack to clear it out -- this may be a bug.
     sqlite3_exec (db, "", 0, 0, 0);
 
@@ -252,16 +251,34 @@ mozStorageStatement::GetColumnName(PRUin
         return NS_ERROR_ILLEGAL_VALUE;
 
     const char *cname = sqlite3_column_name(mDBStatement, aColumnIndex);
     _retval.Assign(nsDependentCString(cname));
 
     return NS_OK;
 }
 
+/* unsigned long getColumnIndex(in AUTF8String aName); */
+NS_IMETHODIMP
+mozStorageStatement::GetColumnIndex(const nsACString &aName, PRUint32 *_retval)
+{
+    NS_ASSERTION (mDBConnection && mDBStatement, "statement not initialized");
+
+    // Surprisingly enough, SQLite doesn't provide an API for this.  We have to
+    // determine it ourselves sadly.
+    for (PRUint32 i = 0; i < mResultColumnCount; i++) {
+        if (mColumnNames[i]->Equals(aName)) {
+            *_retval = i;
+            return NS_OK;
+        }
+    }
+
+    return NS_ERROR_INVALID_ARG;
+}
+
 /* void reset (); */
 NS_IMETHODIMP
 mozStorageStatement::Reset()
 {
     NS_ASSERTION (mDBConnection && mDBStatement, "statement not initialized");
 
     PR_LOG(gStorageLog, PR_LOG_DEBUG, ("Resetting statement: '%s'", nsPromiseFlatCString(mStatementString).get()));
 
--- a/storage/src/mozStorageStatement.h
+++ b/storage/src/mozStorageStatement.h
@@ -63,16 +63,16 @@ private:
     ~mozStorageStatement();
 
 protected:
     nsCString mStatementString;
     nsCOMPtr<mozIStorageConnection> mDBConnection;
     sqlite3_stmt *mDBStatement;
     PRUint32 mParamCount;
     PRUint32 mResultColumnCount;
-    nsStringArray mColumnNames;
+    nsCStringArray mColumnNames;
     PRBool mExecuting;
 
     // recreate the statement, and transfer bindings
     nsresult Recreate();
 };
 
 #endif /* _MOZSTORAGESTATEMENT_H_ */
--- a/storage/test/unit/test_storage_statement.js
+++ b/storage/test/unit/test_storage_statement.js
@@ -81,16 +81,40 @@ function test_columnCount()
 
 function test_getColumnName()
 {
   var stmt = createStatement("SELECT name, id FROM test");
   do_check_eq("id", stmt.getColumnName(1));
   do_check_eq("name", stmt.getColumnName(0));
 }
 
+function test_getColumnIndex_same_case()
+{
+  var stmt = createStatement("SELECT name, id FROM test");
+  do_check_eq(0, stmt.getColumnIndex("name"));
+  do_check_eq(1, stmt.getColumnIndex("id"));
+}
+
+function test_getColumnIndex_different_case()
+{
+  var stmt = createStatement("SELECT name, id FROM test");
+  try {
+    do_check_eq(0, stmt.getColumnIndex("NaMe"));
+    do_throw("should not get here");
+  } catch (e) {
+    do_check_eq(Cr.NS_ERROR_INVALID_ARG, e.result);
+  }
+  try {
+  do_check_eq(1, stmt.getColumnIndex("Id"));
+    do_throw("should not get here");
+  } catch (e) {
+    do_check_eq(Cr.NS_ERROR_INVALID_ARG, e.result);
+  }
+}
+
 function test_state_ready()
 {
   var stmt = createStatement("SELECT name, id FROM test");
   do_check_eq(Ci.mozIStorageStatement.MOZ_STORAGE_STATEMENT_READY, stmt.state);
 }
 
 function test_state_executing()
 {
@@ -107,17 +131,19 @@ function test_state_executing()
               stmt.state);
   stmt.reset();
   do_check_eq(Ci.mozIStorageStatement.MOZ_STORAGE_STATEMENT_READY, stmt.state);
 }
 
 var tests = [test_parameterCount_none, test_parameterCount_one,
              test_getParameterName, test_getParameterIndex_different,
              test_getParameterIndex_same, test_columnCount,
-             test_getColumnName, test_state_ready, test_state_executing];
+             test_getColumnName, test_getColumnIndex_same_case,
+             test_getColumnIndex_different_case, test_state_ready,
+             test_state_executing];
 
 function run_test()
 {
   setup();
 
   for (var i = 0; i < tests.length; i++)
     tests[i]();