Revision 165415 of User talk:sdwilsh

  • Revision slug: User_talk:sdwilsh
  • Revision title: User talk:sdwilsh
  • Revision id: 165415
  • Created:
  • Creator: sdwilsh
  • Is current revision? No
  • Comment Removed FUEL stuff

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
// you should be able to bind numbered parameters (as well as unnumbered ones)
conn.executeAsync(
  "SELECT * FROM moz_downloads WHERE state = ?1",
  [Ci.nsIDownloadManager.DOWNLOAD_FINISHED],
  {
    handleResult: function(aResult)
    {
      for (let row in aResult) {
        // process data
        // should be able to access data in a row by name or argument number
      }
    },
    handleError: function(aError)
    {
      // update UI accordingly
    }
  }
);

// You should be able to bind parameters by name as well
conn.executeAsync(
  "SELECT * FROM moz_downloads WHERE state = :state",
  {state: Ci.nsIDownloadManager.DOWNLOAD_FAILED},
  {
    handleResult: function(aResult)
    {
      for (let row in aResult) {
        // process data
        // should be able to access data in a row by name or argument number
      }
    },
    handleError: function(aError)
    {
      // update UI accordingly
    }
  }
);
C++
class Listener : public Callback {
  NS_IMETHODIMP HandleResult(ResultSet aResult)
  {
    nsCOMPtr<mozIStorageValueArray> row;
    while (NS_SUCCEEDED(aResult->GetRow(row)) && row) {
      // do something with result
    }
  }

  NS_IMETHODIMP HandleError(?? aError)
  {
  }
};

// Special object for C++ to bind params - implements some predefined interface
nsRefPtr<Parameters> params(new Parameters());
params->Bind(0, nsIDownloadManager::DOWNLOAD_FINISHED);

// conn is a mozIStorageConnection
(void)conn->ExecuteAsync(
  NS_LITERAL_CSTRING("SELECT * FROM moz_downloads WHERE state = ?1"),
  params,
  new Listener()
);

// Also allows binding of named parameters
params = new Parameters();
parms->Bind(NS_LITERAL_CSTRING("state"), nsIDownloadManager::DOWNLOAD_FINISHED);
(void)conn->ExecuteAsync(
  NS_LITERAL_CSTRING("SELECT * FROM moz_downloads WHERE state = ?1"),
  params,
  new Listener()
);

Proposed Interface

This is a work in progress. Comments welcome.

mozIStorageConnection

These are necessary changes to the mozIStorageConnection interface.


void execute(in AUTF8String aSQL, [optional] in Parameters aParameters, [optional] in Callback aCallback);

Executes a sql statement and calls the callback when a result is returned.

Parameters

Interface to handle the adding of properties. This just offers a series of getters for storage to call. JS callers will be able to pass in an object or an array and the back-end will figure everything out. We'll provide a default implementation for C++ callers to use to make their lives easier as well.

unsigned short namedParameters;

The number of named parameters being bound

nsIVariant namedParameter(in unsigned short aStoredIndex, out AUTF8String name);

Obtains the value of a named parameter, as well as it's name.

unsigned short numberedParameters;

The number of numbered parameters being bound. This includes any parameters of the form \?{{mediawiki.external('0-9')}}*

nsIVariant numberedParameter(in unsigned short aStoredIndex, out unsigned long aBindingIndex);

Obtains the value of a numbered parameter, as well as it's bound index.

Callback

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

void handleResult(in ResultSet aResultSet);

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

void handleError(in SQLError aError);

Handles an error of the statement.

ResultSet

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

mozIStorageValueArray getNextResult();

Obtains the next tuple of results and advances the cursor. Null if no results available.

SQLError

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 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 name="Sample_Code"> Sample Code </h4>
<p>This is an attempt at some sample code on using async statements.
</p>
<h5 name="JavaScript"> JavaScript </h5>
<pre>// conn is a mozIStorageConnection
// you should be able to bind numbered parameters (as well as unnumbered ones)
conn.executeAsync(
  "SELECT * FROM moz_downloads WHERE state = ?1",
  [Ci.nsIDownloadManager.DOWNLOAD_FINISHED],
  {
    handleResult: function(aResult)
    {
      for (let row in aResult) {
        // process data
        // should be able to access data in a row by name or argument number
      }
    },
    handleError: function(aError)
    {
      // update UI accordingly
    }
  }
);

