<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Words, punctuated &#187; local SQL database</title>
	<atom:link href="http://probertson.com/articles/category/air/local-sql-database/feed/" rel="self" type="application/rss+xml" />
	<link>http://probertson.com</link>
	<description>Thoughts on web development, user-centered design, code, etc. by Paul Robertson</description>
	<lastBuildDate>Tue, 20 Jul 2010 21:29:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Data &#8220;paging&#8221; in AIR SQLite</title>
		<link>http://probertson.com/articles/2010/04/07/data-paging-in-air-sqlite/</link>
		<comments>http://probertson.com/articles/2010/04/07/data-paging-in-air-sqlite/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 19:25:10 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=435</guid>
		<description><![CDATA[I got an interesting question a few days ago that I thought I&#8217;d share:
My application has thousands of records in one particular table that I need to populate the display with. I was wondering if I can implement paging to speed up the retrieval of those records?
In fact he specifically wanted to know if it [...]]]></description>
			<content:encoded><![CDATA[<p>I got an interesting question a few days ago that I thought I&#8217;d share:</p>
<blockquote><p>My application has thousands of records in one particular table that I need to populate the display with. I was wondering if I can implement paging to speed up the retrieval of those records?</p></blockquote>
<p class="editornote">In fact he specifically wanted to know if it was possible to do data paging with the SQLRunner class in my <a href="/projects/air-sqlite/">air-sqlite library</a>. The answer is yes it works, without even needing any changes to the library. See below for how to do that.</p>
<p>The easiest way to implement data paging (in other words, getting only a subset of a query&#8217;s results at a time) in a <code>SELECT</code> statement is to use the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/localDatabaseSQLSupport.html#select"><code>LIMIT..OFFSET</code> clause</a> in the <code>SELECT</code> statement.</p>
<p>In summary, you can put a <code>LIMIT</code> clause at the end of a <code>SELECT</code> statement and the result set will only include the specified number of rows:</p>
<pre class="brush:sql">SELECT * FROM myTable
LIMIT 3</pre>
<p>Then to get the next 3 rows, you add an <code>OFFSET</code> value:</p>
<pre class="brush:sql">SELECT * FROM myTable
LIMIT 3 OFFSET 3</pre>
<p>Fortunately, you can use statement parameters for the LIMIT and OFFSET values (although the docs don&#8217;t mention this &#8212; shame on me!):</p>
<pre class="brush:sql">SELECT * FROM myTable
LIMIT :limit OFFSET :offset</pre>
<p>Then you just specify values for those parameters and you&#8217;re good to go.</p>
<p>I tested this using the SQLRunner class by adding a <a href="http://github.com/probertson/air-sqlite/blob/master/tests/tests/com/probertson/data/SQLRunnerExecute.as">new set of unit tests</a> and it worked just fine without any changes to the library. (Hooray for unit tests and FlexUnit support in Flash Builder 4 &#8212; they made it nice and easy to test this out since I already had the infrastructure in place.)</p>
<p>Here is <a href="http://github.com/probertson/air-sqlite/blob/master/tests/sql/LoadRowsParameterizedLimitOffset.sql">the SQL statement I used for the unit test</a> using <code>LIMIT..OFFSET</code> with parameters:</p>
<pre class="brush:sql">SELECT colString,
colInt
FROM main.testTable
LIMIT :limit OFFSET :offset</pre>
<p>And here is <a href="http://github.com/probertson/air-sqlite/blob/master/tests/tests/com/probertson/data/SQLRunnerExecute.as#L125">the line of code that calls the statement</a> (modified slightly for readability). <code>test_result</code> is the result handler function. The parameters object specifies that I want 7 result rows, starting with row number 3 (i.e. skipping 2):</p>
<pre class="brush:actionscript3">_sqlRunner.execute(SQL, {limit:7, offset:2}, test_result);</pre>
<p class="editornote">As <a href="#comment-74422">Peter points out in the comments</a>, another approach to do something similar to data paging with AIR is to specify a number of rows to retrieve as the first argument to the <code>SQLStatement.execute()</code> method, then call the <code>SQLStatement.next()</code> method to retrieve additional rows from the same statement. This technique is <a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7d4c.html#WS5b3ccc516d4fbf351e63e3d118666ade46-7d46">described in the documentation</a> so I won&#8217;t go into more detail about it here except to say that it does have a couple of drawbacks (mentioned in my comment below) that make it less suitable for data paging (but still very useful).</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2010/04/07/data-paging-in-air-sqlite/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AIR SQLite library updates</title>
		<link>http://probertson.com/articles/2010/04/02/air-sqlite-library-updates/</link>
		<comments>http://probertson.com/articles/2010/04/02/air-sqlite-library-updates/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 09:18:14 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=432</guid>
		<description><![CDATA[A couple of people have reported a bug in my AIR SQLite utility library. I also recently used it to help build a Robotlegs demo app for the 360&#124;Flex Robotlegs training, and in the process I discovered a missing feature I needed (namely, the ability to get back the SQLResult objects after running a batch [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of people have reported a <a href="http://github.com/probertson/air-sqlite/issues/closed/#issue/1">bug</a> in my <a href="/projects/air-sqlite/">AIR SQLite utility library</a>. I also recently used it to help build a Robotlegs demo app for the 360|Flex Robotlegs training, and in the process I discovered a missing feature I needed (namely, the ability to get back the SQLResult objects after running a batch of statements using <code>SQLRunner.executeModify()</code>).</p>
<p><strong>Warning!</strong> To add the missing feature I had to introduce a non-backwards-compatible api change. Read the details in the <a href="/projects/air-sqlite/#history">project history</a>.</p>
<p>So, the bug is <a href="http://github.com/probertson/air-sqlite/commit/09f2e5cd8ea2c854e5a28475a0fd19f12526e44b">fixed</a>, the feature is <a href="http://github.com/probertson/air-sqlite/commit/27fbeab18a2e8bc1bff194cbc669e9e64c5dd822">added</a>, the version number is incremented (0.1.1 beta), and the <a href="http://github.com/probertson/air-sqlite">code</a> and <a href="http://github.com/probertson/air-sqlite/downloads">SWC</a> are live on Github.</p>
<p><a href="http://github.com/probertson/air-sqlite/downloads">Download the version 0.1.1 SWC</a></p>
<p><a href="/projects/air-sqlite/#history">Read about the changes</a></p>
<p>In conjunction with the release I also added a couple of new examples to the <a href="/projects/air-sqlite/">project page</a>, including a <a href="/projects/air-sqlite/#shortexamples">&#8220;bare bones&#8221; code only example</a> for quick starters, and links to an <a href="/projects/air-sqlite/#robotlegsexamples">example of using the library in a Robotlegs application</a> (the example app from the 360|Flex training).</p>
<p>Enjoy, and as always feel free to report problems as <a href="http://github.com/probertson/air-sqlite/issues">issues in Github</a> or in the <a href="/projects/air-sqlite/#respond">comments on the project page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2010/04/02/air-sqlite-library-updates/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>New project: AIR SQLite utilities</title>
		<link>http://probertson.com/articles/2010/02/03/new-project-air-sqlite-utilities/</link>
		<comments>http://probertson.com/articles/2010/02/03/new-project-air-sqlite-utilities/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 20:44:55 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=367</guid>
		<description><![CDATA[I&#8217;m excited to announce that I&#8217;m &#8220;officially&#8221; releasing a new open-source project that I&#8217;ve been using on personal and work projects for over a year.
For lack of a better name, I call it my &#8220;AIR SQLite utility library&#8221;
The code currently contains one major piece of functionality (well, two different variations on one bit of functionality), [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m excited to announce that I&#8217;m &#8220;officially&#8221; releasing a new open-source project that I&#8217;ve been using on personal and work projects for over a year.</p>
<p>For lack of a better name, I call it my &#8220;<a href="/projects/air-sqlite/">AIR SQLite utility library</a>&#8221;</p>
<p>The code currently contains one major piece of functionality (well, two different variations on one bit of functionality), which is a SQL &#8220;query runner&#8221; library. This is a wrapper for the AIR SQL classes that allows you to run a SQL statement by just passing a few bits of information:</p>
<ul>
<li>The text of the SQL statement itself</li>
<li>An object containing properties with the values for any statement parameters in the SQL</li>
<li>A Function to call when the operation completes</li>
<li>A failure Function</li>
<li>(optionally) a class to use as the data type for the data returned from a <code>SELECT</code> statement</li>
</ul>
<p>The library does all the work of creating SQLStatement objects and caching prepared queries, as well as pooling SQLConnection instances so you can execute multiple statements simultaneously. It also has a variation that allows you to specify a &#8220;batch&#8221; of statements to execute, and they are executed in order in a transaction.</p>
<p>I&#8217;ve also got an additional utility to add to the library. It&#8217;s a &#8220;database copy&#8221; utility that allows you to create a &#8220;deep copy&#8221; of a database &#8212; all it&#8217;s tables, views, etc. &#8212; with or without data. The key reason why this is useful is that you can use it to create an encrypted database from an unencrypted database (and vice-versa). It&#8217;s written and tested, but I decided to modify the structure slightly before releasing it, so it&#8217;s not checked in yet.</p>
<p>I&#8217;ve put the details about how it works and why it&#8217;s designed that way in <a href="/projects/air-sqlite/">the project page</a>. In case you&#8217;ve ever wondered how I design apps, I think the examples and this library give some insight into how I actually do my database-driven AIR app development. At least, how I structure the data-access part of my apps.</p>
<p>On (another) personal note, this project is also my first project that I&#8217;ve posted to <a href="http://github.com/probertson">my Github repository</a> (as opposed to projects I&#8217;ve forked). It was actually posted-but-not-advertised on Google code for a month or so, but I decided to move to Github because the collaboration and checkin-without-network-connection features are so awesome.</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2010/02/03/new-project-air-sqlite-utilities/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multi-table INSERT using one SQL statement in AIR SQLite</title>
		<link>http://probertson.com/articles/2009/11/30/multi-table-insert-one-statement-air-sqlite/</link>
		<comments>http://probertson.com/articles/2009/11/30/multi-table-insert-one-statement-air-sqlite/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 06:00:08 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=343</guid>
		<description><![CDATA[This article describes a way that you can use a single INSERT statement to add data to multiple tables in the SQL dialect supported by the SQLite engine in Adobe AIR.
Normally in SQL, including in AIR&#8217;s built-in SQLite database engine, you can only add data to one table at a time using an INSERT statement. [...]]]></description>
			<content:encoded><![CDATA[<p>This article describes a way that you can use a single <code>INSERT</code> statement to add data to multiple tables in the SQL dialect supported by the SQLite engine in Adobe AIR.</p>
<p>Normally in SQL, including in AIR&#8217;s built-in SQLite database engine, you can only add data to one table at a time using an <code>INSERT</code> statement. In some cases, particularly when you&#8217;re doing a &#8220;bulk loading&#8221; operation such as importing data from a text file into a database, it&#8217;s convenient to be able to insert data into multiple tables using a single <code>INSERT</code> statement.</p>
<p>For example, suppose you have XML data to import into a database such as the following:</p>
<pre>&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;employees&gt;
    &lt;employee firstName=&quot;Bob&quot; lastName=&quot;Smith&quot;
        location=&quot;San Francisco&quot; country=&quot;USA&quot;/&gt;
    &lt;employee firstName=&quot;Harold&quot; lastName=&quot;Jones&quot;
        location=&quot;San Francisco&quot; country=&quot;USA&quot;/&gt;
    &lt;employee firstName=&quot;Tom&quot; lastName=&quot;Donovan&quot;
        location=&quot;Boston&quot; country=&quot;USA&quot;/&gt;
    &lt;employee firstName=&quot;Mike&quot; lastName=&quot;Wilson&quot;
        location=&quot;Calgary&quot; country=&quot;Canada&quot;/&gt;
    &lt;employee firstName=&quot;Steve&quot; lastName=&quot;Thomas&quot;
        location=&quot;London&quot; country=&quot;UK&quot;/&gt;
    &lt;employee firstName=&quot;Joe&quot; lastName=&quot;Nelson&quot;
        location=&quot;London&quot; country=&quot;UK&quot;/&gt;
    &lt;employee firstName=&quot;Juan&quot; lastName=&quot;Varga&quot;
        location=&quot;Buenos Aires&quot; country=&quot;Argentina&quot;/&gt;
    ...
&lt;/employees&gt;</pre>
<p>The XML data isn&#8217;t normalized, so there is duplicate data between the various records. We will import it into a database with the following (normalized) structure:</p>
<p><img src="/resources/2009/11/30/multi_table_insert_data_model.png" width="400" height="430" alt="Data model for the database" /></p>
<p>Assuming the data is going to be imported as a single user operation, it would be painful to need to prompt the user or throw errors for every duplicate entry.</p>
<p>Using the technique described here, you can use a single SQL statement to add an employee and if necessary any related data including office location and country. (You would still loop over the data and execute one <code>INSERT</code> statement per employee record &#8212; but you wouldn&#8217;t need to execute three <code>INSERT</code> statements per employee record, or need to check for duplicate office locations and countries for each employee record to be inserted.)</p>
<p>As mentioned above, this technique is probably only appropriate when you&#8217;re doing &#8220;bulk importing&#8221; of data. If you&#8217;re just adding a single conceptual record (even if it includes data in multiple tables) you&#8217;ll most likely want to use a series of <code>INSERT</code> statements to add the data, so that you can have more precise error checking and handling.</p>
<h2>How to do it</h2>
<p>In an attempt to &#8220;cut to the chase&#8221; I&#8217;m going to put the necessary code here. For more detailed explanations on how this works and why it&#8217;s necessary, see the &#8220;<a href="#details">details</a>&#8221; section below.</p>
<p>This technique for inserting data into multiple tables using a single SQL statement consists of three elements:</p>
<ol>
<li>A view in the database that groups the data to be inserted (from all the tables) into one &#8220;table&#8221;</li>
<li>An <code>INSERT</code> statement to add the data, using the view as the destination &#8220;table&#8221; in the <code>INSERT</code> statement. This is the <code>INSERT</code> statement that you&#8217;ll run from your application while importing the data</li>
<li>A trigger defined on the view, which runs when any <code>INSERT</code> statement is executed against the view. This trigger does the actual work of checking for existing data and inserting data into individual tables.</li>
</ol>
<p>Here&#8217;s the code for each part:</p>
<h3>A view grouping the data to insert</h3>
<p>This combines all the tables that potentially need data inserted into a single &#8220;table&#8221; for the <code>INSERT</code> statement. You run this statement once to create the view in the database.</p>
<pre>CREATE VIEW employees_for_insert AS
SELECT e.firstName,
    e.lastName,
    l.name AS locationName,
    c.name AS countryName
FROM employees e
    INNER JOIN locations l ON e.locationId = l.locationId
    INNER JOIN countries c ON l.countryId = c.countryId</pre>
<h3>An <code>INSERT</code> statement that &#8220;inserts&#8221; the data into the view</h3>
<p>This code isn&#8217;t actually run, but it passes all the data to the database engine for use in the trigger. You execute this SQL statement once for each record to add to the tables.</p>
<pre>INSERT INTO employees_for_insert
(
    firstName,
    lastName,
    locationName,
    countryName
)
VALUES
(
    :firstName,
    :lastName,
    :locationName,
    :countryName
)</pre>
<h3>An <code>INSTEAD OF</code> trigger defined on the view</h3>
<p>This is the code that actually runs when the <code>INSERT</code> statement above is executed. You run this code once to create the trigger. Then the database runs the code in the trigger body automatically. If a location or country doesn&#8217;t exist it is inserted. However, if they do exist, nothing happens (no duplicate record is created). Then the main employee record is inserted.</p>
<pre>CREATE TRIGGER insert_employees_locations_countries
INSTEAD OF INSERT
ON employees_for_insert

BEGIN

INSERT INTO countries (name)
SELECT NEW.countryName
WHERE NOT EXISTS
    (SELECT 1 FROM countries
     WHERE name = NEW.countryName);

INSERT INTO locations (name, countryId)
SELECT NEW.locationName, countries.countryId
FROM countries
WHERE countries.name = NEW.countryName
AND NOT EXISTS
    (SELECT locationId
     FROM locations
     WHERE name = NEW.locationName);

INSERT INTO employees (firstName, lastName, locationId)
SELECT NEW.firstName,
    NEW.lastName,
    locations.locationId
FROM locations
WHERE locations.name = NEW.locationName;

END</pre>
<h2 id="details">Details</h2>
<p>The SQL language is designed for working with relational databases, so in a SQL database you usually use multiple tables to represent a single piece of data. That means that in a normal scenario, if you want to add a new record to a table, you may need to add a new row of data to additional tables that the main data is related to.</p>
<p>In this example, we are using a database with the following structure:</p>
<p><img src="/resources/2009/11/30/multi_table_insert_data_model.png" width="400" height="430" alt="Data model for the database" /></p>
<p>This data represents employees in a large company that has multiple office locations, identified by records in the <code>locations</code> table. In fact, this company is an international company that has offices in different countries, including multiple offices in some countries (represented by the <code>countries</code> table.</p>
<p>Each employee is associated with their primary office location by the <code>locationId</code> field in the <code>employees</code> table, and each location is defined as being in a certain country by the <code>countryId</code> column in the <code>locations</code> table.</p>
<p>In order to add a new employee you would generally have to perform several steps:</p>
<ol>
<li>Check whether the country where the employee&#8217;s office is located exists in the <code>countries</code> table</li>
<li>If not, add it; if so, get its id to create the relationship with the <code>locations</code> table</li>
<li>Make sure the office location exists in the <code>locations</code> table</li>
<li>If necessary add the location record, and get its id to use in the employee record</li>
<li>Add the employee record to the <code>employees</code> table</li>
</ol>
<p>This is a fairly complicated process because a single SQL <code>INSERT</code> statement can only operate on one table at a time. In a simple case where you are adding a single employee record, this complexity isn&#8217;t unbearably difficult. You can execute the series of SQL statements in sequence in a single transaction. If an error occurs, you can break out of the sequence and display an error message or handle the error as desired.</p>
<p>However, if you&#8217;re importing a large set of data it&#8217;s not convenient to throw errors or display dialogs to the user. Instead, it would be nice to be able to just add any dependent data where appropriate, and insert all the data in one step.</p>
<p>The technique that&#8217;s described in this article makes use of database views and a SQLite feature known as <code>INSTEAD OF</code> triggers.</p>
<p>A <em>view</em> is a predefined <code>SELECT</code> statement that&#8217;s saved in a database so it can be used in queries as though it was a table. Because it usually includes data from multiple tables, and doesn&#8217;t necessarily include all the data from any given table, a view is generally read-only &#8212; you can use a <code>SELECT</code> statement to retrieve data from a view, but you can&#8217;t use an <code>INSERT</code>, <code>UPDATE</code>, or <code>DELETE</code> statement to modify the view data.</p>
<p>However, in SQLite (and consequently in AIR) you can define a special type of trigger that&#8217;s associated with a view known as an <code>INSTEAD OF</code> trigger. (A trigger is a set of SQL code that&#8217;s associated with a table. The code is executed when a data manipulation operation is performed on that table.) When a SQL statement attempts to perform an <code>INSERT</code>, <code>DELETE</code>, or <code>UPDATE</code> operation on the view that has an <code>INSTEAD OF</code> trigger defined for that particular operation, the trigger is executed <em>instead of</em> the specified operation. You can only define <code>INSTEAD OF</code> triggers on views (it wouldn&#8217;t make sense to use one for a table). For more information about triggers, see <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/localDatabaseSQLSupport.html#createTrigger">the Adobe AIR SQL reference documentation for the <code>CREATE TRIGGER</code> statement</a>.</p>
<p>In this example, a view is defined that includes all the data in all the tables that potentially need data inserted. When the <code>INSERT</code> statement is executed the database runs the trigger instead. The trigger contains code that checks whether related data in the locations and countries tables already exists, and adds it if necessary. Then it adds the employee record with the related key values.</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2009/11/30/multi-table-insert-one-statement-air-sqlite/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>&#8220;Adobe AIR data privacy and security&#8221; - slides, notes, links</title>
		<link>http://probertson.com/articles/2009/06/09/adobe-air-data-privacy-and-security-slides-notes-links/</link>
		<comments>http://probertson.com/articles/2009/06/09/adobe-air-data-privacy-and-security-slides-notes-links/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 17:03:48 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Privacy/security]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=279</guid>
		<description><![CDATA[On May 20, 2009 at the 360&#124;Flex conference in Indianapolis I gave a presentation titled &#8220;Adobe AIR data privacy and security.&#8221; As I always do (and after a bit of a delay), here are the slides from my presentation. I&#8217;ve added fairly lengthy notes to the slides (I had to make the font smaller so [...]]]></description>
			<content:encoded><![CDATA[<p>On May 20, 2009 at the 360|Flex conference in Indianapolis I gave a presentation titled &#8220;Adobe AIR data privacy and security.&#8221; As I always do (and after a bit of a delay), here are the slides from my presentation. I&#8217;ve added fairly lengthy notes to the slides (I had to make the font smaller so they&#8217;d fit on the pages) so it&#8217;s more than just bullet points.</p>
<p><a href="/resources/2009/06/09/air-data-privacy-security-slides-links.zip">Adobe AIR data privacy and security slides, notes, and links</a> (1 MB .zip)</p>
<p>As a side note for those who actually attended the presentation, in retrospect I think I over-emphasized the security concerns and didn&#8217;t emphasize enough that there are plenty of use cases for which AIR is definitely secure &#8212; especially in the case where you need to keep the user&#8217;s private data secure. Hopefully the notes that accompany the slides help to clarify this somewhat.</p>
<p>I also used and referred to a number of resources in my presentation, which are listed below. The download .zip with the slides also includes an html page with all these links.</p>
<h2>Introduction</h2>
<ul>
<li>&quot;<a href="http://tv.adobe.com/#vi+f15384v1025">Maintaining security with Adobe AIR</a>&quot; by Ethan Malasky and Peleus Uhley (Adobe MAX 2008)</li>
</ul>
<h2>Background</h2>
<ul>
<li>&quot;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7fa3.html">AIR security</a>&quot; (Adobe AIR documentation)</li>
<li>&quot;<a href="http://blogs.adobe.com/simplicity/2009/03/why_air_does_not_include_your_favorite_feature.html">Why Adobe AIR Doesn&#8217;t (Yet) Include the Feature You Most Want</a>&quot; by Oliver Goldman</li>
<li>&quot;<a href="http://tv.adobe.com/#vi+f15384v1102">Understanding the Flash Player Security Model</a>&quot; by Deneb Meketa (Adobe MAX 2008)</li>
<li>&quot;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS34990ABF-C893-47ec-B813-9C9D9587A398.html">Considerations for using encryption with a database</a>&quot; (Adobe AIR documentation)</li>
<li>&quot;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118676a5be7-8000.html">Using digital rights management</a>&quot; (Adobe AIR documentation)</li>
<li>Operating system security (user and &quot;admin&quot; rights)
<ul>
<li>&quot;<a href="http://blogs.adobe.com/simplicity/2009/04/what_are_administrative_rights.html">What are Adminstrative Rights, Anyway?</a>&quot; by Oliver Goldman</li>
<li>&quot;<a href="http://blogs.adobe.com/simplicity/2009/04/does_installing_an_air_app_require_admin_rights.html">Does Installing an AIR Application Require Admin Rights?</a>&quot; by Oliver Goldman</li>
</ul>
</li>
<li>Source code visibility
<ul>
<li><a href="http://www.buraks.com/asv/">Action Script Viewer (ASV)</a></li>
<li>&quot;<a href="http://www.gotoandlearn.com/play?id=70">Ethical SWF Decompiling</a>&quot; by Lee Brimelow</li>
<li><a href="http://www.nitrolm.com/home">Nitro-LM</a></li>
</ul>
</li>
<li>Encryption: ActionScript  crypto libraries:
<ul>
<li><a href="http://code.google.com/p/as3crypto/">as3crypto</a></li>
<li><a href="http://labs.adobe.com/wiki/index.php/Alchemy:Libraries">OpenSSL (partially) cross-compiled to ActionScript</a> using <a href="http://labs.adobe.com/technologies/alchemy/">Alchemy</a></li>
</ul>
</li>
</ul>
<h2>AIR application installation</h2>
<ul>
<li>Sign your app with a trusted cert
<ul>
<li>&quot;<a href="http://www.ddj.com/architect/210004209">Code Signing in Adobe AIR</a>&quot; by Oliver Goldman</li>
<li>&quot;<a href="http://www.stage.adobe.com/devnet/air/articles/signing_air_applications.html">Digitally signing Adobe AIR applications</a>&quot; by Todd Prekaski</li>
<li>Promotion: get a free signing certificate (while supplies last) by submitting your app to the <a href="http://www.adobe.com/go/airmarketplace">Adobe AIR marketplace</a></li>
</ul>
</li>
<li>Plan for updates
<ul>
<li>&quot;<a href="http://www.adobe.com/devnet/air/articles/tips_building_air_apps.html">Building AIR applications that can be easily updated</a>&quot; by David Deraedt</li>
<li>&quot;<a href="http://www.adobe.com/devnet/air/flex/quickstart/update_framework.html">Using the Adobe AIR update framework</a>&quot; Quick Start article by Jeff Swartz (Adobe AIR documentation)</li>
</ul>
</li>
</ul>
<h2>Modular applications</h2>
<ul>
<li>Sandbox bridge
<ul>
<li>&quot;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7e5c.html">Scripting between content in different domains</a>&quot; (Adobe AIR documentation)</li>
</ul>
</li>
<li>XML signature validation
<ul>
<li>&quot;<a href="http://www.adobe.com/devnet/air/flex/quickstart/xml_signatures.html">Creating and validating XML signatures</a>&quot; by Joe Ward</li>
<li>&quot;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WSe3d2d529026165536d4beb2c11c33737198-8000.html">Using the XML signature validation classes</a>&quot; (Adobe AIR documentation)</li>
<li>&quot;<a href="http://livedocs.adobe.com/flex/3/langref/index.html?flash/security/package-detail.html&amp;flash/security/class-list.html">flash.security package</a>&quot; reference (Adobe AIR documentation)</li>
</ul>
</li>
</ul>
<h2>Local shared objects</h2>
<p>[No links]</p>
<h2>Encrypted Local Store</h2>
<ul>
<li>&quot;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7e31.html">Storing encrypted data</a>&quot; (Adobe AIR documentation)</li>
<li>&quot;<a href="http://livedocs.adobe.com/flex/3/langref/index.html?flash/data/EncryptedLocalStore.html&amp;flash/data/class-list.html">EncryptedLocalStore class</a>&quot; reference (Adobe AIR documentation)</li>
</ul>
<h2>Local files</h2>
<p>[No links]</p>
<h2>Local SQL database (SQLite)</h2>
<ul>
<li>SQL injection attack
<ul>
<li>&quot;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7d42.html">Using parameters in statements</a>&quot; (Adobe AIR documentation)</li>
<li>&quot;<a href="http://livedocs.adobe.com/flex/3/langref/index.html?flash/data/SQLStatement.html#parameters&amp;flash/data/class-list.html">SQLStatement.parameters property</a>&quot; reference (Adobe AIR documentation)</li>
</ul>
</li>
<li>Encrypted database
<ul>
<li>&quot;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS8AFC5E35-DC79-4082-9AD4-DE1A2B41DAAF.html">Using encryption with SQL databases</a>&quot; (Adobe AIR documentation)</li>
<li>&quot;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS44EC31A7-61B1-4e0a-8C61-D720AA95DE03.html">Using the EncryptionKeyGenerator class to obtain a secure encryption key</a>&quot; (Adobe AIR documentation)</li>
<li><a href="http://code.google.com/p/as3corelib/">as3corelib project</a> (includes the EncryptionKeyGenerator class and hashing algorithms</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2009/06/09/adobe-air-data-privacy-and-security-slides-notes-links/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A new (old) tool for AIR SQLite development</title>
		<link>http://probertson.com/articles/2009/04/22/a-new-old-tool-for-air-sqlite-development/</link>
		<comments>http://probertson.com/articles/2009/04/22/a-new-old-tool-for-air-sqlite-development/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 22:41:33 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=272</guid>
		<description><![CDATA[This is pretty much old news by internet time standards, but I haven&#8217;t had time to write about it until now. (We&#8217;re working hard to make future Flex/AIR/ActionScript/Flash documentation more focused on how you actually use documentation, better than ever before.)
A couple of years ago, before AIR beta 1 (&#8220;Apollo&#8221;), I wrote a tool for [...]]]></description>
			<content:encoded><![CDATA[<p>This is pretty much old news by internet time standards, but I haven&#8217;t had time to write about it until now. (We&#8217;re working hard to make future Flex/AIR/ActionScript/Flash documentation more focused on how you actually use documentation, better than ever before.)</p>
<p>A couple of years ago, before AIR beta 1 (&#8220;Apollo&#8221;), I wrote a tool for testing SQL statements in AIR. Later (I can&#8217;t remember exactly when) I released it under the name &#8220;<a href="/projects/doppler-air-sql-admin-tool/">Doppler</a>.&#8221; I had plans to make it a full-fledged database management tool, but those plans never really panned out. I&#8217;ve told this story lots of times now, about how I now use (and even help develop) <a href="http://www.dehats.com/drupal/?q=node/58">David Deraedt’s “Lita” SQLite admin tool</a>.</p>
<p>However, &#8220;Doppler&#8221; in its current form served a different need than Lita &#8212; Lita is great for creating and managing database structure (you&#8217;ll never have to write a CREATE TABLE statement again), but it isn&#8217;t as strong for testing individual SQL statements. Over the past several months I&#8217;ve been doing some &#8220;serious&#8221; app development, working on an AIR app that makes heavy use of SQLite. I found my little tool to be quite handy, and also found and implemented a number of small improvements that make it much more useful.</p>
<p>Since my original intentions were never going to come to fruition, and I had new future plans for the app, I decided a new name was in order. Since it is for running SQL statements, &#8220;run&#8221; was an easy and obvious choice. So now, (several weeks after posting it), allow me to officially introduce you to the <a href="/projects/run-air-sqlite-query-testing-tool/">Run! AIR SQL query authoring and testing tool</a> &#8212; the next generation of Doppler.</p>
<p>If you look at the <a href="/projects/run-air-sqlite-query-testing-tool/#history">full feature list for the latest release</a>, you&#8217;ll see that I&#8217;ve added several types of changes. A few of the ones that I&#8217;ve found most useful in my day-to-day work are:</p>
<ul>
<li>Auto-update and badge install &#8212; no more downloading the .air file (admittedly not a big deal) and no more uninstall and reinstall each time there&#8217;s a new version (a big deal)</li>
<li>&#8220;Recent SQL files&#8221; and &#8220;Recent databases&#8221; menu items</li>
<li>Opening and saving SQL files (plus keyboard shortcuts)</li>
<li>&#8220;Row count&#8221; and &#8220;execution time&#8221; displayed for SELECT statements</li>
<li>Line numbers and auto-indent in the SQL panel</li>
</ul>
<p>And yes, I did say &#8220;day-to-day&#8221; work. On some days, Run! has been my primary IDE, as I&#8217;m writing and testing and rewriting large SQL statements. It&#8217;s been kind of strange and kind of fun building a developer tool and using it as much as I use Run!.</p>
<p>I&#8217;ve already gotten a bug report and I&#8217;m working on features for the next big release, so if you have thoughts or comments please comment on the project page!</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2009/04/22/a-new-old-tool-for-air-sqlite-development/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A useful tool, the joy of shipping code, and a great developer</title>
		<link>http://probertson.com/articles/2009/03/12/useful-tool-joy-of-shipping-code/</link>
		<comments>http://probertson.com/articles/2009/03/12/useful-tool-joy-of-shipping-code/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 18:23:09 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=240</guid>
		<description><![CDATA[If you use David Deraedt&#8217;s great AIR SQLite administration tool Lita, you probably already saw that he just pushed an update (v. 1.2) a few days ago. Aside from my general happiness from seeing that this release fixes some bugs and adds new features that were important to me, this release has personal significance for [...]]]></description>
			<content:encoded><![CDATA[<p>If you use <a href="http://www.dehats.com/">David Deraedt</a>&#8217;s great <a href="http://www.dehats.com/drupal/?q=node/58">AIR SQLite administration tool Lita</a>, you probably already saw that he just pushed an update (v. 1.2) a few days ago. Aside from my general happiness from seeing that this release fixes some bugs and adds new features that were important to me, this release has personal significance for me as well. As David <a href="http://www.dehats.com/drupal/?q=node/75">noted last week</a>, I have joined him as a contributor to the project. So in fact, some of those bug fixes and new features were done by me! I&#8217;ve discovered that there are few feelings greater than wanting a feature in a tool you use every day, and then actually implementing it. =) Upgrading is more fun when you see your own bugs in the release notes, too =)</p>
<p>As David pointed out, the fact that I&#8217;m an Adobe employee and am participating in the project doesn&#8217;t mean it&#8217;s now an official Adobe product (for good or bad). I&#8217;m doing this 100% on my own time. And my role is still pretty small &#8212; David is certainly the lead, main, primary, controlling, etc. author. I just file bugs as I find them, add some comments about feature requests, and fix issues when I know how to.</p>
<p>In case you&#8217;re curious, the back story is really pretty straightforward. I started writing my own version of an AIR SQLite admin tool back before AIR beta 1, but never had time to take it beyond a &#8220;query runner&#8221; tool. Late in 2008 I discovered Lita, and once I started using it I realized that 1) it is implemented in a similar way to many of the ideas I had, and 2) It&#8217;s already got a big head start in features, so there&#8217;s not much point in me trying to &#8220;compete&#8221; or anything like that, especially for something that I wasn&#8217;t planning to make money from.</p>
<p>After using it for a while I discovered a few bugs, and decided to email David about them. (He and I had communicated a bit previously, about the <a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS8AFC5E35-DC79-4082-9AD4-DE1A2B41DAAF.html">encrypted database functionality added in Adobe AIR 1.5</a> and how to integrate it into Lita.) I think I probably mentioned in that message that I would be willing/interested to fix issues myself as I have time. Fortunately David was very kind and accepted my offer. So, as I said, now when I find issues I get to fix them myself, which is nice because I can fix them quickly, but also adds some responsibility since now the burden is on me to make those changes myself =)</p>
<p>As a side note, I really want to point out that David is a really great developer &#8212; something I appreciate greatly as we work in the same codebase. It is a big testament to his architectural and coding skills that I was able to dive right in and fix four bugs/feature requests in a very short time (literally a matter of minutes after first looking at the code). I&#8217;ve learned a lot just from seeing his code, and now I&#8217;m anxious to read his <a href="http://www.dehats.com/drupal/?q=node/32">&#8220;Flex Architecture Fundamentals&#8221; series</a> to learn more about the thinking behind the great code.</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2009/03/12/useful-tool-joy-of-shipping-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Now updated: &#8220;Doppler&#8221; AIR SQL query testing tool</title>
		<link>http://probertson.com/articles/2009/01/26/updates-to-doppler-air-sql-query-testing-tool/</link>
		<comments>http://probertson.com/articles/2009/01/26/updates-to-doppler-air-sql-query-testing-tool/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 06:20:45 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Elsewhere on the web]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Sites to remember]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=224</guid>
		<description><![CDATA[I just wanted to write a quick note to say that I&#8217;ve released an update to my &#8220;Doppler&#8221; AIR SQL admin tool. You can get it from the Doppler project page. (I&#8217;ve been working on an actual real application, one with a fair amount of database work, so naturally I&#8217;ve found motivation to fix some [...]]]></description>
			<content:encoded><![CDATA[<p>I just wanted to write a quick note to say that I&#8217;ve released an update to my &#8220;Doppler&#8221; AIR SQL admin tool. You can get it from the <a href="/projects/doppler-air-sql-admin-tool/">Doppler project page</a>. (I&#8217;ve been working on an actual real application, one with a fair amount of database work, so naturally I&#8217;ve found motivation to fix some lingering bugs and add some missing functionality.)</p>
<p>As with previous versions, if you&#8217;ve been using the app you&#8217;ll need to uninstall it before installing the new version. Someday I&#8217;ll add updating support, but I&#8217;m not going to promise anything real soon.</p>
<p>Along with this release, I&#8217;ve also made a change to how I describe the tool, and to my future intentions for it. I&#8217;ve always had it in my mind to make this a full-fledged database admin tool, similar to the tools that come with SQL Server or other enterprise databases. However, time has obviously not allowed me to do that, and in the mean time other tools have been released by other developers. I&#8217;ve found one, <a href="http://www.dehats.com/drupal/?q=node/58">David Deraedt’s “Lita” SQLite admin tool</a> that is sufficiently mature that I use it in my day-to-day work now and it definitely beats doing things by hand! There are still improvements to be made and features to be added, but when I&#8217;ve reported bugs and feature requests he&#8217;s been quick to respond and release updates.</p>
<p>So while I&#8217;m sure nobody&#8217;s been holding their breath waiting for me to finish the &#8220;admin tool&#8221; portion of my app, I just wanted to clarify the new direction I&#8217;m taking it &#8212; or rather, the fact that I&#8217;m not planning to take it in as many new directions! (Hence the change in title for the project from &#8220;AIR SQL admin tool&#8221; to &#8220;AIR SQL query testing tool.&#8221;)</p>
<p>That doesn&#8217;t mean I&#8217;m done developing this tool by any means. In past jobs where I did heavy database development, and in a project I&#8217;m currently working on that involves heavy database development, I find it very useful to have two different kinds of database tools &#8212; one for creating and managing database objects and structure, and another for testing queries. While Lita does in fact have a tab for testing queries, I personally find Doppler to be a bit (not a lot, but a bit =) more developed in that specific area. On the other hand, Lita certainly does a lot in the db management space that Doppler doesn&#8217;t do. So I find the tools very complementary in terms of my actual development work.</p>
<p>As always, I welcome feedback, questions, thoughts, etc. And thanks to everyone who&#8217;s already reported bugs and offered suggestions!</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2009/01/26/updates-to-doppler-air-sql-query-testing-tool/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>AIR 1.5 encrypted SQLite database &#8212; how to use it, best practices, and new projects</title>
		<link>http://probertson.com/articles/2008/11/18/air-1_5-encrypted-sqlite-database-how-to/</link>
		<comments>http://probertson.com/articles/2008/11/18/air-1_5-encrypted-sqlite-database-how-to/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 08:30:25 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[Life at Adobe]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Writing]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=214</guid>
		<description><![CDATA[Over a year ago I described a potential area of concern for using a SQLite database with an AIR application &#8212; because all apps use the same database engine, any AIR app can read any other app&#8217;s database (as long as it can find the database file).
As you may have heard among all the news [...]]]></description>
			<content:encoded><![CDATA[<p>Over a year ago I described <a href="/articles/2007/06/21/securing-air-sql-database/">a potential area of concern for using a SQLite database with an AIR application</a> &#8212; because all apps use the same database engine, any AIR app can read any other app&#8217;s database (as long as it can find the database file).</p>
<p>As you may have heard among all the news that&#8217;s coming out from MAX right now, <a href="http://www.adobe.com/devnet/logged_in/rchristensen_lpolanco_air_1.5.html">Adobe AIR 1.5 has just been released</a>. Most of the features of AIR 1.5 are features that were introduced with Flash Player 10. However, one new feature in AIR 1.5 that helps address the easy-to-read database issue is AIR 1.5&#8217;s new support for AES encrypted databases.</p>
<p>I&#8217;ve had the interesting and at times complex job of writing the documentation for this new feature. The bulk of the new documentation is in a new section &#8220;<a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS8AFC5E35-DC79-4082-9AD4-DE1A2B41DAAF.html">Using encryption with SQL databases</a>&#8221; in the SQL database chapter of the manual &#8220;Developing Adobe AIR Applications&#8221;.</p>
<p>It&#8217;s pretty straightforward to use an encrypted database. You have to create the database as an encrypted db. To create or open it, you call the SQLConnection class&#8217;s <code>open()</code> or <code>openAsync()</code> methods, just as you normally do, and there&#8217;s a new parameter where you provide a 16-byte ByteArray encryption key for the database. That&#8217;s all there is to it.</p>
<p>The SQLConnection class also has a new <code>reencrypt()</code> method, that you use to change the encryption key of an already encrypted database.</p>
<p>If you want to see some code examples, check out the documentation listed above, or see these quick start articles on the Adobe developer center:</p>
<ul>
<li><a href="http://www.adobe.com/devnet/air/flex/quickstart/encrypted_database.html">Working with the encrypted local SQLite database (Flex)</a></li>
<li><a href="http://www.adobe.com/devnet/air/flash/quickstart/encrypted_database_flash.html">Working with the encrypted local SQLite database (Flash)</a></li>
<li><a href="http://www.stage.adobe.com/devnet/air/ajax/quickstart/encrypted_database.html">Working with the encrypted local SQLite database (HTML/JavaScript)</a></li>
</ul>
<p>There are a couple of parts of the new documentation that I think are particularly interesting (although I&#8217;m obviously biased since I wrote it all):</p>
<ul>
<li><a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS34990ABF-C893-47ec-B813-9C9D9587A398.html">Considerations for using encryption with a database</a> talks about some of the various reasons you may want to use an encrypted database, and some of the differences in how you might architect your application to account for the desired level of security and privacy.</li>
<li>
<p><a href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS61068DCE-9499-4d40-82B8-B71CC35D832C.html">Example: Generating and using an encryption key</a> goes into great depth into one technique for creating an encryption key for your database. You have to provide a ByteArray encryption key to encrypt your database. How you come up with that encryption key can have a big impact on the actual security of your app data.</p>
<p>This was definitely the most involved example I&#8217;ve written for the documentation. the techniques it uses were specified to me by security engineers at Adobe. The documentation goes into lots of detail describing how these techniques are used and why. Both the code and the text went through a series of reviews by engineers and security experts.</p>
<p>I ended up writing the example as a simple UI, plus a class that anyone can just pull into their own app (rather than having to pull apart the example and turn it into something you can use. I&#8217;m also excited to share that <a href="http://mikechambers.com/">Mike Chambers</a> and <a href="http://weblogs.macromedia.com/cantrell/">Christian Cantrell</a> decided that this &#8220;encryption key generator&#8221; class is useful enough that it&#8217;s now included in the <a href="http://code.google.com/p/as3corelib/">open-source ActionScript 3.0 core library (as3corelib) project</a>.</p>
</li>
</ul>
<p>Now that AIR 1.5 is out the door, I&#8217;ve updated my <a href="http://probertson.com/projects/doppler-air-sql-admin-tool/">AIR database admin tool</a> to support encrypted databases (when you try to open an encrypted database it prompts you for an encryption key, which you enter as a Base-64 string). I already mentioned that I wrote the encryption key generator class that&#8217;s now in as3corelib. I&#8217;ve also got at least one more new encrypted database-related open-source project that I&#8217;m about to release&#8230;but I&#8217;ll wait until the MAX &#8220;firehose&#8221; dies down a bit before I write more about that one. =)</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2008/11/18/air-1_5-encrypted-sqlite-database-how-to/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>360&#124;Flex slides for &#8220;AIR SQLite: An optimization conversation&#8221;</title>
		<link>http://probertson.com/articles/2008/08/22/360flex-slides-for-air-sqlite-optimization-conversation/</link>
		<comments>http://probertson.com/articles/2008/08/22/360flex-slides-for-air-sqlite-optimization-conversation/#comments</comments>
		<pubDate>Sat, 23 Aug 2008 00:16:24 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=188</guid>
		<description><![CDATA[Updates (Oct. 30, 2008): The video of my presentation has been posted, so I added a link to it at the bottom of this post. Also, I just learned about another AIR-based SQLite admin tool which looks interesting, so I added it to the list of resources even though it&#8217;s obviously not discussed in the [...]]]></description>
			<content:encoded><![CDATA[<p class="editornote">Updates (Oct. 30, 2008): The video of my presentation has been posted, so I added a link to it at the bottom of this post. Also, I just learned about another AIR-based SQLite admin tool which looks interesting, so I added it to the list of resources even though it&#8217;s obviously not discussed in the presentation.</p>
<p>As I mentioned briefly before, this week I presented at the 360|Flex San Jose (August 2008) conference. My presentation was titled &#8220;Adobe AIR SQLite: An optimization conversation.&#8221; As I mentioned in the presentation, the term &#8220;optimization&#8221; could mean a few different things &#8212; for example, optimization meaning improving performance, or optimization meaning improving developer productivity. While my presentation focused mostly on the first type of optimization, I included suggestions for tools, libraries, and strategies that fall in the &#8220;developer productivity&#8221; type of optimization as well.</p>
<p>Anyway, as always I&#8217;m happy to make my presentation materials available. Here are the slides (with some notes) from my presentation:</p>
<p><a href="/resources/2008/08/22/air_sqlite_optimization_slides.zip">&#8220;Adobe AIR SQLite: An optimization conversation&#8221; slides</a> (PDF in .zip - 504kb)</p>
<p>I don&#8217;t really have any specific code examples, apart from what&#8217;s in the slides, so there&#8217;s no &#8220;source code&#8221; download. However, I did link to a lot of external tools and resources (including a few of my own). To save you the trouble of digging into the PDF, here are the links:</p>
<p>Tools</p>
<ul>
<li><a href="http://coenraets.org/blog/2008/02/air-based-sqlite-admin-updated-for-beta-3/">Cristophe Coenraets&#8217; &#8220;SQLite Admin&#8221;</a></li>
<li><a href="/projects/doppler-air-sql-admin-tool/">My tool for testing queries</a></li>
<li><a href="http://www.dehats.com/drupal/?q=node/59">&#8220;Lita&#8221; by David Deraedt</a> (I learned about this one after the presentation, so it&#8217;s not discussed in my slides/video, but I thought it&#8217;d be worth mentioning anyway.)</li>
</ul>
<p>Application architecture/patterns/libraries</p>
<ul>
<li><a href="http://www.peterelst.com/blog/2008/04/07/introduction-to-sqlite-in-adobe-air/">SQLite MXML wrapper classes</a> (Peter Elst)</li>
<li><a href="http://www.brandonellis.org/?p=49">Data access layer</a> (Brandon Ellis)</li>
<li><a href="http://code.google.com/p/asqlib/">asqlib SQL statement generator</a> (Miran Loncaric)</li>
<li>&#8220;Command&#8221; classes (me) as <a href="/projects/addressbook/">demonstrated by my AddressBook sample application</a></li>
<li><a href="http://code.google.com/p/air-activerecord/">AIR ActiveRecord source</a> and <a href="http://jacwright.com/blog/79/air-activerecord-is-open-source/">blog post explaining its usage</a> (Jacob Wright)</li>
<li><a href="http://www.ericfeminella.com/blog/2008/06/22/air-cairngorm-20/">AIR SQLite Cairngorm services</a> (Eric Feminella)</li>
<li>Connection and statement pools, mentioned (with source code) in the article <a href="http://www.adobe.com/devnet/air/flex/articles/air_sql_operations.html">User experience considerations with SQLite operations</a> (Daniel Rinehart)</li>
</ul>
<p>Finally, as you may have heard, Adobe sponsored the recording of every presentation at 360|Flex, and they&#8217;re all going to be made available free of charge via a channel in Adobe Media Player. They&#8217;re rolling them out in phases, <span class="cut">and mine isn&#8217;t available yet. When it is, I&#8217;ll update this post with the video as well.</span> Update: the video is <a href="http://onflash.org/ted/2008/10/360flex-sj-2008-air-sqlite-optimization.php">now available on Ted Patrick&#8217;s blog</a> as well as in Adobe Media Player.</p>
<p>In the mean time, 360|Flex was full of awesome presentations. I wasn&#8217;t able to get to all the ones I wanted to see, due to conflicts and me trying to finish up preparation for my presentation. So I&#8217;m going to be spending some time watching many of those videos as well. If you&#8217;d like to see the videos, Ted Patrick has posted instructions on his blog:</p>
<p><a href="http://www.onflex.org/ted/2008/08/360flex-sessions-media-rss-feed.php">How to view 360|Flex San Jose 8/08 session videos in Adobe Media Player</a></p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2008/08/22/360flex-slides-for-air-sqlite-optimization-conversation/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Peter Elst on AIR local SQL databases</title>
		<link>http://probertson.com/articles/2008/04/07/peter-elst-on-air-local-sql-databases/</link>
		<comments>http://probertson.com/articles/2008/04/07/peter-elst-on-air-local-sql-databases/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 21:52:23 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Articles to remember]]></category>
		<category><![CDATA[Elsewhere on the web]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/?p=166</guid>
		<description><![CDATA[Peter Elst, an excellent Flex/Flash developer and speaker, just finished touring as part of the on AIR Europe tour. He&#8217;s posted his slides and sample applications from his presentation, &#8220;Introduction to SQLite in Adobe AIR&#8221;. Looks like it was a great presentation, and even without hearing him he&#8217;s got some nice samples to dig through.
(via [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.peterelst.com/">Peter Elst</a>, an excellent Flex/Flash developer and speaker, just finished touring as part of the <a href="http://onair.adobe.com/">on AIR Europe tour</a>. He&#8217;s posted his slides and sample applications from his presentation, &#8220;<a href="http://www.peterelst.com/blog/2008/04/07/introduction-to-sqlite-in-adobe-air/">Introduction to SQLite in Adobe AIR</a>&#8221;. Looks like it was a great presentation, and even without hearing him he&#8217;s got some nice samples to dig through.</p>
<p>(via Twitter from Peter himself)</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2008/04/07/peter-elst-on-air-local-sql-databases/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adobe AIR 1.0 ships! SQL changes, and other thoughts</title>
		<link>http://probertson.com/articles/2008/03/24/air-1_0-final-sql-changes-and-thoughts/</link>
		<comments>http://probertson.com/articles/2008/03/24/air-1_0-final-sql-changes-and-thoughts/#comments</comments>
		<pubDate>Mon, 24 Mar 2008 21:04:26 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Opinions]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/articles/2008/03/24/air-1_0-final-sql-changes-and-thoughts/</guid>
		<description><![CDATA[Now that Adobe AIR 1.0 is in the wild, I wanted to post an update about changes that happened with the local SQL database functionality between beta 3 and the final release. Plus, I&#8217;ve had some general thoughts about the release of the software that I thought I&#8217;d share.
For some reason, the final time that [...]]]></description>
			<content:encoded><![CDATA[<p>Now that Adobe AIR 1.0 is in the wild, I wanted to post an update about changes that happened with the local SQL database functionality between beta 3 and the final release. Plus, I&#8217;ve had some general thoughts about the release of the software that I thought I&#8217;d share.</p>
<p class="editornote">For some reason, the final time that I saved this post before publishing it, my changes didn&#8217;t get saved. So if you saw this soon after it was posted, and wondered why it didn&#8217;t really talk about SQL changes, and why it had some messed up headings&#8230;that&#8217;s why. Sadly I&#8217;m sure I can&#8217;t recreate the text as well as I wrote it the first time. But here&#8217;s my best effort&#8230;</p>
<p>First of all, allow me to clear something up. I am aware that Adobe AIR 1.0 shipped almost exactly a month ago, so this shouldn&#8217;t be news to anyone who&#8217;s actually interested in it. I intentionally held off on publishing my thoughts (and a description of changes since beta 3). As a rule, I never post anything in the week or so following a big product announcement &#8212; there are so many &#8220;me too&#8221; posts about the product, and so little actual different thoughts or original ideas, that I don&#8217;t want to clog up the aggregaters by adding to the hubbub (the &#8220;MXNA firehose&#8221; as I&#8217;ve heard <a href="http://weblogs.macromedia.com/jd/">JD</a> describe it).</p>
<p>That&#8217;s not a complete excuse, of course. The truth is also that I&#8217;ve just gotten busy with a lot of post-launch cleanup activities, and of course moving ahead on future projects (Flash Player 10 and AIR 2.0), so I&#8217;ve neglected this post for longer than it deserved.</p>
<p>And now, lest I postpone it any longer, here are a few bits of news and opinion from my corner of the Flex/AIR world:</p>
<ul>
<li><a href="#sql_changes">Local SQL database changes</a></li>
<li><a href="#release">What does &#8220;finished&#8221; really mean?</a></li>
<li><a href="#flex3_source">Go right to the source</a></li>
</ul>
<h2 id="sql_changes">Local SQL database feature changes</h2>
<p>Wait a minute &#8212; didn&#8217;t I say a couple of months ago that as of beta 3 AIR is API frozen? Indeed that was the intention, and with one small exception it&#8217;s true. And that was the first thing that came to my mind when I read the notification (shortly after beta 3 was locked down) that some changes to the SQL functionality had been checked in to source control. But I was correct before &#8212; the API hasn&#8217;t changed &#8212; just one particular behavior has.</p>
<p>The specific change is with how the runtime treats column data types in database tables. In betas 1-3, AIR was consistent with the <a href="http://sqlite.org/datatype3.html#affinity">&#8220;default&#8221; SQLite behavior</a>:</p>
<blockquote>
<p>the type of a value is associated with the value itself, not with the column or variable in which the value is stored&#8230;. All other SQL databases engines that we are aware of use the more restrictive system of static typing where the type is associated with the container, not the value.</p>
<p>In order to maximize compatibility between SQLite and other database engines, SQLite support [<em>sic</em>] the concept of &#8220;type affinity&#8221; on columns. The type affinity of a column is the recommended type for data stored in that column. The key here is that the type is recommended, not required. Any column can still store any type of data, in theory. It is just that some columns, given the choice, will prefer to use one storage class over another. The preferred storage class for a column is called its &#8220;affinity&#8221;.</p>
</blockquote>
<p>So under the &#8220;affinity&#8221; system, if in your <code>CREATE TABLE</code> statement you specify that a column stores INTEGER data, and you write an <code>INSERT</code> statement that stores a String instance in that column, the runtime allows it. (I initially wrote &#8220;it works just fine&#8221; but that may not be true &#8212; since your application may be assuming that values retrieved from that column are always integers.) When I first read about this behavior when we were reviewing the spec for the feature, I recognized that it was different than what I&#8217;d done before, but I figured it was okay &#8212; I&#8217;d just have to be extra careful when inserting values into the database, and enforce the data types myself by convention even if the runtime didn&#8217;t enforce them in practice.</p>
<p>However, the feedback we got from developers was that this doesn&#8217;t really match what they&#8217;re used to from typical web app database code (which likely uses databases such as Oracle, SQL Server, or MySQL). As a result, in the final release, the declared data types of database columns are more strictly enforced. If you declare a data type for a column, then attempt to store a value that isn&#8217;t an instance of that type, the database will try to convert the value to the appropriate type (for example, turning a number into a string, or parsing a string to see if its text is actually a number). If the value can be converted, then the converted value is stored; otherwise, the runtime throws an error. (For more details, see <a href="http://livedocs.adobe.com/flex/3/langref/localDatabaseSQLSupport.html#columnAffinity">the column affinity description in the documentation</a>.)</p>
<p>Personally I&#8217;m pretty happy with this solution. It&#8217;s still a bit more flexible than the databases I mentioned before &#8212; usually they won&#8217;t even try to convert a value, and will just choke if the data type doesn&#8217;t match. But I think that the way it works in AIR 1.0 is consistent philosophically (and actually) with <a href="/articles/2005/11/08/actionscript-3-unit-testing-recommended/">the way data types work in ActionScript 3.0</a> where values can be strongly typed or weakly typed at compile time, but either way at runtime the type must match.</p>
<p>So, what do you do if you were one of the people with more SQLite experience than other db experience, of who otherwise preferred the old behavior? Well, there is still a workaround. If you don&#8217;t declare any data type for your columns, you can store data of any type without causing errors. This isn&#8217;t the same as the previous behavior, but based on some anecdotal observations I&#8217;d guess that developers who intentionally mix data types in columns are less likely to declare a column data type, in any case.</p>
<p>Also, as a side note, I decided to keep the term &#8220;column affinity&#8221; in the documentation even though the behavior changed. I did this for a couple of reasons: 1) Developers who&#8217;d been reading the docs were probably familiar with the term now, and 2) the data types still aren&#8217;t strictly enforced, in the sense that the runtime attempts to convert values before storing them (just as a default SQLite implementation does). For example, just about anything can be stored in a TEXT column without an error occurring. So in that sense, the data type specified in a <code>CREATE TABLE</code> statement is still somewhat of an &#8220;affinity&#8221; rather than a traditional strictly enforced data type.</p>
<h2 id="release">What does &#8220;finished&#8221; really mean?</h2>
<p>Not too many years ago, my definition of a &#8220;release version&#8221; of software was different than it is now. I knew that any software, no matter how much it is tested, is bound to have <em>some</em> bugs in it &#8212; it&#8217;s just not possible to ship software of any notable size without making a mistake somewhere. However, I had enough faith in big software companies that I assumed that when a company declares a product to be a &#8220;release&#8221; or &#8220;shipping&#8221; version, that it at least doesn&#8217;t have any bugs <em>that they know of</em>.</p>
<p>I&#8217;m not sure when I realized that this view is far from reality. I suppose it was probably with the first private beta I was involved with, though maybe it was before that.</p>
<p>In any case, I hope I&#8217;m not shocking anyone&#8217;s sensibilities when I point out the reality, that even though Flex 3 and AIR 1.0 have shipped, they do have bugs &#8212; and <em>Adobe even knows it</em>! The recent openness of Flex, in particular the introduction of the <a href="http://bugs.adobe.com/flex/">public Flex bugbase</a>, makes this reality much more transparent. A quick search on the Flex SDK project, looking only at bugs (as opposed to feature requests), shows 309 &#8220;open&#8221;, &#8220;in progress&#8221;, &#8220;community&#8221;, or &#8220;new&#8221; issues. And that&#8217;s not even taking into account &#8220;deferred&#8221; bugs, such as <a href="https://bugs.adobe.com/jira/browse/SDK-14339">SDK-14339 &#8220;WindowedApplication doesn&#8217;t update/show menu when it changes during runtime&#8221;</a>.</p>
<p>While Adobe AIR doesn&#8217;t have a public bugbase, that doesn&#8217;t mean it&#8217;s any more free of bugs. Try calling the <code>NativeMenu.display()</code> method on a PowerPC Mac running OS X 10.4 and you&#8217;ll see what I mean (hint: the menu appears at the mouse cursor rather than at the specified coordinates).</p>
<p>So what does &#8220;release quality&#8221; software really mean? Well, it means that it doesn&#8217;t have any bugs that are &#8220;showstopper&#8221; issues, or that are &#8220;really bad.&#8221; Yes, I&#8217;m intentionally using non-specific terms here. The reality of life is that if Adobe (or any software company) waited to release software until all known bugs are fixed, the software would never get released. So instead, they use a process that&#8217;s sort of like this (I&#8217;m generalizing and also stating this based on my own observations, not on any review of actual process or guidelines within Adobe):</p>
<ol>
<li>The decision makers figure out a date by which the software should be done. (I&#8217;m not talking about at the beginning of a product cycle &#8212; I&#8217;m starting somewhere in the middle.)</li>
<li>Throughout the process, bugs are reported. Any time a bug is reported, it is investigated and a decision is made as to whether resources can/should be allocated to fixing it. The criteria for this decision are generally based on how severe the bug is (whether it crashes the software/computer, causes data loss, is a usability issue, etc); how hard it is to fix; how much time it will take to fix; how likely it is that someone will run into the bug; whether or not there&#8217;s a workaround; etc.</li>
<li>As the product moves closer to the release date, the threshold for whether a bug will be fixed goes up &#8212; the closer the software is to the release date, the more severe and less difficult to fix a bug must be in order for it to get fixed.</li>
</ol>
<p>This can be frustrating for people who file bugs, like me. Often, due to workload and general stability issues, it&#8217;s not practical for me to start writing the documentation for a feature until it&#8217;s fairly stable and close to finished. But that means that when I do find bugs, there&#8217;s a good chance it&#8217;s too late in the process for the bug to get fixed in time for the product release.</p>
<p>Ah, tradeoffs.</p>
<h2 id="flex3_source">Go right to the source</h2>
<p>Now that Flex 3 has shipped, the <a href="http://opensource.adobe.com/wiki/display/flexsdk/Get+Source+Code">Flex 3 source code</a> is available in the Flex Subversion (SVN) repository. I&#8217;ve actually been accessing it there for a while &#8212; internally we made the switch from Perforce to Subversion around the first of the year. I was pretty worried at the time, because I had never used SVN before. The majority of the Flex 3 work was already done at that point &#8212; they were just in final bug fixing mode. We still had about a week before our content had to be locked down, so I was working furiously to try and finish up some work I was doing on the Flex AIR components. I wasn&#8217;t too excited about the prospect of switching source control systems in the middle of that crunch. Fortunately, SVN turned out to be pretty straightforward. (In case you&#8217;re wondering, I use <a href="http://tortoisesvn.net/">TortoiseSVN</a>). It&#8217;s actually been good for me to learn SVN at work &#8212; it made it easier for me to move some of my code projects over to Google Code (a few that are already there, and a few more that I&#8217;ve started but not posted on <a href="/projects/">my projects page</a> yet). So overall I give SVN thumbs up, and I&#8217;m happy that the Flex source code is available that way.</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2008/03/24/air-1_0-final-sql-changes-and-thoughts/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>AIR beta 3 and local SQL database changes</title>
		<link>http://probertson.com/articles/2007/12/18/air-beta-3-and-local-sql-database-changes/</link>
		<comments>http://probertson.com/articles/2007/12/18/air-beta-3-and-local-sql-database-changes/#comments</comments>
		<pubDate>Tue, 18 Dec 2007 19:55:51 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Opinions]]></category>
		<category><![CDATA[Writing]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/articles/2007/12/18/air-beta-3-and-local-sql-database-changes/</guid>
		<description><![CDATA[Note: Sorry for the delay on this article. I composed this article a couple of weeks ago, and then I got busy with work and holidays and I forgot and didn&#8217;t publish it until now =(
If you&#8217;ve been following my posts on AIR and the SQL database functionality, you may have noticed a trend: every [...]]]></description>
			<content:encoded><![CDATA[<p class="editornote">Note: Sorry for the delay on this article. I composed this article a couple of weeks ago, and then I got busy with work and holidays and I forgot and didn&#8217;t publish it until now =(</p>
<p>If you&#8217;ve been following my posts on AIR and the SQL database functionality, you may have noticed a trend: every time there&#8217;s a new beta, I tend to go silent for a few weeks beforehand as I try to get things finished up with the documentation. Well, here we went again &#8212; another period of silence, another AIR beta.</p>
<p>The marketing team kept things pretty low-key with announcing this new beta, especially compared to previous rounds. I&#8217;m not sure of all the reasons for that, but there are a few that are important and helpful for you to know if you&#8217;re developing AIR applications:</p>
<ul>
<li>AIR is now API-frozen &#8212; as of this beta, there <strong>shouldn&#8217;t</strong> be any changes to the AIR apis. In fact, the goal was to have as few API changes as possible between AIR beta 2 and AIR beta 3, as things get closer to being locked down. Naturally, if we find a big security issue that requires us to change an API, we&#8217;re going to consider it &#8212; but aside from that, things are now the way they will be for AIR 1.0 (phew &#8212; it&#8217;s been tiring for me to update apps every beta, and I&#8217;m sure it has been for you, too).</li>
<li>Along with the new AIR beta, Adobe also released a beta of a new product code-named &#8220;<a href="http://labs.adobe.com/technologies/blazeds/">BlazeDS</a>&#8221;. This very cool offering is a free, open-source, slimmed down LiveCycle Data Services &#8212; basically it includes the RPC Components (&#8220;Flash Remoting&#8221;) functionality as well as the Messaging functionality. In addition, we&#8217;re releasing an official specification for the AMF format. While the format was (for the most part) reverse-engineered long ago, I think it&#8217;s great to have something official for all the other open-source offerings like <a href="http://www.amf-php.org/">AMFPHP</a>, <a href="http://www.fluorinefx.com/">Fluorine</a>, etc. to work from.</li>
<li>Along with beta 3, Adobe created the &#8220;<a href="http://www.adobe.com/go/marketplace">Adobe AIR Marketplace</a>&#8221; where developers can post apps for people to download and try out &#8212; basically an extension of the
<li><a href="http://labs.adobe.com/technologies/flex/flexbuilder3/">Flex 3 beta 3 is officially the last Flex 3 beta before Flex 3/AIR 1.0</a> (second paragraph, also in the <a href="http://labs.adobe.com/technologies/flex/faq.pdf">FAQ PDF</a>). &#8216;nuff said =)</li>
</ul>
<p>Of course, following the trend of my going silent before each beta, you can expect that to be magnified as we continue leading up to AIR 1.0. There have been a few things each beta that I wanted to do but had to put off until later &#8212; but of course, this time there isn&#8217;t any &#8220;until later&#8221; &#8212; so it&#8217;s now or never!</p>
<p>Talking specifically about the local SQL database functionality, there were only a few changes this beta, but they&#8217;re pretty significant and maybe even a bit sneaky so you&#8217;ll want to pay attention to them:</p>
<ul>
<li>
<p>Specifying synchronous and asynchronous execution: Synchronous database execution was added to SQLConnection in beta 2. At that point, to specify that a SQLConnection&#8217;s operations were synchronous rather than asynchronous, you had to specify a <code>true</code> parameter in the <code><a href="http://livedocs.adobe.com/labs/flex3/langref/flash/data/SQLConnection.html#SQLConnection()">SQLConnection()</a></code> constructor. Now, however, the <code>SQLConnection()</code> constructor doesn&#8217;t accept any parameters. Instead, you specify the execution mode when you open the connection to the main database. To specify that you want to use synchronous execution, you call the <code><a href="http://livedocs.adobe.com/labs/flex3/langref/flash/data/SQLConnection.html#open()">SQLConnection.open()</a></code> method; to specify async execution, you call the new <code><a href="http://livedocs.adobe.com/labs/flex3/langref/flash/data/SQLConnection.html#openAsync()">SQLConnection.openAsync()</a></code> method.</p>
<p>The most important thing to note surrounding this change is this: <em>if you&#8217;re migrating an app from beta 2 to beta 3, you may be changing the behavior of your app without even realizing it!</em> If you want a connection to be synchronous, you&#8217;ll know you have to change things because the code won&#8217;t compile (<code>SQLConnection()</code> no longer accepts a parameter). However, if you <em>want</em> you connection to be asynchronous, then if you don&#8217;t change anything the code will still work but it will actually use synchronous rather than asynchronous execution. If you have a long-running query and it&#8217;s freezing the UI now, that&#8217;s probably the reason &#8212; the exact code you used previously to specify asynchronous execution (no <code>SQLConnection()</code> parameter, and <code>open()</code> to connect the db) now is the way to specify <em>synchronous</em> execution. If your code doesn&#8217;t cause any errors, you might not even notice immediately because the SQLConnection and SQLStatement events are still triggered even in synchronous execution &#8212; so your &#8220;success&#8221; event listeners will still get called (but error listeners won&#8217;t &#8212; the operations will throw exceptions instead).</p>
</li>
<li>There were a couple of changes to the SQLError class and related classes: The <code>SQLError.code</code> property was removed (because it already inherited <code>errorID</code> from Error) and the <code>details</code> property was added, providing a more detailed error message in certain cases. Along with this, the SQLErrorCode class was removed entirely (tragically &#8212; I spent a fair amount of time hammering out those error descriptions with Jason, the engineer for the feature).</li>
</ul>
<p>I think that&#8217;s it, but please let me know if I&#8217;ve forgotten another change!</p>
<p>In the mean time, In addition to the SQL database stuff I&#8217;ve been doing more with another part of AIR that I&#8217;ve previously been working on as I&#8217;ve had time &#8212; the AIR-related Flex components. This release includes a new one, the FlexNativeMenu component, which is pretty slick. Watch for more on this in the (hopefully near) future!</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2007/12/18/air-beta-3-and-local-sql-database-changes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AIR embedded SQL database: What&#8217;s new in beta 2</title>
		<link>http://probertson.com/articles/2007/10/09/air-sql-database-what-s-new-in-beta-2/</link>
		<comments>http://probertson.com/articles/2007/10/09/air-sql-database-what-s-new-in-beta-2/#comments</comments>
		<pubDate>Tue, 09 Oct 2007 23:41:55 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Articles by Paul]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/articles/2007/10/09/air-sql-database-what-s-new-in-beta-2/</guid>
		<description><![CDATA[Now that the roar of MAX is over, and since AIR public beta 2 is now available on Adobe Labs, I thought I&#8217;d highlight what&#8217;s new in beta 2 specifically around the embedded SQL database in AIR:

Synchronous database operations
Schema API (database instrospection)
Additional data types
Other new documentation
Bug fixes

Synchronous database operations
From the various public and internal feedback [...]]]></description>
			<content:encoded><![CDATA[<p>Now that the roar of MAX is over, and since <a href="http://labs.adobe.com/technologies/air/">AIR public beta 2</a> is now available on Adobe Labs, I thought I&#8217;d highlight what&#8217;s new in beta 2 specifically around the embedded SQL database in AIR:</p>
<ul>
<li><a href="#sync">Synchronous database operations</a></li>
<li><a href="#schema">Schema API (database instrospection)</a></li>
<li><a href="#types">Additional data types</a></li>
<li><a href="#docs">Other new documentation</a></li>
<li><a href="#bugs">Bug fixes</a></li>
</ul>
<h2 id="sync">Synchronous database operations</h2>
<p>From the various public and internal feedback forums I&#8217;ve seen (discussion lists, mailing lists, etc.) this is definitely the most-requested feature from beta 1 (at least related to the embedded database). It&#8217;s in there now &#8212; when you instantiate a SQLConnection object, just add <code>true</code> as a constructor argument and all the operations (including SQL statements) that are executed through that SQLConnection will run synchronously.</p>
<p>The good news is it&#8217;s really very similar to the way things worked in beta 1, so if you&#8217;ve already been doing things asynchronously you won&#8217;t have to do much to get going with synchronous db operations. Note that a lot of people have referred to this as a &#8220;synchronous API&#8221; but in fact there isn&#8217;t a separate synchronous API &#8212; it&#8217;s the same API, with the exception of the single <code>SQLConnection()</code> argument.</p>
<p>To learn more, here&#8217;s the place where you should probably start: Developing AIR Applications > Working with files and data > Working with local SQL databases > Using synchronous and asynchronous database operations (<a href="http://livedocs.adobe.com/labs/air/1/devappsflex/SQL_23.html#1096192">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/devappshtml/SQL_23.html#1096192">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/devappsflash/SQL_23.html#1096192">Flash</a>)</p>
<h2 id="schema">Schema API (database instrospection)</h2>
<p>One limitation that developers pointed out in beta 1 was that there wasn&#8217;t any built-in way to get information about the structure of a database, tables, etc. In beta 2, there&#8217;s a new set of classes that can be used to get at that information. There isn&#8217;t any information in the developers guide about this yet, but in this case you can figure it out by looking in the API reference. The best place to start is probably with the <code>SQLConnection.loadSchema()</code> method (<a href="http://livedocs.adobe.com/labs/flex3/langref/flash/data/SQLConnection.html#loadSchema()">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/jslr/flash/data/SQLConnection.html#loadSchema()">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/aslr/flash/data/SQLConnection.html#loadSchema()">Flash</a>).</p>
<p>There are also several new classes that are used for the various types of schema information you can get:</p>
<ul>
<li>SQLTableSchema (<a href="http://livedocs.adobe.com/labs/flex3/langref/flash/data/SQLTableSchema.html">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/jslr/flash/data/SQLTableSchema.html">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/aslr/flash/data/SQLTableSchema.html">Flash</a>)</li>
<li>SQLViewSchema (<a href="http://livedocs.adobe.com/labs/flex3/langref/flash/data/SQLViewSchema.html">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/jslr/flash/data/SQLViewSchema.html">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/aslr/flash/data/SQLViewSchema.html">Flash</a>)</li>
<li>SQLIndexSchema (<a href="http://livedocs.adobe.com/labs/flex3/langref/flash/data/SQLIndexSchema.html">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/jslr/flash/data/SQLIndexSchema.html">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/aslr/flash/data/SQLIndexSchema.html">Flash</a>)</li>
<li>SQLTriggerSchema (<a href="http://livedocs.adobe.com/labs/flex3/langref/flash/data/SQLTriggerSchema.html">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/jslr/flash/data/SQLTriggerSchema.html">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/aslr/flash/data/SQLTriggerSchema.html">Flash</a>)</li>
<li>SQLColumnSchema (<a href="http://livedocs.adobe.com/labs/flex3/langref/flash/data/SQLColumnSchema.html">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/jslr/flash/data/SQLColumnSchema.html">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/aslr/flash/data/SQLColumnSchema.html">Flash</a>)</li>
</ul>
<h2 id="types">Additional data types</h2>
<p>Several ActionScript/JavaScript data types can now be used as column data types in the <code>CREATE TABLE</code> statements. When you specify one of these data types for your column, you can pass an instance of that type into an SQL statement (using a parameter) and it will property store and retrieve the data as the ActionScript/JavaScript data type. The new supported data types are:</p>
<ul>
<li>Boolean</li>
<li>Date</li>
<li>XML</li>
</ul>
<p>More information about these data types can be found in the developers guide section &#8220;Working with database data types&#8221; (<a href="http://livedocs.adobe.com/labs/air/1/devappsflex/SQL_19.html#1095961">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/devappshtml/SQL_19.html#1095961">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/devappsflash/SQL_19.html#1095961">Flash</a>) and in the language reference appendix &#8220;SQL support in local databases&#8221; (specifically the &#8220;<a href="http://livedocs.adobe.com/labs/flex3/langref/localDatabaseSQLSupport.html#dataTypes">data type support</a>&#8221; section). (Note that the link goes to the Flex language reference. I couldn&#8217;t find that appendix in the Flash or HTML/JS versions, although the content is identical for all of them since it&#8217;s really just talking about SQL.)</p>
<h2 id="docs">Other new documentation</h2>
<p>Although I did take several weeks between beta 1 and beta 2 to move from Indiana to the San Francisco bay area, I did get some additional documentation written. If I remember right, these are the sections that are new for beta 2 (other than the ones I&#8217;ve already mentioned above):</p>
<ul>
<li>Using parameters in statements (<a href="http://livedocs.adobe.com/labs/air/1/devappsflex/SQL_10.html">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/devappshtml/SQL_10.html">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/devappsflash/SQL_10.html">Flash</a>)</li>
<li>Strategies for working with SQL databases (<a href="http://livedocs.adobe.com/labs/air/1/devappsflex/SQL_26.html#1084956">Flex</a> | <a href="http://livedocs.adobe.com/labs/air/1/devappshtml/SQL_26.html#1084956">HTML/JavaScript</a> | <a href="http://livedocs.adobe.com/labs/air/1/devappsflash/SQL_26.html#1084956">Flash</a>) - new sections on improving performance and best practices</li>
<li>&#8230; and more! (improvements and corrections in various other sections)</li>
</ul>
<h2 id="bugs">Bug fixes</h2>
<p>Need I say more? =)</p>
<p>(In seriousness, lots of bugs were fixed, so if there&#8217;s an issue you were running into, try it out in beta 2 and <a href="http://www.adobe.com/go/wish/">let us know</a> if it&#8217;s still not working.)</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2007/10/09/air-sql-database-what-s-new-in-beta-2/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Asynchronous database operations with AIR, SQL, and JavaScript</title>
		<link>http://probertson.com/articles/2007/08/10/asynch-db-queries-air-javascript/</link>
		<comments>http://probertson.com/articles/2007/08/10/asynch-db-queries-air-javascript/#comments</comments>
		<pubDate>Fri, 10 Aug 2007 17:13:58 +0000</pubDate>
		<dc:creator>Paul Robertson</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Articles to remember]]></category>
		<category><![CDATA[Elsewhere on the web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[local SQL database]]></category>

		<guid isPermaLink="false">http://probertson.com/articles/2007/08/10/asynch-db-queries-air-javascript/</guid>
		<description><![CDATA[Justin (&#8220;AlternateIdea&#8221;) has a nice, fairly technical write up of dealing with asynchronous operations when you&#8217;re using the AIR SQL database with JavaScript.
I admit, my JavaScript is much rustier than my ActionScript/Flex, so I&#8217;m glad to see these sorts of things &#8212; it helps me to see what patterns and approaches work for the larger-than-you-might-imagine [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://alternateidea.com/">Justin (&#8220;AlternateIdea&#8221;)</a> has <a href="http://alternateidea.com/blog/articles/2007/8/7/asynchronous-sqlite-adobe-air">a nice, fairly technical write up of dealing with asynchronous operations when you&#8217;re using the AIR SQL database with JavaScript</a>.</p>
<p>I admit, my JavaScript is much rustier than my ActionScript/Flex, so I&#8217;m glad to see these sorts of things &#8212; it helps me to see what patterns and approaches work for the larger-than-you-might-imagine JavaScript AIR developer audience.</p>
<p class="editornote">Update: added links, so that you can actually find the article (Doh!)</p>
]]></content:encoded>
			<wfw:commentRss>http://probertson.com/articles/2007/08/10/asynch-db-queries-air-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
