<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html" />
  <link rel="self" type="application/atom+xml" href="http://www.insideria.com/atom.xml" />
  <id>tag:www.insideria.com,2009://34/tag:www.insideria.com,2008://34.23426-</id>
  <updated>2009-11-16T15:46:45Z</updated>
  <title>Comments for AIR API - Additional Query Techniques (http://www.insideria.com/2008/04/air-api-additional-query-tech.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2008://34.23426</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://blogs.oreilly.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=34/entry_id=23426" title="AIR API - Additional Query Techniques" />
    <published>2008-04-19T03:46:39Z</published>
    <updated>2008-04-18T12:21:42Z</updated>
    <title>AIR API - Additional Query Techniques</title>
    <summary><![CDATA[

In the previous tutorial, I demonstrated how to return all of the rows of a database table and access the results within AIR.  Many times you will not want to retrieve all of the rows in a table, so today I will examine some techniques for querying your tables.  I will focus on two main areas: Strongly Typing Results and Parameterized Queries.
&nbsp;]]></summary>
    <author>
      <name>David Tucker</name>
      <uri>http://www.davidtucker.net/</uri>
    </author>
    
    <category term="Blogs" />
    
    <content type="html" xml:lang="en" xml:base="http://www.insideria.com/">
      <![CDATA[<div class="ap_r" style="margin: 0 16px 16px 16px;"><a href="http://www.insideria.com/airLogo-Shadow.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/airLogo-Shadow.jpg" alt="airLogo-Shadow.jpg" title="Click to enlarge" width="148"/></a></div>

<p>In the <a href="http://www.insideria.com/2008/04/air-api-retrieving-results-fro.html">previous tutorial</a>, I demonstrated how to return all of the rows of a database table and access the results within AIR.  Many times you will not want to retrieve all of the rows in a table, so today I will examine some techniques for querying your tables.  I will focus on two main areas: Strongly Typing Results and Parameterized Queries.</p>

<h2><strong>Strongly Typing Your Results</strong></h2>

<p>As I mentioned in the previous article, by default SQLResult returns all of your data as weakly-typed objects.  AIR has the capability to return strongly-typed values to you as well.  To do this, you need to use the <code>itemClass</code> property of the SQLStatement class.  There are a few important things to consider though:</p>

<blockquote>
Any class assigned to this property must have a constructor that does not require any parameters. In addition, the class must have a single property for each column returned by the SELECT statement. It is considered an error if a column in the SELECT list does not have a matching property name in the itemClass class.
<br /><br />
<em>Reference: <a href="http://livedocs.adobe.com/flex/3/langref/flash/data/SQLStatement.html#itemClass" target="_blank">http://livedocs.adobe.com/flex/3/langref/flash/data/SQLStatement.html#itemClass</a></em>
</blockquote>

<p>If you already have VO's for your data, this would work very well.  If your class does not meet these requirements, your application will throw an error and let you know what property it could not map to your class.  If things work properly, your results should look different from the last tutorial.  Instead of a generic weakly-types Object, the results come back in the strongly typed format of choice (the sample below is from the example application included with this article).  You can use the <code>itemClass</code> property as below:</p>

<div class="acode" style="overflow:auto;padding: 10px;"><div style="overflow-x:visible;">
<code language="perl">
<pre>
<span class="linecomment">// Import the Needed Class</span>
<span class="category1">import</span> vo.Conctact;
...
<span class="linecomment">// Set the itemClass Property</span>
query.itemClass = Contact;</pre>
</code>

</div></div>

<div class="ap_c" style="margin: 16px;"><a href="http://www.insideria.com/dtucker/sqlresult3-large.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/dtucker/sqlresult3-small.jpg" alt="sqlresult3-small.jpg" title="Click to enlarge" width="400"/></a><div class="apcaption">Figure 1. Weakly Typed SQLResult Data</div></div>

<div class="ap_c" style="margin: 16px;"><a href="http://www.insideria.com/dtucker/sqlresult2-large.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/dtucker/sqlresult2-large.jpg" alt="sqlresult2-large.jpg" title="Click to enlarge" width="400"/></a><div class="apcaption">Figure 2. Striongly Typed SQLResult Data</div></div>

<h2><strong>Parameterized Queries</strong></h2>

<p>Another great feature within AIR is the ability to have parameterized queries.  This gives many benefits including: cleaner code, protection again SQL injection, and even closer type-matching to the database table.  Basically, it allows you to substitute  values in the query upon execution.  Let's look at an example:</p>

<div class="acode" style="overflow:auto;padding: 10px;"><div style="overflow-x:visible;">
<code language="perl">
<pre>
<span class="linecomment">// Create SQLStatement</span>
<span class="category1">var</span> query:SQLStatement = <span class="category1">new</span> SQLStatement;
<span class="category1">var</span> queryString:<span class="category2">String</span> = "<span class="quote">SELECT * from contacts WHERE firstName = :firstName AND lastName = :lastName</span>";
...
<span class="linecomment">// ADD-In Parameter Values</span>
query.parameters["<span class="quote">:firstName</span>"] = "<span class="quote">David</span>";
query.parameters["<span class="quote">:lastName</span>"] = "<span class="quote">Tucker</span>";

<span class="linecomment">// Populatr and Execute the Query</span>
query.<span class="category2">text</span> = queryString;
query.execute;</pre>
</code>

</div></div>

<p>In this example, the query string contains two parameters.  Parameters either begin with a : or a @ symbol.  After the symbol, is the name of the given parameter.  The actual instance of the query class also contains a property, parameters.  You can then assign your parameter names and values to the parameters property as shown above.</p>

<p>There is another way that you can use parameters - indexed parameters.  When you use indexed parameters, you don't refers to parameters by name, but rather you refer to them in the order that they appear in the query string.  Instead of using the previously mentioned symbols, indexed parameters are denoted by a ? in the query string.</p>

<div class="acode" style="overflow:auto;padding: 10px;"><div style="overflow-x:visible;">
<code language="perl">
<pre>
<span class="linecomment">// Create SQLStatement</span>
<span class="category1">var</span> query:SQLStatement = <span class="category1">new</span> SQLStatement;
<span class="category1">var</span> queryString:<span class="category2">String</span> = "<span class="quote">SELECT * from contacts WHERE firstName = ? AND lastName = ?</span>";
...
<span class="linecomment">// ADD-In Parameter Values</span>
query.parameters[0] = "<span class="quote">David</span>";
query.parameters[1] = "<span class="quote">Tucker</span>";

<span class="linecomment">// Populatr and Execute the Query</span>
query.<span class="category2">text</span> = queryString;
query.execute;</pre>
</code>

</div></div>

<p>Using either of these methods provides much cleaner and concise code than attempting to inject the value directly into the query string.</p>

<h2><strong>Example Application</strong></h2>

<p>This sample application uses both of the principles covered today: strongly typed results and parameterized queries.  This application also demonstrates the ability of AIR to handle larger databases.  Unlike the previous example (with 500 rows), this example has 10,000 rows.  Despite this additional data, the application still runs very quickly (at least on my machine).  This database is also included in the application files should you want to it one of your own projects.  If you want to look at the data, you can use of the SQLite administration tools that I mentioned in the <a href="http://www.insideria.com/2008/03/air-api-introduction-to-the-sq.html">first article of this series</a>.</p>

<p>To use the application, you will first need to click the connect button.  This will open the connection to the database file.  Next, you can type in anything into the search field and the application will look for matching values in either the firstName or lastName fields.  The results will be displayed in the DataGrid.  I also created a Contact value-object which allows the results to be strongly typed.  Finally, this data is passed to the SQLStatement through a parameterized query.  As always, <em>View Source</em> is enabled on the application and the source files can be downloaded below.</p>

<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = 9;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 115;
// AIR Version Required
var airVersion = "1.0";
// AIR Application Name
var airApplicationName = "Basic Query Example";
// AIR Application URL
var airApplicationURL = "http://www.insideria.com/dtucker/sqlite2.air";
// AIR Application Image
var airApplicationImage = "/dtucker/sqlite2.jpg";
// Directory of badge.swf file (optional)
var badgeDirectory = "/dtucker/";
// Directory of playerProductInstall.swf (optional)
var expressInstallDirectory = "/dtucker/"; 
// -----------------------------------------------------------------------------
// -->
</script>

<script src="/dtucker/AC_RunActiveContent.js" language="javascript"></script>
<div style="width: auto;text-align: center">
<script src="/dtucker/InstallBadge.js" language="javascript"></script>
</div>

<br />

<p><strong>Application Source Code</strong><br />
<a href="/dtucker/sqlite2.zip" target="_blank">Download</a> (259 kb)</p>]]>
      
    </content>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23426-comment:2016676</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23426" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html#comment-2016676" />
    <title>Comment from Ward Bell on 2008-04-20</title>
    <author>
        <name>Ward Bell</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>It looks like your random name generator mixed up first and last names; no big deal.</p>

<p>I'm new to FLEX and AIR and the DataGrid and ran into a problem when I tried to include the "id" as a DataGridColumn.  I tried different approaches with the Type and tried to do a substitution (public override function toString():String ) like your reference suggests, but all to no avail.</p>

<p>Is "id" a reserved word?  Had no problem with adding Gender to the Grid and changing the SQL so that results were filtered by gender, but I could not get a display of the "id" within the DataGrid.  What am I doing wrong?</p>]]>
    </content>
    <published>2008-04-20T22:59:22Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23426-comment:2016696</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23426" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html#comment-2016696" />
    <title>Comment from David Tucker on 2008-04-21</title>
    <author>
        <name>David Tucker</name>
        <uri>http://www.davidtucker.net/</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.davidtucker.net/">
        <![CDATA[<p>@Ward - It seems to work ok on my end.  Here is the DataGridColumn I used for the ID.</p>

<p></p>

<p>Let me know if you still are having issues with it.</p>]]>
    </content>
    <published>2008-04-21T17:15:14Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23426-comment:2016697</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23426" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html#comment-2016697" />
    <title>Comment from David Tucker on 2008-04-21</title>
    <author>
        <name>David Tucker</name>
        <uri>http://www.davidtucker.net/</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.davidtucker.net/">
        <![CDATA[<p>It didn't let me leave the actual code.  Just be sure to set dataField equal to id, but set id equal to something like dataID.</p>]]>
    </content>
    <published>2008-04-21T17:16:39Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23426-comment:2016706</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23426" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html#comment-2016706" />
    <title>Comment from Ward Bell on 2008-04-21</title>
    <author>
        <name>Ward Bell</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>@David -- Thanks, that worked like a charm!  I guess the issues was that setting "id = id" is a no-no!  Making it "dataID" solved the problem; must be some sort of key word thing.</p>]]>
    </content>
    <published>2008-04-22T03:44:15Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23426-comment:2068458</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23426" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/04/air-api-additional-query-tech.html#comment-2068458" />
    <title>Comment from Doug on 2009-07-17</title>
    <author>
        <name>Doug</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>What is a VO?</p>

<p>If you had used the full name, and not an acronym, I could have looked this up myself.</p>]]>
    </content>
    <published>2009-07-17T15:54:54Z</published>
  </entry>

</feed