// You should be able to bind parameters by name as well
conn.executeAsync(
  "SELECT * FROM moz_downloads WHERE state = :state",
  {state: Ci.nsIDownloadManager.DOWNLOAD_FAILED},
  {
    handleResult: function(aResult)
    {
      for (let row in aResult) {
        // process data
        // should be able to access data in a row by name or argument number
      }
    },
    handleError: function(aError)
    {
      // update UI accordingly
    }
  }
);
</pre>
<h5 name="C.2B.2B"> C++ </h5>
<pre>class Listener : public Callback {
  NS_IMETHODIMP HandleResult(ResultSet aResult)
  {
    nsCOMPtr&lt;mozIStorageValueArray&gt; row;
    while (NS_SUCCEEDED(aResult-&gt;GetRow(row)) &amp;&amp; row) {
      // do something with result
    }
  }

  NS_IMETHODIMP HandleError(?? aError)
  {
  }
};

// Special object for C++ to bind params - implements some predefined interface
nsRefPtr&lt;Parameters&gt; params(new Parameters());
params-&gt;Bind(0, nsIDownloadManager::DOWNLOAD_FINISHED);

// conn is a mozIStorageConnection
(void)conn-&gt;ExecuteAsync(
  NS_LITERAL_CSTRING("SELECT * FROM moz_downloads WHERE state = ?1"),
  params,
  new Listener()
);

// Also allows binding of named parameters
params = new Parameters();
parms-&gt;Bind(NS_LITERAL_CSTRING("state"), nsIDownloadManager::DOWNLOAD_FINISHED);
(void)conn-&gt;ExecuteAsync(
  NS_LITERAL_CSTRING("SELECT * FROM moz_downloads WHERE state = ?1"),
  params,
  new Listener()
);
</pre>
<h4 name="Proposed_Interface"> Proposed Interface </h4>
<p>This is a work in progress.  Comments welcome.
</p>
<h5 name="mozIStorageConnection"> mozIStorageConnection </h5>
<p>These are necessary changes to the mozIStorageConnection interface.
</p><p><br>
<code>void execute(in <a href="en/AUTF8String">AUTF8String</a> aSQL, <span class="plain">[optional]</span> in <a href="#Parameters">Parameters</a> aParameters, <span class="plain">[optional]</span> in <a href="#Callback">Callback</a> aCallback);</code>
</p><p>Executes a sql statement and calls the callback when a result is returned.
</p>
<h5 name="Parameters"> Parameters </h5>
<p>Interface to handle the adding of properties.  This just offers a series of getters for storage to call.  JS callers will be able to pass in an object or an array and the back-end will figure everything out.  We'll provide a default implementation for C++ callers to use to make their lives easier as well.
</p><p><code>unsigned short namedParameters;</code>
</p><p>The number of named parameters being bound
</p><p><code><a href="en/NsIVariant">nsIVariant</a> namedParameter(in unsigned short aStoredIndex, out <a href="en/AUTF8String">AUTF8String</a> name);</code>
</p><p>Obtains the value of a named parameter, as well as it's name.
</p><p><code>unsigned short numberedParameters;</code>
</p><p>The number of numbered parameters being bound.  This includes any parameters of the form <code>\?{{mediawiki.external('0-9')}}*</code>
</p><p><code><a href="en/NsIVariant">nsIVariant</a> numberedParameter(in unsigned short aStoredIndex, out unsigned long aBindingIndex);</code>
</p><p>Obtains the value of a numbered parameter, as well as it's bound index.
</p>
<h5 name="Callback"> Callback </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="#ResultSet">ResultSet</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="#ResultSet">ResultSet</a> each time representing new data.
</p><p><code>void handleError(in <a href="#SQLError">SQLError</a> aError);</code>
</p><p>Handles an error of the statement.
</p>
<h5 name="ResultSet"> ResultSet </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="en/MozIStorageValueArray">mozIStorageValueArray</a> getNextResult();</code>
</p><p>Obtains the next tuple of results and advances the cursor.  Null if no results available.
</p>
<h5 name="SQLError"> SQLError </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 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