mozilla

Revision 165423 of User talk:sdwilsh

  • Revision slug: User_talk:sdwilsh
  • Revision title: User talk:sdwilsh
  • Revision id: 165423
  • Created:
  • Creator: Mardak
  • Is current revision? Yes
  • Comment /* storageIStatementCallback */ typo fix: now -> no

Revision Content

Async Storage Statements

This is loosely based off of the HTML 5 SQL spec. This is targeting Firefox 3.1 and whatever version of Gecko that will correlate with.

Sample Code

This is an attempt at some sample code on using async statements.

JavaScript
// conn is a mozIStorageConnection
let stmt = conn.createStatement("SELECT * FROM moz_downloads WHERE state = ?1");
stmt.bindInt32Parameter(0, Ci.nsIDownloadManager.DOWNLOAD_FINISHED);

stmt.executeAsync(
  {
    handleResult: function(aResultSet)
    {
      let tuple;
      while (tuple = aResultSet.getNextTuple()) {
        let value1 = tuple.getResultByName('columnName');
        let value2 = tuple.getResultByIndex(0);
      }
    },
    handleError: function(aError)
    {
      // update UI accordingly
    },
    handleCompletion: function()
    {
      // update UI accordingly
    }
  }
);
C++
class Listener : public Callback {
  NS_IMETHODIMP HandleResult(ResultSet aResult)
  {
    nsCOMPtr<storageITuple> tuple;
    while (NS_SUCCEEDED(aResult->GetNextTuple(tuple)) && tuple) {
      // do something with result
    }
  }

  NS_IMETHODIMP HandleError(SQLError aError)
  {
  }

  NS_IMETHODIMP HandleCompletion()
  {
  }
};

// conn is a mozIStorageConnection
nsCOMPtr<mozIStorageStatement> stmt;
(void)conn->CreateStatement(NS_LITERAL_CSTRING(
  "SELECT * FROM moz_downloads WHERE state = ?1"), getter_AddRefs(stmt));
(void)stmt->BindInt32Parameter(0, nsIDownloadManager::DOWNLOAD_FINISHED);

nsCOMPtr<nsICancelable> canceler; // This shouldn't be necessary to pass in.
(void)stmt->ExecuteAsync(new Listener(), getter_AddRefs(canceler));

Proposed Interface

This is a work in progress. Comments welcome.

mozIStorageStatement

These are necessary changes to the mozIStorageStatement interface.


nsICancelable executeAsync([optional] in storageIStatementCallback aCallback);

Executes a prepared mozIStorageStatement and calls the callback (if provided) when a result is returned. This statement is then reset, and can be reused synchronously or asynchronously again immediately. Returns an object that can be used to cancel the execution of the statement immediately.

storageIStatementCallback

Interface handles some sort of callback on the calling thread. This does not have to be the main thread.

void handleResult(in storageIResultSet aResultSet);

Handles a successful execution of the statement. This function may be called more than once with a different storageIResultSet each time representing new data.

void handleError(in storageIError aError);

Handles an error of the statement.

const unsigned short REASON_FINISHED = 0;
const unsigned short REASON_CANCELED = 1;
const unsigned short REASON_ERROR = 2;
void handleCompletion(in unsigned short aReason);

Called when there are no more results to be obtained. This is called only once with the reason why it is being called. REASON_FINISHED means that it finished successfully, REASON_CANCELED means that it was canceled, and REASON_ERROR means a fatal error occurred that execution could not continue from.

storageIResultSet

Interface used to get the data back. In JS, this should be able to be used as an Iterator.

storageITuple getNextTuple();

Obtains the next tuple from the result set and advances the cursor. Null if no results available.

storageITuple

Interface used to get data for a specific tuple. Inherits from mozIStorageValueArray.

nsIVariant getResultByIndex(in unsigned long aIndex);

Obtains the result for a given index in a JS friendly way.

nsIVariant getResultByName(in AUTF8String aName);

Obtains the result for a given named column in the tuple in a JS friendly way.

storageIError

Interface used to give information about an error.

TODO: What type of information do we want to give here?

Discussion

Please provide feedback in mozilla.dev.planning

Revision Source

<h3 id="Async_Storage_Statements" name="Async_Storage_Statements"> Async Storage Statements </h3>
<p>This is loosely based off of the <a class="external" href="http://www.whatwg.org/specs/web-apps/current-work/#executing">HTML 5 SQL spec</a>. This is targeting Firefox 3.1 and whatever version of Gecko that will correlate with.
</p>
<h4 id="Sample_Code" name="Sample_Code"> Sample Code </h4>
<p>This is an attempt at some sample code on using async statements.
</p>
<h5 id="JavaScript" name="JavaScript"> JavaScript </h5>
<pre>// conn is a mozIStorageConnection
let stmt = conn.createStatement("SELECT * FROM moz_downloads WHERE state = ?1");
stmt.bindInt32Parameter(0, Ci.nsIDownloadManager.DOWNLOAD_FINISHED);

