Bug 388059 - Add a getColumnIndex method to mozIStorageStatement. r=sspitzer
--- 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]();