stmt.executeAsync(
  {
    handleResult: function(aResultSet)
    {
      let tuple;
      while (tuple = aResultSet.getNextTuple()) {
        let value1 = tuple.getResultByName('columnName');
        let value2 = tuple.getResultByIndex(0);
      }
    },
    handleError: function(aError)
    {
      // update UI accordingly
    },
    handleCompletion: function()
    {
      // update UI accordingly
    }
  }
);
</pre>
<h5 id="C.2B.2B" name="C.2B.2B"> C++ </h5>
<pre>class Listener : public Callback {
  NS_IMETHODIMP HandleResult(ResultSet aResult)
  {
    nsCOMPtr&lt;storageITuple&gt; tuple;
    while (NS_SUCCEEDED(aResult-&gt;GetNextTuple(tuple)) &amp;&amp; tuple) {
      // do something with result
    }
  }

  NS_IMETHODIMP HandleError(SQLError aError)
  {
  }

  NS_IMETHODIMP HandleCompletion()
  {
  }
};

// conn is a mozIStorageConnection
nsCOMPtr&lt;mozIStorageStatement&gt; stmt;
(void)conn-&gt;CreateStatement(NS_LITERAL_CSTRING(
  "SELECT * FROM moz_downloads WHERE state = ?1"), getter_AddRefs(stmt));
(void)stmt-&gt;BindInt32Parameter(0, nsIDownloadManager::DOWNLOAD_FINISHED);

nsCOMPtr&lt;nsICancelable&gt; canceler; // This shouldn't be necessary to pass in.
(void)stmt-&gt;ExecuteAsync(new Listener(), getter_AddRefs(canceler));
</pre>
<h4 id="Proposed_Interface" name="Proposed_Interface"> Proposed Interface </h4>
<p>This is a work in progress. Comments welcome.
</p>
<h5 id="mozIStorageStatement" name="mozIStorageStatement"> mozIStorageStatement </h5>
<p>These are necessary changes to the <a href="en/MozIStorageStatement">mozIStorageStatement</a> interface.
</p><p><br>
<code><a href="en/NsICancelable">nsICancelable</a> executeAsync(<span class="nowiki">[optional]</span> in <a href="#storageIStatementCallback">storageIStatementCallback</a> aCallback);</code>
</p><p>Executes a prepared <a href="en/MozIStorageStatement">mozIStorageStatement</a> and calls the callback (if provided) when a result is returned. This statement is then reset, and can be reused synchronously or asynchronously again immediately. Returns an object that can be used to cancel the execution of the statement immediately.
</p>
<h5 id="storageIStatementCallback" name="storageIStatementCallback"> storageIStatementCallback </h5>
<p>Interface handles some sort of callback on the calling thread. This does not have to be the main thread.
</p><p><code>void handleResult(in <a href="#storageIResultSet">storageIResultSet</a> aResultSet);</code>
</p><p>Handles a successful execution of the statement. This function may be called more than once with a different <a href="#storageIResultSet">storageIResultSet</a> each time representing new data.
</p><p><code>void handleError(in <a href="#storageIError">storageIError</a> aError);</code>
</p><p>Handles an error of the statement.
</p><p><code>const unsigned short REASON_FINISHED = 0;</code><br>
<code>const unsigned short REASON_CANCELED = 1;</code><br>
<code>const unsigned short REASON_ERROR = 2;</code><br>
<code>void handleCompletion(in unsigned short aReason);</code>
</p><p>Called when there are no more results to be obtained. This is called only once with the reason why it is being called. REASON_FINISHED means that it finished successfully, REASON_CANCELED means that it was canceled, and REASON_ERROR means a fatal error occurred that execution could not continue from.
</p>
<h5 id="storageIResultSet" name="storageIResultSet"> storageIResultSet </h5>
<p>Interface used to get the data back. In JS, this should be able to be used as an Iterator.
</p><p><code><a href="#storageITuple">storageITuple</a> getNextTuple();</code>
</p><p>Obtains the next tuple from the result set and advances the cursor. Null if no results available.
</p>
<h4 id="storageITuple" name="storageITuple"> storageITuple </h4>
<p>Interface used to get data for a specific tuple. Inherits from <a href="en/MozIStorageValueArray">mozIStorageValueArray</a>.
</p><p><code><a href="en/NsIVariant">nsIVariant</a> getResultByIndex(in unsigned long aIndex);</code>
</p><p>Obtains the result for a given index in a JS friendly way.
</p><p><code><a href="en/NsIVariant">nsIVariant</a> getResultByName(in <a href="en/AUTF8String">AUTF8String</a> aName);</code>
</p><p>Obtains the result for a given named column in the tuple in a JS friendly way.
</p>
<h5 id="storageIError" name="storageIError"> storageIError </h5>
<p>Interface used to give information about an error.
</p><p>TODO: What type of information do we want to give here?
</p>
<h4 id="Discussion" name="Discussion"> Discussion </h4>
<p>Please provide feedback in <a class="external" href="http://groups.google.com/group/mozilla.dev.planning/browse_thread/thread/045fed0ecba487cc#">mozilla.dev.planning</a>
</p>
Revert to this revision